Skip to content

Commit 596b56c

Browse files
committedNov 13, 2015
Faster PointsInPolygon(+Unique/Weighted) algorithms
- Avoid use of seperate feature requests for every point - Use GEOS prepared geometries when testing for point containment Quick stats: ~1500 point layer BEFORE: 17 seconds AFTER: 3 seconds ~900k point layer BEFORE: 30 mins = canceled at 20% AFTER: 2.5 mins = 100% complete
1 parent 7c8177e commit 596b56c

File tree

3 files changed

+25
-29
lines changed

3 files changed

+25
-29
lines changed
 

‎python/plugins/processing/algs/qgis/PointsInPolygon.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,25 @@ def processAlgorithm(self, progress):
7676
geom = QgsGeometry()
7777

7878
current = 0
79-
hasIntersections = False
8079

8180
features = vector.features(polyLayer)
8281
total = 100.0 / float(len(features))
8382
for ftPoly in features:
8483
geom = ftPoly.geometry()
84+
engine = QgsGeometry.createGeometryEngine(geom.geometry())
85+
engine.prepareGeometry()
86+
8587
attrs = ftPoly.attributes()
8688

8789
count = 0
88-
hasIntersections = False
8990
points = spatialIndex.intersects(geom.boundingBox())
9091
if len(points) > 0:
91-
hasIntersections = True
92-
93-
if hasIntersections:
94-
for i in points:
95-
request = QgsFeatureRequest().setFilterFid(i)
96-
ftPoint = pointLayer.getFeatures(request).next()
97-
tmpGeom = QgsGeometry(ftPoint.geometry())
98-
if geom.contains(tmpGeom):
92+
request = QgsFeatureRequest().setFilterFids(points)
93+
fit = pointLayer.getFeatures(request)
94+
ftPoint = QgsFeature()
95+
while fit.nextFeature(ftPoint):
96+
tmpGeom = ftPoint.geometry()
97+
if engine.contains(tmpGeom.geometry()):
9998
count += 1
10099

101100
outFeat.setGeometry(geom)

‎python/plugins/processing/algs/qgis/PointsInPolygonUnique.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,26 +80,25 @@ def processAlgorithm(self, progress):
8080
geom = QgsGeometry()
8181

8282
current = 0
83-
hasIntersections = False
8483

8584
features = vector.features(polyLayer)
8685
total = 100.0 / float(len(features))
8786
for ftPoly in features:
8887
geom = ftPoly.geometry()
88+
engine = QgsGeometry.createGeometryEngine(geom.geometry())
89+
engine.prepareGeometry()
90+
8991
attrs = ftPoly.attributes()
9092

9193
classes = []
92-
hasIntersections = False
9394
points = spatialIndex.intersects(geom.boundingBox())
9495
if len(points) > 0:
95-
hasIntersections = True
96-
97-
if hasIntersections:
98-
for i in points:
99-
request = QgsFeatureRequest().setFilterFid(i)
100-
ftPoint = pointLayer.getFeatures(request).next()
96+
request = QgsFeatureRequest().setFilterFids(points)
97+
fit = pointLayer.getFeatures(request)
98+
ftPoint = QgsFeature()
99+
while fit.nextFeature(ftPoint):
101100
tmpGeom = QgsGeometry(ftPoint.geometry())
102-
if geom.contains(tmpGeom):
101+
if engine.contains(tmpGeom.geometry()):
103102
clazz = ftPoint.attributes()[classFieldIndex]
104103
if clazz not in classes:
105104
classes.append(clazz)

‎python/plugins/processing/algs/qgis/PointsInPolygonWeighted.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,27 +86,25 @@ def processAlgorithm(self, progress):
8686
geom = QgsGeometry()
8787

8888
current = 0
89-
hasIntersections = False
90-
9189
features = vector.features(polyLayer)
9290
total = 100.0 / float(len(features))
9391
for ftPoly in features:
9492
geom = ftPoly.geometry()
93+
engine = QgsGeometry.createGeometryEngine(geom.geometry())
94+
engine.prepareGeometry()
95+
9596
attrs = ftPoly.attributes()
9697

9798
count = 0
98-
hasIntersections = False
9999
points = spatialIndex.intersects(geom.boundingBox())
100100
if len(points) > 0:
101-
hasIntersections = True
102-
103-
if hasIntersections:
104101
progress.setText(unicode(len(points)))
105-
for i in points:
106-
request = QgsFeatureRequest().setFilterFid(i)
107-
ftPoint = pointLayer.getFeatures(request).next()
102+
request = QgsFeatureRequest().setFilterFids(points)
103+
fit = pointLayer.getFeatures(request)
104+
ftPoint = QgsFeature()
105+
while fit.nextFeature(ftPoint):
108106
tmpGeom = QgsGeometry(ftPoint.geometry())
109-
if geom.contains(tmpGeom):
107+
if engine.contains(tmpGeom.geometry()):
110108
weight = unicode(ftPoint.attributes()[fieldIdx])
111109
try:
112110
count += float(weight)

0 commit comments

Comments
 (0)
Please sign in to comment.