Geopandas Línea Polígono Intersección

11

Estoy tratando de encontrar dónde varias líneas se cruzan con un polígono para dos geodataframes diferentes:

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

Así es como se ven los geodataframes anteriores (uno tiene un polígono y el otro tiene dos líneas). Me parece que ambas líneas se cruzan con el polígono:

Polígono y líneas

Sin embargo, la salida de intersección es muy confusa:

print(line_gdf.intersects(poly_gdf))

0 verdadero

1 falso

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

Cierto

Cierto

¿Por qué el geopandas intersectmétodo da un resultado diferente al estándar shapely?

Estoy usando Python 3.5.3 y Geopandas 0.2.1, todo en Anaconda.

bgordon
fuente
Cuando dices print(line.intersects(polygon))que tienes acceso a una variable que no está definida hasta donde puedo ver. Has definido line1y line2anteriormente en el código. No sé por qué eso volvería Verdadero.
Paul
2
Me gustaría saber la respuesta a esto también. Parece que solo puede asignar una sola columna de geometría a un geodataframe. Creo que su marco de datos line_gdf intenta agregar dos columnas de geometría. Echa un vistazo a geopandas.org/data_structures.html#geodataframe
Paul
@ Paul mis disculpas, print(line.intersects(polygon))fue un error tipográfico. He actualizado la pregunta para referirme a line1qué es lo que quise decir originalmente.
bgordon
@Paul Puedo ver en la documentación cómo tener dos columnas de geometría podría causar un problema, pero no estoy muy seguro de por qué se agregarían dos columnas de geometría en primer lugar.
bgordon
line_gdf.infoconfirma que solo tiene una columna de geometría única. Estoy perplejo. Seguiré si encuentro algo.
Paul

Respuestas:

7

Al comparar geodataframes con operaciones de geometría en Geopandas, las geometrías primero coinciden por índice. En el caso de que no haya un índice coincidente (porque solo tiene un solo polígono, por ejemplo), entonces el resultado será False.

Si se comparara cada objeto en el GeoSeries, necesitaría recuperar un marco de datos rectangular completo de valores booleanos, y esto probablemente sería muy ineficiente.

Si desea comparar todas las geometrías, tiene dos opciones. El primero (y probablemente el más fácil) es usar el sjoinmétodo de geopandas :

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

Esto devuelve un nuevo GeoDataFramecon las geometrías para cada objeto en el marco de datos izquierdo repetido para cada geometría que se cruzan en la derecha, con el índice del objeto en la derecha, es decir:

                        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

El segundo método es para nosotros el applymétodo pandas GeoSeriespara devolver el marco de datos rectangular:

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

Lo que a su vez regresa (con una creciente ineficiencia a medida que crecen los marcos de datos):

index_right     0
index_left
0            True
1            True

En general, a menos que necesite la matriz cuadrada, mi consejo sería seguir el sjoinmétodo.

om_henners
fuente