Menambahkan bidang dan menghitung ekspresi dengan PyQGIS?

10

Saya ingin menggunakan PyQGIS untuk menambahkan bidang baru dan menghitung nilai untuk setiap fitur. Mirip dengan opsi Kalkulator Lapangan.

Ekspresi 'Kalkulator Bidang' saya misalnya: 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()

Ini adalah kesalahan yang saya dapatkan:

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
sumber

Jawaban:

11

Kesalahan yang Anda dapatkan mengatakan indeks bidang adalah -1, jadi bidang baru Anda tidak ditemukan di tabel atribut Anda.

Itu mungkin terjadi karena:

  1. Anda harus menggunakan QVariant.Doublebukan QVariant.Float.
  2. Anda belum berkomitmen bidang baru ke penyedia lapisan sebelum meminta indeks kolom baru Anda.
  3. Anda meminta indeks myNewColumntetapi penyedia Anda hanya dapat menyimpan 10 karakter untuk nama bidang, sehingga telah disimpan myNewColum(tidak ada akhir n). (Kebetulan saya saat memberikan jawaban mencoba)

Coba ini sebagai gantinya:

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

Sekarang idxharus berbeda dari -1, Anda dapat memeriksanya:

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

Omong-omong, Anda dapat menjalankan #step 1kode dari blok edit.

Germán Carrillo
sumber
1
Setelah beberapa pengujian dasar saya pikir ini adalah batas karakter nama field. Tentu saja mengirim 'x coord' ke QVariant.Int juga bukan ide yang baik, tidak ada kesalahan, pemrograman yang buruk. Dobel harus ada di sana. terima kasih
OHTO
Sejujurnya, ini pertama kalinya saya menghadapi masalah seperti itu. Seperti biasa, pengujian baris demi baris memberi Anda petunjuk tentang apa yang mungkin terjadi.
Germán Carrillo