22.7. 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.
Il n’y a pas de console spécifique au module de traitements de QGIS mais toutes les commandes du module sont disponibles via la console Python de QGIS. Cela signifie que vous pouvez intégrer ces commandes dans votre travail et les connecter aux autres fonctions accessibles depuis la console (dont les méthodes issues de l’API QGIS).
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 cette section, nous allons voir comme utiliser des algorithmes issus du module de Traitements à partir de la console Python de QGIS et également comment écrire des algorithmes en Python.
22.7.1. Appeler des algorithmes depuis la console Python¶
La première chose à faire est d’importer les fonctions de traitement à l’aide de l’instruction suivante:
>>> from qgis 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 run
, 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, vous pouvez utiliser processingRegistry
en tapant dans la console la commande suivante :
>>> for alg in QgsApplication.processingRegistry().algorithms():
print(alg.id(), "->", alg.displayName())
Vous obtiendrez quelque chose de ce genre (avec quelques tirets en plus pour la lisibilité).
3d:tessellate --------------> Tessellate
gdal:aspect ----------------> Aspect
gdal:assignprojection ------> Assign projection
gdal:buffervectors ---------> Buffer vectors
gdal:buildvirtualraster ----> Build Virtual Raster
gdal:cliprasterbyextent ----> Clip raster by extent
gdal:cliprasterbymasklayer -> Clip raster by mask layer
gdal:clipvectorbyextent ----> Clip vector by extent
gdal:clipvectorbypolygon ---> Clip vector by mask layer
gdal:colorrelief -----------> Color relief
gdal:contour ---------------> Contour
gdal:convertformat ---------> Convert format
gdal:dissolve --------------> Dissolve
...
Il s’agit là de la liste des identifiants de tous les algorithmes disponibles, triés par le nom du fournisseur puis l’ID de l’algorithme, accompagnés du nom littéral de l’algorithme.
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 des paramètres à fournir à l’appel de la méthode run()
.
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 algorithmHelp(id_algorithme)
. Veillez à bien utiliser l’ID de l’algorithme et non le nom descriptif.
En appelant la méthode avec native: buffer
comme paramètre ( qgis: buffer
est un alias pour native: buffer
et fonctionnera également), vous obtenez la description suivante:
>>> processing.algorithmHelp("native:buffer")
Buffer (native:buffer)
This algorithm computes a buffer area for all the features in an
input layer, using a fixed or dynamic distance.
The segments parameter controls the number of line segments to
use to approximate a quarter circle when creating rounded
offsets.
The end cap style parameter controls how line endings are handled
in the buffer.
The join style parameter specifies whether round, miter or
beveled joins should be used when offsetting corners in a line.
The miter limit parameter is only applicable for miter join
styles, and controls the maximum distance from the offset curve
to use when creating a mitered join.
----------------
Input parameters
----------------
INPUT: Input layer
Parameter type: QgsProcessingParameterFeatureSource
Accepted data types:
- str: layer ID
- str: layer name
- str: layer source
- QgsProcessingFeatureSourceDefinition
- QgsProperty
- QgsVectorLayer
DISTANCE: Distance
Parameter type: QgsProcessingParameterDistance
Accepted data types:
- int
- float
- QgsProperty
SEGMENTS: Segments
Parameter type: QgsProcessingParameterNumber
Accepted data types:
- int
- float
- QgsProperty
END_CAP_STYLE: End cap style
Parameter type: QgsProcessingParameterEnum
Available values:
- 0: Round
- 1: Flat
- 2: Square
Accepted data types:
- int
- str: as string representation of int, e.g. '1'
- QgsProperty
JOIN_STYLE: Join style
Parameter type: QgsProcessingParameterEnum
Available values:
- 0: Round
- 1: Miter
- 2: Bevel
Accepted data types:
- int
- str: as string representation of int, e.g. '1'
- QgsProperty
MITER_LIMIT: Miter limit
Parameter type: QgsProcessingParameterNumber
Accepted data types:
- int
- float
- QgsProperty
DISSOLVE: Dissolve result
Parameter type: QgsProcessingParameterBoolean
Accepted data types:
- bool
- int
- str
- QgsProperty
OUTPUT: Buffered
Parameter type: QgsProcessingParameterFeatureSink
Accepted data types:
- str: destination vector file, e.g. 'd:/test.shp'
- str: 'memory:' to store result in temporary memory layer
- str: using vector provider ID prefix and destination URI,
e.g. 'postgres:...' to store result in PostGIS table
- QgsProcessingOutputLayerDefinition
- QgsProperty
----------------
Outputs
----------------
OUTPUT: <QgsProcessingOutputVectorLayer>
Buffered
Vous disposez maintenant de tout ce dont vous avez besoin pour exécuter n’importe quel algorithme. Comme nous l’avons déjà mentionné, les algorithmes peuvent être exécutés en utilisant:run()
. Sa syntaxe est la suivante:
>>> processing.run(name_of_the_algorithm, parameters)
Où paramètres est un dictionnaire de paramètres qui dépendent de l’algorithme que vous souhaitez exécuter, et est exactement la liste que la méthode algorithmHelp()
vous donne.
>>> processing.run("native:buffer", {'INPUT': '/data/lines.shp',
'DISTANCE': 100.0,
'SEGMENTS': 10,
'DISSOLVE': True,
'END_CAP_STYLE': 0,
'JOIN_STYLE': 0,
'MITER_LIMIT': 10,
'OUTPUT': '/data/buffers.shp'})
Lorsqu’un paramètre est facultatif et que vous ne souhaitez pas l’utiliser, ne l’incluez pas dans le dictionnaire.
Lorsqu’un paramètre n’est pas indiqué, sa valeur par défaut est appliquée.
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.
Enumeration. Si un algorithme possède un paramètre d’énumération, la valeur de ce paramètre doit être saisie en utilisant une valeur entière. Pour connaître les options disponibles, vous pouvez utiliser la commande
algorithmHelp()
, comme ci-dessus. Par exemple, l’algorithmenative:buffer
a une énumération appelée JOIN_STYLE :JOIN_STYLE: Join style Parameter type: QgsProcessingParameterEnum Available values: - 0: Round - 1: Miter - 2: Bevel Accepted data types: - int - str: as string representation of int, e.g. '1' - QgsProperty
Dans ce cas, le paramètre a trois options. Notez que la commande est basée sur zéro.
Booléen. Utilisez
True
ouFalse
.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
etymax
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.
Les paramètres d’entrée tels que les chaînes, les booléens ou les valeurs numériques ont des valeurs par défaut. La valeur par défaut est utilisée si l’entrée de paramètre correspondante est manquante.
Pour les objets de données en sortie, saisissez le chemin d’accès au fichier à utiliser pour l’enregistrer, comme cela se fait à partir de la boîte à outils. Si l’objet de sortie n’est pas spécifié, le résultat est enregistré dans un fichier temporaire (ou ignoré s’il s’agit d’une sortie facultative). L’extension du fichier détermine le format du fichier. Si vous entrez une extension de fichier non prise en charge par l’algorithme, le format de fichier par défaut pour ce type de sortie sera utilisé et son extension correspondante ajoutée au chemin de fichier donné.
Contrairement à lorsqu’un algorithme est exécuté à partir de la boîte à outils, les sorties ne sont pas ajoutées au canevas de carte si vous exécutez ce même algorithme à partir de la console Python en utilisant run()
, mais runAndLoadResults()
le fera.
La méthode run
renvoie un dictionnaire avec un ou plusieurs noms de sortie (ceux indiqués dans la description de l’algorithme) sous forme de clés et les chemins de fichier de ces sorties sous forme de valeurs:
>>> myresult = processing.run("native:buffer", {'INPUT': '/data/lines.shp',
'DISTANCE': 100.0,
'SEGMENTS': 10,
'DISSOLVE': True,
'END_CAP_STYLE': 0,
'JOIN_STYLE': 0,
'MITER_LIMIT': 10,
'OUTPUT': '/data/buffers.shp'})
>>> myresult['OUTPUT']
/data/buffers.shp
Vous pouvez charger la sortie de la fonction en passant les chemins de fichiers correspondants à la méthode load()
. Ou vous pouvez utiliser runAndLoadResults()
au lieu de run()
pour les charger immédiatement.
Si vous voulez ouvrir un dialogue d’algorithme depuis la console, vous pouvez utiliser la méthode « createAlgorithmDialog ». Le seul paramètre obligatoire est le nom de l’algorithme, mais vous pouvez également définir le dictionnaire des paramètres afin que le dialogue soit rempli automatiquement :
>>> my_dialog = processing.createAlgorithmDialog("native:buffer", {
'INPUT': '/data/lines.shp',
'DISTANCE': 100.0,
'SEGMENTS': 10,
'DISSOLVE': True,
'END_CAP_STYLE': 0,
'JOIN_STYLE': 0,
'MITER_LIMIT': 10,
'OUTPUT': '/data/buffers.shp'})
>>> my_dialog.show()
La méthode « ExecAlgorithmDialog » ouvre le dialogue immédiatement :
>>> processing.execAlgorithmDialog("native:buffer", {
'INPUT': '/data/lines.shp',
'DISTANCE': 100.0,
'SEGMENTS': 10,
'DISSOLVE': True,
'END_CAP_STYLE': 0,
'JOIN_STYLE': 0,
'MITER_LIMIT': 10,
'OUTPUT': '/data/buffers.shp'})
22.7.2. Créer des scripts et les exécuter depuis la boîte à outils¶
Vous pouvez créer vos propres algorithmes en écrivant du code Python. Les scripts de traitement étendent QgsProcessingAlgorithm
, vous devez donc ajouter des lignes de code supplémentaires pour implémenter les fonctions obligatoires. Vous pouvez trouver Créer un nouveau script (feuille blanche) et Créer un nouveau script à partir d’un modèle (modèle qui inclut le code pour les fonctions obligatoires de QgsProcessingAlgorithm
) sous le menu déroulant Scripts en haut de la boîte à outils Traitement. L’éditeur de script de traitement s’ouvre et c’est là que vous devez taper votre code. L’enregistrement du script à partir de là dans le dossier scripts
(le dossier par défaut lorsque vous ouvrez la boîte de dialogue d’enregistrement du fichier) avec une extension .py
devrait créer l’algorithme correspondant.
Le nom de l’algorithme (celui que vous verrez dans la boîte à outils) est défini dans le code.
Jetons un coup d’œil au code suivant, qui définit un algorithme de traitement qui effectue une opération de tampon avec une distance de tampon définie par l’utilisateur sur une couche vectorielle spécifiée par l’utilisateur, après avoir d’abord lissé la couche.
from qgis.core import (QgsProcessingAlgorithm,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink)
from qgis import processing
class algTest(QgsProcessingAlgorithm):
INPUT_BUFFERDIST = 'BUFFERDIST'
OUTPUT_BUFFER = 'OUTPUT_BUFFER'
INPUT_VECTOR = 'INPUT_VECTOR'
def __init__(self):
super().__init__()
def name(self):
return "algTest"
def displayName(self):
return "algTest script"
def createInstance(self):
return type(self)()
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(
self.INPUT_VECTOR, "Input vector"))
self.addParameter(QgsProcessingParameterNumber(
self.INPUT_BUFFERDIST, "Buffer distance",
QgsProcessingParameterNumber.Double,
100.0))
self.addParameter(QgsProcessingParameterFeatureSink(
self.OUTPUT_BUFFER, "Output buffer"))
def processAlgorithm(self, parameters, context, feedback):
#DO SOMETHING
algresult = processing.run("native:smoothgeometry",
{'INPUT': parameters[self.INPUT_VECTOR],
'ITERATIONS':2,
'OFFSET':0.25,
'MAX_ANGLE':180,
'OUTPUT': 'memory:'},
context=context, feedback=feedback, is_child_algorithm=True)
smoothed = algresult['OUTPUT']
algresult = processing.run('native:buffer',
{'INPUT': smoothed,
'DISTANCE': parameters[self.INPUT_BUFFERDIST],
'SEGMENTS': 5,
'END_CAP_STYLE': 0,
'JOIN_STYLE': 0,
'MITER_LIMIT': 10,
'DISSOLVE': True,
'OUTPUT': parameters[self.OUTPUT_BUFFER]},
context=context, feedback=feedback, is_child_algorithm=True)
buffered = algresult['OUTPUT']
return {self.OUTPUT_BUFFER: buffered}
Après avoir effectué les importations nécessaires, les fonctions suivantes QgsProcessingAlgorithm
sont spécifiées:
name
: L’id de l’algorithme (en minuscules).displayName
: Un nom lisible par l’homme pour l’algorithme.createInstance
: Créez une nouvelle instance de la classe d’algorithme.initAlgorithm
: Configurez le parameterDefinitions et outputDefinitions.Ici, vous décrivez les paramètres et la sortie de l’algorithme. Dans ce cas, une source d’entités pour l’entrée, un récepteur d’entités pour le résultat et un nombre pour la distance du tampon.
processAlgorithm
: déclenche l’algorithmeIci, nous exécutons d’abord l’algorithme
smoothgeometry
pour lisser la géométrie, puis nous exécutons l’algorithmebuffer
sur la sortie lissée. Pour pouvoir exécuter des algorithmes à partir d’un autre algorithme, nous devons définir une fonction fictive pour le paramètreonFinish
pourexécuter
. Il s’agit de la fonctionno_post_process
. Vous pouvez voir comment les paramètres d’entrée et de sortie sont utilisés comme paramètres pour les algorithmes desmoothgeometry
et debuffer
.
Plusieurs types de paramètres différents sont disponibles pour l’entrée et la sortie. Vous trouverez ci-dessous une liste triée par ordre alphabétique:
Le premier paramètre pour les constructeurs est le nom du paramètre et le second est la description du paramètre (pour l’interface utilisateur). Les autres paramètres du constructeur sont spécifiques au type de paramètre.
L’entrée peut être transformée en classes QGIS en utilisant les fonctions parameterAs
de QgsProcessingAlgorithm
. Par exemple, pour obtenir le nombre fourni pour la distance du tampon sous forme de double
self.parameterAsDouble(parameters, self.INPUT_BUFFERDIST, context)).
La fonction processAlgorithm
doit renvoyer un dictionnaire contenant des valeurs pour chaque sortie définie par l’algorithme. Cela permet d’accéder à ces sorties à partir d’autres algorithmes, y compris d’autres algorithmes contenus dans le même modèle.
Des algorithmes bien comportés devraient définir et renvoyer autant de sorties que cela a du sens. Les sorties sans entité, telles que les nombres et les chaînes, sont très utiles lors de l’exécution de votre algorithme dans le cadre d’un modèle plus large, car ces valeurs peuvent être utilisées comme paramètres d’entrée pour les algorithmes suivants au sein du modèle. Pensez à ajouter des sorties numériques pour des choses comme le nombre d’entités traitées, le nombre d’entités non valides rencontrées, le nombre de sorties d’entités, etc. Plus vous renvoyez de sorties, plus votre algorithme devient utile!
22.7.2.1. Retour d’information¶
L’objet feedback
passé à processAlgorithm
doit être utilisé pour les commentaires / interactions des utilisateurs. Vous pouvez utiliser la fonction setProgress
de l’objet feedback
pour mettre à jour la barre de progression (0 à 100) pour informer l’utilisateur sur la progression de l’algorithme. Ceci est très utile si votre algorithme prend beaucoup de temps.
L’objet feedback
fournit une méthode isCanceled
qui doit être surveillée pour permettre l’annulation de l’algorithme par l’utilisateur. La méthode pushInfo
de feedback
peut être utilisée pour envoyer des informations à l’utilisateur et reportError
est pratique pour transmettre des erreurs non fatales aux utilisateurs.
Les algorithmes doivent éviter d’utiliser d’autres formes de rétroaction pour les utilisateurs, telles que des instructions d’impression ou la journalisation de QgsMessageLog
, et doivent toujours utiliser à la place l’objet de rétroaction. Cela permet une journalisation détaillée de l’algorithme et est également compatible avec les threads (ce qui est important, étant donné que les algorithmes sont généralement exécutés dans un thread d’arrière-plan).
22.7.2.2. Gestion des erreurs¶
Si votre algorithme rencontre une erreur qui l’empêche de s’exécuter, telle que des valeurs d’entrée non valides ou une autre condition à partir de laquelle il ne peut pas ou ne doit pas récupérer, alors vous devez déclencher une QgsProcessingException
. Par exemple.:
if feature['value'] < 20:
raise QgsProcessingException('Invalid input value {}, must be >= 20'.format(feature['value']))
Essayez d’éviter de déclencher QgsProcessingException
pour les erreurs non fatales (par exemple lorsqu’une entité a une géométrie nulle), et au lieu de cela, signalez simplement ces erreurs via feedback.reportError()
et ignorer l’entité. Cela permet de rendre votre algorithme «convivial pour le modèle», car il évite d’arrêter l’exécution d’un algorithme entier lorsqu’une erreur non fatale est rencontrée.
22.7.2.3. Documenter ses scripts¶
Comme dans le cas des modèles, vous pouvez créer une documentation supplémentaire pour vos scripts, pour expliquer ce qu’ils font et comment les utiliser.
La classe QgsProcessingAlgorithm
fournit les métodes helpString
, shortHelpString
et helpUrl
à cet effet. Spécifiez / remplacez-les pour fournir plus d’aide à l’utilisateur.
shortDescription
est utilisé dans l’info-bulle lors du survol de l’algorithme dans la boîte à outils.
22.7.3. Scripts de pré et post-exécution¶
Les scripts peuvent également être utilisés comme hooks avant et après l’exécution qui sont exécutés avant et après l’exécution d’un algorithme, respectivement. Cela peut être utilisé pour automatiser les tâches qui doivent être effectuées chaque fois qu’un algorithme est exécuté.
La syntaxe est identique à celle qui est expliquée plus haut mais une variable globale nommée alg
est disponible. Elle représente l’objet alogrithme qui vient (ou qui va) être lancé.
Dans le groupe Général de la boîte de dialogue des options de traitement, vous trouverez deux entrées nommées Script de pré-exécution et Script de post-exécution où les noms de fichiers des scripts à exécuter chaque cas peut être saisi.