4

I am using QGIS 3.12 and I want to update the content of a field by storing the feature's X and Y coordinates. The following code works given that a point layer is in the layer panel. The function works when the layer.updateFeature(feat.id()) statement is blocked, and so I could not understand the use of this method?

layer = iface.activeLayer()
layer.startEditing()
all_features = layer.getFeatures()
for feat in all_features:
    geom = feat.geometry()
    x = geom.asPoint().x()
    y = geom.asPoint().y()
    
    new_x = {feat.fieldNameIndex('x'): x}
    layer.dataProvider().changeAttributeValues({feat.id(): new_x })
    
    new_y = {feat.fieldNameIndex('y'): y}
    layer.dataProvider().changeAttributeValues({feat.id(): new_y })
    
    #layer.updateFeature(feat.id()) #?
 
# Commit changes
layer.commitChanges()

1 Answer 1

6

You need to either use only the .dataProvider() (QgsVectorDataProvider) methods which call the underlying data and modify it or use the edit methods of QgsVectorLayer.

so, either :

layer = iface.activeLayer()
layer.startEditing()
all_features = layer.getFeatures()
for feat in all_features:
    geom = feat.geometry()
    x = geom.asPoint().x()
    y = geom.asPoint().y()
    
    feat.setAttribute('x', x)
    feat.setAttribute('y', y)
    
    layer.updateFeature(feat)
 
# Commit changes
layer.commitChanges()

or

layer = iface.activeLayer()
all_features = layer.getFeatures()
for feat in all_features:
    geom = feat.geometry()
    x = geom.asPoint().x()
    y = geom.asPoint().y()
    
    new_xy = {
        feat.fieldNameIndex('x'): x, 
        feat.fieldNameIndex('y'): y
    }
    layer.dataProvider().changeAttributeValues({feat.id(): new_xy})

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.