Aggiunta di campo e calcolo dell'espressione con PyQGIS?


10

Voglio usare PyQGIS per aggiungere un nuovo campo e calcolare i valori per ogni funzione. Simile all'opzione Field Calculator.

La mia espressione "Field Calculator" è ad esempio: 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()

Questo è l'errore che ottengo:

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'

Risposte:


11

L'errore che viene visualizzato indica che l'indice di campo è -1, quindi il nuovo campo non è stato trovato nella tabella degli attributi.

Ciò può accadere perché:

  1. È necessario utilizzare QVariant.Doubleinvece di QVariant.Float.
  2. Non hai assegnato il nuovo campo al provider di livelli prima di aver richiesto il tuo nuovo indice di colonna.
  3. Stai chiedendo l'indice di myNewColumnma il tuo provider può memorizzare solo 10 caratteri per i nomi dei campi, quindi ha archiviato myNewColum(manca il finale n). (Mi è appena successo mentre provavo la risposta)

Prova questo invece:

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

Ora idxdovrebbe essere diverso da -1, puoi controllarlo:

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

A proposito, è possibile eseguire il #step 1codice dal blocco di modifica.


1
Dopo alcuni test di base penso che sia il limite di caratteri del nome del campo. Naturalmente inviare 'x coord' a un QVariant. Non è una buona idea, nessun errore, solo una cattiva programmazione. Il doppio dovrebbe essere lì. grazie
OHTO

Ad essere onesti, è la prima volta che mi trovo ad affrontare questo problema. Come sempre, testare riga per riga fornisce suggerimenti su ciò che potrebbe accadere.
Germán Carrillo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.