Skip to content

Commit 9f43f2f

Browse files
committed
[FEATURE][processing] New "Add values by expression" option for
populating batch processing dialog This option adds news rows using the values from an expression which returns an array. (As opposed to "Calculate by Expression", which works only on existing rows). The intended use case is to allow populating the batch dialog using complex numeric series, e.g. those created by the "generate_series" expression function. For example, adding rows for a batch buffer using the expression generate_series(100, 1000, 50) (results in new rows with values 100, 150, 200, .... 1000)
1 parent ee7daa8 commit 9f43f2f

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

python/plugins/processing/gui/BatchPanel.py

+46-14
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ def createMenu(self):
130130
calculate_by_expression.setToolTip(self.tr('Calculates parameter values by evaluating an expression'))
131131
self.menu.addAction(calculate_by_expression)
132132

133+
add_by_expression = QAction(QCoreApplication.translate('BatchPanel', 'Add Values by Expression…'),
134+
self.menu)
135+
add_by_expression.triggered.connect(self.addByExpression)
136+
add_by_expression.setToolTip(self.tr('Adds new parameter values by evaluating an expression'))
137+
self.menu.addAction(add_by_expression)
138+
133139
if isinstance(self.parameterDefinition, (QgsProcessingParameterFile,
134140
QgsProcessingParameterMapLayer,
135141
QgsProcessingParameterRasterLayer,
@@ -192,6 +198,18 @@ def calculateByExpression(self):
192198
"""
193199
Calculates parameter values by evaluating expressions.
194200
"""
201+
self.populateByExpression(adding=False)
202+
203+
def addByExpression(self):
204+
"""
205+
Adds new parameter values by evaluating an expression
206+
"""
207+
self.populateByExpression(adding=True)
208+
209+
def populateByExpression(self, adding=False):
210+
"""
211+
Populates the panel using an expression
212+
"""
195213
context = dataobjects.createContext()
196214
expression_context = context.expressionContext()
197215

@@ -211,27 +229,41 @@ def calculateByExpression(self):
211229
expression_context.setHighlightedVariables(highlighted_vars)
212230

213231
dlg = QgsExpressionBuilderDialog(layer=None, context=context.expressionContext())
232+
if adding:
233+
dlg.setExpectedOutputFormat(self.tr('An array of values corresponding to each new row to add'))
234+
214235
if not dlg.exec_():
215236
return
216237

217-
for row in range(self.panel.batchRowCount()):
218-
params = self.panel.parametersForRow(row, warnOnInvalid=False)
238+
if adding:
239+
exp = QgsExpression(dlg.expressionText())
240+
res = exp.evaluate(expression_context)
219241

220-
# remove previous algorithm scope -- we need to rebuild this completely, using the
221-
# other parameter values from the current row
222-
expression_context.popScope()
223-
alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context)
242+
if type(res) is not list:
243+
res = [res]
224244

225-
for k, v in params.items():
226-
alg_scope.setVariable(k, v, True)
245+
first_row = self.panel.batchRowCount() if self.panel.batchRowCount() > 1 else 0
246+
for row, value in enumerate(res):
247+
self.setRowValue(row + first_row, value, context)
248+
else:
249+
for row in range(self.panel.batchRowCount()):
250+
params = self.panel.parametersForRow(row, warnOnInvalid=False)
227251

228-
expression_context.appendScope(alg_scope)
252+
# remove previous algorithm scope -- we need to rebuild this completely, using the
253+
# other parameter values from the current row
254+
expression_context.popScope()
255+
alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context)
229256

230-
# rebuild a new expression every time -- we don't want the expression compiler to replace
231-
# variables with precompiled values
232-
exp = QgsExpression(dlg.expressionText())
233-
value = exp.evaluate(expression_context)
234-
self.setRowValue(row, value, context)
257+
for k, v in params.items():
258+
alg_scope.setVariable(k, v, True)
259+
260+
expression_context.appendScope(alg_scope)
261+
262+
# rebuild a new expression every time -- we don't want the expression compiler to replace
263+
# variables with precompiled values
264+
exp = QgsExpression(dlg.expressionText())
265+
value = exp.evaluate(expression_context)
266+
self.setRowValue(row, value, context)
235267

236268

237269
class BatchPanel(BASE, WIDGET):

0 commit comments

Comments
 (0)