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)
1 Answer 1
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)
-
1Thanks 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– antonio2016年03月04日 13:49:27 +00:00Commented Mar 4, 2016 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– Joseph2016年03月04日 14:01:51 +00:00Commented Mar 4, 2016 at 14:01 -
1That'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– antonio2016年03月04日 14:07:58 +00:00Commented Mar 4, 2016 at 14:07
-
1
-
1@antonio - Haha thanks! The
with edit(layer):
statement is the exact same as usinglayer.startEditing()
andlayer.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– Joseph2016年03月04日 14:52:35 +00:00Commented Mar 4, 2016 at 14:52