Skip to content

Commit ae2e32b

Browse files
committedJul 24, 2017
[processing] restore Random points in layer bounds
1 parent eb9f45c commit ae2e32b

File tree

2 files changed

+86
-34
lines changed

2 files changed

+86
-34
lines changed
 

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
from .RandomExtract import RandomExtract
8686
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
8787
from .RandomPointsExtent import RandomPointsExtent
88+
from .RandomPointsLayer import RandomPointsLayer
8889
from .RegularPoints import RegularPoints
8990
from .ReverseLineDirection import ReverseLineDirection
9091
from .Ruggedness import Ruggedness
@@ -142,7 +143,6 @@
142143
# from .PointsDisplacement import PointsDisplacement
143144
# from .PointsFromPolygons import PointsFromPolygons
144145
# from .PointsFromLines import PointsFromLines
145-
# from .RandomPointsLayer import RandomPointsLayer
146146
# from .RandomPointsPolygonsFixed import RandomPointsPolygonsFixed
147147
# from .RandomPointsPolygonsVariable import RandomPointsPolygonsVariable
148148
# from .RandomPointsAlongLines import RandomPointsAlongLines
@@ -273,6 +273,7 @@ def getAlgs(self):
273273
RandomExtract(),
274274
RandomExtractWithinSubsets(),
275275
RandomPointsExtent(),
276+
RandomPointsLayer(),
276277
RegularPoints(),
277278
ReverseLineDirection(),
278279
Ruggedness(),

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

Lines changed: 84 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,37 @@
3030

3131
from qgis.PyQt.QtGui import QIcon
3232
from qgis.PyQt.QtCore import QVariant
33-
from qgis.core import (QgsGeometry, QgsFeatureSink, QgsFields, QgsField, QgsSpatialIndex, QgsWkbTypes,
34-
QgsPointXY, QgsFeature, QgsFeatureRequest,
35-
QgsMessageLog,
36-
QgsProcessingUtils)
33+
from qgis.core import (QgsField,
34+
QgsFeatureSink,
35+
QgsFeature,
36+
QgsFields,
37+
QgsGeometry,
38+
QgsPoint,
39+
QgsPointXY,
40+
QgsWkbTypes,
41+
QgsSpatialIndex,
42+
QgsFeatureRequest,
43+
QgsProcessing,
44+
QgsProcessingException,
45+
QgsProcessingParameterNumber,
46+
QgsProcessingParameterBoolean,
47+
QgsProcessingParameterFeatureSource,
48+
QgsProcessingParameterFeatureSink,
49+
QgsProcessingParameterDefinition)
3750

3851
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
39-
from processing.core.parameters import ParameterVector
40-
from processing.core.parameters import ParameterNumber
41-
from processing.core.outputs import OutputVector
42-
from processing.tools import dataobjects, vector
52+
from processing.tools import vector
4353

4454
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
4555

4656

4757
class RandomPointsLayer(QgisAlgorithm):
4858

49-
VECTOR = 'VECTOR'
50-
POINT_NUMBER = 'POINT_NUMBER'
59+
INPUT = 'INPUT'
60+
POINTS_NUMBER = 'POINTS_NUMBER'
5161
MIN_DISTANCE = 'MIN_DISTANCE'
62+
ADD_Z = 'ADD_Z'
63+
ADD_M = 'ADD_M'
5264
OUTPUT = 'OUTPUT'
5365

5466
def icon(self):
@@ -61,13 +73,31 @@ def __init__(self):
6173
super().__init__()
6274

6375
def initAlgorithm(self, config=None):
64-
self.addParameter(ParameterVector(self.VECTOR,
65-
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_POLYGON]))
66-
self.addParameter(ParameterNumber(self.POINT_NUMBER,
67-
self.tr('Points number'), 1, None, 1))
68-
self.addParameter(ParameterNumber(self.MIN_DISTANCE,
69-
self.tr('Minimum distance'), 0.0, None, 0.0))
70-
self.addOutput(OutputVector(self.OUTPUT, self.tr('Random points'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
76+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
77+
self.tr('Input layer'),
78+
[QgsProcessing.TypeVectorPolygon]))
79+
self.addParameter(QgsProcessingParameterNumber(self.POINTS_NUMBER,
80+
self.tr('Number of points'),
81+
QgsProcessingParameterNumber.Integer,
82+
1, False, 1, 1000000000))
83+
self.addParameter(QgsProcessingParameterNumber(self.MIN_DISTANCE,
84+
self.tr('Minimum distance between points'),
85+
QgsProcessingParameterNumber.Double,
86+
0, False, 0, 1000000000))
87+
params = []
88+
params.append(QgsProcessingParameterBoolean(self.ADD_Z,
89+
self.tr('Add Z coordinate'),
90+
False))
91+
params.append(QgsProcessingParameterBoolean(self.ADD_M,
92+
self.tr('Add M coordinate'),
93+
False))
94+
for p in params:
95+
p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
96+
self.addParameter(p)
97+
98+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
99+
self.tr('Random points'),
100+
type=QgsProcessing.TypeVectorPoint))
71101

