Geo pandas - разделить линии на пересечении с полигонами, сохранить идентификатор полигона в новых атрибутах ссылки - PullRequest
1 голос
/ 22 марта 2020

У меня есть два геоданных: один содержит много строк, а другой содержит много полигонов. Эти линии и полигоны пересекаются друг с другом. Вывод, который я пытаюсь получить, - это новый геоданный, содержащий ссылки, которые были разбиты в любом месте, где они пересекаются с полигоном.

Упрощенный тестовый код выглядит следующим образом:

import geopandas
from shapely.geometry import Polygon, LineString

#Create geodataframe containing 2 links:
linkID = ['1','2']
link_geom = [LineString([(0, 0), (10, 10)]),LineString([(10, 10), (20, 10)])]
a = {'linkID':linkID,'geometry':link_geom}
gdf_links = geopandas.GeoDataFrame(a)

#Create geodataframe containing 2 polygons:
polyID = ['100','200']
poly_geom = [Polygon([(2, 1), (2, 3), (4, 3), (4, 1)]),Polygon([(15, 7), (15, 13), (18, 13), (18, 7)])]
b = {'polyID':polyID,'geometry':poly_geom}
gdf_poly = geopandas.GeoDataFrame(b)

Вы можете увидеть, что линии пересекают полигоны, запустив следующий код:

links = gdf_links.unary_union
polys = gdf_poly.unary_union
geopandas.GeoSeries([links,polys]).plot(cmap='tab10')

, который генерирует следующее цифра (аннотация добавлена ​​красным / зеленым цветом для отображения различных элементов):

enter image description here

Разделение двух линий, где бы они ни пересекались с полигоном, приведет к 6 сегменты (как отмечено зеленым цветом на рисунке выше).

В идеале, вывод, который я хотел бы получить, выглядит примерно так, как показано ниже, с колонкой 'poly_intersect', в которой перечислены идентификаторы многоугольника, в котором разделение имеет произошло. Обратите внимание, что пункты 2 и 5 содержат два идентификатора многоугольника, потому что они дважды пересекают многоугольник.

enter image description here

1 Ответ

2 голосов
/ 23 марта 2020

Вы можете получить эти строки, выполнив «наложение» линий на полигоны (используя операцию «объединение» при наложении). Тем не менее, он не даст точно ожидаемый результат, как вы изобразили для столбца «poly_intersect»:

>> geopandas.overlay(gdf_links, gdf_poly, how='union').explode().reset_index(drop=True)

  linkID polyID                   geometry
0      1    100      LINESTRING (2 2, 3 3)
1      2    200  LINESTRING (15 10, 18 10)
2      1    NaN      LINESTRING (0 0, 2 2)
3      1    NaN    LINESTRING (3 3, 10 10)
4      2    NaN  LINESTRING (10 10, 15 10)
5      2    NaN  LINESTRING (18 10, 20 10)

Некоторые замечания:

  • Я использую explode(), потому что overlay() Операция возвращает MultiLineStrings для части одной строки до и после пересечения многоугольника. Разнесение разделит эти "мульти" геометрии.
  • Столбец "polyID" указывает, какие линии линий произошли от пересечения с какой полигоном. Но у него нет информации о других строках линий, к которым они относятся, многоугольник.

Так что, если вы хотите, чтобы эта информация также потребовалась (полный столбец «poly_intersect»), вы можете выполнить некоторые последующие действия. анализ, проверяющий, какая из линий строк касается какого из полигонов.

...