Fonctions sur une couche vecteur#
Boucler sur les entités d'une couche sans expression#
On peut parcourir les entités d'une couche QgsVectorLayer
à l'aide de getFeatures()
:
1 2 3 4 |
|
Utilisation des expressions QGIS#
- Les expressions sont très présentes dans QGIS, tant dans l'interface graphique que dans l'utilisation en Python.
- Nous partons de la couche des
COMMUNES
uniquement chargé dans QGIS.
Sélection d'entité#
Nous souhaitons sélectionner les entités dont le code INSEE commence par 77
.
Commençons par faire cela graphiquement dans QGIS Desktop. À l'aide d'une expression QGIS, sélectionner
les codes INSEE qui commencent par 77
(à choisir un code INSEE propre au jeu de données).
Solution en mode graphique :
1 |
|
Nous allons faire la même chose, mais en utilisant Python. Pensez à désélectionner les entités.
1 2 3 4 5 |
|
Le raccourci iface.activeLayer()
est très pratique, mais de temps en temps, on a besoin de plusieurs couches qui
sont déjà dans la légende. Il existe dans QgsProject
plusieurs méthodes pour récupérer des couches dans la légende :
1 2 3 |
|
Notons le s dans mapLayersByName
. Il peut y avoir plusieurs couches avec ce même nom de couche. La fonction retourne
donc une liste de couches. Il convient alors de regarder si la liste est vide ou si elle contient plusieurs couches avec
len(communes)
par exemple.
1 2 3 4 5 6 |
|
Exemple d'une sélection avec un export#
On souhaite pouvoir exporter les communes par département.
On peut créer une variable depts = ['34', '30']
puis boucler dessus pour exporter les entités sélectionnées dans
un nouveau fichier.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Si l'on souhaite parcourir automatiquement les départements existants, on peut récupérer les valeurs uniques. Pour cela, il faut modifier deux lignes :
1 2 |
|
Boucler sur les entités à l'aide d'une expression#
L'objectif est d'afficher dans la console le nom des communes dont la population ne contient pas NC
.
Info
Avec PyQGIS, on peut accéder aux attributs d'une QgsFeature
simplement avec l'opérateur []
sur
l'objet courant comme s'il s'agissait d'un dictionnaire Python :
1 2 |
|
L'exemple à ne pas faire, même si cela fonctionne (car on peut l'optimiser très facilement) :
1 2 3 4 |
|
Tip
Ce qui prend du temps lors de l'exécution, c'est surtout le print
en lui-même.
Si vous n'utilisez pas print
, mais un autre traitement, cela sera plus rapide.
Un simple print ralenti l'exécution d'un script.
Optimisation de la requête#
Dans la documentation, observez bien la signature de la fonction getFeatures
. Que remarquez-vous ?
Utilisons donc une expression pour limiter les résultats.
1 2 3 |
|
Nous pouvons accessoirement ordonner les résultats et surtout encore optimiser la requête en :
- Ne demandant pas de charger la géométrie
- Ne demandant pas de charger tous les attributs
La solution pour les experts
1 2 3 4 5 6 7 8 |
|
-
Faire le test en affichant un champ qui n'est pas dans la requête.
-
Rajoutons une intersection spatiale avec l'emprise suivante :
1 |
|
Si l'on souhaite "enregistrer" le résultat de cette expression QGIS, on peut la matérialiser dans une nouvelle couche :
1 2 |
|
Warning
Attention à la ligne iface.activeLayer() qui peut changer lors de l'ajout d'une nouvelle couche dans la légende.
Regardons le résultat et corrigeons ce problème d'export afin d'obtenir les géométries et les attributs,
il faut supprimer la ligne NoGeometry
si vous l'avez.
Valeur NULL#
En PyQGIS, il existe la valeur NULL
qui peut être présente dans la table attributaire d'une couche vecteur.
1 2 3 4 5 6 7 8 |
|
Calculer un champ#
Avant-dernier exercice, afficher une liste des communes en incluant la densité de population.
Mais regardons avant la gestion des erreurs lors d'un traitement. En effet, nous allons
vouloir "caster" (transformer le type) de la variable population
en entier, mais attention,
il y a des valeurs NC
dans les valeurs.
Les exceptions en Python#
Avant de traiter cet exercice, nous devons voir ce qu'est une exception en Python.
À plusieurs reprises depuis le début de la formation, il est fort à parier que nous ayons des messages en rouges dans la console de temps en temps. Ce sont des exceptions. C'est une notion de programmation qui existe dans beaucoup de languages.
Dans le langage informatique, une exception peut-être :
- levée ("raise" en anglais) pour déclencher une erreur
- attrapée ("catch" en anglais, ou plutôt "except" en Python) pour traiter l'erreur
Essayons dans la console de faire une opération 10 / 2 :
1 |
|
Essayons cette fois-ci 10 / 0, ce qui est mathématiquement impossible :
1 |
|
Passons cette fois-ci dans un script pour que cela soit plus simple, et voir que le script s'arrête brutalement 😉
1 2 3 |
|
On peut "attraper" cette erreur Python à l'aide d'un try ... except...
:
1 2 3 4 5 6 |
|
Le try
permet d'essayer le code qui suit. Le except
permet d'attraper en filtrant s'il y a des exceptions
et de traiter l'erreur si besoin.
Tip
On peut avoir une ou plusieurs lignes de code dans chacun de ces blocs. On peut appeler des fonctions, etc.
Une exception remonte le fil d'exécution du programme#
Important, une exception remonte tant qu'elle n'est pas attrapée :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
On voit que Python, quand il peut, nous indique la "stacktrace" ou encore "traceback", c'est-à-dire une sorte de fil d'ariane.
Héritage des exceptions#
Toutes les exceptions héritent de Exception
donc le code ci-dessous fonctionne, mais n'est pas
recommandé, car il masque d'autres erreurs :
1 2 3 4 |
|
On peut par contre "enchaîner" les exceptions, afin de filtrer progressivement les exceptions.
1 2 3 4 5 6 |
|
Il existe d'autres mots-clés en Python pour les exceptions comme finally:
et else:
.
Voir un autre tutoriel.
On peut imaginer faire une fonction qui divise deux nombres et affiche le résultat
dans la QgsMessageBar
de QGIS, sans tenir compte de la division par zéro :
1 2 3 4 5 6 |
|
En tenant compte d'une possible erreur lors de l'opération mathématique :
1 2 3 4 5 6 7 8 9 |
|
Évidement, on peut vérifier la valeur de b
en amont si c'est égal à 0. Mais ceci est pour présenter le
concept des exceptions en Python.
Retour à l'exercice#
On souhaite donc savoir si un nombre est transformable en entier, dans le cas de la
population (s'il y a NC
par exemple) :
1 2 |
|
Correction possible de l'exercice :
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Nous souhaitons enregistrer ces informations dans une vraie table avec un nouveau champ densite_population
.
Solution plus simple :
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 26 |
|
Solution un peu plus complexe :
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 |
|
Manipulons désormais la géométrie en ajoutant le centroïde de la commune dans une colonne latitude
et
longitude
en degrées.
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 26 27 28 29 30 31 32 33 34 35 36 |
|