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()
1 Answer 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
lang-py
changeAttributeValue
fromfeatures
(which is aQgsFeatureIterator
). You need to call it from aQgsVectorLayer
(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/…