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()
PolyGeo
  • 65,136
  • 29
  • 109
  • 338
HMadadi
  • 1,046
  • 11
  • 24

1 Answers1

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()
artwork21
  • 35,114
  • 8
  • 66
  • 134
  • Hi artwork21, Thanks for your comments, but try it made below error: Traceback (most recent call last): File "", line 1, in File "/tmp/tmp5675J0.py", line 41, in layer.changeAttributeValues({feature.id() : {layer.fieldNameMap()[attrName]: np.mean(group)}}) AttributeError: 'QgsVectorLayer' object has no attribute 'changeAttributeValues' – HMadadi 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. – HMadadi 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. – HMadadi Jun 26 '17 at 18:17