8

In the Memory provider described in PyQGIS Cookbook and in the question Creating new empty vector layer with PyQGIS I can see how to create a Vector Layer programmatically using standard fields (String, Int, Double).

With PyQGIS/QGIS 1.8.0, is it possible to programmatically add calculated fields like the ones defined using the Field Calculator?

After reading about QgsExpression I'm thinking in something like this:

exp = QgsExpression('Column * 3')
pr.addAttributes( [ QgsField( "fieldName", QVariant.Expression, exp ) ] )
Taras
  • 32,823
  • 4
  • 66
  • 137
rpet
  • 159
  • 1
  • 10

1 Answers1

9

To accomplish this, you have to take a two-step approach. The first step is to create the field, the second one is to loop over all your features, evaluate the expression and update the attribute for each feature.

vl is your QgsVectorLayer

QGIS 2.0

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

vl.startEditing()

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

#step 2 e = QgsExpression( 'Column * 3' ) e.prepare( vl.pendingFields() )

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

vl.commitChanges()

QGIS 1.8

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

vl.startEditing()

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

#step 2 e = QgsExpression( 'Column * 3' ) e.prepare( vl.pendingFields() )

f = QgsFeature() vl.select( vl.pendingAllAttributesList() ) while vl.nextFeature( f ): vl.changeAttributeValue( f.id(), idx, e.evaluate( f ) )

vl.commitChanges()

Taras
  • 32,823
  • 4
  • 66
  • 137
Matthias Kuhn
  • 27,780
  • 3
  • 88
  • 129