Filtern nach Begrenzungsrahmen in Geopandas?

11

Ich habe einen Geopandas-Datenrahmen in EPSG: 4326 und würde einen neuen Datenrahmen erstellen, der aus allen Zeilen besteht, die in einen bestimmten Begrenzungsrahmen fallen.

Zuerst erhalte ich den Begrenzungsrahmen, der mir wichtig ist (der eigentlich der Begrenzungsrahmen eines anderen Datenrahmens ist):

print df_sussex.total_bounds
[ -1.57239292  50.57467674   0.14528384  51.27465152]

Dann erstelle ich einen Datenrahmen, der nur aus diesem Begrenzungsrahmen besteht:

pts = gpd.GeoDataFrame(df_sussex.total_bounds)

Und schließlich versuche ich, alle Merkmale zu ermitteln, die sich mit diesem Begrenzungsrahmen überschneiden:

sac_sussex = gpd.overlay(pts, df_sac, how='intersection')

Aber das gibt mir AttributeError: No geometry data set yet (expected in column 'geometry'.

Was mache ich falsch?

Richard
quelle
Das Problem liegt darin, dass Sie die Methode 'total_bounds' verwenden. Es wird nur ein Tupel mit den Max- und Min-Punkten des Begrenzungsrahmens erzeugt. Die zu verwendende Methode ist "Umschlag". vor dem Erstellen des jeweiligen GeoDataFrame .
Xunilk

Antworten:

5

Das Problem liegt darin, dass Sie die Methode 'total_bounds' verwenden. Es wird nur ein Tupel mit den Max- und Min-Punkten des Begrenzungsrahmens erzeugt. Die zu verwendende Methode ist "Umschlag". vorher, um seinen jeweiligen 'GeoDataFrame' zu erstellen. Lesen Sie beispielsweise meine Shapefiles als GeoDataFrame :

import geopandas as gpd
pol1 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon1.shp")
pol8 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon8.shp")

Erstellen eines Begrenzungsrahmens von pol1 und Erstellen des entsprechenden GeoDataFrame :

bounding_box = pol1.envelope
df = gpd.GeoDataFrame(gpd.GeoSeries(bounding_box), columns=['geometry'])

Beide GeoDataFrame schneiden :

intersections = gpd.overlay(df, pol8, how='intersection')

Darstellungsergebnisse:

from matplotlib import pyplot as plt
plt.ion()
intersections.plot() 

Geben Sie hier die Bildbeschreibung ein

Es hat wie erwartet funktioniert.

Bearbeitungshinweis:

Mit der Methode 'total_bounds' (da die Methode 'Envelope' den Begrenzungsrahmen für jedes Merkmal von Polygonen zurückgibt) kann folgender Ansatz verwendet werden:

from matplotlib import pyplot as plt
import geopandas as gpd
from shapely.geometry import Point, Polygon

pol1 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon1.shp")
pol8 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon8.shp")

bbox = pol1.total_bounds

p1 = Point(bbox[0], bbox[3])
p2 = Point(bbox[2], bbox[3])
p3 = Point(bbox[2], bbox[1])
p4 = Point(bbox[0], bbox[1])

np1 = (p1.coords.xy[0][0], p1.coords.xy[1][0])
np2 = (p2.coords.xy[0][0], p2.coords.xy[1][0])
np3 = (p3.coords.xy[0][0], p3.coords.xy[1][0])
np4 = (p4.coords.xy[0][0], p4.coords.xy[1][0])

bb_polygon = Polygon([np1, np2, np3, np4])

df2 = gpd.GeoDataFrame(gpd.GeoSeries(bb_polygon), columns=['geometry'])

intersections2 = gpd.overlay(df2, pol8, how='intersection')

plt.ion()
intersections2.plot()

und Ergebnis ist identisch.

xunilk
quelle
21

Sie können die cxMethode für einen Geodatenrahmen verwenden, um Zeilen innerhalb eines Begrenzungsrahmens auszuwählen. Für Ihre Beispielrahmen:

xmin, ymin, xmax, ymax = df_sussex.total_bounds
sac_sussex = df_sac.cx[xmin:xmax, ymin:ymax]

Von http://geopandas.org/indexing.html :

Zusätzlich zu den Standard-Pandas-Methoden bietet GeoPandas auch eine koordinatenbasierte Indizierung mit dem cx- Indexer, der mithilfe eines Begrenzungsrahmens schneidet. Geometrien in der GeoSeries oder im GeoDataFrame, die den Begrenzungsrahmen schneiden, werden zurückgegeben.

jdmcbr
quelle
Diese Lösung hat bei mir funktioniert. Vielen Dank. Ich habe mich jedoch gefragt, ob es einen schnelleren Weg zur Implementierung gibt. Filtern der OSM-Landnutzung und von Orten, die in den Begrenzungsrahmen einer Provinz fallen.
EFL
Beachten Sie, dass .cxdies etwas anderes als die gpd.overlayLösung bewirkt : Es werden Zeilen ausgewählt, die den Begrenzungsrahmen schneiden, aber die Geometrien intakt lassen, während die gpd.overlayLösung nur die Teile der Geometrien im Begrenzungsrahmen zurückgibt. Je nach Situation möchten Sie vielleicht das eine oder andere.
Danvk