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?
2 Answers 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})
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