72102
def name(self):
73103
return 'randompointsinlayerbounds'
@@ -76,16 +106,26 @@ def displayName(self):
76106
return self.tr('Random points in layer bounds')
77107

78108
def processAlgorithm(self, parameters, context, feedback):
79-
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.VECTOR), context)
80-
pointCount = int(self.getParameterValue(self.POINT_NUMBER))
81-
minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
109+
source = self.parameterAsSource(parameters, self.INPUT, context)
110+
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
111+
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
112+
addZ = self.parameterAsBool(parameters, self.ADD_Z, context)
113+
addM = self.parameterAsBool(parameters, self.ADD_M, context)
82114

83-
bbox = layer.extent()
84-
idxLayer = QgsProcessingUtils.createSpatialIndex(layer, context)
115+
bbox = source.sourceExtent()
116+
sourceIndex = QgsSpatialIndex(source, feedback)
85117

86118
fields = QgsFields()
87119
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
88-
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context)
120+
121+
wkbType = QgsWkbTypes.Point
122+
if addZ:
123+
wkbType = QgsWkbTypes.addZ(wkbType)
124+
if addM:
125+
wkbType = QgsWkbTypes.addM(wkbType)
126+
127+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
128+
fields, wkbType, source.sourceCrs())
89129

90130
nPoints = 0
91131
nIterations = 0
@@ -98,32 +138,43 @@ def processAlgorithm(self, parameters, context, feedback):
98138
random.seed()
99139

100140
while nIterations < maxIterations and nPoints < pointCount:
141+
if feedback.isCanceled():
142+
break
143+
101144
rx = bbox.xMinimum() + bbox.width() * random.random()
102145
ry = bbox.yMinimum() + bbox.height() * random.random()
103146

104-
pnt = QgsPointXY(rx, ry)
105-
geom = QgsGeometry.fromPoint(pnt)
106-
ids = idxLayer.intersects(geom.buffer(5, 5).boundingBox())
147+
pnt = QgsPoint(rx, ry)
148+
p = QgsPointXY(rx, ry)
149+
if addZ:
150+
pnt.addZValue(0.0)
151+
if addM:
152+
pnt.addMValue(0.0)
153+
geom = QgsGeometry(pnt)
154+
ids = sourceIndex.intersects(geom.buffer(5, 5).boundingBox())
107155
if len(ids) > 0 and \
108-
vector.checkMinDistance(pnt, index, minDistance, points):
156+
vector.checkMinDistance(p, index, minDistance, points):
109157
request = QgsFeatureRequest().setFilterFids(ids).setSubsetOfAttributes([])
110-
for f in layer.getFeatures(request):
158+
for f in source.getFeatures(request):
159+
if feedback.isCanceled():
160+
break
161+
111162
tmpGeom = f.geometry()
112163
if geom.within(tmpGeom):
113164
f = QgsFeature(nPoints)
114165
f.initAttributes(1)
115166
f.setFields(fields)
116167
f.setAttribute('id', nPoints)
117168
f.setGeometry(geom)
118-
writer.addFeature(f, QgsFeatureSink.FastInsert)
169+
sink.addFeature(f, QgsFeatureSink.FastInsert)
119170
index.insertFeature(f)
120-
points[nPoints] = pnt
171+
points[nPoints] = p
121172
nPoints += 1
122173
feedback.setProgress(int(nPoints * total))
123174
nIterations += 1
124175

125176
if nPoints < pointCount:
126-
QgsMessageLog.logMessage(self.tr('Can not generate requested number of random points. '
127-
'Maximum number of attempts exceeded.'), self.tr('Processing'), QgsMessageLog.INFO)
177+
feedback.pushInfo(self.tr('Could not generate requested number of random points. '
178+
'Maximum number of attempts exceeded.'))
128179

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

0 commit comments

Comments
 (0)
Please sign in to comment.