Skip to content

Commit b9e0b46

Browse files
committed
Fix running algorithms in iterating mode
1 parent 60ea095 commit b9e0b46

File tree

3 files changed

+48
-31
lines changed

3 files changed

+48
-31
lines changed

python/plugins/processing/gui/AlgorithmDialog.py

+5
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,14 @@ def accept(self):
228228
start_time = time.time()
229229

230230
if self.iterateParam:
231+
self.buttonCancel.setEnabled(self.alg.flags() & QgsProcessingAlgorithm.FlagCanCancel)
231232
if executeIterating(self.alg, parameters, self.iterateParam, context, feedback):
233+
feedback.pushInfo(
234+
self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))
235+
self.buttonCancel.setEnabled(False)
232236
self.finish(parameters, context, feedback)
233237
else:
238+
self.buttonCancel.setEnabled(False)
234239
QApplication.restoreOverrideCursor()
235240
self.resetGUI()
236241
else:

python/plugins/processing/gui/AlgorithmExecutor.py

+35-30
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@
2828
__revision__ = '$Format:%H$'
2929

3030
import sys
31-
31+
from copy import deepcopy
3232
from qgis.PyQt.QtCore import QCoreApplication
3333
from qgis.core import (QgsFeature,
3434
QgsVectorFileWriter,
3535
QgsProcessingFeedback,
3636
QgsSettings,
3737
QgsProcessingUtils,
38-
QgsMessageLog)
38+
QgsMessageLog,
39+
QgsProperty,
40+
QgsProcessingParameters,
41+
QgsProcessingOutputLayerDefinition)
3942
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
4043
from processing.gui.Postprocessing import handleAlgorithmResults
4144
from processing.tools import dataobjects
@@ -69,41 +72,43 @@ def executeIterating(alg, parameters, paramToIter, context, feedback):
6972
# Generate all single-feature layers
7073
settings = QgsSettings()
7174
systemEncoding = settings.value('/UI/encoding', 'System')
72-
layerfile = parameters[paramToIter]
73-
layer = QgsProcessingUtils.mapLayerFromString(layerfile, context, False)
74-
feat = QgsFeature()
75-
filelist = []
76-
outputs = {}
77-
features = QgsProcessingUtils.getFeatures(layer, context)
78-
for feat in features:
79-
output = getTempFilename('shp')
80-
filelist.append(output)
81-
writer = QgsVectorFileWriter(output, systemEncoding,
82-
layer.fields(), layer.wkbType(), layer.crs())
83-
writer.addFeature(feat)
84-
del writer
75+
76+
parameter_definition = alg.parameterDefinition(paramToIter)
77+
if not parameter_definition:
78+
return False
79+
80+
iter_source = QgsProcessingParameters.parameterAsSource(parameter_definition, parameters, context)
81+
sink_list = []
82+
for feat in iter_source.getFeatures():
83+
if feedback.isCanceled():
84+
return False
85+
86+
sink, sink_id = QgsProcessingUtils.createFeatureSink('memory:', context, iter_source.fields(), iter_source.wkbType(), iter_source.sourceCrs())
87+
sink_list.append(sink_id)
88+
sink.addFeature(feat)
89+
del sink
8590

8691
# store output values to use them later as basenames for all outputs
87-
for out in alg.outputs:
88-
outputs[out.name] = out.value
92+
outputs = {}
93+
for out in alg.destinationParameterDefinitions():
94+
outputs[out.name()] = parameters[out.name()]
8995

9096
# now run all the algorithms
91-
for i, f in enumerate(filelist):
97+
for i, f in enumerate(sink_list):
98+
if feedback.isCanceled():
99+
return False
100+
92101
parameters[paramToIter] = f
93-
for out in alg.outputs:
94-
filename = outputs[out.name]
95-
if filename:
96-
filename = filename[:filename.rfind('.')] + '_' + str(i) \
97-
+ filename[filename.rfind('.'):]
98-
out.value = filename
99-
feedback.setProgressText(tr('Executing iteration {0}/{1}...').format(i, len(filelist)))
100-
feedback.setProgress(i * 100 / len(filelist))
101-
ret, results = execute(alg, parameters, None, feedback)
102-
if ret:
103-
handleAlgorithmResults(alg, context, None, False)
104-
else:
102+
for out in alg.destinationParameterDefinitions():
103+
o = outputs[out.name()]
104+
parameters[out.name()] = QgsProcessingUtils.generateIteratingDestination(o, i, context)
105+
feedback.setProgressText(tr('Executing iteration {0}/{1}...').format(i, len(sink_list)))
106+
feedback.setProgress(i * 100 / len(sink_list))
107+
ret, results = execute(alg, parameters, context, feedback)
108+
if not ret:
105109
return False
106110

111+
handleAlgorithmResults(alg, context, feedback, False)
107112
return True
108113

109114

python/plugins/processing/gui/Postprocessing.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True):
5656
feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers'))
5757
i = 0
5858
for l, details in context.layersToLoadOnCompletion().items():
59+
if feedback.isCanceled():
60+
return False
61+
62+
if len(context.layersToLoadOnCompletion()) > 2:
63+
# only show progress feedback if we're loading a bunch of layers
64+
feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion())))
65+
5966
try:
6067
layer = QgsProcessingUtils.mapLayerFromString(l, context)
6168
if layer is not None:
@@ -98,7 +105,7 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True):
98105
# wrongLayers.append(out.description)
99106
# elif isinstance(out, OutputHTML):
100107
# resultsList.addResult(alg.icon(), out.description, out.value)
101-
# i += 1
108+
i += 1
102109

103110
QApplication.restoreOverrideCursor()
104111
if wrongLayers:

0 commit comments

Comments
 (0)