我如何正确地重新投影具有多个几何体的地理数据框?

问题描述 投票:0回答:1

[the geopandas documentation中说

A GeoDataFrame也可能包含具有几何(形状)对象的其他列,但是一次只能有一个列是活动几何。要更改哪个列为活动几何列,请使用set_geometry方法。

我想知道如果目标是将这些不同列中的几何数据灵活地reproject到一个或多个其他坐标参考系统,那么如何使用这样的GeoDataFrame。这是我尝试过的。

第一次尝试

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'

到目前为止,很好。如果我想将geom2设置为“几何”列,然后重新投影该列,则事情就不那么容易了:

#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)

好,因此,显然,在更改用作几何的列时,.crsgdf属性不会重置为其原始值-似乎没有为各个列存储crs。如果是这种情况,我看到对该数据帧使用重新投影的唯一方法是回溯:开始->选择列作为几何图形->将gdf重新投影到crs_new->使用/可视化/ ...->将gdf重新投影回crs_lonlat->转到开始。如果我想在一个图中将两个列都可视化,则此方法不可用。

第二次尝试

我的第二次尝试是,通过将上面脚本中的相应行更改为:,将crs与每列分别存储:

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)

但是,很快就知道,尽管这些列初始化为GeoSeries,但它们是正常的pandas Series,并且没有.crs属性具有与GeoSeries相同的属性:

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'

这里有什么我想念的吗?

是唯一的方案,可以事先确定'final'crs,并在添加列之前进行所有重新投影?像这样...

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! :/

...,然后,当需要另一个crs时,从头开始重建整个gdf吗?那不可能是预期的使用方式。

python geopandas reprojection-error
1个回答
0
投票

不幸的是,目前这不可能。由于包装中的限制,geopandas目前无法容纳此用例,如this issue in the github repo中所示。

我的解决方法是完全不使用GeoDataFrame,而是将正常pandas DataFrame(用于非形状数据)与几个单独的geopandas GeoSeries(用于几何形状数据)组合在一起。每个GeoSeries都有自己的crs,可以在需要时正确地重新投影。

© www.soinside.com 2019 - 2024. All rights reserved.