Para las comparaciones, ver más eficiente Unión espacial en Python sin QGIS, ArcGIS, PostGIS, etc . La solución presentada utiliza los módulos Python Fiona , Shapely y rtree (Spatial Index).
Con PyQGIS y el mismo ejemplo dos capas, point
y polygon
:
1) Sin un índice espacial:
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 el índice espacial 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
¿Qué significan estos índices?
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)]]
Mismas conclusiones que en el Más Eficiente Unión espacial en Python sin QGIS, ArcGIS, PostGIS, etc :
- Sin un índice, debe recorrer en iteración todas las geometrías (polígonos y puntos).
- Con un índice espacial delimitador (QgsSpatialIndex ()), itera solo a través de las geometrías que tienen la posibilidad de cruzarse con su geometría actual ('filtro' que puede ahorrar una cantidad considerable de cálculos y tiempo ...).
- También puede usar otros módulos de Python de índice espacial ( rtree , Pyrtree o Quadtree ) con PyQGIS como en Uso de un índice espacial QGIS para acelerar su código (con QgsSpatialIndex () y rtree )
- pero un índice espacial no es una varita mágica. Cuando se debe recuperar una gran parte del conjunto de datos, un índice espacial no puede proporcionar ningún beneficio de velocidad.
Otro ejemplo en GIS se: ¿Cómo encontrar la línea más cercana a un punto en QGIS? [duplicar]