Come modificare il valore di un attributo usando QgsFeature in PyQGIS?


12

Vorrei aggiornare un attributo di una funzione. Tuttavia, non so aggiornarlo utilizzando l'oggetto funzione. Devo utilizzare il fornitore di dati per aggiornarlo.

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 })

Posso cambiare il valore di un attributo usando QgsFeatureobject?

Inoltre, è possibile eseguire il loop utilizzando un oggetto iteratore?


come posso modificare i valori senza usare l'indice? Vorrei cambiare i valori nominando il loro nome campo. Sarebbe molto più comodo. Grazie mille! Saluti Robert
Robert BK,

Basta usare my_index = layer.fieldNameIndex("my_field_name")per ottenere l'indice.
Germán Carrillo,

in questo caso non posso aggiungere nel campo la stringa come posso fare?
Hamed Makian,

Se hai una nuova domanda, chiedila facendo clic sul pulsante Poni domanda . Includere un collegamento a questa domanda se aiuta a fornire un contesto. - Dalla recensione
Dan C

Hamed, benvenuto in GIS Stack Exchange! Poiché a questa domanda è già stata data risposta, si prega di porre la propria domanda come una nuova domanda separata qui gis.stackexchange.com/questions/ask .
cm1

Risposte:


17

Rispondere alle tue due domande:

  1. È possibile modificare i valori della funzione layerdall'oggetto, senza bisogno di accedere a dataProvider().

  2. Sì, puoi utilizzare l'iteratore in un forciclo.

Controlla il codice qui sotto:

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()

In questo modo il terzo valore del campo (indice 2) viene aggiornato a 30 per tutte le funzioni di livello.


Nota: come hai sottolineato, per qualche motivo l'oggetto QgsFeature non può aggiornare i valori delle funzionalità, sebbene l'API lo dica.


5

Sì, ma devi conoscere l'indice del campo:

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

È possibile ottenere i campi utilizzando QgsFeature::fieldse quindi scorrere attraverso di essi fino a trovare quello desiderato o QgsFeature::attribute(const QString & name )trovare l'indice dei campi per nome.

Il motivo di QVariant è che setAttribute può accettare i tipi Integer, Float, Date e Text. QgsFeature.attribute (name) restituisce una variante anche di tipo int se l'attributo viene trovato e qualcos'altro se non può essere trovato .. sii consapevole di questo nel tuo codice. Un blocco try..except sarebbe garantito, prova a convertire in int e tranne se type non è int.

È possibile che la tua funzione non supporti questo metodo. Un altro metodo che ho impiegato è QgsVectorLayer::changeAttributeValue:

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

Questo dice al layer di aggiornare una funzionalità e un attributo specifici. Nel caso di esempio il valore proviene da un widget.


Ho provato feat.setAttribute(1, QVariant(20))ma il sistema ha detto TypeError: PyQt4.QtCore.QVariant rappresenta un tipo mappato e non può essere istanziato
wannik

feat.setAttribute (1, 20) è come l'ho fatto prima. Ciò significa che il valore "20" viene attribuito all'attributo 1.
Michael Stimson,

Ho provato feat.setAttribute(1, 20)ma i valori non cambiano. Tuttavia, possoprint(feat.attributes()[1])
wannik il

Vedi le modifiche, forse devi chiamare QgsVectorLayer.changeAttributeValue che dovrebbe usare il driver per apportare le modifiche.
Michael Stimson,
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.