From 29207a1617678eb3a3922ff3dd74c3b6b6b193a5 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Wed, 4 Jul 2018 18:30:30 +0300 Subject: [PATCH 1/2] [processing] fix Random extract/select within subset when subset is smaller than number of requested features (fix #19322) --- .../algs/qgis/RandomExtractWithinSubsets.py | 2 +- .../algs/qgis/RandomSelectionWithinSubsets.py | 2 +- .../tests/testdata/qgis_algorithm_tests.yaml | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py b/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py index 7ba41634ec7d..10826a165b16 100644 --- a/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py +++ b/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py @@ -127,7 +127,7 @@ def processAlgorithm(self, parameters, context, feedback): for subset in classes.values(): selValue = value if method != 1 else int(round(value * len(subset), 0)) - selran.extend(random.sample(subset, selValue)) + selran.extend(random.sample(subset, min(selValue, len(subset)))) total = 100.0 / featureCount if featureCount else 1 for (i, feat) in enumerate(selran): diff --git a/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py b/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py index 9281da0545b3..98ce833d9951 100644 --- a/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py +++ b/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py @@ -138,7 +138,7 @@ def processAlgorithm(self, parameters, context, feedback): break selValue = value if method != 1 else int(round(value * len(subset), 0)) - selran.extend(random.sample(subset, selValue)) + selran.extend(random.sample(subset, min(selValue, len(subset)))) layer.selectByIds(selran) else: diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml index 6db7255abd07..239e17459576 100644 --- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml +++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml @@ -3923,6 +3923,21 @@ tests: name: points_weighted.gml compare: false + - algorithm: qgis:randomextractwithinsubsets + name: Random extract within subset (subset smaller than number) + params: + FIELD: id2 + INPUT: + name: points.gml + type: vector + METHOD: 0 + NUMBER: 3 + results: + OUTPUT: + type: vector + name: points.gml + compare: false + - algorithm: qgis:heatmapkerneldensityestimation name: Heatmap (Kernel density estimation) params: @@ -5355,6 +5370,7 @@ tests: compare: fields: fid: skip + - algorithm: native:difference name: Test Difference B - A (basic) params: From b72f5d1a5387377cde1e63562456ef81ca14e0ff Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Wed, 4 Jul 2018 19:15:29 +0300 Subject: [PATCH 2/2] [processing] log cases when subset is smaller than requested number of features --- .../processing/algs/qgis/RandomExtractWithinSubsets.py | 7 +++++-- .../processing/algs/qgis/RandomSelectionWithinSubsets.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py b/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py index 10826a165b16..7afffe0411bf 100644 --- a/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py +++ b/python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py @@ -125,9 +125,12 @@ def processAlgorithm(self, parameters, context, feedback): classes[attrs[index]].append(feature) feedback.setProgress(int(i * total)) - for subset in classes.values(): + for k, subset in classes.items(): selValue = value if method != 1 else int(round(value * len(subset), 0)) - selran.extend(random.sample(subset, min(selValue, len(subset)))) + if selValue > len(subset): + selValue = len(subset) + feedback.reportError(self.tr('Subset "{}" is smaller than requested number of features.'.format(k))) + selran.extend(random.sample(subset, selValue)) total = 100.0 / featureCount if featureCount else 1 for (i, feat) in enumerate(selran): diff --git a/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py b/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py index 98ce833d9951..4321f1d586db 100644 --- a/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py +++ b/python/plugins/processing/algs/qgis/RandomSelectionWithinSubsets.py @@ -133,12 +133,15 @@ def processAlgorithm(self, parameters, context, feedback): feedback.setProgress(int(i * total)) selran = [] - for subset in classes.values(): + for k, subset in classes.items(): if feedback.isCanceled(): break selValue = value if method != 1 else int(round(value * len(subset), 0)) - selran.extend(random.sample(subset, min(selValue, len(subset)))) + if selValue > len(subset): + selValue = len(subset) + feedback.reportError(self.tr('Subset "{}" is smaller than requested number of features.'.format(k))) + selran.extend(random.sample(subset, selValue)) layer.selectByIds(selran) else: