2

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?

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Sergio
  • 948
  • 9
  • 15

2 Answers2

2

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}) 
Detlev
  • 4,608
  • 19
  • 26
1

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

Jelen
  • 191
  • 1
  • 3