Pour les comparaisons, regardez spatiale plus efficace se joindre en Python sans QGIS, ArcGIS, PostGIS, etc . La solution présentée utilise les modules Python Fiona , Shapely et rtree (Spatial Index).
Avec PyQGIS et le même exemple deux couches, point
et polygon
:
1) Sans indice spatial:
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) Avec l' index spatial 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
Que signifient ces indices?
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)]]
Mêmes conclusions que dans Jointure spatiale plus efficace en Python sans QGIS, ArcGIS, PostGIS, etc .:
- Sans et index, vous devez parcourir toutes les géométries (polygones et points).
- Avec un index spatial englobant (QgsSpatialIndex ()), vous itérez uniquement à travers les géométries qui ont une chance de se croiser avec votre géométrie actuelle (`` filtre '' qui peut économiser une quantité considérable de calculs et de temps ...).
- Vous pouvez également utiliser d' autres index spatial modules Python ( rtree , Pyrtree ou QuadTree ) avec PyQGIS comme dans l' aide d' un index spatial QGIS pour accélérer votre code (avec QgsSpatialIndex () et rtree )
- mais un indice spatial n'est pas une baguette magique. Lorsqu'une très grande partie de l'ensemble de données doit être récupérée, un index spatial ne peut pas apporter d'avantage de vitesse.
Autre exemple dans SIG se: Comment trouver la ligne la plus proche d'un point dans QGIS? [dupliquer]