Dodawanie pola i obliczanie wyrażenia za pomocą PyQGIS?

10

Chcę użyć PyQGIS, aby dodać nowe pole i obliczyć wartości dla każdej funkcji. Podobne do opcji Field Calculator.

Moje wyrażenie „Field Calculator” to na przykład: 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()

To jest błąd, który otrzymuję:

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
źródło

Odpowiedzi:

11

Otrzymany błąd mówi, że indeks pola jest -1, więc twoje nowe pole nie zostało znalezione w tabeli atrybutów.

Może się tak zdarzyć, ponieważ:

  1. Musisz użyć QVariant.Doublezamiast QVariant.Float.
  2. Nie przekazałeś nowego pola dostawcy warstwy przed zapytaniem o nowy indeks kolumny.
  3. Pytasz o indeks, myNewColumnale twój dostawca może przechowywać tylko 10 znaków dla nazw pól, więc zostało ono zapisane myNewColum(brakuje finału n). (Właśnie mi się przydarzyło podczas próby odpowiedzi)

Spróbuj zamiast tego:

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

Teraz idxpowinno być inne niż -1możesz to sprawdzić:

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

Nawiasem mówiąc, możesz uruchomić #step 1kod z bloku edycji.

Germán Carrillo
źródło
1
Po kilku podstawowych testach myślę, że jest to limit znaków w nazwie pola. Oczywiście wysyłanie „x koordyn” do QVariant. Nie jest to również dobry pomysł, choć nie ma błędu, po prostu złe programowanie. Podwójnie powinno tam być. dzięki
OHTO,
Szczerze mówiąc, po raz pierwszy mam taki problem. Jak zawsze, testowanie linia po linii daje wskazówki, co może się dziać.
Germán Carrillo,