Bagaimana cara mengubah nilai atribut menggunakan QgsFeature di PyQGIS?

12

Saya ingin memperbarui satu atribut fitur. Namun, saya tidak tahu untuk memperbaruinya menggunakan objek fitur. Saya harus menggunakan penyedia data untuk memperbaruinya.

layers = QgsMapLayerRegistry.instance().mapLayersByName('my_line') 
layer = layers[0]
dp = layer.dataProvider()
it = dp.getFeatures()

for i in range(0, dp.featureCount()):
  feat = it.next()
  attrs = { 2 : 30 }
  layer.dataProvider().changeAttributeValues({ feat.id() : attrs })

Bisakah saya mengubah nilai atribut menggunakan QgsFeatureobjek?

Selain itu, apakah mungkin untuk mengulang menggunakan objek iterator?

wannik
sumber
bagaimana saya bisa mengubah nilai tanpa menggunakan indeks? Saya ingin mengubah nilai dengan memberi nama fieldname mereka. Itu akan jauh lebih nyaman. Terima kasih banyak! Salam Robert
Robert BK
Cukup gunakan my_index = layer.fieldNameIndex("my_field_name")untuk mendapatkan indeks.
Germán Carrillo
dalam hal ini saya tidak dapat menambahkan di bidang string bagaimana saya bisa lakukan?
Hamed Makian
Jika Anda memiliki pertanyaan baru, silakan tanyakan dengan mengklik tombol Ajukan Pertanyaan . Sertakan tautan ke pertanyaan ini jika itu membantu menyediakan konteks. - Dari Ulasan
Dan C
Hamed, Selamat Datang di GIS Stack Exchange! Karena pertanyaan ini telah dijawab, tanyakan pertanyaan Anda sebagai pertanyaan baru yang terpisah di sini gis.stackexchange.com/questions/ask .
cm1

Jawaban:

17

Menjawab dua pertanyaan Anda:

  1. Anda dapat mengubah nilai fitur dari layerobjek, tidak perlu mengakses dataProvider().

  2. Ya, Anda bisa menggunakan iterator dalam satu forlingkaran.

Periksa kode di bawah ini:

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

layer.startEditing()
for feat in it:
  layer.changeAttributeValue(feat.id(), 2, 30)

layer.commitChanges()

Ini memperbarui nilai bidang ketiga (indeks 2) ke 30 untuk semua fitur lapisan.


Catatan: Seperti yang Anda tunjukkan, untuk beberapa alasan objek QgsFeature tidak dapat memperbarui nilai fitur, meskipun API mengatakan itu bisa.

Germán Carrillo
sumber
5

Ya, tetapi Anda harus tahu indeks bidang:

QgsFeature::setAttribute(int field,const QVariant & attr )  

Anda bisa mendapatkan bidang menggunakan QgsFeature::fieldsdan kemudian beralih melalui mereka sampai Anda menemukan yang Anda inginkan atau QgsFeature::attribute(const QString & name )untuk menemukan indeks bidang dengan nama.

Alasan untuk QVariant adalah bahwa setAttribute dapat menggunakan tipe Integer, Float, Date dan Text. QgsFeature.attribute (nama) mengembalikan varian juga dari tipe int jika atribut ditemukan dan sesuatu yang lain jika tidak dapat ditemukan .. sadari hal ini dalam kode Anda. Blok try..except akan dibenarkan, cobalah untuk mengonversi ke int dan kecuali jika jenisnya tidak int.

Mungkin saja fitur Anda tidak mendukung metode ini. Metode lain yang saya gunakan adalah QgsVectorLayer::changeAttributeValue:

self.canvas.currentLayer().changeAttributeValue(UpdateFeatureID,FieldToUpdate,self.CurrentWidget.text(),True)

Ini memberitahu layer untuk memperbarui fitur dan atribut tertentu. Dalam contoh kasus, nilai berasal dari widget.

Michael Stimson
sumber
Saya mencoba feat.setAttribute(1, QVariant(20))tetapi sistem mengatakan TypeError: PyQt4.QtCore.QVariant mewakili tipe yang dipetakan dan tidak dapat dipakai
wannik
feat.setAttribute (1, 20) adalah cara saya melakukannya sebelumnya. Yaitu memasukkan nilai '20' ke atribut 1.
Michael Stimson
Saya mencoba feat.setAttribute(1, 20)tetapi nilainya tidak berubah. Namun, saya bisaprint(feat.attributes()[1])
wannik
Lihat suntingan, mungkin Anda harus memanggil QgsVectorLayer.changeAttributeValue yang harus menggunakan driver untuk melakukan perubahan.
Michael Stimson