Per i confronti, guarda Join spaziale più efficiente in Python senza QGIS, ArcGIS, PostGIS, ecc . La soluzione presentata utilizza i moduli Python Fiona , Shapely e rtree (Spatial Index).
Con PyQGIS e lo stesso esempio due livelli point
e polygon
:
1) Senza un indice spaziale:
polygons = [feature for feature in polygon.getFeatures()]
points = [feature for feature in point.getFeatures()]
for pt in points:
point = pt.geometry()
for pl in polygons:
poly = pl.geometry()
if poly.contains(point):
print point.asPoint(), poly.asPolygon()
(184127,122472) [[(183372,123361), (184078,123130), (184516,122631), (184516,122265), (183676,122144), (183067,122570), (183128,123105), (183372,123361)]]
(183457,122850) [[(183372,123361), (184078,123130), (184516,122631), (184516,122265), (183676,122144), (183067,122570), (183128,123105), (183372,123361)]]
(184723,124043) [[(184200,124737), (185368,124372), (185466,124055), (185515,123714), (184955,123580), (184675,123471), (184139,123787), (184200,124737)]]
(182179,124067) [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
2) Con l' indice spaziale R-Tree PyQGIS:
# build the spatial index with all the polygons and not only a bounding box
index = QgsSpatialIndex()
for poly in polygons:
index.insertFeature(poly)
# intersections with the index
# indices of the index for the intersections
for pt in points:
point = pt.geometry()
for id in index.intersects(point.boundingBox()):
print id
0
0
1
2
Cosa significano questi indici?
for i, pt in enumerate(points):
point = pt.geometry()
for id in index.intersects(point.boundingBox()):
print "Point ", i, points[i].geometry().asPoint(), "is in Polygon ", id, polygons[id].geometry().asPolygon()
Point 1 (184127,122472) is in Polygon 0 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
Point 2 (183457,122850) is in Polygon 0 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
Point 4 (184723,124043) is in Polygon 1 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
Point 6 (182179,124067) is in Polygon 2 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
Stesse conclusioni dell'adesione spaziale più efficiente in Python senza QGIS, ArcGIS, PostGIS, ecc .:
- Senza e indicizzare, è necessario scorrere tutte le geometrie (poligoni e punti).
- Con un indice spaziale delimitante (QgsSpatialIndex ()), si esegue l'iterazione solo attraverso le geometrie che hanno la possibilità di intersecarsi con la geometria corrente ('filtro' che può risparmiare una notevole quantità di calcoli e tempo ...).
- È inoltre possibile utilizzare altri moduli Python indice spaziale ( R-tree , Pyrtree o quadtree ) con PyQGIS come in Utilizzo di un QGIS indice spaziale per velocizzare il codice (con QgsSpatialIndex () e R-tree )
- ma un indice spaziale non è una bacchetta magica. Quando è necessario recuperare gran parte del set di dati, un indice spaziale non può offrire alcun vantaggio in termini di velocità.
Altro esempio in GIS: Come trovare la linea più vicina a un punto in QGIS? [duplicare]