Пересечение полигонов линии Геопанды

11

Я пытаюсь найти, где несколько линий пересекают многоугольник для двух разных геоданных:

from shapely.geometry import Polygon, LineString
import geopandas as gpd

polygon = Polygon([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)])
line1 = LineString([(0.5, 0.5), (0.7, 0.7)])
line2 = LineString([(0.9, 0.9), (0.2, 0.6)])


poly_gdf = gpd.GeoDataFrame(geometry=[polygon])
line_gdf = gpd.GeoDataFrame(geometry=[line1, line2])

Так выглядят вышеперечисленные геоданные (у одного есть многоугольник, а у другого две линии). Мне кажется, что обе линии пересекают многоугольник:

Полигон и Линии

Однако вывод о пересечении очень запутанный:

print(line_gdf.intersects(poly_gdf))

0 Правда

1 ложь

print(line1.intersects(polygon))
print(line2.intersects(polygon))

Правда

Правда

Почему geopandas intersectметод дает другой вывод по сравнению со стандартным shapely?

Я использую Python 3.5.3 и Geopandas 0.2.1 все на Anaconda.

bgordon
источник
Когда вы говорите, у print(line.intersects(polygon))вас есть доступ к переменной, которая не определена, насколько я вижу. Вы определили line1и line2ранее в коде. Я не знаю, почему это вернуло бы Истину.
Пол
2
Я также хотел бы знать ответ на этот вопрос. Кажется, что вы можете назначить только один столбец геометрии для геоданных. Я думаю, что ваш фрейм данных line_gdf пытается добавить два столбца геометрии. Посетите веб-сайт geopandas.org/data_structures.html#geodataframe
Пол
@ Пол мои извинения, print(line.intersects(polygon))была опечатка. Я обновил вопрос, чтобы обратиться к line1тому, что я имел в виду.
бгордон
@Paul Я могу видеть из документации, как наличие двух столбцов геометрии может вызвать проблемы, но я не совсем уверен, почему два столбца геометрии были бы добавлены в первую очередь.
бгордон
line_gdf.infoподтверждает, что у вас есть только один столбец геометрии. Я в тупике. Я буду следить, если найду что-нибудь.
Пол

Ответы:

7

При сравнении геоданных и операций с геометрией в Geopandas геометрии сначала сопоставляются по индексу. В случае, когда нет соответствующего индекса (потому что у вас есть только один полигон, например), тогда будет результат False.

Если бы он сравнивал каждый объект в, GeoSeriesвам вместо этого нужно было бы получить полный прямоугольный массив данных с логическими значениями, и это, вероятно, было бы очень неэффективно.

Если вы хотите сравнить все геометрии, у вас есть два варианта. Первое (и, вероятно, самое простое) - это использование sjoinметода геопанды :

gpd.sjoin(line_gdf, poly_gdf, op='intersects')

Это возвращает новое GeoDataFrameс геометриями для каждого объекта в левом кадре данных, повторяемыми для каждой геометрии, которую они пересекают справа, с индексом объекта справа, то есть:

                        geometry  index_right
0  LINESTRING (0.5 0.5, 0.7 0.7)            0
1  LINESTRING (0.9 0.9, 0.2 0.6)            0

Второй метод - это applyметод pandas GeoSeriesдля возврата прямоугольного фрейма данных:

line_gdf.geometry.apply(lambda g: poly_gdf.intersects(g))

Что, в свою очередь, возвращает (с ростом неэффективности по мере роста кадров данных):

index_right     0
index_left
0            True
1            True

В общем, если вам не нужна квадратная матрица, мой совет будет придерживаться sjoinметода.

om_henners
источник