mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[processing] port Random points within extent
This commit is contained in:
parent
2723f4f199
commit
eb9f45cbb0
@ -84,6 +84,7 @@ from .PolygonsToLines import PolygonsToLines
|
||||
from .PostGISExecuteSQL import PostGISExecuteSQL
|
||||
from .RandomExtract import RandomExtract
|
||||
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
|
||||
from .RandomPointsExtent import RandomPointsExtent
|
||||
from .RegularPoints import RegularPoints
|
||||
from .ReverseLineDirection import ReverseLineDirection
|
||||
from .Ruggedness import Ruggedness
|
||||
@ -141,7 +142,6 @@ from .ZonalStatistics import ZonalStatistics
|
||||
# from .PointsDisplacement import PointsDisplacement
|
||||
# from .PointsFromPolygons import PointsFromPolygons
|
||||
# from .PointsFromLines import PointsFromLines
|
||||
# from .RandomPointsExtent import RandomPointsExtent
|
||||
# from .RandomPointsLayer import RandomPointsLayer
|
||||
# from .RandomPointsPolygonsFixed import RandomPointsPolygonsFixed
|
||||
# from .RandomPointsPolygonsVariable import RandomPointsPolygonsVariable
|
||||
@ -272,6 +272,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
PostGISExecuteSQL(),
|
||||
RandomExtract(),
|
||||
RandomExtractWithinSubsets(),
|
||||
RandomPointsExtent(),
|
||||
RegularPoints(),
|
||||
ReverseLineDirection(),
|
||||
Ruggedness(),
|
||||
|
@ -31,18 +31,26 @@ import random
|
||||
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
from qgis.PyQt.QtCore import QVariant
|
||||
from qgis.core import (QgsGeometry, QgsFeatureSink, QgsRectangle, QgsFeature, QgsFields, QgsWkbTypes,
|
||||
QgsField, QgsSpatialIndex, QgsPointXY,
|
||||
QgsCoordinateReferenceSystem,
|
||||
QgsMessageLog,
|
||||
QgsProcessingUtils)
|
||||
from qgis.core import (QgsField,
|
||||
QgsFeatureSink,
|
||||
QgsFeature,
|
||||
QgsFields,
|
||||
QgsGeometry,
|
||||
QgsPoint,
|
||||
QgsPointXY,
|
||||
QgsWkbTypes,
|
||||
QgsSpatialIndex,
|
||||
QgsProcessing,
|
||||
QgsProcessingException,
|
||||
QgsProcessingParameterExtent,
|
||||
QgsProcessingParameterNumber,
|
||||
QgsProcessingParameterCrs,
|
||||
QgsProcessingParameterBoolean,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingParameterDefinition)
|
||||
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.core.parameters import ParameterExtent
|
||||
from processing.core.parameters import ParameterNumber
|
||||
from processing.core.parameters import ParameterCrs
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.tools import vector, dataobjects
|
||||
from processing.tools import vector
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
@ -50,10 +58,12 @@ pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
class RandomPointsExtent(QgisAlgorithm):
|
||||
|
||||
EXTENT = 'EXTENT'
|
||||
POINT_NUMBER = 'POINT_NUMBER'
|
||||
POINTS_NUMBER = 'POINTS_NUMBER'
|
||||
MIN_DISTANCE = 'MIN_DISTANCE'
|
||||
TARGET_CRS = 'TARGET_CRS'
|
||||
ADD_Z = 'ADD_Z'
|
||||
ADD_M = 'ADD_M'
|
||||
OUTPUT = 'OUTPUT'
|
||||
CRS = 'CRS'
|
||||
|
||||
def icon(self):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'random_points.png'))
|
||||
@ -65,15 +75,33 @@ class RandomPointsExtent(QgisAlgorithm):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.addParameter(ParameterExtent(self.EXTENT,
|
||||
self.tr('Input extent'), optional=False))
|
||||
self.addParameter(ParameterNumber(self.POINT_NUMBER,
|
||||
self.tr('Points number'), 1, None, 1))
|
||||
self.addParameter(ParameterNumber(self.MIN_DISTANCE,
|
||||
self.tr('Minimum distance'), 0.0, None, 0.0))
|
||||
self.addParameter(ParameterCrs(self.CRS,
|
||||
self.tr('Output layer CRS'), 'ProjectCrs'))
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Random points'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
|
||||
self.addParameter(QgsProcessingParameterExtent(self.EXTENT, self.tr('Input extent')))
|
||||
self.addParameter(QgsProcessingParameterNumber(self.POINTS_NUMBER,
|
||||
self.tr('Number of points'),
|
||||
QgsProcessingParameterNumber.Integer,
|
||||
1, False, 1, 1000000000))
|
||||
self.addParameter(QgsProcessingParameterNumber(self.MIN_DISTANCE,
|
||||
self.tr('Minimum distance between points'),
|
||||
QgsProcessingParameterNumber.Double,
|
||||
0, False, 0, 1000000000))
|
||||
self.addParameter(QgsProcessingParameterCrs(self.TARGET_CRS,
|
||||
self.tr('Target CRS'),
|
||||
'ProjectCrs'))
|
||||
|
||||
params = []
|
||||
params.append(QgsProcessingParameterBoolean(self.ADD_Z,
|
||||
self.tr('Add Z coordinate'),
|
||||
False))
|
||||
params.append(QgsProcessingParameterBoolean(self.ADD_M,
|
||||
self.tr('Add M coordinate'),
|
||||
False))
|
||||
for p in params:
|
||||
p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
|
||||
self.addParameter(p)
|
||||
|
||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
|
||||
self.tr('Random points'),
|
||||
type=QgsProcessing.TypeVectorPoint))
|
||||
|
||||
def name(self):
|
||||
return 'randompointsinextent'
|
||||
@ -82,24 +110,26 @@ class RandomPointsExtent(QgisAlgorithm):
|
||||
return self.tr('Random points in extent')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
pointCount = int(self.getParameterValue(self.POINT_NUMBER))
|
||||
minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
|
||||
extent = str(self.getParameterValue(self.EXTENT)).split(',')
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
|
||||
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
|
||||
crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
|
||||
addZ = self.parameterAsBool(parameters, self.ADD_Z, context)
|
||||
addM = self.parameterAsBool(parameters, self.ADD_M, context)
|
||||
|
||||
crsId = self.getParameterValue(self.CRS)
|
||||
crs = QgsCoordinateReferenceSystem()
|
||||
crs.createFromUserInput(crsId)
|
||||
|
||||
xMin = float(extent[0])
|
||||
xMax = float(extent[1])
|
||||
yMin = float(extent[2])
|
||||
yMax = float(extent[3])
|
||||
extent = QgsGeometry().fromRect(
|
||||
QgsRectangle(xMin, yMin, xMax, yMax))
|
||||
extent = QgsGeometry().fromRect(bbox)
|
||||
|
||||
fields = QgsFields()
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, crs, context)
|
||||
|
||||
wkbType = QgsWkbTypes.Point
|
||||
if addZ:
|
||||
wkbType = QgsWkbTypes.addZ(wkbType)
|
||||
if addM:
|
||||
wkbType = QgsWkbTypes.addM(wkbType)
|
||||
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
fields, wkbType, crs)
|
||||
|
||||
nPoints = 0
|
||||
nIterations = 0
|
||||
@ -112,27 +142,35 @@ class RandomPointsExtent(QgisAlgorithm):
|
||||
random.seed()
|
||||
|
||||
while nIterations < maxIterations and nPoints < pointCount:
|
||||
rx = xMin + (xMax - xMin) * random.random()
|
||||
ry = yMin + (yMax - yMin) * random.random()
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
pnt = QgsPointXY(rx, ry)
|
||||
geom = QgsGeometry.fromPoint(pnt)
|
||||
rx = bbox.xMinimum() + bbox.width() * random.random()
|
||||
ry = bbox.yMinimum() + bbox.height() * random.random()
|
||||
|
||||
pnt = QgsPoint(rx, ry)
|
||||
p = QgsPointXY(rx, ry)
|
||||
if addZ:
|
||||
pnt.addZValue(0.0)
|
||||
if addM:
|
||||
pnt.addMValue(0.0)
|
||||
geom = QgsGeometry(pnt)
|
||||
if geom.within(extent) and \
|
||||
vector.checkMinDistance(pnt, index, minDistance, points):
|
||||
vector.checkMinDistance(p, index, minDistance, points):
|
||||
f = QgsFeature(nPoints)
|
||||
f.initAttributes(1)
|
||||
f.setFields(fields)
|
||||
f.setAttribute('id', nPoints)
|
||||
f.setGeometry(geom)
|
||||
writer.addFeature(f, QgsFeatureSink.FastInsert)
|
||||
sink.addFeature(f, QgsFeatureSink.FastInsert)
|
||||
index.insertFeature(f)
|
||||
points[nPoints] = pnt
|
||||
points[nPoints] = p
|
||||
nPoints += 1
|
||||
feedback.setProgress(int(nPoints * total))
|
||||
nIterations += 1
|
||||
|
||||
if nPoints < pointCount:
|
||||
QgsMessageLog.logMessage(self.tr('Can not generate requested number of random points. '
|
||||
'Maximum number of attempts exceeded.'), self.tr('Processing'), QgsMessageLog.INFO)
|
||||
feedback.pushInfo(self.tr('Could not generate requested number of random points. '
|
||||
'Maximum number of attempts exceeded.'))
|
||||
|
||||
del writer
|
||||
return {self.OUTPUT: dest_id}
|
||||
|
Loading…
x
Reference in New Issue
Block a user