Utiliser les algorithmes du module de traitements depuis la console Python

La console permet aux utilisateurs confirmés d’accroître leur productivité en réalisant des opérations complexes qui ne pourraient par être réalisées à partir de l’interface graphique du module de Traitements. Les modèles impliquant plusieurs algorithmes peuvent être définis à partir de l’interface en lignes de commandes et des opérations additionnelles comme les boucles ou les branchements conditionnels permettent de créer des flux de traitements plus puissants et plus flexibles.

There is not a proccesing console in QGIS, but all processing commands are available instead from the QGIS built-in Python console. That means that you can incorporate those command to your console work and connect processing algorithms to all the other features (including methods from the QGIS API) available from there.

Le code exécuté à partir de la console Python, même s’il n’utilise pas de méthodes de traitements particulières, peut être converti en un nouveau algorithme pour être réutilisé dans la boîte à outils, le modeleur ou dans un autre flux de traitements, comme tout autre algorithme. Ainsi certains algorithmes que vous pouvez trouver dans la boîte à outils sont en fait de simples scripts.

Dans ces chapitre, nous allons voir comme utiliser des algorithme issus du module de Traitements à partir de la console Python de QGIS et également comment écrire vos propres algorithmes en Python.

Appeler de algorithmes depuis la console Python

La première chose à faire est d’importer les fonctions de traitement à l’aide de l’instruction suivante:

>>> import processing

A présent, la seule instruction (intéressante) à faire est d’exécuter un algorithme. Cela est effectué en utilisant la méthode runalg(), qui prend en premier paramètre le nom de l’algorithme à lancer, puis tous les paramètres nécessaires à son exécution. Vous devez donc connaître le nom de commande de l’algorithme, qui peut être différent de celui affiché dans la boîte à outils. Pour le trouver, tapez alglist() dans la console :

>>> processing.alglist()

Vous devriez avoir quelque chose qui ressemble à ceci.

Accumulated Cost (Anisotropic)---------------->saga:accumulatedcost(anisotropic)
Accumulated Cost (Isotropic)------------------>saga:accumulatedcost(isotropic)
Add Coordinates to points--------------------->saga:addcoordinatestopoints
Add Grid Values to Points--------------------->saga:addgridvaluestopoints
Add Grid Values to Shapes--------------------->saga:addgridvaluestoshapes
Add Polygon Attributes to Points-------------->saga:addpolygonattributestopoints
Aggregate------------------------------------->saga:aggregate
Aggregate Point Observations------------------>saga:aggregatepointobservations
Aggregation Index----------------------------->saga:aggregationindex
Analytical Hierarchy Process------------------>saga:analyticalhierarchyprocess
Analytical Hillshading------------------------>saga:analyticalhillshading
Average With Mask 1--------------------------->saga:averagewithmask1
Average With Mask 2--------------------------->saga:averagewithmask2
Average With Thereshold 1--------------------->saga:averagewiththereshold1
Average With Thereshold 2--------------------->saga:averagewiththereshold2
Average With Thereshold 3--------------------->saga:averagewiththereshold3
B-Spline Approximation------------------------>saga:b-splineapproximation
...

Il s’agit de la liste des algorithmes disponibles, par ordre alphabétique, accompagnés des noms de commande.

Vous pouvez également passer une chaine de caractères en paramètre de cette méthode. Au lieu de retourner lal iste complète des algorithmes, elle filtrera les résultats selon la chaîne fournies. Par exemple, si vous recherchez un algorithme premettant de calculer la pente d’un MNT, l’instruction alglist("slope") donnera le résultat suivant:

DTM Filter (slope-based)---------------------->saga:dtmfilter(slope-based)
Downslope Distance Gradient------------------->saga:downslopedistancegradient
Relative Heights and Slope Positions---------->saga:relativeheightsandslopepositions
Slope Length---------------------------------->saga:slopelength
Slope, Aspect, Curvature---------------------->saga:slopeaspectcurvature
Upslope Area---------------------------------->saga:upslopearea
Vegetation Index[slope based]----------------->saga:vegetationindex[slopebased]

Ce résultat peut différer d’un système à l’autre selon les algorithmes disponibles.

Il est ainsi facile de trouver l’algorithme recherché et son nom de commande, ici saga:slopeaspectcurvature.

