Как правильно перепроецировать геоданные с несколькими столбцами геометрии? - PullRequest
0 голосов
/ 15 февраля 2020

В документации Geo pandas говорится, что

A GeoDataFrame также может содержать другие столбцы с геометрическими (фигурными) объектами, но может быть только один столбец активная геометрия за один раз. Чтобы изменить, какой столбец является активным столбцом геометрии, используйте метод set_geometry.

Мне интересно, как использовать такой 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'

Пока все хорошо. Вещи go сбрасывают с рельсов, если я хочу установить 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)

Хорошо, так что, очевидно, атрибут .crs атрибута gdf не сбрасывается в исходное значение при изменении столбца, который служит геометрией - кажется, 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 с нуля? Это не может быть способ, которым это было предназначено для использования.

1 Ответ

0 голосов
/ 22 февраля 2020

К сожалению, желаемое поведение в настоящее время невозможно. Из-за ограничений в пакете, geopandas на данный момент не поддерживает этот сценарий использования, как видно из этой проблемы в репозитории github .

Мой обходной путь - не использовать a GeoDataFrame вообще, но вместо этого объедините нормальный pandas DataFrame для несимметричных данных с несколькими отдельными geopandas GeoSeries для данных стройной геометрии. Каждый из GeoSeries имеет свои собственные crs и может быть корректно перепроектирован при необходимости.

...