Intersection de polygones de lignes de géopandas

11

J'essaie de trouver où plusieurs lignes coupent un polygone pour deux géodonnées différentes:

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

Voici à quoi ressemblent les géodonnées ci-dessus (l'une a un polygone et l'autre a deux lignes). Il me semble que les deux lignes coupent le polygone:

Polygone et lignes

Cependant, la sortie d'intersection est très déroutante:

print(line_gdf.intersects(poly_gdf))

0 Vrai

1 Faux

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

Vrai

Vrai

Pourquoi la geopandas intersectméthode donne-t-elle une sortie différente de celle standard shapely?

J'utilise Python 3.5.3 et Geopandas 0.2.1 tous sur Anaconda.

bgordon
la source
Lorsque vous dites print(line.intersects(polygon))que vous accédez à une variable qui n'est pas définie pour autant que je puisse voir. Vous avez défini line1et line2plus tôt dans le code. Je ne sais pas pourquoi cela reviendrait Vrai.
Paul
2
J'aimerais également connaître la réponse. Il semble que vous ne pouvez affecter qu'une seule colonne de géométrie à un géodonnées. Je pense que votre bloc de données line_gdf essaie d'ajouter deux colonnes de géométrie. Consultez geopandas.org/data_structures.html#geodataframe
Paul
@Paul mes excuses, print(line.intersects(polygon))était une faute de frappe. J'ai mis à jour la question pour me référer à line1ce que je voulais dire à l'origine.
bgordon
@Paul Je peux voir dans la documentation comment avoir deux colonnes de géométrie pourrait causer un problème, mais je ne sais pas trop pourquoi deux colonnes de géométrie seraient ajoutées en premier lieu.
bgordon
line_gdf.infoconfirme que vous n'avez qu'une seule colonne de géométrie. Je suis perplexe. Je ferai un suivi si je trouve quelque chose.
Paul

Réponses:

7

Lorsque vous comparez des géodonnées avec des opérations de géométrie dans Geopandas, les géométries sont d'abord mises en correspondance par index. Dans le cas où il n'y a pas d'index correspondant (parce que vous n'avez qu'un seul polygone par exemple), le résultat sera False.

S'il devait comparer chaque objet dans le, GeoSeriesvous auriez plutôt besoin de récupérer un cadre de données rectangulaire complet de valeurs booléennes, et cela serait probablement très inefficace.

Si vous souhaitez comparer toutes les géométries, vous avez deux options. La première (et probablement la plus simple) consiste à utiliser la sjoinméthode des géopandas :

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

Cela renvoie un nouveau GeoDataFrameavec les géométries pour chaque objet sur la trame de données gauche répétées pour chaque géométrie qu'ils croisent à droite, avec l'index de l'objet à droite, c'est-à-dire:

                        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

La deuxième méthode est pour nous la applyméthode pandas sur le GeoSeriespour retourner la trame de données rectangulaire:

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

Qui à son tour retourne (avec une inefficacité croissante à mesure que les trames de données se développent):

index_right     0
index_left
0            True
1            True

En général, à moins que vous n'ayez besoin de la matrice carrée, mon conseil serait de vous en tenir à la sjoinméthode.

om_henners
la source