Une fois trouvé le nom de commande de l’algorithme, il s’agit de connaître la bonne syntaxe pour l’exécuter. Cela comprend la liste et l’ordre des paramètres à fournir à l’appel de la méthode runalg(). Une méthode est destinée à décrire en détail un algorithme et renvoie la liste des paramètres nécessaires et le type de sorties générées : il s’agit de la méthode alghelp(nom_de_l_algorithme). Veillez à bien utiliser le nom de commande et non le nom descriptif.

L’appel à la méthode avec le paramètre saga:slopeaspectcurvature donnera la description suivante.

>>> processing.alghelp("saga:slopeaspectcurvature")
ALGORITHM: Slope, Aspect, Curvature
   ELEVATION <ParameterRaster>
   METHOD <ParameterSelection>
   SLOPE <OutputRaster>
   ASPECT <OutputRaster>
   CURV <OutputRaster>
   HCURV <OutputRaster>
   VCURV <OutputRaster>

Vous avez à présent tout ce qu’il faut pour exécute n’importe quel algorithme. Comme indiqué précédemment, l’instruction runalg() suffit pour exécuter un algorithme. Sa syntaxe est la suivante:

>>> processing.runalg(name_of_the_algorithm, param1, param2, ..., paramN,
         Output1, Output2, ..., OutputN)

La liste des paramètres et des sorties à fournir dépend de l’algorithme à exécuter et correspond au résultat, dans l’ordre donné, de la méthode alghelp().

