1

In a QGIS processing script I try to update an attribute value in a feature with changeAttributeValue but I am not able to.

I'm following: https://courses.spatialthoughts.com/pyqgis-in-a-day.html#processing-scripts

from PyQt5.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
                       QgsProcessingAlgorithm,
                       QgsProcessingParameterFeatureSource,
                       QgsProcessingParameterField,
                       QgsProcessingParameterFileDestination,
                       )
#from qgis import processing



class SaveAttributesAlgorithm(QgsProcessingAlgorithm):
    """Saves the attributes of a vector layer to a CSV file."""
    OUTPUT = 'OUTPUT'
    INPUT = 'INPUT'
    X_FIELD = 'x_field' # champ centroid X
    Y_FIELD = 'y_field' # champ centroid Y
    SURFACE_FIELD = 'surface_field'  # champ surface



def initAlgorithm(self, config=None):
    self.addParameter(
        QgsProcessingParameterFeatureSource(
            self.INPUT,
            self.tr('Input layer'),
            [QgsProcessing.TypeVectorAnyGeometry]
        )
    )
    self.addParameter(
    QgsProcessingParameterField(
            self.X_FIELD,
            'Champ centroide X',
            '',
            self.INPUT))
    self.addParameter(
    QgsProcessingParameterField(
            self.Y_FIELD,
            'Champ centroide Y',
            '',
            self.INPUT))
    self.addParameter(
    QgsProcessingParameterField(
            self.SURFACE_FIELD,
            'Champ Surface',
            '',
            self.INPUT))


def processAlgorithm(self, parameters, context, feedback):
    source = self.parameterAsSource(parameters, self.INPUT, context)
    csv = self.parameterAsFileOutput(parameters, self.OUTPUT, context)
    
    x_field = self.parameterAsString(
        parameters,
        self.X_FIELD,
        context)
    y_field = self.parameterAsString(
        parameters,
        self.Y_FIELD,
        context)
    surface_field = self.parameterAsString(
        parameters,
        self.SURFACE_FIELD,
        context)

    fieldnames = [field.name() for field in source.fields()]

    # Compute the number of steps to display within the progress bar and
    # get features from source
    total = 100.0 / source.featureCount() if source.featureCount() else 0
    
    features = source.getFeatures()
    
    fieldIdx = source.fields().indexFromName(surface_field)
    feedback.pushInfo(str(fieldIdx))
    feedback.pushInfo(surface_field)
    feedback.pushInfo(x_field)
    feedback.pushInfo(y_field)

    
    for current, f in enumerate(features):
         # Stop the algorithm if cancel button has been clicked
        if feedback.isCanceled():
            break
        feedback.pushInfo(str(f.geometry().centroid()))
        feedback.pushInfo(str(f.geometry().area()))
        feedback.pushInfo(str(f.id()))
        #changeAttributeValue(f.id(),source.fields().indexFromName(surface_field), f.geometry().area())            
          
          

          # Update the progress bar
        feedback.setProgress(int(current * total))

    return {self.OUTPUT: csv}

def name(self):
    return 'save_attributes'

def displayName(self):
    return self.tr('Update X,Y,area')

def group(self):
    return self.tr(self.groupId())

def groupId(self):
    return ''

def tr(self, string):
    return QCoreApplication.translate('Processing', string)

def createInstance(self):
    return SaveAttributesAlgorithm()
5
  • 1
    What do you mean by not able? Do you get errors?
    – BERA
    Dec 8, 2021 at 14:44
  • In tried features.changeAttributeValue(f.id(),source.fields().indexFromName(surface_field), f.geometry().area()) but it doesnt work
    – Alex
    Dec 8, 2021 at 15:17
  • the error is Traceback (most recent call last): File "<string>", line 90, in processAlgorithm AttributeError: 'QgsFeatureIterator' object has no attribute 'changeAttributeValue'
    – Alex
    Dec 8, 2021 at 15:18
  • Thanks for the ansewer but f.changeAttributeValue gives AttributeError: 'QgsFeature' object has no attribute 'changeAttributeValue'
    – Alex
    Dec 8, 2021 at 16:16
  • You cannot call changeAttributeValue from features (which is a QgsFeatureIterator). You need to call it from a QgsVectorLayer (source object in your case) if you open an edit session. That's well documented in the PyQGIS Cookbook. Have a look at: docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/… Dec 8, 2021 at 23:44

1 Answer 1

0

I found the way by replacing source = self.parameterAsSource(parameters, self.INPUT, context) with source = self.parameterAsVectorLayer(parameters, self.INPUT, context)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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