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()
PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Dec 8, 2021 at 14:40
5
  • 1
    What do you mean by not able? Do you get errors? Commented Dec 8, 2021 at 14:44
  • In tried features.changeAttributeValue(f.id(),source.fields().indexFromName(surface_field), f.geometry().area()) but it doesnt work Commented 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' Commented Dec 8, 2021 at 15:18
  • Thanks for the ansewer but f.changeAttributeValue gives AttributeError: 'QgsFeature' object has no attribute 'changeAttributeValue' Commented 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/… Commented Dec 8, 2021 at 23:44

1 Answer 1

1

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

MrXsquared
36.2k22 gold badges76 silver badges127 bronze badges
answered Dec 10, 2021 at 7:55

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.