Skip to content

Commit eb9f45c

Browse files
committedJul 24, 2017
[processing] port Random points within extent
1 parent 2723f4f commit eb9f45c

File tree

2 files changed

+86
-47
lines changed

2 files changed

+86
-47
lines changed
 

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
from .PostGISExecuteSQL import PostGISExecuteSQL
8585
from .RandomExtract import RandomExtract
8686
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
87+
from .RandomPointsExtent import RandomPointsExtent
8788
from .RegularPoints import RegularPoints
8889
from .ReverseLineDirection import ReverseLineDirection
8990
from .Ruggedness import Ruggedness
@@ -141,7 +142,6 @@
141142
# from .PointsDisplacement import PointsDisplacement
142143
# from .PointsFromPolygons import PointsFromPolygons
143144
# from .PointsFromLines import PointsFromLines
144-
# from .RandomPointsExtent import RandomPointsExtent
145145
# from .RandomPointsLayer import RandomPointsLayer
146146
# from .RandomPointsPolygonsFixed import RandomPointsPolygonsFixed
147147
# from .RandomPointsPolygonsVariable import RandomPointsPolygonsVariable
@@ -272,6 +272,7 @@ def getAlgs(self):
272272
PostGISExecuteSQL(),
273273
RandomExtract(),
274274
RandomExtractWithinSubsets(),
275+
RandomPointsExtent(),
275276
RegularPoints(),
276277
ReverseLineDirection(),
277278
Ruggedness(),

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

Lines changed: 84 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,39 @@
3131

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

4052
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
41-
from processing.core.parameters import ParameterExtent
42-
from processing.core.parameters import ParameterNumber
43-
from processing.core.parameters import ParameterCrs
44-
from processing.core.outputs import OutputVector
45-
from processing.tools import vector, dataobjects
53+
from processing.tools import vector
4654

4755
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
4856

4957

5058
class RandomPointsExtent(QgisAlgorithm):
5159

5260
EXTENT = 'EXTENT'
53-
POINT_NUMBER = 'POINT_NUMBER'
61+
POINTS_NUMBER = 'POINTS_NUMBER'
5462
MIN_DISTANCE = 'MIN_DISTANCE'
63+
TARGET_CRS = 'TARGET_CRS'
64+
ADD_Z = 'ADD_Z'
65+
ADD_M = 'ADD_M'
5566
OUTPUT = 'OUTPUT'
56-
CRS = 'CRS'
5767

5868
def icon(self):
5969
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'random_points.png'))
@@ -65,15 +75,33 @@ def __init__(self):
6575
super().__init__()
6676

