geopandas / geopandas

Python tools for geographic data
http://geopandas.org/
BSD 3-Clause "New" or "Revised" License
4.51k stars 935 forks source link

Reprojection from two identical Coordinate Reference Systems providing different results #923

Open RiccardoDC opened 5 years ago

RiccardoDC commented 5 years ago

Hello, When I run Code1 I get a reprojection that is slightly shifted (Output1). When I run Code 2 the reprojection is correct (Output2). I am curious to know why; I changed the input of the to_crs function from manhole.crs to sewer.crs. However, they have the same crs; in fact, they are perfectly aligned in both cases. It gets even worse if I try to reproject the sewer and the manhole using the crs of the buildings. Could you please help? Thank you very much, Riccardo

Code1: import geopandas as gpd

import files from openstreetmap

bld = gpd.read_file("buildings.shp") # buildings

import from dxf conversion

sewer= gpd.read_file("prova-line.shp") # sewer

import from R with CRS

manhole = gpd.read_file("junctions.shp") # manholes

shows coordinates system

print(bld.crs) print(sewer.crs) print(manhole.crs)

reprojection

bld = bld.to_crs(sewer.crs)

bld = bld.to_crs(manhole.crs)

creates centroids for buildings

bld['centroid_column'] = bld.centroid bld_centroid = bld.set_geometry('centroid_column')

figures

sewer_plot = sewer.plot(markersize = 4, figsize=(15,15), color = "black"); manhole.plot(ax=sewer_plot, markersize = 10, figsize=(15,15), color = "red"); bld.plot(ax=sewer_plot, markersize = 4, figsize=(15,15), color = "grey");

Output 1: {'init': 'epsg:4326'} {'init': 'epsg:21781'} {'proj': 'somerc', 'lat_0': 46.95240555555556, 'lon_0': 7.439583333333333, 'k_0': 1, 'x_0': 600000, 'y_0': 200000, 'ellps': 'bessel', 'units': 'm', 'no_defs': True} image

Code 2:

reprojection

bld = bld.to_crs(sewer.crs)

bld = bld.to_crs(manhole.crs)

Output 2: {'init': 'epsg:4326'} {'init': 'epsg:21781'} {'proj': 'somerc', 'lat_0': 46.95240555555556, 'lon_0': 7.439583333333333, 'k_0': 1, 'x_0': 600000, 'y_0': 200000, 'ellps': 'bessel', 'units': 'm', 'no_defs': True} image

phildias commented 5 years ago

Is it possible to provide access to the buildings.shp, prova-line.shp and junctions.shp files?

RiccardoDC commented 5 years ago

Thank you for answering. Sure! I attached the files. files.zip

ljwolf commented 5 years ago

Reading the .prj files of the three you've sent and also in the output you state above, none are actually precisely the same projection... What's the intended projection for each?

RiccardoDC commented 5 years ago

Hello, thanks for answering. Each files comes from a diffrent source. bld from openstreetmap, sewer from a dxt file and converted it as a shp file and, manhole from an inp file and converted with the inp_to_files function in R. The crs of the file sewer and manhole are the same, in fact they are always aligned in both cases. What I don't understand is why geopandas reprojects the bld correctly if uses the sewer projection while, incorrectly if it uses the manhole projection. I found this post (https://gis.stackexchange.com/questions/297528/wrong-reprojecting-of-a-shapefile-with-to-crs-in-geopandas) where they had the same curiosity but with no clear answer.

ljwolf commented 5 years ago

The files for sewer and manhole are close and have the same meaning, but they're indeed not identical files:

junctions.prj

PROJCS["Hotine_Oblique_Mercator_Azimuth_Center",
    GEOGCS["GCS_Bessel 1841",
        DATUM["D_unknown",
            SPHEROID["bessel",6377397.155,299.1528128]
        ],
        PRIMEM["Greenwich",0],
        UNIT["Degree",0.017453292519943295]
    ],
    PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],
    PARAMETER["latitude_of_center",46.95240555555556],
    PARAMETER["longitude_of_center",7.439583333333333],
    PARAMETER["azimuth",90],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",600000],
    PARAMETER["false_northing",200000],
    UNIT["Meter",1]
]

prova-line.prj

