1

I run a processing algorithm in QGIS in an iteration with a stepwise parameter increment from numeric model input A (minimum) to numeric model input B (maximum) by a fixed step size.

Here's what the processing script for a buffer example currently looks like (exported from a graphical model and modified for iteration):

from qgis.core import (
    QgsProcessing,
    QgsProcessingUtils,
    QgsProcessingAlgorithm,
    QgsProcessingMultiStepFeedback,
    QgsProcessingParameterVectorLayer,
    QgsProcessingParameterNumber,
    QgsProcessingParameterFeatureSink,
    QgsProcessingLayerPostProcessorInterface
)
import processing

class ProcessingParameterIteration(QgsProcessingAlgorithm):

def initAlgorithm(self, config=None):
    self.addParameter(QgsProcessingParameterVectorLayer('polygon_layer', 'Polygon layer', types=[QgsProcessing.TypeVectorPolygon], defaultValue=None))
    self.addParameter(QgsProcessingParameterNumber('minimum_buffer', 'Minimum Buffer', type=QgsProcessingParameterNumber.Integer, minValue=25, maxValue=5000, defaultValue=25))
    self.addParameter(QgsProcessingParameterNumber('maximum_buffer', 'Maximum Buffer', type=QgsProcessingParameterNumber.Integer, minValue=25, maxValue=7500, defaultValue=50))
    self.addParameter(QgsProcessingParameterFeatureSink('Buffered', 'buffered', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, supportsAppend=True, defaultValue=None))

def processAlgorithm(self, parameters, context, model_feedback):
    # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
    # overall progress through the model
    feedback = QgsProcessingMultiStepFeedback(1, model_feedback)
    results = {}
    outputs = {}

    current_buffer_size = parameters['minimum_buffer']

    global renamer

    while current_buffer_size <= parameters['maximum_buffer']:

        # Buffer
        alg_params = {
            'DISSOLVE': False,
            'DISTANCE': current_buffer_size,
            'END_CAP_STYLE': 0,  # Round
            'INPUT': parameters['polygon_layer'],
            'JOIN_STYLE': 0,  # Round
            'MITER_LIMIT': 2,
            'SEGMENTS': 5,
            'SEPARATE_DISJOINT': False,
            'OUTPUT': parameters['Buffered']
        }
        outputs['Buffer'] = processing.run('native:buffer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        buffer_layer_name = QgsProcessingUtils.mapLayerFromString(parameters['polygon_layer'], context).name()

        renamer = LayerRenamer(buffer_layer_name + '_buffered'  + str(current_buffer_size) + 'm')
        context.layerToLoadOnCompletionDetails(outputs['Buffer']['OUTPUT']).setPostProcessor(renamer)

        current_buffer_size += 25

    results['Buffered'] = outputs['Buffer']['OUTPUT']
    return results

def name(self):
    return 'processing_parameter_iteration'

def displayName(self):
    return 'Processing Parameter Iteration'

def group(self):
    return ''

def groupId(self):
    return ''

def createInstance(self):
    return ProcessingParameterIteration()

class LayerRenamer(QgsProcessingLayerPostProcessorInterface): def init(self, layer_name): self.name = layer_name super().init()

def postProcessLayer(self, layer, context, feedback):
    layer.setName(self.name)

The LayerRenamer() class has been added based on this answer.

So far, renaming only works for the last iteration. How do I have to modify the script to set the modified name for all iterations?

winnewoerp
  • 1,504
  • 11
  • 21
  • 2
    This post may help. – Kadir Şahbaz Nov 13 '23 at 07:05
  • Thank you, Kadir. Indeed, it looks very helpful and will hopefully solve my issue. I will test it and if my case adds something still missing in the linked posts, I will post an answer here. – winnewoerp Nov 13 '23 at 17:33
  • Hi @KadirŞahbaz (and all): See my edited answer. With this edit, it's definitely not a duplicate, from my point of view. The renaming unfortunately only works for the last iteration so far. – winnewoerp Nov 15 '23 at 05:17

0 Answers0