IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Demande d'aide sur Python 2.7 pour QGIS / PyQGIS (MAJ Champ existant en fonction d'un autre) [Python 2.X]


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Géomaticien et Web Journaliste
    Inscrit en
    Septembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Géomaticien et Web Journaliste
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2014
    Messages : 9
    Points : 9
    Points
    9
    Par défaut Demande d'aide sur Python 2.7 pour QGIS / PyQGIS (MAJ Champ existant en fonction d'un autre)
    Bonjour à Toutes et à Tous,

    Je me permets de vous contacter pour une demande en Python PyQGIS :

    Je cherche à mettre à jour, en Python 2.7 pour QGIS 2.18 Las Palmas, un champ existant ( "ETIQUETTE") d'une table attributaire en fonction d'un autre champ ("MODE_ADDUC"), c'est-à-dire l'équivalent d'un CASE WHEN .... THEN .... ELSE ..... END en langage SQL.

    -----------------------------------------------------------------
    J'ai testé le code suivant en utilisant une condition if .....elif .......else (au lieu du CASE WHEN du langage SQL) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    #TEST : mettre à jour un champ existant avec boucle
    from PyQt4.QtCore import *
    from qgis.core import *
    vl = iface.activeLayer()
    vl.startEditing()
     
    #step 1
    vl.updateFields()
    idx = vl.dataProvider().fieldNameIndex( 'ETIQUETTE' )
    adduc = vl.dataProvider().fieldNameIndex( 'MODE_ADDUC' )
     
    #step 2
    for f in vl.getFeatures():
        if f[adduc] == 'AERIEN':
            f[idx] = 'CIEL'
        elif f[adduc] == 'FACADE':
            f[idx] = 'MUR'
        elif f[adduc] == 'SOUTERRAIN':
            f[idx] = 'TERRE'
        else:
            f[idx] = 'RIEN'
        vl.updateFeature( f ) 
     
    vl.commitChanges()
    mais la console Python me retourne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Traceback (most recent call last):
      File "<input>", line 2, in <module>
    KeyError: '-1'
    Pouvez-vous m'aider ?
    -----------------------------------------------------------------
    Pour info :

    Le même type de code fonctionne, mais sans la condition if .... elif .... else :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    #mettre à jour un champ existant
    from PyQt4.QtCore import QVariant
    from qgis.core import QgsField, QgsExpression, QgsFeature
    vl = iface.activeLayer()
    vl.startEditing()
     
    #step 1
    vl.updateFields()
    idx = vl.fieldNameIndex( 'ETIQUETTE' )
     
    #step 2
     
    for f in vl.getFeatures():
        f[idx] = 'ETIQPHIL'
        vl.updateFeature( f )
     
    vl.commitChanges()

    En pièce Jointe : le Shapefile zippé "test_adresses.zip" contenant les champs mentionnés dans mes précédents exemples.

    En vous remerciant par avance,

    Philippe Schitter
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    -1 est la valeur retournée par .fieldNameIndex pour signaler qu'il ne trouve pas le champ recherché ('MODE_ADDUC').

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Géomaticien et Web Journaliste
    Inscrit en
    Septembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Géomaticien et Web Journaliste
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2014
    Messages : 9
    Points : 9
    Points
    9
    Par défaut fieldNameIndex( 'MOD_ADDUC' ) corrigé OK + problème sur le bouclage ?
    Citation Envoyé par wiztricks Voir le message
    Salut,

    -1 est la valeur retournée par .fieldNameIndex pour signaler qu'il ne trouve pas le champ recherché ('MODE_ADDUC').

    - W
    Bonjour Wiztricks/Modérateur,

    Tout d'abord Merci pour votre réponse.
    L'erreur est très bête de ma part, le champ est orthographié ('MOD_ADDUC') et non ('MODE_ADDUC').

    Ensuite, dans la déclaration des champs, j'ai supprimé la fonction dataProvider() inutile ici et génératrice d'erreurs.

    Extraits du code au niveau des deux corrections :

    Avant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #step 1
    vl.updateFields()
    idx = vl.dataProvider().fieldNameIndex( 'ETIQUETTE' )
    adduc = vl.dataProvider().fieldNameIndex( 'MODE_ADDUC' )
    Après :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #step 1
    vl.updateFields()
    idx = vl.fieldNameIndex( 'ETIQUETTE' )
    adduc = vl.fieldNameIndex( 'MOD_ADDUC' )
    Suite à à ces deux corrections (('MOD_ADDUC') bien orthographié et dataProvider() supprimé),
    le code ne génère plus d'erreur dans l'interpréteur mais ne modifie pas le champ ('ETIQUETTE'); bref, il ne fait rien.
    Le bouclage sur l'ensemble des objets ne se lance pas visiblement.

    Rappel 1 : le shapefile zippé "test_adresses.zip" est en pièce jointe depuis ma 1ère publication.

    Rappel 2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    #TEST : mettre à jour un champ existant avec boucle
    from PyQt4.QtCore import QVariant
    from qgis.core import QgsField, QgsExpression, QgsFeature
    vl = iface.activeLayer()
    vl.startEditing()
     
    #step 1
    vl.updateFields()
    idx = vl.fieldNameIndex( 'ETIQUETTE' )
    adduc = vl.fieldNameIndex( 'MOD_ADDUC' )
    #step 2
     
    for f in vl.getFeatures():
    	if f[adduc] == 'AERIEN':
    		f[idx] = 'CIEL'
    	elif f[adduc] == 'FACADE':
    		f[idx] = 'MUR'
    	elif f[adduc] == 'SOUTERRAIN':
    		f[idx] = 'TERRE'
    	else:
    		f[idx] = 'RIEN'
    		vl.updateFeature( f ) 
     
    vl.commitChanges()
    Par conséquent, et sans vouloir abuser de votre temps, avez-vous une piste de correction à me suggérer ?

    En vous remerciant par avance,

    Bien Cordialement,

    Philippe Schitter

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Citation Envoyé par philippe_schitter Voir le message
    Par conséquent, et sans vouloir abuser de votre temps, avez-vous une piste de correction à me suggérer ?
    Relisez le dernier code que vous avez posté et regardez quand est effectué l'appel à vl.updateFeature( f ) (ou comparez ces lignes aux premiers codes que vous avez posté).
    note: je ne connais pas pyqgis, je lis juste votre code.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Géomaticien et Web Journaliste
    Inscrit en
    Septembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Géomaticien et Web Journaliste
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2014
    Messages : 9
    Points : 9
    Points
    9
    Par défaut MERCI (1 indentation en trop) + une dernière question d'ordre général
    Citation Envoyé par wiztricks Voir le message
    Salut,



    Relisez le dernier code que vous avez posté et regardez quand est effectué l'appel à vl.updateFeature( f ) (ou comparez ces lignes aux premiers codes que vous avez posté).
    note: je ne connais pas pyqgis, je lis juste votre code.

    - W
    MERCI beaucoup Wiztricks !
    Effectivement, une indentation en trop à l'issue de ma condition if ... elif ... else.

    Le bon code est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    #TEST : mettre à jour un champ existant avec boucle
    from PyQt4.QtCore import QVariant
    from qgis.core import QgsField, QgsExpression, QgsFeature
    vl = iface.activeLayer()
    vl.startEditing()
     
    #step 1
    vl.updateFields()
    idx = vl.fieldNameIndex( 'ETIQUETTE' )
    adduc = vl.fieldNameIndex( 'MOD_ADDUC' )
    #step 2
     
    for f in vl.getFeatures():
    	if f[adduc] == 'AERIEN':
    		f[idx] = 'CIEL'
    	elif f[adduc] == 'FACADE':
    		f[idx] = 'MUR'
    	elif f[adduc] == 'SOUTERRAIN':
    		f[idx] = 'TERRE'
    	else:
    		f[idx] = 'RIEN'
    	vl.updateFeature( f ) 
     
    vl.commitChanges()

    Par ailleurs, se suis débutant en Python et j'apprends en autodidacte avec les tutos et forums.

    Ma question d'ordre général : lorsqu'on souhaite réaliser une série d'actions successives, un petit peu comme dans un ETL de type modèle graphique QGIS ou FME,
    doit-on lancer, en Python, une action par Classe/Classe d'objets ? ou Non ?

    Par exemple, en VisualBasic (MapBasic pour MapInfo) : chaque action est intégrée dans une procédure "Sub"
    (Sub Main; Sub "Extraire points d'une polyligne"; Sub "Mettre À Jour un champ existant de la Table Attributaire; ......).

    MERCI beaucoup encore.

    Bien Cordialement,

    Philippe Schitter

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par philippe_schitter Voir le message
    doit-on lancer, en Python, une action par Classe/Classe d'objets ? ou Non ?
    Ce n'est pas nécessaire: vous structurez votre code comme vous pouvez/voulez pourvu que vous respectiez la structure de block imposée.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Géomaticien et Web Journaliste
    Inscrit en
    Septembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Géomaticien et Web Journaliste
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2014
    Messages : 9
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Ce n'est pas nécessaire: vous structurez votre code comme vous pouvez/voulez pourvu que vous respectiez la structure de block imposée.

    - W
    OK Merci Wiztricks

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. demande d'aide sur python
    Par dekiss dans le forum Général Python
    Réponses: 2
    Dernier message: 01/03/2012, 16h05
  2. Demande d'aide sur les regexp
    Par Uld dans le forum Langage
    Réponses: 1
    Dernier message: 18/08/2006, 22h15
  3. [VB6] Demande d'aide sur un programme !
    Par Lucas42 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 16/06/2006, 11h49
  4. Demande d'aide sur XPDL (XML Process Definition Language)
    Par Bebert71 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 17/02/2006, 09h23
  5. demande d'aide sur samba
    Par marcoss dans le forum Développement
    Réponses: 5
    Dernier message: 04/12/2003, 19h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo