Skip to content

Commit 68687c1

Browse files
committed
Port counts points in polygon alg to new API
and add auto-reprojection support if points layer is in different CRS to polygon layer
1 parent 455769c commit 68687c1

File tree

3 files changed

+71
-70
lines changed

3 files changed

+71
-70
lines changed

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

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,18 @@
3030
from qgis.PyQt.QtGui import QIcon
3131
from qgis.PyQt.QtCore import QVariant
3232

33-
from qgis.core import QgsGeometry, QgsFeatureSink, QgsFeatureRequest, QgsFeature, QgsField, QgsProcessingUtils
33+
from qgis.core import (QgsGeometry,
34+
QgsFeatureSink,
35+
QgsFeatureRequest,
36+
QgsFeature,
37+
QgsField,
38+
QgsProcessing,
39+
QgsProcessingParameterFeatureSink,
40+
QgsProcessingParameterFeatureSource,
41+
QgsProcessingParameterString,
42+
QgsSpatialIndex)
3443

3544
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
36-
from processing.core.parameters import ParameterVector
37-
from processing.core.parameters import ParameterString
38-
from processing.core.outputs import OutputVector
39-
from processing.tools import dataobjects, vector
4045

4146
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
4247

@@ -58,13 +63,13 @@ def __init__(self):
5863
super().__init__()
5964

6065
def initAlgorithm(self, config=None):
61-
self.addParameter(ParameterVector(self.POLYGONS,
62-
self.tr('Polygons'), [dataobjects.TYPE_VECTOR_POLYGON]))
63-
self.addParameter(ParameterVector(self.POINTS,
64-
self.tr('Points'), [dataobjects.TYPE_VECTOR_POINT]))
65-
self.addParameter(ParameterString(self.FIELD,
66-
self.tr('Count field name'), 'NUMPOINTS'))
67-
self.addOutput(OutputVector(self.OUTPUT, self.tr('Count'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))
66+
self.addParameter(QgsProcessingParameterFeatureSource(self.POLYGONS,
67+
self.tr('Polygons'), [QgsProcessing.TypeVectorPolygon]))
68+
self.addParameter(QgsProcessingParameterFeatureSource(self.POINTS,
69+
self.tr('Points'), [QgsProcessing.TypeVectorPoint]))
70+
self.addParameter(QgsProcessingParameterString(self.FIELD,
71+
self.tr('Count field name'), defaultValue='NUMPOINTS'))
72+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Count'), QgsProcessing.TypeVectorPolygon))
6873

6974
def name(self):
7075
return 'countpointsinpolygon'
@@ -73,54 +78,49 @@ def displayName(self):
7378
return self.tr('Count points in polygon')
7479

7580
def processAlgorithm(self, parameters, context, feedback):
76-
polyLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.POLYGONS), context)
77-
pointLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.POINTS), context)
78-
fieldName = self.getParameterValue(self.FIELD)
81+
poly_source = self.parameterAsSource(parameters, self.POLYGONS, context)
82+
point_source = self.parameterAsSource(parameters, self.POINTS, context)
83+
field_name = self.parameterAsString(parameters, self.FIELD, context)
7984

80-
fields = polyLayer.fields()
81-
fields.append(QgsField(fieldName, QVariant.Int))
85+
fields = poly_source.fields()
86+
if fields.lookupField(field_name) < 0:
87+
fields.append(QgsField(field_name, QVariant.Int))
88+
field_index = fields.lookupField(field_name)
8289

83-
(idxCount, fieldList) = vector.findOrCreateField(polyLayer,
84-
polyLayer.fields(), fieldName)
90+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
91+
fields, poly_source.wkbType(), poly_source.sourceCrs())
8592

86-
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, polyLayer.wkbType(),
87-
polyLayer.crs(), context)
93+
spatialIndex = QgsSpatialIndex(point_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(poly_source.sourceCrs())))
8894

89-
spatialIndex = QgsProcessingUtils.createSpatialIndex(pointLayer, context)
95+
features = poly_source.getFeatures()
96+
total = 100.0 / poly_source.featureCount() if poly_source.featureCount() else 0
97+
for current, polygon_feature in enumerate(features):
98+
count = 0
99+
output_feature = QgsFeature()
100+
if polygon_feature.hasGeometry():
101+
geom = polygon_feature.geometry()
102+
engine = QgsGeometry.createGeometryEngine(geom.geometry())
103+
engine.prepareGeometry()
90104

91-
ftPoly = QgsFeature()
92-
ftPoint = QgsFeature()
93-
outFeat = QgsFeature()
94-
geom = QgsGeometry()
105+
count = 0
106+
points = spatialIndex.intersects(geom.boundingBox())
107+
if len(points) > 0:
108+
request = QgsFeatureRequest().setFilterFids(points).setSubsetOfAttributes([]).setDestinationCrs(poly_source.sourceCrs())
109+
for point_feature in point_source.getFeatures(request):
110+
if engine.contains(point_feature.geometry().geometry()):
111+
count += 1
95112