6777
def initAlgorithm(self, config=None):
68-
self.addParameter(ParameterExtent(self.EXTENT,
69-
self.tr('Input extent'), optional=False))
70-
self.addParameter(ParameterNumber(self.POINT_NUMBER,
71-
self.tr('Points number'), 1, None, 1))
72-
self.addParameter(ParameterNumber(self.MIN_DISTANCE,
73-
self.tr('Minimum distance'), 0.0, None, 0.0))
74-
self.addParameter(ParameterCrs(self.CRS,
75-
self.tr('Output layer CRS'), 'ProjectCrs'))
76-
self.addOutput(OutputVector(self.OUTPUT, self.tr('Random points'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
78+
self.addParameter(QgsProcessingParameterExtent(self.EXTENT, self.tr('Input extent')))
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+
self.addParameter(QgsProcessingParameterCrs(self.TARGET_CRS,
88+
self.tr('Target CRS'),
89+
'ProjectCrs'))
90+
91+
params = []
92+
params.append(QgsProcessingParameterBoolean(self.ADD_Z,
93+
self.tr('Add Z coordinate'),
94+
False))
95+
params.append(QgsProcessingParameterBoolean(self.ADD_M,
96+
self.tr('Add M coordinate'),
97+
False))
98+
for p in params:
99+
p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
100+
self.addParameter(p)
101+
102+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
103+
self.tr('Random points'),
104+
type=QgsProcessing.TypeVectorPoint))
77105

78106
def name(self):
79107
return 'randompointsinextent'
@@ -82,24 +110,26 @@ def displayName(self):
82110
return self.tr('Random points in extent')
83111

84112
def processAlgorithm(self, parameters, context, feedback):
85-
pointCount = int(self.getParameterValue(self.POINT_NUMBER))
86-
minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
87-
extent = str(self.getParameterValue(self.EXTENT)).split(',')
113+
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
114+
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
115+
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
116+
crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
117+
addZ = self.parameterAsBool(parameters, self.ADD_Z, context)
118+
addM = self.parameterAsBool(parameters, self.ADD_M, context)
88119

89-
crsId = self.getParameterValue(self.CRS)
90-
crs = QgsCoordinateReferenceSystem()
91-
crs.createFromUserInput(crsId)
92-
93-
xMin = float(extent[0])
94-
xMax = float(extent[1])
95-
yMin = float(extent[2])
96-
yMax = float(extent[3])
97-
extent = QgsGeometry().fromRect(
98-
QgsRectangle(xMin, yMin, xMax, yMax))
120+
extent = QgsGeometry().fromRect(bbox)
99121

100122
fields = QgsFields()
101123
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
102-
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, crs, context)
124+
125+
wkbType = QgsWkbTypes.Point
126+
if addZ:
127+
wkbType = QgsWkbTypes.addZ(wkbType)
128+
if addM:
129+
wkbType = QgsWkbTypes.addM(wkbType)
130+
131+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
132+
fields, wkbType, crs)
103133

104134
nPoints = 0
105135
nIterations = 0
@@ -112,27 +142,35 @@ def processAlgorithm(self, parameters, context, feedback):
112142
random.seed()
113143

114144
while nIterations < maxIterations and nPoints < pointCount:
115-
rx = xMin + (xMax - xMin) * random.random()
116-
ry = yMin + (yMax - yMin) * random.random()
117-
118-
pnt = QgsPointXY(rx, ry)
119-
geom = QgsGeometry.fromPoint(pnt)
145+
if feedback.isCanceled():
146+
break
147+
148+
rx = bbox.xMinimum() + bbox.width() * random.random()
149+
ry = bbox.yMinimum() + bbox.height() * random.random()
150+
151+
pnt = QgsPoint(rx, ry)
152+
p = QgsPointXY(rx, ry)
153+
if addZ:
154+
pnt.addZValue(0.0)
155+
if addM:
156+
pnt.addMValue(0.0)
157+
geom = QgsGeometry(pnt)
120158
if geom.within(extent) and \
121-
vector.checkMinDistance(pnt, index, minDistance, points):
159+
vector.checkMinDistance(p, index, minDistance, points):
122160
f = QgsFeature(nPoints)
123161
f.initAttributes(1)
124162
f.setFields(fields)
125163
f.setAttribute('id', nPoints)
126164
f.setGeometry(geom)
127-
writer.addFeature(f, QgsFeatureSink.FastInsert)
165+
sink.addFeature(f, QgsFeatureSink.FastInsert)
128166
index.insertFeature(f)
129-
points[nPoints] = pnt
167+
points[nPoints] = p
130168
nPoints += 1
131169
feedback.setProgress(int(nPoints * total))
132170
nIterations += 1
133171

134172
if nPoints < pointCount:
135-
QgsMessageLog.logMessage(self.tr('Can not generate requested number of random points. '
136-
'Maximum number of attempts exceeded.'), self.tr('Processing'), QgsMessageLog.INFO)
173+
feedback.pushInfo(self.tr('Could not generate requested number of random points. '
174+
'Maximum number of attempts exceeded.'))
137175

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

0 commit comments

Comments
 (0)
Please sign in to comment.