Создавайте полигоны из точек с помощью GeoPandas - PullRequest
1 голос
/ 23 февраля 2020

У меня есть geo pandas фрейм данных, содержащий список геометрических фигур POINT. Есть еще один столбец со списком идентификаторов, который указывает, к какому уникальному полигону относится каждая точка. Упрощенный входной код:

import pandas as pd
from shapely.geometry import Point, LineString, Polygon
from geopandas import GeoDataFrame

data = [[1,10,10],[1,15,20],[1,20,10],[2,30,30],[2,35,40],[2,40,30]] 
df_poly = pd.DataFrame(data, columns = ['poly_ID','lon', 'lat']) 
geometry = [Point(xy) for xy in zip(df_poly.lon, df_poly.lat)]
geodf_poly = GeoDataFrame(df_poly, geometry=geometry)
geodf_poly.head()

Я хотел бы сгруппировать poly_ID для преобразования геометрии из POINT в POLYGON. Этот вывод будет выглядеть примерно так:

poly_ID   geometry
1         POLYGON ((10 10, 15 20, 20 10))
2         POLYGON ((30 30, 35 40, 40 30))

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

geodf_poly = geodf_poly.groupby(['poly_ID'])['geometry'].apply(lambda x: LineString(x.tolist()))

Простая замена LineString на Polygon приводит к TypeError: объект типа 'Point' не имеет len ()

1 Ответ

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

Ваш запрос немного сложен для выполнения sh в Pandas, потому что в выходных данных вы хотите, чтобы текст 'POLYGON', но цифры в скобках.

См. Приведенные ниже варианты работы для вас

from itertools import chain
df_poly.groupby('poly_ID').agg(list).apply(lambda x: tuple(chain.from_iterable(zip(x['lon'], x['lat']))), axis=1).reset_index(name='geometry')

выход

poly_ID     geometry
0   1   (10, 10, 15, 20, 20, 10)
1   2   (30, 30, 35, 40, 40, 30)

или

from itertools import chain

df_new =df_poly.groupby('poly_ID').agg(list).apply(lambda x: tuple(chain.from_iterable(zip(x['lon'], x['lat']))), axis=1).reset_index(name='geometry')
df_new['geometry']=df_new.apply(lambda x: 'POLYGON ('+str(x['geometry'])+')',axis=1 )
df_new

Выход

poly_ID     geometry
0   1   POLYGON ((10, 10, 15, 20, 20, 10))
1   2   POLYGON ((30, 30, 35, 40, 40, 30))

Примечание: Столбец geometry - это строка, и я не уверен, что вы можете указать это непосредственно в Shapely

...