mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[processing] port Random points in polygons
This commit is contained in:
parent
ae2e32b36e
commit
f8b0c06942
@ -86,6 +86,7 @@ from .RandomExtract import RandomExtract
|
||||
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
|
||||
from .RandomPointsExtent import RandomPointsExtent
|
||||
from .RandomPointsLayer import RandomPointsLayer
|
||||
from .RandomPointsPolygons import RandomPointsPolygons
|
||||
from .RegularPoints import RegularPoints
|
||||
from .ReverseLineDirection import ReverseLineDirection
|
||||
from .Ruggedness import Ruggedness
|
||||
@ -143,8 +144,6 @@ from .ZonalStatistics import ZonalStatistics
|
||||
# from .PointsDisplacement import PointsDisplacement
|
||||
# from .PointsFromPolygons import PointsFromPolygons
|
||||
# from .PointsFromLines import PointsFromLines
|
||||
# from .RandomPointsPolygonsFixed import RandomPointsPolygonsFixed
|
||||
# from .RandomPointsPolygonsVariable import RandomPointsPolygonsVariable
|
||||
# from .RandomPointsAlongLines import RandomPointsAlongLines
|
||||
# from .PointsToPaths import PointsToPaths
|
||||
# from .SetVectorStyle import SetVectorStyle
|
||||
@ -274,6 +273,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
RandomExtractWithinSubsets(),
|
||||
RandomPointsExtent(),
|
||||
RandomPointsLayer(),
|
||||
RandomPointsPolygons(),
|
||||
RegularPoints(),
|
||||
ReverseLineDirection(),
|
||||
Ruggedness(),
|
||||
|
220
python/plugins/processing/algs/qgis/RandomPointsPolygons.py
Normal file
220
python/plugins/processing/algs/qgis/RandomPointsPolygons.py
Normal file
@ -0,0 +1,220 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
RandomPointsPolygons.py
|
||||
---------------------
|
||||
Date : April 2014
|
||||
Copyright : (C) 2014 by Alexander Bruy
|
||||
Email : alexander dot bruy at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = 'Alexander Bruy'
|
||||
__date__ = 'April 2014'
|
||||
__copyright__ = '(C) 2014, Alexander Bruy'
|
||||
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
import random
|
||||
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
from qgis.PyQt.QtCore import QVariant
|
||||
from qgis.core import (QgsField,
|
||||
QgsFeatureSink,
|
||||
QgsFeature,
|
||||
QgsFields,
|
||||
QgsGeometry,
|
||||
QgsPoint,
|
||||
QgsPointXY,
|
||||
QgsWkbTypes,
|
||||
QgsSpatialIndex,
|
||||
QgsFeatureRequest,
|
||||
QgsExpression,
|
||||
QgsDistanceArea,
|
||||
QgsProject,
|
||||
QgsProcessing,
|
||||
QgsProcessingException,
|
||||
QgsProcessingParameterNumber,
|
||||
QgsProcessingParameterBoolean,
|
||||
QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingParameterExpression,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterDefinition)
|
||||
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.tools import vector
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
|
||||
class RandomPointsPolygons(QgisAlgorithm):
|
||||
|
||||
INPUT = 'INPUT'
|
||||
EXPRESSION = 'EXPRESSION'
|
||||
MIN_DISTANCE = 'MIN_DISTANCE'
|
||||
STRATEGY = 'STRATEGY'
|
||||
ADD_Z = 'ADD_Z'
|
||||
ADD_M = 'ADD_M'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def icon(self):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'random_points.png'))
|
||||
|
||||
def group(self):
|
||||
return self.tr('Vector creation tools')
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.strategies = [self.tr('Points count'),
|
||||
self.tr('Points density')]
|
||||
|
||||
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
|
||||
self.tr('Input layer'),
|
||||
[QgsProcessing.TypeVectorPolygon]))
|
||||
self.addParameter(QgsProcessingParameterEnum(self.STRATEGY,
|
||||
self.tr('Sampling strategy'),
|
||||
self.strategies,
|
||||
False,
|
||||
0))
|
||||
self.addParameter(QgsProcessingParameterExpression(self.EXPRESSION,
|
||||
self.tr('Expression'),
|
||||
parentLayerParameterName=self.INPUT))
|
||||
self.addParameter(QgsProcessingParameterNumber(self.MIN_DISTANCE,
|
||||
self.tr('Minimum distance between points'),
|
||||
QgsProcessingParameterNumber.Double,
|
||||
0, False, 0, 1000000000))
|
||||
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 'randompointsinsidepolygons'
|
||||
|
||||
def displayName(self):
|
||||
return self.tr('Random points inside polygons')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
|
||||
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
|
||||
addZ = self.parameterAsBool(parameters, self.ADD_Z, context)
|
||||
addM = self.parameterAsBool(parameters, self.ADD_M, context)
|
||||
|
||||
expression = QgsExpression(self.parameterAsString(parameters, self.EXPRESSION, context))
|
||||
if expression.hasParserError():
|
||||
raise ProcessingException(expression.parserErrorString())
|
||||
|
||||
expressionContext = self.createExpressionContext(parameters, context)
|
||||
if not expression.prepare(expressionContext):
|
||||
raise ProcessingException(
|
||||
self.tr('Evaluation error: {0}').format(expression.evalErrorString()))
|
||||
|
||||
fields = QgsFields()
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
|
||||
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, source.sourceCrs())
|
||||
|
||||
da = QgsDistanceArea()
|
||||
da.setSourceCrs(source.sourceCrs())
|
||||
da.setEllipsoid(QgsProject.instance().ellipsoid())
|
||||
|
||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
||||
for current, f in enumerate(source.getFeatures()):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
expressionContext.setFeature(f)
|
||||
value = expression.evaluate(expressionContext)
|
||||
if expression.hasEvalError():
|
||||
feedback.pushInfo(
|
||||
self.tr('Evaluation error for feature ID {}: {}').format(f.id(), expression.evalErrorString()))
|
||||
continue
|
||||
|
||||
fGeom = f.geometry()
|
||||
bbox = fGeom.boundingBox()
|
||||
if strategy == 0:
|
||||
pointCount = int(value)
|
||||
else:
|
||||
pointCount = int(round(value * da.measureArea(fGeom)))
|
||||
|
||||
if pointCount == 0:
|
||||
feedback.pushInfo("Skip feature {} as number of points for it is 0.")
|
||||
continue
|
||||
|
||||
index = QgsSpatialIndex()
|
||||
points = dict()
|
||||
|
||||
nPoints = 0
|
||||
nIterations = 0
|
||||
maxIterations = pointCount * 200
|
||||
total = 100.0 / pointCount if pointCount else 1
|
||||
|
||||
random.seed()
|
||||
|
||||
while nIterations < maxIterations and nPoints < pointCount:
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
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(fGeom) and \
|
||||
vector.checkMinDistance(p, index, minDistance, points):
|
||||
f = QgsFeature(nPoints)
|
||||
f.initAttributes(1)
|
||||
f.setFields(fields)
|
||||
f.setAttribute('id', nPoints)
|
||||
f.setGeometry(geom)
|
||||
sink.addFeature(f, QgsFeatureSink.FastInsert)
|
||||
index.insertFeature(f)
|
||||
points[nPoints] = p
|
||||
nPoints += 1
|
||||
feedback.setProgress(int(nPoints * total))
|
||||
nIterations += 1
|
||||
|
||||
if nPoints < pointCount:
|
||||
feedback.pushInfo(self.tr('Could not generate requested number of random '
|
||||
'points. Maximum number of attempts exceeded.'))
|
||||
|
||||
feedback.setProgress(0)
|
||||
|
||||
return {self.OUTPUT: dest_id}
|
@ -1,150 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
RandomPointsPolygonsFixed.py
|
||||
---------------------
|
||||
Date : April 2014
|
||||
Copyright : (C) 2014 by Alexander Bruy
|
||||
Email : alexander dot bruy at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = 'Alexander Bruy'
|
||||
__date__ = 'April 2014'
|
||||
__copyright__ = '(C) 2014, Alexander Bruy'
|
||||
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
import random
|
||||
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
from qgis.PyQt.QtCore import QVariant
|
||||
from qgis.core import (QgsFields, QgsFeatureSink, QgsField, QgsDistanceArea, QgsGeometry, QgsWkbTypes,
|
||||
QgsSpatialIndex, QgsPointXY, QgsFeature,
|
||||
QgsMessageLog,
|
||||
QgsProcessingUtils,
|
||||
QgsProject)
|
||||
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.core.parameters import ParameterVector
|
||||
from processing.core.parameters import ParameterNumber
|
||||
from processing.core.parameters import ParameterSelection
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.tools import dataobjects, vector
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
|
||||
class RandomPointsPolygonsFixed(QgisAlgorithm):
|
||||
|
||||
VECTOR = 'VECTOR'
|
||||
VALUE = 'VALUE'
|
||||
MIN_DISTANCE = 'MIN_DISTANCE'
|
||||
STRATEGY = 'STRATEGY'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def icon(self):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'random_points.png'))
|
||||
|
||||
def group(self):
|
||||
return self.tr('Vector creation tools')
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.strategies = [self.tr('Points count'),
|
||||
self.tr('Points density')]
|
||||
|
||||
self.addParameter(ParameterVector(self.VECTOR,
|
||||
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_POLYGON]))
|
||||
self.addParameter(ParameterSelection(self.STRATEGY,
|
||||
self.tr('Sampling strategy'), self.strategies, 0))
|
||||
self.addParameter(ParameterNumber(self.VALUE,
|
||||
self.tr('Number or density of points'), 0.0001, None, 1.0))
|
||||
self.addParameter(ParameterNumber(self.MIN_DISTANCE,
|
||||
self.tr('Minimum distance'), 0.0, None, 0.0))
|
||||
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Random points'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
|
||||
|
||||
def name(self):
|
||||
return 'randompointsinsidepolygonsfixed'
|
||||
|
||||
def displayName(self):
|
||||
return self.tr('Random points inside polygons (fixed)')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.VECTOR), context)
|
||||
value = float(self.getParameterValue(self.VALUE))
|
||||
minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
|
||||
strategy = self.getParameterValue(self.STRATEGY)
|
||||
|
||||
fields = QgsFields()
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context)
|
||||
|
||||
da = QgsDistanceArea()
|
||||
da.setSourceCrs(layer.sourceCrs())
|
||||
da.setEllipsoid(QgsProject.instance().ellipsoid())
|
||||
|
||||
features = QgsProcessingUtils.getFeatures(layer, context)
|
||||
for current, f in enumerate(features):
|
||||
fGeom = f.geometry()
|
||||
bbox = fGeom.boundingBox()
|
||||
if strategy == 0:
|
||||
pointCount = int(value)
|
||||
else:
|
||||
pointCount = int(round(value * da.measureArea(fGeom)))
|
||||
|
||||
if pointCount == 0:
|
||||
feedback.pushInfo("Skip feature {} as number of points for it is 0.")
|
||||
continue
|
||||
|
||||
index = QgsSpatialIndex()
|
||||
points = dict()
|
||||
|
||||
nPoints = 0
|
||||
nIterations = 0
|
||||
maxIterations = pointCount * 200
|
||||
total = 100.0 / pointCount if pointCount else 1
|
||||
|
||||
random.seed()
|
||||
|
||||
while nIterations < maxIterations and nPoints < pointCount:
|
||||
rx = bbox.xMinimum() + bbox.width() * random.random()
|
||||
ry = bbox.yMinimum() + bbox.height() * random.random()
|
||||
|
||||
pnt = QgsPointXY(rx, ry)
|
||||
geom = QgsGeometry.fromPoint(pnt)
|
||||
if geom.within(fGeom) and \
|
||||
vector.checkMinDistance(pnt, index, minDistance, points):
|
||||
f = QgsFeature(nPoints)
|
||||
f.initAttributes(1)
|
||||
f.setFields(fields)
|
||||
f.setAttribute('id', nPoints)
|
||||
f.setGeometry(geom)
|
||||
writer.addFeature(f, QgsFeatureSink.FastInsert)
|
||||
index.insertFeature(f)
|
||||
points[nPoints] = pnt
|
||||
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.setProgress(0)
|
||||
|
||||
del writer
|
@ -1,151 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
RandomPointsPolygonsVariable.py
|
||||
---------------------
|
||||
Date : April 2014
|
||||
Copyright : (C) 2014 by Alexander Bruy
|
||||
Email : alexander dot bruy at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = 'Alexander Bruy'
|
||||
__date__ = 'April 2014'
|
||||
__copyright__ = '(C) 2014, Alexander Bruy'
|
||||
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
import random
|
||||
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
from qgis.PyQt.QtCore import QVariant
|
||||
from qgis.core import (QgsFields, QgsFeatureSink, QgsField, QgsFeature, QgsPointXY, QgsWkbTypes,
|
||||
QgsGeometry, QgsSpatialIndex, QgsDistanceArea,
|
||||
QgsMessageLog,
|
||||
QgsProject,
|
||||
QgsProcessingUtils)
|
||||
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.core.parameters import ParameterVector
|
||||
from processing.core.parameters import ParameterTableField
|
||||
from processing.core.parameters import ParameterNumber
|
||||
from processing.core.parameters import ParameterSelection
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.tools import dataobjects, vector
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
|
||||
class RandomPointsPolygonsVariable(QgisAlgorithm):
|
||||
|
||||
VECTOR = 'VECTOR'
|
||||
FIELD = 'FIELD'
|
||||
MIN_DISTANCE = 'MIN_DISTANCE'
|
||||
STRATEGY = 'STRATEGY'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def icon(self):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'random_points.png'))
|
||||
|
||||
def group(self):
|
||||
return self.tr('Vector creation tools')
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.strategies = [self.tr('Points count'),
|
||||
self.tr('Points density')]
|
||||
|
||||
self.addParameter(ParameterVector(self.VECTOR,
|
||||
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_POLYGON]))
|
||||
self.addParameter(ParameterSelection(self.STRATEGY,
|
||||
self.tr('Sampling strategy'), self.strategies, 0))
|
||||
self.addParameter(ParameterTableField(self.FIELD,
|
||||
self.tr('Number field'),
|
||||
self.VECTOR, ParameterTableField.DATA_TYPE_NUMBER))
|
||||
self.addParameter(ParameterNumber(self.MIN_DISTANCE,
|
||||
self.tr('Minimum distance'), 0.0, None, 0.0))
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Random points'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
|
||||
|
||||
def name(self):
|
||||
return 'randompointsinsidepolygonsvariable'
|
||||
|
||||
def displayName(self):
|
||||
return self.tr('Random points inside polygons (variable)')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.VECTOR), context)
|
||||
fieldName = self.getParameterValue(self.FIELD)
|
||||
minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
|
||||
strategy = self.getParameterValue(self.STRATEGY)
|
||||
|
||||
fields = QgsFields()
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context)
|
||||
|
||||
da = QgsDistanceArea()
|
||||
da.setSourceCrs(layer.sourceCrs())
|
||||
da.setEllipsoid(QgsProject.instance().ellipsoid())
|
||||
|
||||
features = QgsProcessingUtils.getFeatures(layer, context)
|
||||
for current, f in enumerate(features):
|
||||
fGeom = f.geometry()
|
||||
bbox = fGeom.boundingBox()
|
||||
if strategy == 0:
|
||||
pointCount = int(f[fieldName])
|
||||
else:
|
||||
pointCount = int(round(f[fieldName] * da.measureArea(fGeom)))
|
||||
|
||||
if pointCount == 0:
|
||||
feedback.pushInfo("Skip feature {} as number of points for it is 0.")
|
||||
continue
|
||||
|
||||
index = QgsSpatialIndex()
|
||||
points = dict()
|
||||
|
||||
nPoints = 0
|
||||
nIterations = 0
|
||||
maxIterations = pointCount * 200
|
||||
total = 100.0 / pointCount if pointCount else 1
|
||||
|
||||
random.seed()
|
||||
|
||||
while nIterations < maxIterations and nPoints < pointCount:
|
||||
rx = bbox.xMinimum() + bbox.width() * random.random()
|
||||
ry = bbox.yMinimum() + bbox.height() * random.random()
|
||||
|
||||
pnt = QgsPointXY(rx, ry)
|
||||
geom = QgsGeometry.fromPoint(pnt)
|
||||
if geom.within(fGeom) and \
|
||||
vector.checkMinDistance(pnt, index, minDistance, points):
|
||||
f = QgsFeature(nPoints)
|
||||
f.initAttributes(1)
|
||||
f.setFields(fields)
|
||||
f.setAttribute('id', nPoints)
|
||||
f.setGeometry(geom)
|
||||
writer.addFeature(f, QgsFeatureSink.FastInsert)
|
||||
index.insertFeature(f)
|
||||
points[nPoints] = pnt
|
||||
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.setProgress(0)
|
||||
|
||||
del writer
|
Loading…
x
Reference in New Issue
Block a user