4

I'm using the following code with processing algorithm "Aggregate" to find neighbor polygons of some selected features in a polygon layer:

from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterVectorLayer
from qgis.core import QgsProcessingParameterFeatureSink
import processing

class DissolveAdjacentPolygons(QgsProcessingAlgorithm):

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterVectorLayer('Inputpolygonlayer', 'Input polygon layer', types=[QgsProcessing.TypeVectorPolygon], defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Agg', 'Agg', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, supportsAppend=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Fixed', 'Fixed', type=QgsProcessing.TypeVectorAnyGeometry, 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(2, model_feedback)
        results = {}
        outputs = {}

        # Fix geometries
        alg_params = {
            'INPUT': parameters['Inputpolygonlayer'],
            'OUTPUT': parameters['Fixed']
        }
        outputs['FixGeometries'] = processing.run('native:fixgeometries', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Fixed'] = outputs['FixGeometries']['OUTPUT']

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        # Field calculator
        alg_params = {
            'FIELD_LENGTH': 250,
            'FIELD_NAME': 'Z930',
            'FIELD_PRECISION': 0,
            'FIELD_TYPE': 2,
            'FORMULA': 'aggregate(\r\n layer:= \'Layer_name\',\r\n aggregate:=\'concatenate\',\r\n expression:=to_string(\"ZIPCODE\"),\r\n concatenator:=\', \',\r\n filter:=intersects($geometry, geometry(@parent)),order_by:=$area\r\n )',
            'INPUT': outputs['FixGeometries']['OUTPUT'],
            'OUTPUT': parameters['Agg']
        }
        outputs['FieldCalculator'] = processing.run('native:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Agg'] = outputs['FieldCalculator']['OUTPUT']
        return results

    def name(self):
        return 'Dissolve adjacent polygons'

    def displayName(self):
        return 'Dissolve adjacent polygons'

    def group(self):
        return 'Dissolve'

    def groupId(self):
        return 'Dissolve'

    def createInstance(self):
        return DissolveAdjacentPolygons()

This works fine, aggregates data based on field "ZIPCODE" in field "Z930", and sort the results by feature area. The problem with de formula in the field calculator algorithm, is that the layer name (layer:= 'Layer_name') refers to an existing layer on the TOC, but I need to find a way to relate this 'Layer_name' with the output of the native:fixgeometries algorithm used above. How can I do this?

7
  • The output of the algorithm Fix geometries is called 'Fixed geometries' does that work in place of 'Layer name'? You can also set the output name with results['Fixed'].setName('my new layer name'). Having said that, it may need to be loaded into the canvas for the expression to recognise it, but it could be immediately removed afterwards if needed.
    – Matt
    Commented Feb 3, 2022 at 21:17
  • Unfortunately no: Using 'Fixed geometries' gives the following error: Cannot find layer with name or ID 'Fixed geometries'. Trying results['Fixed'].setName('my new layer name'), gives this error: 'str' object has no attribute 'setName' .
    – MLourdes
    Commented Feb 3, 2022 at 22:08
  • Are you able to make a layer from results['Fixed'] with QgsVectorLayer(results['Fixed'], 'layer name', 'memory') and add it to the canvas? You would need to import QgsVectorLayer and QgsProject from qgis.core.
    – Matt
    Commented Feb 3, 2022 at 22:40
  • A 'Fixed Geometries' layer was already added to the canvas, but using the above suggestion, no other layer was added.
    – MLourdes
    Commented Feb 3, 2022 at 23:10
  • 1
    Works perfectly! Many thanks Matt.
    – MLourdes
    Commented Feb 4, 2022 at 13:18

1 Answer 1

1

Use @layer in place of \'Layer_name\' in the expression.

@layer is the variable name for the current layer that the Field Calculator is applied on.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.