12

I want to use PyQGIS to add a new field and calculate the values for each feature. Similar to the Field Calculator option.

My 'Field Calculator' expression is for example: y(start_point($geometry))

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

vl = iface.activeLayer()

vl.startEditing()

#step 1 myField = QgsField( 'myNewColumn', QVariant.Float ) vl.addAttribute( myField ) idx = vl.fieldNameIndex( 'myNewColumn' )

#step 2 e = QgsExpression( 'y(start_point($geometry))' ) e.prepare( vl.pendingFields() )

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

vl.commitChanges()

This is the error I get:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/var/folders/0r/q6nxg6w54fv4l7c8gksb2t500000gn/T/tmp9dosIe.py", line 30, in <module>
    f[idx] = e.evaluate( f )
KeyError: '-1'
Taras
  • 32,823
  • 4
  • 66
  • 137
OHTO
  • 243
  • 2
  • 7

1 Answers1

15

The error you get says the field index is -1, so your new field wasn't found in your attribute table.

That may be happening because:

  1. You need to use QVariant.Double instead of QVariant.Float.
  2. You've not committed the new field to the layer provider before asking for your new column index.
  3. You're asking for the index of myNewColumn but your provider can only store 10 characters for field names, so it has stored myNewColum (missing final n). (Just happened to me while giving the answer a try)

Try this instead:

# Step 1
myField = QgsField('newColumn', QVariant.Double)
vl.dataProvider().addAttributes([myField])
vl.updateFields()
idx = vl.fields().indexOf('newColumn')

Now idx should be different than -1, you can check it:

if idx != -1:
    print("Field found!")

By the way, you can run the #step 1 code out of the edit block.

Germán Carrillo
  • 36,307
  • 5
  • 123
  • 178
  • 1
    After some basic testing I think its the character limit of the field name. Of course sending 'x coord' to an QVariant.Int isn't a good idea too, no error though, just bad programming. Double should be there. thanks – OHTO Jun 09 '16 at 14:22
  • To be honest, it's the first time I face such problem. As always, testing line by line gives you hints on what might be happening. – Germán Carrillo Jun 09 '16 at 14:25
  • Does someone know how to proceed with pyqgis 3 ? – wanderzen Feb 17 '21 at 09:16
  • 1
    There you go @wanderzen. I just updated the answer to QGIS v3.x – Germán Carrillo Apr 17 '21 at 17:16