Filtrer par boîte englobante dans les géopandas?


11

J'ai un cadre de données géopandas dans EPSG: 4326 et je ferais un nouveau cadre de données composé de toutes les lignes qui se trouvent dans une certaine boîte englobante.

D'abord, j'obtiens le cadre de délimitation qui m'importe (qui est en fait le cadre de délimitation d'une autre trame de données):

print df_sussex.total_bounds
[ -1.57239292  50.57467674   0.14528384  51.27465152]

Ensuite, je crée une trame de données composée uniquement de cette boîte englobante:

pts = gpd.GeoDataFrame(df_sussex.total_bounds)

Et enfin, j'essaie d'obtenir toutes les fonctionnalités qui se croisent avec cette boîte englobante:

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

Mais cela me donne AttributeError: No geometry data set yet (expected in column 'geometry'.

Qu'est-ce que je fais mal?


Le problème est dû au fait que vous utilisez la méthode 'total_bounds'. Il ne produit qu'un tuple avec des points max et min de boîte englobante. La méthode à utiliser est «enveloppe»; précédent pour construire son GeoDataFrame respectif .
xunilk

Réponses:


5

Le problème est dû au fait que vous utilisez la méthode 'total_bounds'. Il ne produit qu'un tuple avec des points max et min de boîte englobante. La méthode à utiliser est «enveloppe»; précédent pour construire son «GeoDataFrame» respectif. Par exemple, lire mes fichiers de formes en tant que GeoDataFrame :

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

Construire la boîte englobante de pol1 et créer son GeoDataFrame respectif :

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

Intersection des deux GeoDataFrame :

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

Tracer les résultats:

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

entrez la description de l'image ici

Cela a fonctionné comme prévu.

Note d'édition:

En utilisant la méthode 'total_bounds' (car la méthode 'enveloppe' renvoie le cadre de délimitation pour chaque entité de polygones), il peut être utilisé cette approche:

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

et le résultat est identique.


21

Vous pouvez utiliser la cxméthode sur un cadre de données géographiques pour sélectionner des lignes dans un cadre de sélection. Pour vos exemples de cadres:

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

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

En plus des méthodes pandas standard, GeoPandas fournit également une indexation basée sur les coordonnées avec l' indexeur cx , qui tranche à l'aide d'un cadre de sélection. Les géométries de GeoSeries ou GeoDataFrame qui coupent la zone de délimitation seront renvoyées.


Cette solution a fonctionné pour moi. Je vous remercie. Cependant, je me demandais s'il y avait un moyen plus rapide de mettre en œuvre. Filtrer l'utilisation des terres OSM et les endroits qui relèvent de la zone de délimitation d'une province.
EFL

Notez que cela .cxfait quelque chose de légèrement différent de la gpd.overlaysolution: il sélectionne les lignes qui coupent la boîte englobante mais laisse les géométries intactes, tandis que la gpd.overlaysolution ne renverra que les parties des géométries dans la boîte englobante. Selon la situation, vous voudrez peut-être l'un ou l'autre.
danvk
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.