Ajouter un champ et calculer l'expression avec PyQGIS?

10

Je souhaite utiliser PyQGIS pour ajouter un nouveau champ et calculer les valeurs de chaque entité. Similaire à l'option Calculatrice de champ.

Mon expression «Field Calculator» est par exemple: y(start_point($geometry))

from PyQt4.QtCore import QVariant
from qgis.core import QgsField, QgsExpression, QgsFeature
vl = iface.activeLayer()

vl.startEditing()

#step 1
myField = QgsField( 'myNewColumn', QVariant.Float )
vl.addAttribute( myField )
idx = vl.fieldNameIndex( 'myNewColumn' )

#step 2
e = QgsExpression( 'y(start_point($geometry))' )
e.prepare( vl.pendingFields() )

for f in vl.getFeatures():
    f[idx] = e.evaluate( f )
    vl.updateFeature( f )

vl.commitChanges()

Voici l'erreur que j'obtiens:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/var/folders/0r/q6nxg6w54fv4l7c8gksb2t500000gn/T/tmp9dosIe.py", line 30, in <module>
    f[idx] = e.evaluate( f )
KeyError: '-1'
OHTO
la source

Réponses:

11

L'erreur que vous obtenez indique que l'index de champ est -1, donc votre nouveau champ n'a pas été trouvé dans votre table attributaire.

Cela peut se produire parce que:

  1. Vous devez utiliser à la QVariant.Doubleplace de QVariant.Float.
  2. Vous n'avez pas validé le nouveau champ au fournisseur de couches avant de demander votre nouvel index de colonne.
  3. Vous demandez l'index de myNewColumnmais votre fournisseur ne peut stocker que 10 caractères pour les noms de champ, il a donc été stocké myNewColum(final manquant n). (Je viens de m'arriver en essayant la réponse)

Essayez plutôt ceci:

#step 1
myField = QgsField( 'newColumn', QVariant.Double )
vl.dataProvider().addAttributes([myField])
vl.updateFields()
idx = vl.fieldNameIndex( 'newColumn' )

Maintenant idxdevrait être différent de -1, vous pouvez le vérifier:

if idx != -1:
    print "Field found!"

Au fait, vous pouvez exécuter le #step 1code hors du bloc d'édition.

Germán Carrillo
la source
1
Après quelques tests de base, je pense que c'est la limite de caractères du nom de champ. Bien sûr, l'envoi de 'x coord' à un QVariant.Int n'est pas une bonne idée aussi, pas d'erreur cependant, juste une mauvaise programmation. Le double devrait être là. merci
OHTO
Pour être honnête, c'est la première fois que je rencontre un tel problème. Comme toujours, le test ligne par ligne vous donne des indices sur ce qui pourrait se passer.
Germán Carrillo