PROJCS["CH1903_LV03",
    GEOGCS["GCS_CH1903",
        DATUM["D_CH1903",
            SPHEROID["Bessel_1841",6377397.155,299.1528128]
        ],
        PRIMEM["Greenwich",0],
        UNIT["Degree",0.017453292519943295]
    ],
    PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],
    PARAMETER["latitude_of_center",46.95240555555556],
    PARAMETER["longitude_of_center",7.439583333333333],
    PARAMETER["azimuth",90],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",600000],
    PARAMETER["false_northing",200000],
    UNIT["Meter",1]
]

buildings.prj

GEOGCS["GCS_WGS_1984",
    DATUM["D_WGS_1984",
        SPHEROID["WGS_1984",6378137,298.257223563]
    ],
    PRIMEM["Greenwich",0],
    UNIT["Degree",0.017453292519943295]
]

This looks like it bears similarity with the question you link on stackexchange because of the datum differences, although those look superficial... will need to dig.

RiccardoDC commented 5 years ago

Thank you very much! It is more clear to me now:) Thanks a lot.

jorisvandenbossche commented 5 years ago

@RiccardoDC @ljwolf this can be closed? (didn't fully follow the issue)

ljwolf commented 5 years ago

I'd leave open because it's:

snowman2 commented 5 years ago

I believe this issue is due to the loss of projection information when converting from the WKT form of the projection to a PROJ string. See: https://proj4.org/faq.html#what-is-the-best-format-for-describing-coordinate-reference-systems

snowman2 commented 5 years ago

I tried it out with #998, and it definitely appears that you have 3 different projection systems: image image

snowman2 commented 5 years ago

But, all the same, I get the same results as presented in this issue, even using the WKT strings. So, that is not the issue.

snowman2 commented 5 years ago

I also attempted:

bld_man = bld.to_crs(manhole.crs)
sewer_man = sewer.to_crs(manhole.crs)

But, the sewer lined up properly with the manholes even in this case. So, I am not convinced that it is an issue with the input data either.

snowman2 commented 5 years ago

Same issue with fiona transform as well: image

snowman2 commented 5 years ago

And if you go to the bld crs, everything is wonky: image image

snowman2 commented 5 years ago

Looks like the results with PROJ are different as well:

$ cs2cs
Rel. 6.1.0, May 15th, 2019
$ cs2cs -v 'EPSG:4326' 'PROJCRS["Hotine_Oblique_Mercator_Azimuth_Center",BASEGEOGCRS["GCS_Bessel 1841",DATUM["unknown",ELLIPSOID["bessel",6377397.155,299.1528128,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["Degree",0.0174532925199433]]],CONVERSION["unnamed",METHOD["Hotine Oblique Mercator (variant B)",ID["EPSG",9815]],PARAMETER["Latitude of projection centre",46.9524055555556,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8811]],PARAMETER["Longitude of projection centre",7.43958333333333,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8812]],PARAMETER["Azimuth of initial line",90,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8813]],PARAMETER["Angle from Rectified to Skew Grid",90,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8814]],PARAMETER["Scale factor on initial line",1,SCALEUNIT["unity",1],ID["EPSG",8815]],PARAMETER["Easting at projection centre",600000,LENGTHUNIT["metre",1],ID["EPSG",8816]],PARAMETER["Northing at projection centre",200000,LENGTHUNIT["metre",1],ID["EPSG",8817]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]]'
# ---- From Coordinate System ----
EPSG:4326
# ---- To Coordinate System ----
PROJCRS["Hotine_Oblique_Mercator_Azimuth_Center",BASEGEOGCRS["GCS_Bessel 1841",DATUM["unknown",ELLIPSOID["bessel",6377397.155,299.1528128,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["Degree",0.0174532925199433]]],CONVERSION["unnamed",METHOD["Hotine Oblique Mercator (variant B)",ID["EPSG",9815]],PARAMETER["Latitude of projection centre",46.9524055555556,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8811]],PARAMETER["Longitude of projection centre",7.43958333333333,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8812]],PARAMETER["Azimuth of initial line",90,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8813]],PARAMETER["Angle from Rectified to Skew Grid",90,ANGLEUNIT["Degree",0.0174532925199433],ID["EPSG",8814]],PARAMETER["Scale factor on initial line",1,SCALEUNIT["unity",1],ID["EPSG",8815]],PARAMETER["Easting at projection centre",600000,LENGTHUNIT["metre",1],ID["EPSG",8816]],PARAMETER["Northing at projection centre",200000,LENGTHUNIT["metre",1],ID["EPSG",8817]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]]
8.760606547874517 47.39417481896241
5634675.35  -2870535.30 0.00
$ cs2cs -v 'EPSG:4326' 'BOUNDCRS[SOURCECRS[PROJCRS["CH1903 / LV03",BASEGEOGCRS["CH1903",DATUM["CH1903",ELLIPSOID["Bessel 1841",6377397.155,299.1528128,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4149]],CONVERSION["unnamed",METHOD["Hotine Oblique Mercator (variant B)",ID["EPSG",9815]],PARAMETER["Latitude of projection centre",46.9524055555556,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8811]],PARAMETER["Longitude of projection centre",7.43958333333333,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8812]],PARAMETER["Azimuth of initial line",90,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8813]],PARAMETER["Angle from Rectified to Skew Grid",90,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8814]],PARAMETER["Scale factor on initial line",1,SCALEUNIT["unity",1],ID["EPSG",8815]],PARAMETER["Easting at projection centre",600000,LENGTHUNIT["metre",1],ID["EPSG",8816]],PARAMETER["Northing at projection centre",200000,LENGTHUNIT["metre",1],ID["EPSG",8817]]],CS[Cartesian,2],AXIS["y",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["x",north,ORDER[2],LENGTHUNIT["metre",1]],ID["EPSG",21781]]],TARGETCRS[GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["latitude",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["longitude",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]]],ABRIDGEDTRANSFORMATION["Transformation from CH1903 to WGS84",METHOD["Position Vector transformation (geog2D domain)",ID["EPSG",9606]],PARAMETER["X-axis translation",674.374,ID["EPSG",8605]],PARAMETER["Y-axis translation",15.056,ID["EPSG",8606]],PARAMETER["Z-axis translation",405.346,ID["EPSG",8607]],PARAMETER["X-axis rotation",0,ID["EPSG",8608]],PARAMETER["Y-axis rotation",0,ID["EPSG",8609]],PARAMETER["Z-axis rotation",0,ID["EPSG",8610]],PARAMETER["Scale difference",1,ID["EPSG",8611]]]]'
# ---- From Coordinate System ----
EPSG:4326
# ---- To Coordinate System ----
BOUNDCRS[SOURCECRS[PROJCRS["CH1903 / LV03",BASEGEOGCRS["CH1903",DATUM["CH1903",ELLIPSOID["Bessel 1841",6377397.155,299.1528128,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4149]],CONVERSION["unnamed",METHOD["Hotine Oblique Mercator (variant B)",ID["EPSG",9815]],PARAMETER["Latitude of projection centre",46.9524055555556,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8811]],PARAMETER["Longitude of projection centre",7.43958333333333,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8812]],PARAMETER["Azimuth of initial line",90,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8813]],PARAMETER["Angle from Rectified to Skew Grid",90,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8814]],PARAMETER["Scale factor on initial line",1,SCALEUNIT["unity",1],ID["EPSG",8815]],PARAMETER["Easting at projection centre",600000,LENGTHUNIT["metre",1],ID["EPSG",8816]],PARAMETER["Northing at projection centre",200000,LENGTHUNIT["metre",1],ID["EPSG",8817]]],CS[Cartesian,2],AXIS["y",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["x",north,ORDER[2],LENGTHUNIT["metre",1]],ID["EPSG",21781]]],TARGETCRS[GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["latitude",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["longitude",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]]],ABRIDGEDTRANSFORMATION["Transformation from CH1903 to WGS84",METHOD["Position Vector transformation (geog2D domain)",ID["EPSG",9606]],PARAMETER["X-axis translation",674.374,ID["EPSG",8605]],PARAMETER["Y-axis translation",15.056,ID["EPSG",8606]],PARAMETER["Z-axis translation",405.346,ID["EPSG",8607]],PARAMETER["X-axis rotation",0,ID["EPSG",8608]],PARAMETER["Y-axis rotation",0,ID["EPSG",8609]],PARAMETER["Z-axis rotation",0,ID["EPSG",8610]],PARAMETER["Scale difference",1,ID["EPSG",8611]]]]
8.760606547874517 47.39417481896241
5635343.40  -2870582.65 0.00