1

Based on xunilk code in previous post I improved it to add mean distances to "MeanDist" field, while I can print mean distance for each point id, but this data didn't write in attribute of layer. what is the problem for add data to the attribute?

from PyQt4.QtCore import *
import itertools
import numpy as np

layer = iface.activeLayer()

feats = [ feat for feat in layer.getFeatures() ]

n = len(feats)

comb = range(n)

distances = [ [] for i in range(n) ]
indexes = [ [] for i in range(n) ]

for i, j in itertools.combinations(comb, 2):

    dist = feats[i].geometry().distance(feats[j].geometry())

    if dist < 500:
        i_dist= distances[i].append(dist)
        i_index= indexes[i].append([i,j])
        j_dist= distances[j].append(dist)
        j_index= indexes[j].append([i,j])

prov = layer.dataProvider()
layer.startEditing()

if prov.fieldNameIndex("MeanDist") == -1:
    prov.addAttributes([QgsField("MeanDist", QVariant.Double, "double",    10, 2)])
else:
    pass

for feature in layer.getFeatures():
    attrName = "MeanDist"
    for i, group in enumerate(distances):
        if i == feature.id():
            print feature.id(), np.mean(group)   # print for test results, it must remove.
            prov.changeAttributeValues({feature.id() : {prov.fieldNameMap()[attrName]: np.mean(group)}})
            layer.updateFeature(feature)

layer.updateFields()
layer.commitChanges()
2

I see several issues:

  1. Include .updateFields() after adding the attribute
  2. .fieldNameIndex() should be done on the layer not the provider
  3. .changeAttributeValues() should be done on the layer not the provider
  4. .updateFields() should be done on the layer not the provider
  5. Start edit session after .updateFields() method
  6. You do not need layer.updateFeature(feature)

Try:

if layer.fieldNameIndex("MeanDist") == -1:
    prov.addAttributes([QgsField("MeanDist", QVariant.Double, "double",    10, 2)])
    layer.updateFields()
else:
    pass

layer.startEditing()
for feature in layer.getFeatures():
    attrName = "MeanDist"
    for i, group in enumerate(distances):
        if i == feature.id():
            print feature.id(), np.mean(group)   # print for test results, it must remove.
            layer.changeAttributeValue(feature.id(), layer.fieldNameIndex(attrName), np.mean(group))

layer.commitChanges()
  • Hi artwork21, Thanks for your comments, but try it made below error: Traceback (most recent call last): File "<input>", line 1, in <module> File "/tmp/tmp5675J0.py", line 41, in <module> layer.changeAttributeValues({feature.id() : {layer.fieldNameMap()[attrName]: np.mean(group)}}) AttributeError: 'QgsVectorLayer' object has no attribute 'changeAttributeValues' – nickan Jun 26 '17 at 14:42
  • 1
    @nikan, you had a "s" at the end of .changeAttributeValues(), it should be .changeAttributeValue(), also I reformatted the various arguments within the method, see my updated answer. – artwork21 Jun 26 '17 at 15:56
  • Thanks for help, Sorry It's done but incomplete. When I run this code in QGIS console It makes a field with name of "MeanDist" but with "0.00" values for all points. – nickan Jun 26 '17 at 17:14
  • Very thanks @artwork21, I added "float" before "np.mean(group)" in pre last line code and results added to attribute. – nickan Jun 26 '17 at 18:17

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.