In the geopandas documentation it says that
GeoDataFramemay also contain other columns with geometrical (shapely) objects, but only one column can be the active geometry at a time. To change which column is the active geometry column, use the
import geopandas as gpd from shapely.geometry import Point crs_lonlat = 'epsg:4326' #geometries entered in this crs (lon, lat in degrees) crs_new = 'epsg:3395' #geometries needed in (among others) this crs gdf = gpd.GeoDataFrame(crs=crs_lonlat) gdf['geom1'] = [Point(9,53), Point(9,54)] gdf['geom2'] = [Point(8,63), Point(8,64)] #Working: setting geometry and reprojecting for first time. gdf = gdf.set_geometry('geom1') gdf = gdf.to_crs(crs_new) #geom1 is reprojected to crs_new, geom2 still in crs_lonlat gdf Out: geom1 geom2 0 POINT (1001875.417 6948849.385) POINT (8 63) 1 POINT (1001875.417 7135562.568) POINT (8 64) gdf.crs Out: 'epsg:3395'
So far, so good. Things go off the rails if I want to set
geom2 as the geometry column, and reproject that one as well:
#Not working: setting geometry and reprojecting for second time. gdf = gdf.set_geometry('geom2') #still in crs_lonlat... gdf.crs #...but this still says crs_new... Out: 'epsg:3395' gdf = gdf.to_crs(crs_new) #...so this doesn't do anything! (geom2 unchanged) gdf Out: geom1 geom2 0 POINT (1001875.417 6948849.385) POINT (8.00000 63.00000) 1 POINT (1001875.417 7135562.568) POINT (8.00000 64.00000)
Ok, so, apparently, the
.crs attribute of the
gdf is not reset to its original value when changing the column that serves as the geometry - it seems, the crs is not stored for the individual columns. If that is the case, the only way I see to use reprojection with this dataframe, is to backtrack: start --> select column as geometry --> reproject gdf to crs_new --> use/visualize/... --> reproject gdf back to crs_lonlat --> goto start. This is not usable if I want to visualise both columns in one figure.
My second attempt was, to store the
crs with each column separately, by changing the corresponding lines in the script above to:
gdf = gpd.GeoDataFrame() gdf['geom1'] = gpd.GeoSeries([Point(9,53), Point(9,54)], crs=crs_lonlat) gdf['geom2'] = gpd.GeoSeries([Point(8,63), Point(8,64)], crs=crs_lonlat)
However, it soon became clear that, though initialised as a
GeoSeries, these columns are normal
Series, and don't have a
.crs attribute the same way
gdf['geom1'].crs AttributeError: 'Series' object has no attribute 'crs' s = gpd.GeoSeries([Point(9,53), Point(9,54)], crs=crs_lonlat) s.crs Out: 'epsg:4326'
gdf = gpd.GeoDataFrame(crs=crs_new) gdf['geom1'] = gpd.GeoSeries([Point(9,53), Point(9,54)], crs=crs_lonlat).to_crs(crs_new) gdf['geom2'] = gpd.GeoSeries([Point(8,63), Point(8,64)], crs=crs_lonlat).to_crs(crs_new) #no more reprojecting done/necessary/possible! :/
...and then, when another crs is needed, rebuild the entire
gdf from scratch? That can't be the way this was intended to be used.