3

I have script that calculates length of lines and adds values to attribute table. It works for vector layer, but for memory layer it skip always one value, as you can see on the pic. I calculated length by field calculator to show that it moves the value one row up.

First column is from field calculator, 2nd one from my script

Here is the code:

from PyQt4.QtCore import *
layer = qgis.utils.iface.activeLayer()
provider = layer.dataProvider()
lengths = [feat.geometry().length() 
        for feat in layer.getFeatures() ]

field = QgsField("length5", QVariant.Double)
provider.addAttributes([field])
layer.updateFields()

idx = layer.fieldNameIndex('length5') 
for length in lengths:
    new_values = {idx : float(length)}
    provider.changeAttributeValues({lengths.index(length):new_values})

How should I edit code to get right value in right row? I suppose that the problem is in last line: the "{lengths.index(length):" doesn't work proper for memory layer. Am I right?

(Working in QGIS 2.12)

3

Not sure why the last feature is not getting updated. But I modified your code and it works for me for both vector and memory layers:

from PyQt4.QtCore import *
layer = qgis.utils.iface.activeLayer()
provider = layer.dataProvider()

field = QgsField("length5", QVariant.Double)
provider.addAttributes([field])
layer.updateFields()

idx = layer.fieldNameIndex('length5') 
with edit(layer):
    for feat in layer.getFeatures():
        lengths = feat.geometry().length()
        layer.changeAttributeValue(feat.id(), idx, lengths)
  • 1
    Thanks for answer @Joseph but it didn't solve my problem. It still doesn't work for memory layer... Did you check if my code works at your computer for memory layer? If not, can you do it for me, please? :) Maybe problem is somewhere deeper (settings, installed components, I don't know), not in the code. – antonio Mar 4 '16 at 13:49
  • @antonio - I tested your code on a shapefile with 12 line features. From the real shapefile, only 10 features were updated; for the memory layer, only 11 features were updated. I'm not python savvy but my guess is how you defined lengths. Sorry I can't be of much help ;) – Joseph Mar 4 '16 at 14:01
  • 1
    That's a pity! But anyway, thanks for your help. I'll try to work with your code, maybe I'll solve the problem somehow. – antonio Mar 4 '16 at 14:07
  • 1
    @antonio - I think the word you're looking for is "D'oh!" :) – Joseph Mar 4 '16 at 14:14
  • 1
    @antonio - Haha thanks! The with edit(layer): statement is the exact same as using layer.startEditing() and layer.commitChanges(). It just puts these in a single statement so you can replace the line if it doesn't work. There is some documentation. – Joseph Mar 4 '16 at 14:52

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.