2

I have a processing script that I created for QGIS 3.4.5 but I keep getting the following error:

Traceback (most recent call last): File "", line 66, in processAlgorithm File "C:/PROGRA~1/QGIS3~1.4/apps/qgis-ltr/./python/plugins\processing\tools\general.py", line 113, in run return Processing.runAlgorithm(algOrName, parameters, onFinish=post_process, feedback=feedback, context=context) File "C:/PROGRA~1/QGIS3~1.4/apps/qgis-ltr/./python/plugins\processing\core\Processing.py", line 138, in runAlgorithm feedback.reportError(msg) TypeError: reportError(self, error: str, fatalError: bool): not enough arguments

Here's my script:

from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterExtent
from qgis.core import QgsProcessingParameterDistance
from qgis.core import QgsProcessingParameterFeatureSink
from qgis.core import QgsExpression
from qgis.core import QgsCoordinateReferenceSystem
import processing


class CreateGrid(QgsProcessingAlgorithm):

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterDistance('distanceinmeters', 'Distance in Meters', parentParameterName='', defaultValue=0))
        self.addParameter(QgsProcessingParameterExtent('extent', 'Extent', defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Gridwgs84', 'GridWGS84', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=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(4, model_feedback)
        results = {}
        outputs = {}

        # Create grid
        alg_params = {
            'CRS': 'ProjectCrs',
            'EXTENT': parameters['extent'],
            'HOVERLAY': 0,
            'HSPACING': parameters['distanceinmeters'],
            'TYPE': 2,
            'VOVERLAY': 0,
            'VSPACING': parameters['distanceinmeters'],
            'OUTPUT': 'memory:'
        }
        outputs['CreateGrid'] = processing.run('qgis:creategrid', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Reproject layer
        alg_params = {
            'INPUT': outputs['CreateGrid']['OUTPUT'],
            'TARGET_CRS': QgsCoordinateReferenceSystem('EPSG:4326'),
            'OUTPUT': 'memory:'
        }
        outputs['ReprojectLayer'] = processing.run('native:reprojectlayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Get Latitude
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Lat',
            'FIELD_PRECISION': 5,
            'FIELD_TYPE': 0,
            'FORMULA': QgsExpression('y(centroid($geometry))').evaluate(),
            'INPUT': outputs['ReprojectLayer']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': 'memory:a'
        }
        outputs['GetLatitude'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

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

        # Get Longitude
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Long',
            'FIELD_PRECISION': 5,
            'FIELD_TYPE': 0,
            'FORMULA': QgsExpression('x(centroid($geometry))').evaluate(),
            'INPUT': outputs['GetLatitude']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': parameters['Gridwgs84']
        }
        outputs['GetLongitude'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Gridwgs84'] = outputs['GetLongitude']['OUTPUT']

        return results

    def name(self):
        return 'create_grid'

    def displayName(self):
        return '1. Create Grid'

    def group(self):
        return 'scripts'

    def groupId(self):
        return 'scripts'

    def createInstance(self):
        return CreateGrid()

I'm not sure why I'm getting this error for the field calculator bit.

1
  • 1
    Not sure but I thought the is_child_algorithm parameter was added to 3.6?
    – Joseph
    Commented Mar 8, 2019 at 12:33

2 Answers 2

3

It is the qgis:fieldcalculator algorithm that complains.

Your QgsExpression('y(centroid($geometry))').evaluate() returns nothing, but qgis:fieldcalculator will accept a string for FORMULA. So I tried to change

        'FORMULA': QgsExpression('y(centroid($geometry))').evaluate(),

to

        'FORMULA': 'y(centroid($geometry))',

and

        'FORMULA': QgsExpression('x(centroid($geometry))').evaluate(),

to

        'FORMULA': 'x(centroid($geometry))',

and that seemed to work.

2

I am not really an expert on qgis processing but it is seems that parameters have to be taken in different form:

First of all you need to declare the input and ouput variables

class CreateGrid(QgsProcessingAlgorithm):

INPUT_DISTANCE = 'Input_Distance'
INPUT_EXTENT   = 'Input_Extent'
OUPUT          = 'Output'

def initAlgorithm(self, config=None):
    self.addParameter(QgsProcessingParameterDistance(self.INPUT_DISTANCE, 'Distance in Meters', parentParameterName='', defaultValue=0))
    self.addParameter(QgsProcessingParameterExtent(self.INPUT_EXTENT, 'Extent', defaultValue=None))
    self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, 'GridWGS84', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue=None))

....

Then you need to extract you input data in a different form:

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(4, model_feedback)
        #results = {}
        #outputs = {}
        distanceInMeters = self.parameterAsDouble(
            parameters,
            self.INPUT_DISTANCE,
            context
        )

etc, etc, etc.

And put the values in your processing algorithm

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.