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?

3
  • 2
    This post may help. Nov 13, 2023 at 7: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, 2023 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, 2023 at 5:17

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.