Tengo un código que estoy usando para determinar qué Polígono Shapely / MultiPolygons se cruzan con una serie de Shapely LineStrings. A través de las respuestas a esta pregunta, el código ha pasado de esto:
import fiona
from shapely.geometry import LineString, Polygon, MultiPolygon, shape
# Open each layer
poly_layer = fiona.open('polygon_layer.shp')
line_layer = fiona.open('line_layer.shp')
# Convert to lists of shapely geometries
the_lines = [shape(line['geometry']) for line in line_layer]
the_polygons = [(poly['properties']['GEOID'], shape(poly['geometry'])) for poly in poly_layer]
# Check for Polygons/MultiPolygons that the LineString intersects with
covered_polygons = {}
for poly_id, poly in the_polygons:
for line in the_lines:
if poly.intersects(line):
covered_polygons[poly_id] = covered_polygons.get(poly_id, 0) + 1
donde se verifica cada posible intersección, para esto:
import fiona
from shapely.geometry import LineString, Polygon, MultiPolygon, shape
import rtree
# Open each layer
poly_layer = fiona.open('polygon_layer.shp')
line_layer = fiona.open('line_layer.shp')
# Convert to lists of shapely geometries
the_lines = [shape(line['geometry']) for line in line_layer]
the_polygons = [(poly['properties']['GEOID'], shape(poly['geometry'])) for poly in poly_layer]
# Create spatial index
spatial_index = rtree.index.Index()
for idx, poly_tuple in enumerate(the_polygons):
_, poly = poly_tuple
spatial_index.insert(idx, poly.bounds)
# Check for Polygons/MultiPolygons that the LineString intersects with
covered_polygons = {}
for line in the_lines:
for idx in list(spatial_index.intersection(line.bounds)):
if the_polygons[idx][1].intersects(line):
covered_polygons[idx] = covered_polygons.get(idx, 0) + 1
donde el índice espacial se usa para reducir el número de verificaciones de intersección.
Con los archivos de forma que tengo (aproximadamente 4000 polígonos y 4 líneas), el código original realiza 12936 .intersection()
comprobaciones y tarda aproximadamente 114 segundos en ejecutarse. La segunda pieza de código que usa el índice espacial realiza solo 1816 .intersection()
comprobaciones, pero también tarda aproximadamente 114 segundos en ejecutarse.
El código para construir el índice espacial solo tarda de 1 a 2 segundos en ejecutarse, por lo que las comprobaciones de 1816 en la segunda parte del código tardan casi la misma cantidad de tiempo en realizarse que las comprobaciones de 12936 en el código original (desde la carga de shapefiles y la conversión a geometrías Shapely es lo mismo en ambas partes del código).
No veo ninguna razón por la que el índice espacial haga que la .intersects()
verificación tarde más, por lo que no sé por qué sucede esto.
Solo puedo pensar que estoy usando el índice espacial RTree incorrectamente. Pensamientos?
intersects()
método lleva más tiempo cuando se usa el índice espacial (consulte la comparación de tiempo anterior), por lo que no estoy seguro de si estoy usando el índice espacial incorrectamente. Al leer la documentación y las publicaciones vinculadas, creo que sí, pero esperaba que alguien pudiera señalar si no fuera así.