Skip to content

Commit

Permalink
Restore random extract + Random Extract within subsets algs
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 22, 2017
1 parent 45eac05 commit 3232ef9
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 56 deletions.
11 changes: 7 additions & 4 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@
from .ImportIntoPostGIS import ImportIntoPostGIS
from .Merge import Merge
from .PostGISExecuteSQL import PostGISExecuteSQL
from .RandomExtract import RandomExtract
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
from .RegularPoints import RegularPoints
from .SymmetricalDifference import SymmetricalDifference
from .VectorSplit import VectorSplit

# from .RandomExtract import RandomExtract
# from .RandomExtractWithinSubsets import RandomExtractWithinSubsets

# from .ExtractByLocation import ExtractByLocation
# from .PointsInPolygon import PointsInPolygon
# from .PointsInPolygonUnique import PointsInPolygonUnique
Expand Down Expand Up @@ -198,8 +199,8 @@ def getAlgs(self):
# VariableDistanceBuffer(), Difference(),
# Intersection(), Union(),
# RandomSelection(), RandomSelectionWithinSubsets(),
# SelectByLocation(), RandomExtract(),
# RandomExtractWithinSubsets(), ExtractByLocation(),
# SelectByLocation(),
# ExtractByLocation(),
# SpatialJoin(),
# DeleteDuplicateGeometries(), TextToFloat(),
# SelectByAttribute(),
Expand Down Expand Up @@ -261,6 +262,8 @@ def getAlgs(self):
ImportIntoPostGIS(),
Merge(),
PostGISExecuteSQL(),
RandomExtract(),
RandomExtractWithinSubsets(),
RegularPoints(),
SymmetricalDifference(),
VectorSplit()
Expand Down
49 changes: 28 additions & 21 deletions python/plugins/processing/algs/qgis/RandomExtract.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
import random

from qgis.core import (QgsApplication,
QgsProcessingUtils)
QgsProcessingUtils,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSink,
QgsProcessingOutputVectorLayer)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterSelection
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputVector


Expand All @@ -59,14 +61,18 @@ def __init__(self):
self.methods = [self.tr('Number of selected features'),
self.tr('Percentage of selected features')]

self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer')))
self.addParameter(ParameterSelection(self.METHOD,
self.tr('Method'), self.methods, 0))
self.addParameter(ParameterNumber(self.NUMBER,
self.tr('Number/percentage of selected features'), 0, None, 10))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))

self.addOutput(OutputVector(self.OUTPUT, self.tr('Extracted (random)')))
self.addParameter(QgsProcessingParameterEnum(self.METHOD,
self.tr('Method'), self.methods, False, 0))

self.addParameter(QgsProcessingParameterNumber(self.NUMBER,
self.tr('Number/percentage of selected features'), QgsProcessingParameterNumber.Integer,
10, False, 0.0, 999999999999.0))

self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extracted (random)')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Extracted (random)')))

def name(self):
return 'randomextract'
Expand All @@ -75,13 +81,12 @@ def displayName(self):
return self.tr('Random extract')

def processAlgorithm(self, parameters, context, feedback):
filename = self.getParameterValue(self.INPUT)
layer = QgsProcessingUtils.mapLayerFromString(filename, context)
method = self.getParameterValue(self.METHOD)
source = self.parameterAsSource(parameters, self.INPUT, context)
method = self.parameterAsEnum(parameters, self.METHOD, context)

features = QgsProcessingUtils.getFeatures(layer, context)
featureCount = QgsProcessingUtils.featureCount(layer, context)
value = int(self.getParameterValue(self.NUMBER))
features = source.getFeatures()
featureCount = source.featureCount()
value = self.parameterAsInt(parameters, self.NUMBER, context)

if method == 0:
if value > featureCount:
Expand All @@ -97,12 +102,14 @@ def processAlgorithm(self, parameters, context, feedback):

selran = random.sample(list(range(featureCount)), value)

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(),
layer.crs(), context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())

