Quelles sont les fonctions équivalentes de QGIS pour la mise à jour / suppression de ligne / champ d'ArcPy?

8

J'essaie de reprogrammer certains scripts d'ArcPy en QGIS (1.8 ou 2.0) et il y a quelques fonctions simples que je veux pouvoir refaire mais malheureusement la documentation dans QGIS manque dans certains domaines.

À savoir les trois plus importants pour moi sont:

Ajouter un champ - Ajouter un champ

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

Calculer la gestion des champs - Mettre à jour ce champ

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

Mettre à jour / supprimer des lignes - Mettre à jour / supprimer des lignes en fonction de la condition (sans copier le fichier de formes)

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

Maintenant, je peux parcourir chaque fonctionnalité de QGIS en utilisant SEXTANTE et obtenir sa géométrie que je devrais pouvoir réécrire dans un nouveau fichier de formes et ainsi mettre à jour / supprimer une ligne ou un champ. Commençant par quelque chose comme ...

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

mais je ne peux pas trouver une solution simple pour ces fonctions mentionnées ci-dessus?

BJEBN
la source
Je ne sais pas trop quel est le but de la dernière partie de votre question. Pourquoi mentionnez-vous SEXTANTE? Vous demandez une méthode pour réécrire dans un nouveau fichier de formes, mais votre extrait de code ne fait rien de tel afaics.
Matthias Kuhn

Réponses:

16

Les exemples suivants sont basés sur l'API QGIS 2.0 (qui sera bientôt publiée). Cela a changé depuis la version 1.8, donc la syntaxe de cette version différera à certains endroits.

La meilleure ressource pour des solutions conformes à la version 1.8 et une explication approfondie du contexte des paramètres (également valable pour la version 2.0) sont le livre de recettes PyQGIS

Nous supposerons que vous avez déjà une référence à une couche vectorielle appelée vlobtenue par exemple

vl = iface.activeLayer()

Transactions

Les exemples suivants fonctionnent dans une transaction (mise en cache localement dans QGIS). Avant de commencer la session d'édition, vous devez appeler

vl.startEditing()

et terminer avec

vl.commitChanges()

pour écrire vos modifications dans la source de données. ou

vl.rollBack()

rejeter les modifications

Vous pouvez également travailler directement vl.dataProvider()et oublier les instructions de contrôle des transactions. (Résultant en un comportement de type autocommit)

Ajout d'un champ

QgsVectorLayer.addAttribute (QgsField)

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

Cela ne fonctionne que si le fournisseur de données implémente la capacité AddAttributes. Vous pouvez vérifier cela avec:

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

Calculer des champs

Voir cette réponse:

Est-il possible d'ajouter par programmation des champs calculés?

Il vise toujours la version 1.8, donc au lieu de vl.select()vous devez appeler l'équivalent 2.0 vl.getFeatures()(voir les modifications de l'API QGIS )

Mettre à jour les lignes

QgsVectorLayer.updateField (featureId, fieldIndex, value)

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

Vérification des prérequis (facultatif):

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

Pour connaître le fieldIndex, vous pouvez utiliser QgsVectorLayer.pendingFields()

Edit: Voir aussi le commentaire de NathanW qui mentionne la QgsVectorLayer.updateFeature( feature )méthode bien lisible .

Supprimer des lignes

QgsVectorLayer.deleteFeature (featureId)

vl.deleteFeature( 1000 )

Vérification des prérequis facultatifs:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteFeatures
Matthias Kuhn
la source
2
Utiliser feature[5] = 'hello'et layer.updateFeature(feature)c'est mieux qu'utiliser vl.updateField IMO
Nathan W
5

Voici comment vous feriez votre code dans PyQGIS:

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
la source