Was sind QGIS-äquivalente Funktionen für ArcPys Aktualisieren / Löschen von Zeilen / Feldern?

8

Ich versuche, einige Skripte von ArcPy auf QGIS (1.8 oder 2.0) neu zu programmieren, und es gibt einige einfache Funktionen, die ich wiederholen möchte, aber leider fehlt in bestimmten Bereichen die Dokumentation in QGIS.

Die drei wichtigsten für mich sind nämlich:

Feld hinzufügen - Feld hinzufügen

arcpy.AddField_management(Feature, "ID", "SHORT")

Feldverwaltung berechnen - Aktualisieren Sie dieses Feld

arcpy.CalculateField_management(Feature,"ID","!FID!")

Zeilen aktualisieren / löschen - Zeilen basierend auf der Bedingung aktualisieren / löschen (ohne das Shapefile zu kopieren)

keep = ["Bob","Janet","John","Mike"]
Counter = 0
rows = arcpy.UpdateCursor(Feature)

for row in rows:
    if row.Name in keep:
        row.ID = Counter
        rows.updateRow(row)
    else:
        rows.deleteRow(row)
    Counter += 1

Jetzt kann ich jedes Feature in QGIS mit SEXTANTE durchlaufen und seine Geometrie erhalten, die ich in ein neues Shapefile umschreiben und dadurch eine Zeile oder ein Feld aktualisieren / löschen kann. Beginnend mit etwas in der Art von ...

layer = st.getobject(Polygon)
features = st.getfeatures(layer)
for f in features:
    f.geometry().asPolygon()

aber ich kann keine einfache Lösung für die oben genannten Funktionen finden?

BJEBN
quelle
Ich bin mir nicht ganz sicher, was das Ziel des letzten Teils Ihrer Frage ist. Warum erwähnen Sie SEXTANTE? Sie fragen nach einer Methode zum Umschreiben in ein neues Shapefile, aber Ihr Code-Auszug macht nichts derartiges.
Matthias Kuhn

Antworten:

16

Die folgenden Beispiele basieren auf der (in Kürze veröffentlichten) QGIS 2.0-API. Dies hat sich seit 1.8 geändert, sodass sich die Syntax für diese Version an einigen Stellen unterscheidet.

Die beste Ressource für 1.8-konforme Lösungen und eine ausführliche Erläuterung des Hintergrunds von Parametern (gilt auch für 2.0) ist das PyQGIS-Kochbuch

Wir gehen davon aus, dass Sie bereits einen Verweis auf eine Vektorebene haben, vldie z

vl = iface.activeLayer()

Transaktionen

Die folgenden Beispiele arbeiten in einer Transaktion (lokal in QGIS zwischengespeichert). Bevor Sie die Bearbeitungssitzung starten, müssen Sie anrufen

vl.startEditing()

und beende es mit

vl.commitChanges()

um Ihre Änderungen in die Datenquelle zu schreiben. oder

vl.rollBack()

die Änderungen zu verwerfen

Sie können auch direkt an vl.dataProvider()den Transaktionssteuerungsanweisungen arbeiten und diese vergessen. (Dies führt zu einem Autocommit-ähnlichen Verhalten)

Feld hinzufügen

QgsVectorLayer.addAttribute (QgsField)

from PyQt4.QtCore import QVariant
vl.addAttribute( QgsField( 'fieldname', QVariant.String ) )

Dies funktioniert nur, wenn der Datenprovider die AddAttributes-Funktion implementiert. Sie können dies überprüfen mit:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues

Felder berechnen

Siehe diese Antwort:

Ist es möglich, berechnete Felder programmgesteuert hinzuzufügen?

Es ist immer noch auf 1.8 ausgerichtet, sodass Sie stattdessen vl.select()das 2.0-Äquivalent aufrufen müssen vl.getFeatures()(siehe Änderungen an der QGIS-API ).

Zeilen aktualisieren

QgsVectorLayer.updateField (featureId, fieldIndex, value)

vl.updateField( 1000, 5, 'hello' )

Voraussetzungsprüfung (optional):

if vl.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues

Um den fieldIndex zu kennen, können Sie verwenden QgsVectorLayer.pendingFields()

Bearbeiten: Siehe auch den Kommentar von NathanW, in dem die gut lesbare QgsVectorLayer.updateFeature( feature )Methode erwähnt wird.

Zeilen löschen

QgsVectorLayer.deleteFeature (featureId)

vl.deleteFeature( 1000 )

Optionale Voraussetzungsprüfung:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteFeatures
Matthias Kuhn
quelle
2
Verwenden feature[5] = 'hello'und layer.updateFeature(feature)ist besser als Verwenden von vl.updateField IMO
Nathan W
5

So würden Sie Ihren Code in PyQGIS erstellen:

keep = ["Bob","Janet","John","Mike"]

for counter, feature in enumerate(layer.getFeatures()):
    if feature['Name'] in keep:
        feature['ID'] = counter
        layer.updateFeature(feature)
    else:
        layer.deleteFeature(feature.id())
Nathan W.
quelle