Selon le type de paramètre, les valeurs peuvent être fournies selon plusieurs manières. Une rapide description de ces possibilités est donnée pour chaque type de paramètre d’entrée :

  • Les couches raster, vectorielles ou les tables. Indiquez simplement le nom identifiant la donnée (le nom dans la liste de couches de QGIS) ou un nom de fichier (si la couche n’a pas encore été ouverte, elle sera chargée mais pas ajoutée au canevas). Si vous avez une instance d’un objet QGIS représentant une couche, vous pouvez également la transmettre en paramètre. Si l’entrée est optionnelle et que vous ne souhaitez pas fournir de données particulières, utilisez la valeur None.

  • Sélection. Si un algorithme possède un paramètre sélection, cette valeur doit être une valeur entière. Pour connaître les options possibles, vous pouvez utilisez la commande algoptions(), comme dans l’exemple suivant :

    >>> processing.algoptions("saga:slopeaspectcurvature")
    METHOD(Method)
        0 - [0] Maximum Slope (Travis et al. 1975)
        1 - [1] Maximum Triangle Slope (Tarboton 1997)
        2 - [2] Least Squares Fitted Plane (Horn 1981, Costa-Cabral & Burgess 1996)
        3 - [3] Fit 2.Degree Polynom (Bauer, Rohdenburg, Bork 1985)
        4 - [4] Fit 2.Degree Polynom (Heerdegen & Beran 1982)
        5 - [5] Fit 2.Degree Polynom (Zevenbergen & Thorne 1987)
        6 - [6] Fit 3.Degree Polynom (Haralick 1983)
    

    Dans l’exemple, l’algorithme présente ces types de paramètres, avec 7 options. Notez que le premier élément a pour numéro 0.

  • Entrées multiples. La valeur est une chaîne de caractères, avec les entrées séparées par des points-virgules (;). Comme pour les couches simples et les tables, chaque élément d’entrée peut être le nom d’une variable objet ou un nom de fichier.

  • Champ de la table XXX. Insérez une chaîne de caractère contenant le nom du champ à utiliser. Ce paramètre est sensible à la casse.

  • Table fixée. Entrez la liste de toutes les valeurs, séparées par des virgules (,) et entre guillemets ("). Les valeurs commencent par la première ligne et se lisent de gauche à droite. Vous pouvez aussi utiliser un tableau à deux dimensions pour représenter la table.

  • SCR. Entrez le code EPSG du système de coordonnées désiré.

  • Étendue. Vous devez fournir une chaîne de caractères avec les valeurs xmin, xmax, ymin et ymax séparées par des virgules (,).

Booléen, fichier, chaîne de caractères et valeurs numériques ne nécessitent pas d’explications particulières.

Pour spécifier les valeurs par défaut des paramètres tels que chaînes de caractères, booléens ou valeurs numériques, entrez None dans l’entrée correspondante.

Pour les données en sortie, entrez le chemin à utiliser, comme dans la boîte à outils. Si vous préférez sauvegarder le résultat dans un fichier temporaire, indiquez None. L’extension du fichier déterminera le format de fichier utilisé. Si elle n’est pas reconnue par l’algorithme, le format de fichier par défaut sera utilisé et l’extension sera ajouté à la fin du nom de fichier.

Unlike when an algorithm is executed from the toolbox, outputs are not added to the map canvas if you execute that same algorithm from the Python Console. If you want to add an output to it, you have to do it yourself after running the algorithm. To do so, you can use QGIS API commands, or, even easier, use one of the handy methods provided for such task.

La méthode runalg renvoie un dictionnaire Python avec pour clés les noms des sorties (correspondant à la description des éléments de l’algorithme) et pour valeurs les chemins des résultats. Vous pouvez charger ces couches de résultat en passant leur chemin à la méthode load().

Fonctions supplémentaires pour gérer des données

Apart from the functions used to call algorithms, importing the processing package will also import some additional functions that make it easier to work with data, particularly vector data. They are just convenience functions that wrap some functionality from the QGIS API, usually with a less complex syntax. These functions should be used when developing new algorithms, as they make it easier to operate with input data.

Below is a list of some of this commands. More information can be found in the classes under the processing/tools package, and aso in the example scripts provided with QGIS.

  • getobject(obj): Returns a QGIS object (a layer or table) from the passed object, which can be a filename or the name of the object in the QGIS Table of Contents.
  • values(layer, fields): Returns the values in the attributes table of a vector layer, for the passed fields. Fields can be passed as field names or as zero-based field indices. Returns a dict of lists, with the passed field identifiers as keys. It considers the existing selection
  • getfeatures(layer): Returns an iterator over the features of a vector layer, considering the existing selection.
  • uniquelabels(layer, field): Returns a list of unique values for a given attribute. Attribute can be passed as a field name or a zero-based field index. It considers the existing selection

Créer des scripts et les exécuter depuis la boîte à outils

You can create your own algorithms by writing the corresponding Python code and adding a few extra lines to supply additional information needed to define the semantics of the algorithm. You can find a Create new script menu under the Tools group in the Script algorithms block of the toolbox. Double-click on it to open the script edition dialog. That’s where you should type your code. Saving the script from there in the scripts folder (the default one when you open the save file dialog), with .py extension, will automatically create the corresponding algorithm.

Le nom de l’algorithme (celui qui apparaît dans la boîte à outils) est généré à partir du nom de fichier, en enlevant son extension et en remplaçant les underscores (‘_’) par des espaces.

Voici par exemple le code permettante de calculer l’Indice d’Humidité Topographique (Topographic Wetness Index, TWI) directement à partir d’un MNT

##dem=raster
##twi=output
ret_slope = processing.runalg("saga:slopeaspectcurvature", dem, 0, None,
                None, None, None, None)
ret_area = processing.runalg("saga:catchmentarea(mass-fluxmethod)", dem,
                0, False, False, False, False, None, None, None, None, None)
processing.runalg("saga:topographicwetnessindex(twi), ret_slope['SLOPE'],
                ret_area['AREA'], None, 1, 0, twi)

Comme vous pouvez le voir, il utilise 3 algorithmes, provenant de SAGA. Le dernier calcule le TWI, mais nécessite de une couche représentant la pente et une autre d’accumulation des flux. Dans la mesure où ces deux couches n’existent pas mais que nous disposons d’un MNT, nous allons les calculer en faisant appel aux algorithmes SAGA adéquats.

Le bout de code où le traitement est effectué n’est pas compliqué à comprendre si vous avez lu les sections précédentes. Cependant, les premières lignes nécessitent quelques explications. Elles fournissent les informations nécessaires pour convertir votre code en un algorithme utilisable à partir d’autres contextes, comme la boîte à outils ou le modeleur graphique.

Ces lignes débutent par deux symboles de commentaire Python (##) et présentent la structure suivante :

[parameter_name]=[parameter_type] [optional_values]

Voici la liste des types de paramètres gérés par les scripts de traitement, leur syntaxe ainsi que quelques exemples.

  • raster. Une couche raster

  • vector. Une couche vectorielle

  • table. Une table

  • number. Une valeur numérique. Une valeur par défaut doit être définie. Par exemple, depth=number 2.4

  • string. Une chaîne de caractère. Comme pour les valeurs numériques, une valeur par défaut doit être définie. Par exemple, name=string Victor

  • boolean. Une valeur booléenne. Ajoutez True (Vrai) ou False (Faux) pour définir la valeur par défaut. Par exemple, verbose=boolean True pour plus un rendu plus parlant

  • multiple raster. Un ensemble de couches raster en entrée.

  • multiple vector. Un ensemble de couches vectorielles en entrée.

  • field. Un champ dans la table d’attributs d’une couche vectorielle. Le nom de la couche doit être ajoutée après l’étiquette field. Par exemple, si vous déclarez une couche vectorielle macouche=vector en entrée, vous pouvez utilisez monchamp=champ1 macouche pour ajouter en paramètre le champ de cette couche.

  • folder. Un répertoire

  • file. Un nom de fichier

Le nom du paramètre correspond à ce qui sera affiché lorsque l’utilisateur exécutera l’algorithme, ainsi qu’au nom de variable à utiliser dans le script. La valeur saisie par l’utilisateur pour ce paramètre sera assignée à cette variable, portant ce nom.

A l’affichage du nom de paramètre, les underscores (‘_’) sont convertis en espaces pour améliorer la lisibilité. Ainsi, par exemple, si vous souhaitez que l’utilisateur saisisse une valeur appelée ‘Valeur numérique’, vous devez utiliser une variable nommée Valeur_numérique.

Layers and tables values are strings containing the filepath of the corresponding object. To turn them into a QGIS object, you can use the processing.getObjectFromUri() function. Multiple inputs also have a string value, which contains the filepaths to all selected object, separated by semicolons (;).

Les sorties sont définies de la même manière, avec les étiquettes suivantes:

  • output raster
  • output vector
  • output table
  • output html
  • output file
  • output number
  • output string

La valeur attribuée à une variable de sortie est toujours une chaîne de caractères contenant le chemin de l’objet. Si le nom est vide, un fichier temporaire sera créé.

Si un résultat est défini, l’algorithme tentera de l’ajouter à QGIS à l’issue de son exécution. C’est la raison pour laquelle la couche résultat TWI, nommée explicitement par l’utilisateur, sera chargée, même si la méthode runalg() ne le fait pas.

N’utilisez donc pas la méthode load() dans vos scripts, mais uniquement à partir de la console. Si un algorithme définit une couche en sortie, celle-ci doit être déclarée ainsi. Dans le cas contraire, vous ne pourriez pas l’utiliser dans le modeleur parce que sa syntaxe (comme définie par ses étiquettes, exposées précédemment) ne correspond âs à ce que l’algorithme crée effectivement.

Les sorties masquées (nombres ou chaînes) n’ont pas de valeur. C’est à vous de leur assigner une valeur. Pour cela, affecter une valeur à la variable pour la déclarer en sortie. Par exemple, vous pourriez utiliser la déclaration suivante,

##average=output number

l’instruction suivante fixe la valeur de sortie à 5:

average = 5

En complément des étiquettes définissant les paramètres et les sorties, vous pouvez définir la catégorie dans laquelle l’algorithme apparaîtra, en utilisant l’étiquette group.

Il est conseillé d’informer l’utilisateur de l’avancée du traitement de l’algorithme. Vous disposez de la variable globale progress, aevc deux méthodes, setText(text) et setPercentage(percent) pour modifier le message et la barre de progression.

Plusieurs exemples sont fournis. Veuillez vous y reporter pour servir d’exemples. Cliquez avec le bouton droit sur un script et choisissez Éditer le script pour voir et éditer le code correspondant.

Documenter ses scripts

Comme pour les modèles, vous pouvez ajouter des commentaires à votre script, pour expliciter le traitement effectué et son utilisation. Dans la fenêtre d’édition du script se situe un bouton [Editer l’aide], qui vous amènera à la fenêtre d’édition de l’aide. Veuillez vous reporter au chapitre Modeleur graphique pour plus d’information sur cette fenêtre.

Les fichiers d’aide sont sauvegardés dans le même répertoire que les scripts, avec l’extention .help.Veuillez noter qu’à la première édition de l’aide, la fermeture de la fenêtre ne sauvegarde pas vos modifications. Par contre, si le fichier a déjà été sauvegardé une fois préalablement, les modifications seront conservées.

Pre- and post-execution script hooks

Scripts can also be used to set pre- and post-execution hooks that are run before and after an algorithm is run. This can be used to automate tasks that should be performed whenever an algorithm is executed.

The syntax is identical to the syntax explained above, but an additional global variable named alg is available, representing the algorithm that has just been (or is about to be) executed.

In the General group of the processing config dialog you will find two entries named Pre-execution script file and Post-execution script file where the filename of the scripts to be run in each case can be entered.