J'ai du code que j'utilise pour déterminer quels polygones / multi-polygones Shapely se croisent avec un certain nombre de chaînes de lignes Shapely. Grâce aux réponses à cette question, le code est passé de ceci:
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
où chaque intersection possible est vérifiée, à ceci:
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
où l'indice spatial est utilisé pour réduire le nombre de vérifications d'intersection.
Avec les fichiers de formes que j'ai (environ 4000 polygones et 4 lignes), le code d'origine effectue 12936 .intersection()
vérifications et prend environ 114 secondes pour s'exécuter. Le deuxième morceau de code qui utilise l'index spatial effectue seulement 1816 .intersection()
vérifications, mais il faut également environ 114 secondes pour s'exécuter.
Le code pour construire l'index spatial ne prend que 1 à 2 secondes à exécuter, donc les vérifications 1816 dans le deuxième morceau de code prennent à peu près le même temps à effectuer que les vérifications 12936 dans le code d'origine (depuis le chargement de les fichiers de formes et la conversion en géométries Shapely sont les mêmes dans les deux morceaux de code).
Je ne vois aucune raison pour laquelle l'index spatial rendrait la .intersects()
vérification plus longue, donc je ne comprends pas pourquoi cela se produit.
Je peux seulement penser que j'utilise incorrectement l'index spatial RTree. Pensées?
intersects()
méthode prend plus de temps lorsque l'index spatial est utilisé (voir la comparaison temporelle ci-dessus), c'est pourquoi je ne suis pas sûr d'utiliser incorrectement l'index spatial. En lisant la documentation et les articles liés, je pense que je le suis, mais j'espérais que quelqu'un pourrait faire remarquer si je ne l'étais pas.