Ich habe Code, mit dem ich feststelle, welche Shapely-Polygone / MultiPolygone sich mit einer Reihe von Shapely-LineStrings schneiden. Durch die Antworten auf diese Frage ist der Code von diesem gegangen:
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
wo jede mögliche Kreuzung überprüft wird, dazu:
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
Dabei wird der räumliche Index verwendet, um die Anzahl der Kreuzungsprüfungen zu verringern.
Mit den Shapefiles, die ich habe (ungefähr 4000 Polygone und 4 Zeilen), führt der ursprüngliche Code 12936 .intersection()
Überprüfungen durch und dauert ungefähr 114 Sekunden, um ausgeführt zu werden. Der zweite Code, der den räumlichen Index verwendet, führt nur 1816 .intersection()
Überprüfungen durch, die Ausführung dauert jedoch ungefähr 114 Sekunden.
Die Ausführung des Codes zum Erstellen des räumlichen Index dauert nur 1-2 Sekunden, sodass die 1816-Überprüfungen im zweiten Codeteil ungefähr genauso lange dauern wie die 12936-Überprüfungen im ursprünglichen Code (seit dem Laden von Shapefiles und das Konvertieren in Shapely-Geometrien sind in beiden Codeteilen gleich.
Ich kann keinen Grund erkennen, warum der räumliche Index die .intersects()
Überprüfung länger dauern würde, daher weiß ich nicht, warum dies geschieht.
Ich kann nur denken, dass ich den RTree-Raumindex falsch verwende. Gedanken?
intersects()
Methode dauert länger, wenn der räumliche Index verwendet wird (siehe Zeitvergleich oben), weshalb ich nicht sicher bin, ob ich den räumlichen Index falsch verwende. Nach dem Lesen der Dokumentation und der verlinkten Beiträge denke ich, dass ich es bin, aber ich hatte gehofft, jemand könnte darauf hinweisen, wenn ich es nicht wäre.