96-
features = QgsProcessingUtils.getFeatures(polyLayer, context)
97-
total = 100.0 / polyLayer.featureCount() if polyLayer.featureCount() else 0
98-
for current, ftPoly in enumerate(features):
99-
geom = ftPoly.geometry()
100-
engine = QgsGeometry.createGeometryEngine(geom.geometry())
101-
engine.prepareGeometry()
113+
output_feature.setGeometry(geom)
102114

103-
attrs = ftPoly.attributes()
115+
attrs = polygon_feature.attributes()
104116

105-
count = 0
106-
points = spatialIndex.intersects(geom.boundingBox())
107-
if len(points) > 0:
108-
request = QgsFeatureRequest().setFilterFids(points).setSubsetOfAttributes([])
109-
fit = pointLayer.getFeatures(request)
110-
ftPoint = QgsFeature()
111-
while fit.nextFeature(ftPoint):
112-
tmpGeom = ftPoint.geometry()
113-
if engine.contains(tmpGeom.geometry()):
114-
count += 1
115-
116-
outFeat.setGeometry(geom)
117-
if idxCount == len(attrs):
117+
if field_index == len(attrs):
118118
attrs.append(count)
119119
else:
120-
attrs[idxCount] = count
121-
outFeat.setAttributes(attrs)
122-
writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
120+
attrs[field_index] = count
121+
output_feature.setAttributes(attrs)
122+
sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
123123

124124
feedback.setProgress(int(current * total))
125125

126-
del writer
126+
return {self.OUTPUT: dest_id}

python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
from .Intersection import Intersection
6666
from .LinesToPolygons import LinesToPolygons
6767
from .Merge import Merge
68+
from .PointsInPolygon import PointsInPolygon
6869
from .PointsLayerFromTable import PointsLayerFromTable
6970
from .PolygonsToLines import PolygonsToLines
7071
from .PostGISExecuteSQL import PostGISExecuteSQL
@@ -85,7 +86,6 @@
8586
from .ZonalStatistics import ZonalStatistics
8687

8788
# from .ExtractByLocation import ExtractByLocation
88-
# from .PointsInPolygon import PointsInPolygon
8989
# from .PointsInPolygonUnique import PointsInPolygonUnique
9090
# from .PointsInPolygonWeighted import PointsInPolygonWeighted
9191
# from .SumLines import SumLines
@@ -185,7 +185,7 @@ def __init__(self):
185185
self.externalAlgs = []
186186

187187
def getAlgs(self):
188-
# algs = [SumLines(), PointsInPolygon(),
188+
# algs = [SumLines(),
189189
# PointsInPolygonWeighted(), PointsInPolygonUnique(),
190190
# NearestNeighbourAnalysis(), MeanCoords(),
191191
# LinesIntersection(), UniqueValues(), PointDistance(),
@@ -257,11 +257,13 @@ def getAlgs(self):
257257
ExtentFromLayer(),
258258
FixGeometry(),
259259
GridPolygon(),
260+
Heatmap(),
260261
ImportIntoPostGIS(),
261262
ImportIntoSpatialite(),
262263
Intersection(),
263264
LinesToPolygons(),
264265
Merge(),
266+
PointsInPolygon(),
265267
PointsLayerFromTable(),
266268
PolygonsToLines(),
267269
PostGISExecuteSQL(),
@@ -279,8 +281,7 @@ def getAlgs(self):
279281
Union(),
280282
VectorSplit(),
281283
VoronoiPolygons(),
282-
ZonalStatistics(),
283-
Heatmap()
284+
ZonalStatistics()
284285
]
285286

286287
if hasPlotly:

python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,22 +1016,22 @@ tests:
10161016
# OUTPUT:
10171017
# name: expected/add_geometry_pointz.gml
10181018
# type: vector
1019-
#
1020-
# - algorithm: qgis:countpointsinpolygon
1021-
# name: Count points in polygon
1022-
# params:
1023-
# FIELD: NUMPOINTS
1024-
# POINTS:
1025-
# name: points_in_polys.gml
1026-
# type: vector
1027-
# POLYGONS:
1028-
# name: polys.gml
1029-
# type: vector
1030-
# results:
1031-
# OUTPUT:
1032-
# name: expected/points_in_polys.gml
1033-
# type: vector
1034-
#
1019+
1020+
- algorithm: qgis:countpointsinpolygon
1021+
name: Count points in polygon
1022+
params:
1023+
FIELD: NUMPOINTS
1024+
POINTS:
1025+
name: points_in_polys.gml
1026+
type: vector
1027+
POLYGONS:
1028+
name: polys.gml
1029+
type: vector
1030+
results:
1031+
OUTPUT:
1032+
name: expected/points_in_polys.gml
1033+
type: vector
1034+
10351035
- algorithm: qgis:aspect
10361036
name: Aspect from QGIS analysis library
10371037
params:

0 commit comments

Comments
 (0)