2

I want to calculate the values for each feature using python.

First I added a new field and it worked excellently (Adding field and calculating expression with PyQGIS?).

Now I want to calculate an Expression

Here is my code

from PyQt4.QtCore import QVariant
from qgis.core import QgsField, QgsExpression, QgsFeature

#add new field
myField = QgsField ('eur1_km2', QVariant.Double)
layer.startEditing()
layer.dataProvider().addAttributes([myField])
layer.updateFields()
idx = layer.dataProvider().fieldNameIndex('eur1_km2')

#calculating values for myField
e = QgsExpression( '[SHAPE_Area]/1000000*6' )

for f in layer.getFeatures():
    f[idx] = e
    layer.updateFeature( f )

layer.commitChanges()

The "SHAPE_Area" is a Field within the attribute table with different values. It is in square metres.

How can I call the values for "SHAPE_Area", so it can be calculated?


I'm using QGIS 3.0 for this dataProvider() is necessary, otherwise an error occurs.

idx = layer.fieldNameIndex('eur1_km2')
Traceback (most recent call last):
  File "C:\PROGRA~1\QGIS3~1.0\apps\Python36\lib\code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
AttributeError: 'QgsVectorLayer' object has no attribute 'fieldNameIndex'

The next is, that in QGIS 3.0 pendingFields() does not longer exists. An error occurs

e.prepare(layer.pendingFields())
Traceback (most recent call last):
  File "C:\PROGRA~1\QGIS3~1.0\apps\Python36\lib\code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
AttributeError: 'QgsVectorLayer' object has no attribute 'pendingFields'

Last point another error arise for the last part

for f in layer.getFeatures():
    f[idx] = e.evaluate( f )
    layer.updateFeature( f )
Traceback (most recent call last):
  File "C:\PROGRA~1\QGIS3~1.0\apps\Python36\lib\code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 2, in <module>
TypeError: QgsExpression.evaluate(): arguments did not match any overloaded call:
  overload 1: too many arguments
  overload 2: argument 1 has unexpected type 'QgsFeature'

So, is there an other method for calling the attribute values?

1

You can remove the square brackets in your expression and replace them with double quotes (or nothing):

e = QgsExpression( '"SHAPE_Area"/(1000000*6)')

You may also need to use the prepare() and evaluate methods when calculating values with QgsExpression:

e = QgsExpression( '"SHAPE_Area"/(1000000*6)')
e.prepare(layer.pendingFields())

for f in layer.getFeatures():
    f[idx] = e.evaluate( f )
    layer.updateFeature( f )

You can also avoid having to call the dataProvider() and add the field and obtain the field index directly:

layer.addAttribute(myField)
layer.updateFields()
idx = layer.fieldNameIndex('eur1_km2')

So your code could look something like:

from PyQt4.QtCore import QVariant
from qgis.core import QgsField, QgsExpression, QgsFeature

#add new field
myField = QgsField('eur1_km2', QVariant.Double)
layer.startEditing()
layer.addAttribute(myField)
layer.updateFields()
idx = layer.fieldNameIndex('eur1_km2')

#calculating values for myField
e = QgsExpression( '"SHAPE_Area"/(1000000*6)')
e.prepare(layer.pendingFields())

for f in layer.getFeatures():
    f[idx] = e.evaluate( f )
    layer.updateFeature( f )

layer.commitChanges()
1

I solved the problem on my own. This is the code which I'm using with QGIS 3.0.1:

#add new field
myField = QgsField ('eur1_km2', QVariant.Double)
layer.startEditing()
layer.dataProvider().addAttributes([myField])
layer.updateFields()
idx = layer.dataProvider().fieldNameIndex('eur1_km2')

#calculate new values
for f in layer.getFeatures():
    sa = layer.dataProvider().fieldNameIndex('SHAPE_Area')
    attr_sa = f.attributes()[sa]
    f[idx] = (attr_sa/1000000*6)
    layer.updateFeature( f )

layer.commitChanges()

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.