Перетин багатокутника лінії Геопандас


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.


Коли ви говорите, що print(line.intersects(polygon))ви отримуєте доступ до змінної, яка не визначена, наскільки я бачу. Ви вказали line1і line2раніше в коді. Я не знаю, чому це поверне Правду.
Пол

2
Я також хотів би дізнатися відповідь на це. Здається, що ви можете призначити геодамарам лише одну колонку геометрії. Я думаю, що ваш кадр даних line_gdf намагається додати два стовпчики геометрії. Перевірте geopandas.org/data_structures.html#geodataframe
Павло

@Paul мої вибачення, print(line.intersects(polygon))був помилковим. Я оновив питання, посилаючись на line1яке я мав на увазі спочатку.
bgordon

@Paul З документації я бачу, як наявність двох стовпців з геометрією спричинить проблему, але я не зовсім впевнений, чому два стовпчики з геометрії будуть додані в першу чергу.
bgordon

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методу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.