total = 100.0 / featureCount
for i, feat in enumerate(features):
if feedback.isCanceled():
break
if i in selran:
writer.addFeature(feat)
sink.addFeature(feat)
feedback.setProgress(int(i * total))
del writer
return {self.OUTPUT: dest_id}
69 changes: 38 additions & 31 deletions python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@
import random

from qgis.core import (QgsApplication,
QgsProcessingUtils)
QgsProcessingUtils,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
QgsProcessingParameterField,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSink,
QgsProcessingOutputVectorLayer)
from collections import defaultdict
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterSelection
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterTableField
from processing.core.outputs import OutputVector


class RandomExtractWithinSubsets(QgisAlgorithm):
Expand All @@ -62,16 +63,21 @@ def __init__(self):
self.methods = [self.tr('Number of selected features'),
self.tr('Percentage of selected features')]

self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer')))
self.addParameter(ParameterTableField(self.FIELD,
self.tr('ID field'), self.INPUT))
self.addParameter(ParameterSelection(self.METHOD,
self.tr('Method'), self.methods, 0))
self.addParameter(ParameterNumber(self.NUMBER,
self.tr('Number/percentage of selected features'), 1, None, 10))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))

self.addOutput(OutputVector(self.OUTPUT, self.tr('Extracted (random stratified)')))
self.addParameter(QgsProcessingParameterField(self.FIELD,
self.tr('ID field'), None, self.INPUT))

self.addParameter(QgsProcessingParameterEnum(self.METHOD,
self.tr('Method'), self.methods, False, 0))

self.addParameter(QgsProcessingParameterNumber(self.NUMBER,
self.tr('Number/percentage of selected features'), QgsProcessingParameterNumber.Integer,
10, False, 0.0, 999999999999.0))

self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extracted (random stratified)')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Extracted (random stratified)')))

def name(self):
return 'randomextractwithinsubsets'
Expand All @@ -80,18 +86,17 @@ def displayName(self):
return self.tr('Random extract within subsets')

def processAlgorithm(self, parameters, context, feedback):
filename = self.getParameterValue(self.INPUT)
source = self.parameterAsSource(parameters, self.INPUT, context)
method = self.parameterAsEnum(parameters, self.METHOD, context)

layer = QgsProcessingUtils.mapLayerFromString(filename, context)
field = self.getParameterValue(self.FIELD)
method = self.getParameterValue(self.METHOD)
field = self.parameterAsString(parameters, self.FIELD, context)

index = layer.fields().lookupField(field)
index = source.fields().lookupField(field)

features = QgsProcessingUtils.getFeatures(layer, context)
featureCount = QgsProcessingUtils.featureCount(layer, context)
unique = QgsProcessingUtils.uniqueValues(layer, index, context)
value = int(self.getParameterValue(self.NUMBER))
features = source.getFeatures()
featureCount = source.featureCount()
unique = source.uniqueValues(index)
value = self.parameterAsInt(parameters, self.NUMBER, context)
if method == 0:
if value > featureCount:
raise GeoAlgorithmExecutionException(
Expand All @@ -104,15 +109,16 @@ def processAlgorithm(self, parameters, context, feedback):
"correct value and try again."))
value = value / 100.0

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(),
layer.crs(), context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())

selran = []
total = 100.0 / (featureCount * len(unique))
features = QgsProcessingUtils.getFeatures(layer, context)

classes = defaultdict(list)
for i, feature in enumerate(features):
if feedback.isCanceled():
break
attrs = feature.attributes()
classes[attrs[index]].append(feature)
feedback.setProgress(int(i * total))
Expand All @@ -121,9 +127,10 @@ def processAlgorithm(self, parameters, context, feedback):
selValue = value if method != 1 else int(round(value * len(subset), 0))
selran.extend(random.sample(subset, selValue))

features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / featureCount
for (i, feat) in enumerate(selran):
writer.addFeature(feat)
if feedback.isCanceled():
break
sink.addFeature(feat)
feedback.setProgress(int(i * total))
del writer
return {self.OUTPUT: dest_id}

0 comments on commit 3232ef9

Please sign in to comment.