4

I'm trying to write a script that will update a field with 2 values (Wrong/Ok) when specific conditions are met. This is what I've come up so far, but I can't get it to work..

from qgis.core import *
from qgis.gui import *

layers = QgsMapLayerRegistry.instance().mapLayersByName('Mukono_Polygon') 
layer = layers[0]
it = layer.getFeatures()
idx = layer.fieldNameIndex('PlotArea')
idy = layer.fieldNameIndex('Pr')
idz = layer.fieldNameIndex('CTRL')

layer.startEditing()
for feat in it:
  if feat.attributes()[idx] <> '888.8888' and feat.attributes()[idx] <> '999.9999' and feat.attributes()[idy] > '120':
    layer.changeAttributeValue(feat.attributes()[idz], 'Wrong')
  elif feat.attributes()[idx] <> '888.8888' and feat.attributes()[idx] <> '999.9999' and feat.attributes()[idy] > '80':
    layer.changeAttributeValue(feat.attributes()[idz], 'Ok')
  else:
    print 'Cant find specific entries'

layer.commitChanges()


Traceback (most recent call last):
  File "", line 23, in 
IOError: [Errno 9] Bad file descriptor

If remove change the line 23 to print '', the script doesnt do anything.

I chose to get the fields by name instead of their number index because it's different from shapefile to shapefile.

8
  • 4
    The QgsVectorLayer::changeAttributeValue() method requires a features id, field and the new value. Try using layer.changeAttributeValue(feat.id(), idz, 'Wrong')
    – Joseph
    Commented Mar 26, 2018 at 11:32
  • 1
    @kidd - What field types are idx and idy? If they are non-string, remove the string quotes around your values in your if statements. E.g. if feat.attributes()[idx] <> 888.8888 and feat.attributes()[idx] <> 999.9999 and feat.attributes()[idy] > 120:
    – Joseph
    Commented Mar 26, 2018 at 12:04
  • 2
    feat objects are dictionnary like, so you can change all feat.attributes()[id] to feat['field_name'].
    – YoLecomte
    Commented Mar 26, 2018 at 12:27
  • 1
    the first argument of changeAttributeValue must the id of the feature. so you need something like layer.changeAttributeValue(feat.id(), layer.fieldNameIndex('field_name'), new_value)
    – YoLecomte
    Commented Mar 26, 2018 at 12:58
  • 1
    That was great. Now it works perfectly. Thank you very much Joseph And YoLecomte. Dunno how to mark both your answers correct. I added + rep. I will post full working code for anyone else.
    – kidd
    Commented Mar 26, 2018 at 13:08

1 Answer 1

4

Many thanks to YoLecomte and Joseph. Here is the final code:

from qgis.core import *
from qgis.gui import *

layers = QgsMapLayerRegistry.instance().mapLayersByName('Mukono_Polygon') 
layer = layers[0]
it = layer.getFeatures()

layer.startEditing()
for feat in it:
  if feat['PlotArea'] <> 888.8888 and feat['PlotArea'] <> 999.9999 and feat['Pr'] > 120:
    layer.changeAttributeValue(feat.id(), layer.fieldNameIndex('CTRL'), 'Wrong')
  elif feat['PlotArea'] <> 888.8888 and feat['PlotArea'] <> 999.9999 and feat['Pr'] > 80:
    layer.changeAttributeValue(feat.id(), layer.fieldNameIndex('CTRL'), 'Ok')
  else:
    print 'Cant find specific entries'

layer.commitChanges()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.