Geopandas-Linienpolygonschnitt

11

Ich versuche herauszufinden, wo mehrere Linien ein Polygon für zwei verschiedene Geodatenrahmen schneiden:

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])

So sehen die obigen Geodatenrahmen aus (einer hat ein Polygon und der andere hat zwei Linien). Es sieht für mich so aus, als ob beide Linien das Polygon schneiden:

Polygon und Linien

Die Schnittmenge ist jedoch sehr verwirrend:

print(line_gdf.intersects(poly_gdf))

0 Richtig

1 Falsch

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

Wahr

Wahr

Warum gibt die geopandas intersectMethode eine andere Ausgabe als die Standardmethode aus shapely?

Ich verwende Python 3.5.3 und Geopandas 0.2.1 alle auf Anaconda.

bgordon
quelle
Wenn Sie sagen, print(line.intersects(polygon))Sie greifen auf eine Variable zu, die meines Erachtens nicht definiert ist. Sie haben line1und line2früher im Code definiert. Ich weiß nicht, warum das True zurückgeben würde.
Paul
2
Ich würde gerne auch die Antwort darauf wissen. Es scheint, dass Sie einem Geodatenrahmen nur eine einzige Geometriespalte zuweisen können. Ich denke, Ihr line_gdf-Datenrahmen versucht, zwei Geometriespalten hinzuzufügen. Überprüfen Sie heraus geopandas.org/data_structures.html#geodataframe
Paul
@ Paul meine Entschuldigung, print(line.intersects(polygon))war ein Tippfehler. Ich habe die Frage aktualisiert, um darauf zu verweisen, line1was ich ursprünglich gemeint habe.
Bgordon
@Paul Ich kann der Dokumentation entnehmen, wie zwei Geometriespalten ein Problem verursachen würden, bin mir aber nicht ganz sicher, warum zwei Geometriespalten überhaupt hinzugefügt werden.
Bgordon
line_gdf.infobestätigt, dass Sie nur eine einzige Geometriespalte haben. Ich bin ratlos. Ich werde nachgehen, wenn ich etwas finde.
Paul

Antworten:

7

Beim Vergleich von Geodatenrahmen mit Geometrieoperationen in Geopandas werden die Geometrien zunächst nach Index abgeglichen. Wenn es keinen passenden Index gibt (weil Sie zum Beispiel nur ein einziges Polygon haben), ist das Ergebnis False.

Wenn Sie jedes Objekt in der vergleichen GeoSerieswürden, müssten Sie stattdessen einen vollständigen rechteckigen Datenrahmen mit booleschen Werten zurückerhalten, und dies wäre wahrscheinlich sehr ineffizient.

Wenn Sie alle Geometrien vergleichen möchten, haben Sie zwei Möglichkeiten. Die erste (und wahrscheinlich einfachste) sjoinMethode ist die Verwendung der Geopandas- Methode:

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

Dies gibt eine neue zurück, GeoDataFramewobei die Geometrien für jedes Objekt im linken Datenrahmen für jede Geometrie wiederholt werden, die sie rechts schneiden, wobei der Index des Objekts rechts angezeigt wird, dh:

                        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

Die zweite Methode ist für uns die Pandas- applyMethode GeoSeries, um den rechteckigen Datenrahmen zurückzugeben:

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

Was wiederum zurückkehrt (mit zunehmender Ineffizienz, wenn die Datenrahmen wachsen):

index_right     0
index_left
0            True
1            True

Im Allgemeinen würde ich mich an die sjoinMethode halten, es sei denn, Sie benötigen die quadratische Matrix .

om_henners
quelle