I need to update fields in attribute table of a vector using QGIS. I use field calculator for each field, but i have too many fields (and too many vectors also) and i need to program the task. The code that i'm using for each first field is:

segALD00*(((xmin($geometry) - xmax($geometry))^2+(ymin($geometry) - ymax($geometry))^2)^0.5)*102.47/longkm

to the last field

segALD23*(((xmin($geometry) - xmax($geometry))^2+(ymin($geometry) - ymax($geometry))^2)^0.5)*102.47/longkm

Then another vector:

segETH00*(((xmin($geometry) - xmax($geometry))^2+(ymin($geometry) - ymax($geometry))^2)^0.5)*102.47/longkm

to the last field

segETH23*(((xmin($geometry) - xmax($geometry))^2+(ymin($geometry) - ymax($geometry))^2)^0.5)*102.47/longkm

How can i code this?


Open Python console and show the editor, and paste the following code.

I suppose that segALD00 is the name of a field which you want to update with a derivative of its own value, and that longkm is another field.

The script defines a local function upd_value, which does the calculation of the new value.

# definition of the function which calculates new values
def upd_value(feat, value):
    # calculations come here, e.g.
    geom = feat.geometry().boundingBox()
    result = value * (((geom.xMinimum() - geom.xMaximum())**2 + 
        (geom.yMinimum() - geom.yMaximum())**2)**.5)*102.47
    return result

# get the active layer
layer = iface.activeLayer()
prov = layer.dataProvider()

# get the fields
fnm = prov.fieldNameMap() 

# get an iterator for the features
feats = prov.getFeatures()

# calculate new values and update fields with fieldnames beginning 
# with 'seg' in one single step
result = prov.changeAttributeValues({feat.id(): \
    {fnm[fn]: upd_value(feat, feat[fn]*feat['longkm']) \
    for fn in fnm if fn.startswith('seg')} \
    for feat in feats}) 

This should help you

You need to import Qtypes for QgsField

from PyQt4.QtCore import QVariant 

method of QgsVectorLayer add ExpressionField create new column filled from expression http://qgis.org/api/classQgsVectorLayer.html#a041b1d9f334eb3c31c893f5d130f7f0d

vl.addExpressionField('xmin($geometry)', QgsField('test',QVariant.Int))

Edit full example:

from PyQt4.QtCore import QVariant

import field types

vl = [v for k, v in QgsMapLayerRegistry.instance().mapLayers().iteritems() if v.name() == 'Ulice'][0]

Select one layer (in this example called 'Ulice')

vl.addExpressionField('$length', QgsField('length',QVariant.Double))

Add field with length

Lots of useful advices I had found there http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/loadlayer.html

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.