Wie ändere ich den Wert eines Attributs mit QgsFeature in PyQGIS?

12

Ich möchte ein Attribut einer Funktion aktualisieren. Ich weiß jedoch nicht, ob ich es mithilfe des Feature-Objekts aktualisieren soll. Ich muss den Datenprovider verwenden, um ihn zu aktualisieren.

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

Kann ich den Wert eines Attributs mithilfe eines QgsFeatureObjekts ändern ?

Ist es außerdem möglich, eine Schleife mit einem Iteratorobjekt durchzuführen?

wannik
quelle
Wie kann ich Werte ändern, ohne den Index zu verwenden? Ich möchte die Werte ändern, indem ich ihren Feldnamen benenne. Das wäre viel bequemer. Vielen Dank! Grüße Robert
Robert BK
Verwenden Sie einfach my_index = layer.fieldNameIndex("my_field_name"), um den Index zu erhalten.
Germán Carrillo
In diesem Fall kann ich nicht in den Feld die Zeichenfolge hinzufügen, wie ich tun kann?
Hamed Makian
Wenn Sie eine neue Frage haben, fragen Sie es bitte durch Klicken Frage stellen Taste. Fügen Sie einen Link zu dieser Frage hinzu, wenn dies zur Bereitstellung des Kontexts beiträgt. - Aus dem Rückblick
Dan C
Hamed, Willkommen bei GIS Stack Exchange! Da diese Frage bereits beantwortet wurde, stellen Sie Ihre Frage bitte als neue, separate Frage hier gis.stackexchange.com/questions/ask .
cm1

Antworten:

17

Beantwortung Ihrer beiden Fragen:

  1. Sie können Ihre Feature-Werte über das layerObjekt ändern , ohne auf das zugreifen zu müssen dataProvider().

  2. Ja, Sie können den Iterator in einer forSchleife verwenden.

Überprüfen Sie den folgenden Code:

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

Dadurch wird der dritte Feldwert (Index 2) für alle Layer-Features auf 30 aktualisiert.


Hinweis: Wie Sie bereits betont haben, kann das QgsFeature-Objekt aus irgendeinem Grund keine Feature-Werte aktualisieren, obwohl die API dies vorschreibt.

Germán Carrillo
quelle
5

Ja, aber Sie müssen den Index des Feldes kennen:

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

Sie können die Felder mithilfe von QgsFeature::fieldsabrufen und dann durchlaufen, bis Sie das gewünschte gefunden haben oder QgsFeature::attribute(const QString & name )den Feldindex nach Namen suchen.

Der Grund für QVariant ist, dass das setAttribute die Typen Integer, Float, Date und Text annehmen kann. QgsFeature.attribute (Name) gibt eine Variante vom Typ int zurück, wenn das Attribut gefunden wird, und etwas anderes, wenn es nicht gefunden werden kann. Beachten Sie dies in Ihrem Code. Ein try..except-Block wäre gerechtfertigt. Versuchen Sie, in int zu konvertieren, und es sei denn, type ist nicht int.

Möglicherweise unterstützt Ihre Funktion diese Methode nicht. Eine andere Methode, die ich angewendet habe, ist QgsVectorLayer::changeAttributeValue:

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

Dadurch wird die Ebene angewiesen, ein bestimmtes Feature und ein bestimmtes Attribut zu aktualisieren. Im Beispielfall stammt der Wert von einem Widget.

Michael Stimson
quelle
Ich habe es versucht, feat.setAttribute(1, QVariant(20))aber das System sagte TypeError: PyQt4.QtCore.QVariant stellt einen zugeordneten Typ dar und kann nicht instanziiert werden
wannik
Mit feat.setAttribute (1, 20) habe ich es schon einmal gemacht. Das heißt, der Wert '20' wird in Attribut 1 gesetzt.
Michael Stimson
Ich habe es versucht, feat.setAttribute(1, 20)aber die Werte ändern sich nicht. Allerdings kann ichprint(feat.attributes()[1])
wannik
Siehe Änderungen, möglicherweise müssen Sie den QgsVectorLayer.changeAttributeValue aufrufen, der den Treiber verwenden sollte, um die Änderungen vorzunehmen.
Michael Stimson