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.
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:
>>> 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.
Calling the method with native:buffer
as parameter
(qgis:buffer
is an alias for native:buffer
and will also
work), you get the following description:
>>> 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
Now you have everything you need to run any algorithm. As we have
already mentioned, algorithms can be run using: run()
.
Its syntax is as follows:
>>> processing.run(name_of_the_algorithm, parameters)
Where parameters is a dictionary of parameters that depend on the
algorithm you want to run, and is exactly the list that the
algorithmHelp()
method gives you.
>>> 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. If an algorithm has an enumeration parameter, the value of that parameter should be entered using an integer value. To know the available options, you can use the
algorithmHelp()
command, as above. For instance, the « native.buffer » algorithm has an enumeration called 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
In this case, the parameter has three options. Notice that ordering is zero-based.
Boolean. Use
True
orFalse
.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.
Input parameters such as strings, booleans, or numerical values have default values. The default value is used if the corresponding parameter entry is missing.
For output data objects, type the file path to be used to save it, just as it is done from the toolbox. If the output object is not specified, the result is saved to a temporary file (or skipped if it is an optional output). The extension of the file determines the file format. If you enter a file extension not supported by the algorithm, the default file format for that output type will be used, and its corresponding extension appended to the given file path.
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 using run()
, but runAndLoadResults()
will do
that.
The run
method returns a dictionary with one or more output names (the
ones shown in the algorithm description) as keys and the file paths of
those outputs as values:
>>> 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
You can load feature output by passing the corresponding file paths to
the load()
method.
Or you could use runAndLoadResults()
instead of run()
to load
them immediately.
Créer des scripts et les exécuter depuis la boîte à outils¶
You can create your own algorithms by writing Python code.
Processing scripts extend
QgsProcessingAlgorithm
, so you
need to add some extra lines of code to implement mandatory functions.
You can find Create new script (clean sheet) and
Create New Script from Template (template that includes
code for mandatory functions of
QgsProcessingAlgorithm
) under
the Scripts dropdown menu on the top of the Processing toolbox.
The Processing Script Editor will open, and that’s where you should type
your code.
Saving the script from there in the scripts
folder (the default folder
when you open the save file dialog) with a .py
extension should
create the corresponding algorithm.
The name of the algorithm (the one you will see in the toolbox) is defined within the code.
Let’s have a look at the following code, which defines a Processing algorithm that performs a buffer operation with a user defined buffer distance on a vector layer that is specified by the user, after first smoothing the layer.
from qgis.core import (QgsProcessingAlgorithm,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink)
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}
After doing the necessary imports, the following
QgsProcessingAlgorithm
functions are specified:
name
: The id of the algorithm (lowercase).displayName
: A human readable name for the algorithm.createInstance
: Create a new instance of the algorithm class.initAlgorithm
: Configure the parameterDefinitions and outputDefinitions.Here you describe the parameters and output of the algorithm. In this case, a feature source for the input, a feature sink for the result and a number for the buffer distance.
processAlgorithm
: Do the work.Here we first run the
smoothgeometry
algorithm to smooth the geometry, and then we run thebuffer
algorithm on the smoothed output. To be able to run algorithms from within another algorithm we have to define a dummy function for theonFinish
parameter forrun
. This is theno_post_process
function. You can see how input and output parameters are used as parameters to thesmoothgeometry
andbuffer
algorithms.
There are a number of different parameter types available for input and output. Below is an alphabetically sorted list:
QgsProcessingParameterField
- A field in the attributes table of a vector layer. The name of the layer has to be specified.
The first parameter to the constructors is the name of the parameter, and the second is the description of the parameter (for the user interface). The rest of the constructor parameters are parameter type specific.
The input can be turned into QGIS classes using the parameterAs
functions
of QgsProcessingAlgorithm
.
For instance to get the number provided for the buffer distance as a double:
self.parameterAsDouble(parameters, self.INPUT_BUFFERDIST, context)).
The processAlgorithm
function should return a dictionary
containing values for every output defined by the algorithm. This
allows access to these outputs from other algorithms, including other
algorithms contained within the same model.
Well behaved algorithms should define and return as many outputs as makes sense. Non-feature outputs, such as numbers and strings, are very useful when running your algorithm as part of a larger model, as these values can be used as input parameters for subsequent algorithms within the model. Consider adding numeric outputs for things like the number of features processed, the number of invalid features encountered, the number of features output, etc. The more outputs you return, the more useful your algorithm becomes!
Feedback¶
The feedback
object passed to
processAlgorithm
should be used for user feedback / interaction.
You can use the setProgress
function of the feedback
object to update
the progress bar (0 to 100) to inform the user about the progress of the
algorithm. This is very useful if your algorithm takes a long time to complete.
The feedback
object provides an
isCanceled
method that
should be monitored to enable cancelation of the algorithm by the user.
The pushInfo
method of
feedback
can be used to send information
to the user, and reportError
is handy for pushing non-fatal errors to users.
Algorithms should avoid using other forms of providing feedback to
users, such as print statements or logging to
QgsMessageLog
, and
should always use the feedback object instead. This allows verbose
logging for the algorithm, and is also thread-safe (which is
important, given that algorithms are typically run in a background
thread).
Handling errors¶
If your algorithm encounters an error which prevents it from
executing, such as invalid input values or some other condition from
which it cannot or should not recover, then you should raise a
QgsProcessingException
.
E.g.:
if feature['value'] < 20:
raise QgsProcessingException('Invalid input value {}, must be >= 20'.format(feature['value']))
Try to avoid raising
QgsProcessingException
for
non-fatal errors
(e.g. when a feature has a null geometry), and instead just report
these errors via feedback.reportError()
and skip the feature. This
helps make your algorithm « model-friendly », as it avoids halting the
execution of an entire algorithm when a non-fatal error is
encountered.
Documenter ses scripts¶
As in the case of models, you can create additional documentation for your scripts, to explain what they do and how to use them.
QgsProcessingAlgorithm
provides the helpString
,
shortHelpString
and
helpUrl
functions for that purpose.
Specify / override these to provide more help to the user.
shortDescription
is used in the tooltip when hovering over the algorithm in the toolbox.
Scripts de pré et post-exécution¶
Scripts can also be used as pre- and post-execution hooks that are run before and after an algorithm is run, respectively. This can be used to automate tasks that should be performed whenever an algorithm is executed.
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é.
In the General group of the processing options dialog, you will find two entries named Pre-execution script and Post-execution script where the filenames of the scripts to be run in each case can be entered.