Wichtig

Übersetzen ist eine Gemeinschaftsleistung Sie können mitmachen. Diese Seite ist aktuell zu 100.00% übersetzt.

27.7. Verarbeitungs-Algorithmen von der Konsole aus verwenden

Die Konsole ermöglicht es fortgeschrittenen Anwendern ihre Produktivität zu erhöhen und komplexe Operationen, die nicht anhand eines der GUI Elemente der Verarbeitungsumgebung ausgeführt werden können, durchzuführen. Modelle mit mehreren Algorithmen können anhand der Kommandozeilenssschnittstelle definiert werden und zusätzliche Operationen wie Schleifen und Bedingungssätze können hinzugefügt werden, um flexiblere und leistungsfähigere Workflows zu erstellen.

Es gibt keine Verarbeitungskonsole in QGIS, aber alle Verarbeitungsbefehle sind stattdessen über die in QGIS eingebaute Python-Konsole 1 verfügbar. Das bedeutet, dass Sie diese Befehle in Ihre Konsolenarbeit einbinden und Verarbeitungsalgorithmen mit allen anderen Elementen (einschließlich Methoden der QGIS-API) verbinden können, die von dort aus verfügbar sind.

Der Code, den Sie von der Python Konsole aus ausführen können, auch wenn er keine spezifische Verarbeitungs-Methode aufruft, kann in einen neuen Algorithmus überführt werden, den Sie später aus der Werkzeugkiste, der Grafischen Modellierung oder jeder anderen Komponente aufrufen können, so wie Sie es mit jedem anderen Algorithmus tun würden. In der Tat sind einige Algorithmen, die Sie in der Werkzeugkiste finden können, einfache Scripte.

In diesem Abschnitt werden wir uns angucken, wie man Verarbeitungsalgorithmen aus der QGIS Python Konsole heraus verwendet und auch wie man Algorithmen in Python schreibt.

27.7.1. Algorithmen von der Python-Konsole aus aufrufen

Das erste, was Sie tun müssen, ist die Verarbeitungs-Funktionen mit der folgenden Zeile importieren:

>>> from qgis import processing

Nun gibt es im Grunde nur eine (interessante) Sache, die Sie damit von der Konsole aus tun können: einen Algorithmus ausführen. Dazu wird die Methode run() verwendet, die den Namen des auszuführenden Algorithmus als ersten Parameter und dann eine variable Anzahl zusätzlicher Parameter je nach den Anforderungen des Algorithmus erhält. Das Erste, was Sie wissen müssen, ist der Name des auszuführenden Algorithmus. Dabei handelt es sich nicht um den Namen, den Sie in der Toolbox sehen, sondern um einen eindeutigen Befehlszeilennamen. Um den richtigen Namen für Ihren Algorithmus zu finden, können Sie die processingRegistry verwenden. Geben Sie die folgende Zeile in Ihre Konsole ein:

>>> for alg in QgsApplication.processingRegistry().algorithms():
        print(alg.id(), "->", alg.displayName())

Sie sehen dann ungefähr so aus (mit einigen zusätzlichen Bindestrichen, um die Lesbarkeit zu verbessern):

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
...

Das ist eine Liste aller verfügbaren Algorithmus-IDs, sortiert nach Anbietername und Algorithmusname, zusammen mit den entsprechenden Namen.

Wenn Sie den Kommandozeilennamen des Algorithmus kennen, müssen Sie als Nächstes die richtige Syntax für seine Ausführung festlegen. Dazu muss man wissen, welche Parameter beim Aufruf der Methode run() benötigt werden.

Es gibt eine Methode zur detaillierten Beschreibung eines Algorithmus, mit der man eine Liste der Parameter, die ein Algorithmus benötigt, und der Ausgaben, die er erzeugt, erhalten kann. Um diese Informationen zu erhalten, können Sie die Methode algorithmHelp(id_of_the_algorithm) verwenden. Verwenden Sie die ID des Algorithmus, nicht den vollständigen beschreibenden Namen.

Ruft man die Methode mit native:buffer als Parameter auf (qgis:buffer ist ein Alias für native:buffer und funktioniert ebenfalls), erhält man folgende Beschreibung:

>>> 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

Jetzt haben Sie alles, was Sie brauchen, um jeden Algorithmus auszuführen. Wie wir bereits erwähnt haben, können Algorithmen mit Hilfe von: run(). Die Syntax lautet wie folgt:

>>> processing.run(name_of_the_algorithm, parameters)

Dabei ist ‚parameters‘ ein Verzeichnis mit Parametern, die von dem Algorithmus abhängen, den Sie ausführen wollen, und ist genau die Liste, die Ihnen die Methode algorithmHelp() liefert.

1 >>> processing.run("native:buffer", {'INPUT': '/data/lines.shp',
2               'DISTANCE': 100.0,
3               'SEGMENTS': 10,
4               'DISSOLVE': True,
5               'END_CAP_STYLE': 0,
6               'JOIN_STYLE': 0,
7               'MITER_LIMIT': 10,
8               'OUTPUT': '/data/buffers.shp'})

Wenn ein Parameter optional ist und Sie ihn nicht verwenden wollen, dann nehmen Sie ihn nicht in das Verzeichnis auf.

Wird ein Parameter nicht angegeben, so wird der Standardwert verwendet.

Abhängig vom Parametertyp werden Werte verschieden eingeführt. Die nächste Liste gibt einen kurzen Überblick darüber, wie man Werte für jeden Typ von Eingabeparameter einführt:

  • Rasterlayer, Vektorlayer oder Tabelle. Verwenden Sie einfach eine Zeichenkette mit dem Namen, der das zu verwendende Datenobjekt identifiziert (der Name, den es im QGIS-Inhaltsverzeichnis hat) oder einen Dateinamen (wenn der entsprechende Layer nicht geöffnet ist, wird er geöffnet, aber nicht zur Kartenansicht hinzugefügt). Wenn Sie über eine Instanz eines QGIS-Objekts verfügen, das den Layer repräsentiert, können Sie auch dieses als Parameter übergeben

  • Aufzählung. Wenn ein Algorithmus einen Aufzählungsparameter hat, sollte der Wert dieses Parameters mit einem Integer-Wert eingegeben werden. Um die verfügbaren Optionen zu kennen, können Sie den Befehl algorithmHelp() verwenden, wie oben beschrieben. Zum Beispiel hat der native:buffer Algorithmus eine Aufzählung namens 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 diesem Fall hat der Parameter drei Optionen. Beachten Sie, dass die Reihenfolge nullbasiert ist.

  • Boolesch. Verwenden Sie True oder False.

  • Multiple input. Der Wert ist ein String mit Eingabebeschreibungen getrennt durch Semikolons (;). Wie im Fall von einfachen Layern oder Tabellen kann jede Eingabebeschreibung der Datenobjektname oder sein Dateipfad sein.

  • Tabellen Feld von XXX. Verwenden Sie einen String mit dem Namen des Feldes, das benutzt werden soll. Dieser Parameter unterscheidet zwischen Groß- und Kleinschreibung.

  • Fixed Table. Geben Sie die Liste aller Tabellenwerte, die durch Kommas (,) getrennt sind und zwischen Anführungsstrichen (") eingeschlossen sind. Die Werte beginnen in der oberen Zeile und gehen von links nach rechts. Sie können auch einen 2D-Array von Werten, die die Tabelle repräsentieren, verwenden.

  • CRS. Geben Sie den EPSG Code des gewünschten KBS ein.

  • Extent. Sie müssen einen String mit xmin, xmax, ymin und ymax Werten getrennt durch Kommas (,) eingeben.

Boolean, file, string und numerical parameters brauchen keien zusätzlichen Erläuterungen.

Eingabeparameter wie Strings, Boolesche oder numerische Werte haben Standardwerte. Der Standardwert wird verwendet, wenn der entsprechende Parametereintrag nicht vorhanden ist.

Bei Ausgabedatenobjekten geben Sie den Dateipfad ein, der zum Speichern verwendet werden soll, so wie es auch in der Toolbox geschieht. Wenn das Ausgabeobjekt nicht angegeben wird, wird das Ergebnis in einer temporären Datei gespeichert (oder übersprungen, wenn es sich um eine optionale Ausgabe handelt). Die Erweiterung der Datei bestimmt das Dateiformat. Wenn Sie eine Dateierweiterung eingeben, die vom Algorithmus nicht unterstützt wird, wird das Standarddateiformat für diesen Ausgabetyp verwendet und die entsprechende Erweiterung an den angegebenen Dateipfad angehängt.

Anders als bei der Ausführung eines Algorithmus über die Toolbox werden die Ausgaben nicht zur Kartenansicht hinzugefügt, wenn Sie denselben Algorithmus über die Python-Konsole mit der Methode run() ausführen. Diese Methode gibt ein Verzeichnis mit einem oder mehreren Ausgabennamen (die in der Algorithmusbeschreibung angegeben sind) als Schlüssel und den Dateipfaden dieser Ausgaben als Werte zurück:

 1 >>> myresult = processing.run("native:buffer", {'INPUT': '/data/lines.shp',
 2               'DISTANCE': 100.0,
 3               'SEGMENTS': 10,
 4               'DISSOLVE': True,
 5               'END_CAP_STYLE': 0,
 6               'JOIN_STYLE': 0,
 7               'MITER_LIMIT': 10,
 8               'OUTPUT': '/data/buffers.shp'})
 9 >>> myresult['OUTPUT']
10 /data/buffers.shp

Sie können die Ausgabe dann als einen beliebigen allgemeinen Layer in das Projekt laden:

1 >>> buffered_layer = myresult['OUTPUT']
2 >>> QgsProject.instance().addMapLayer(buffered_layer)

Um die Verarbeitungsergebnisse sofort in das Projekt zu laden, können Sie die Methode runAndLoadResults() anstelle von run() verwenden.

1 >>> processing.runAndLoadResults("native:buffer", {parameters:values})

Wenn Sie einen Algorithmus-Dialog von der Konsole aus öffnen wollen, können Sie die Methode createAlgorithmDialog verwenden. Der einzige obligatorische Parameter ist der Name des Algorithmus, aber Sie können auch ein Verzeichnis von Parametern definieren, sodass der Dialog automatisch ausgefüllt wird:

 1 >>> my_dialog = processing.createAlgorithmDialog("native:buffer", {
 2               'INPUT': '/data/lines.shp',
 3               'DISTANCE': 100.0,
 4               'SEGMENTS': 10,
 5               'DISSOLVE': True,
 6               'END_CAP_STYLE': 0,
 7               'JOIN_STYLE': 0,
 8               'MITER_LIMIT': 10,
 9               'OUTPUT': '/data/buffers.shp'})
10 >>> my_dialog.show()

Die Methode execAlgorithmDialog öffnet den Dialog sofort:

1 >>> processing.execAlgorithmDialog("native:buffer", {
2               'INPUT': '/data/lines.shp',
3               'DISTANCE': 100.0,
4               'SEGMENTS': 10,
5               'DISSOLVE': True,
6               'END_CAP_STYLE': 0,
7               'JOIN_STYLE': 0,
8               'MITER_LIMIT': 10,
9               'OUTPUT': '/data/buffers.shp'})

27.7.2. Scripte erstellen und diese aus der Werkzeugkiste starten.

Sie können Ihre eigenen Algorithmen erstellen, indem Sie Python-Code schreiben. Verarbeitungsskripte erweitern QgsProcessingAlgorithm, so dass Sie einige zusätzliche Codezeilen hinzufügen müssen, um obligatorische Funktionen zu implementieren. Sie finden Neues Skript erstellen (leeres Blatt) und Neues Skript aus Vorlage erstellen (Vorlage, die Code für die obligatorischen Funktionen von QgsProcessingAlgorithm enthält) unter dem Dropdown-Menü Skripte oben in der Verarbeitungs- Werkzeugkiste. Es öffnet sich der Verarbeitungsskript-Editor, in den Sie Ihren Code eingeben können. Wenn Sie das Skript von dort aus im Ordner scripts (dem Standardordner, wenn Sie den Dialog zum Speichern von Dateien öffnen) mit der Erweiterung .py speichern, wird der entsprechende Algorithmus erstellt.

Der Name des Algorithmus (derjenige, den Sie in der Toolbox sehen) wird im Code definiert.

Schauen wir uns den folgenden Code an, der einen Verarbeitungsalgorithmus definiert, der eine Pufferoperation mit einem benutzerdefinierten Pufferabstand auf einem vom Benutzer angegebenen Vektor-Layer durchführt, nachdem er den Layer zunächst geglättet hat.

 1from qgis.core import (QgsProcessingAlgorithm,
 2       QgsProcessingParameterNumber,
 3       QgsProcessingParameterFeatureSource,
 4       QgsProcessingParameterFeatureSink)
 5
 6from qgis import processing
 7
 8class algTest(QgsProcessingAlgorithm):
 9    INPUT_BUFFERDIST = 'BUFFERDIST'
10    OUTPUT_BUFFER = 'OUTPUT_BUFFER'
11    INPUT_VECTOR = 'INPUT_VECTOR'
12
13    def __init__(self):
14        super().__init__()
15
16    def name(self):
17        return "algTest"
18
19    def displayName(self):
20        return "algTest script"
21
22    def createInstance(self):
23        return type(self)()
24
25    def initAlgorithm(self, config=None):
26        self.addParameter(QgsProcessingParameterFeatureSource(
27            self.INPUT_VECTOR, "Input vector"))
28        self.addParameter(QgsProcessingParameterNumber(
29            self.INPUT_BUFFERDIST, "Buffer distance",
30            QgsProcessingParameterNumber.Double,
31            100.0))
32        self.addParameter(QgsProcessingParameterFeatureSink(
33            self.OUTPUT_BUFFER, "Output buffer"))
34
35    def processAlgorithm(self, parameters, context, feedback):
36        #DO SOMETHING
37        algresult = processing.run("native:smoothgeometry",
38            {'INPUT': parameters[self.INPUT_VECTOR],
39             'ITERATIONS':2,
40             'OFFSET':0.25,
41             'MAX_ANGLE':180,
42             'OUTPUT': 'memory:'},
43            context=context, feedback=feedback, is_child_algorithm=True)
44        smoothed = algresult['OUTPUT']
45        algresult = processing.run('native:buffer',
46            {'INPUT': smoothed,
47            'DISTANCE': parameters[self.INPUT_BUFFERDIST],
48            'SEGMENTS': 5,
49            'END_CAP_STYLE': 0,
50            'JOIN_STYLE': 0,
51            'MITER_LIMIT': 10,
52            'DISSOLVE': True,
53            'OUTPUT': parameters[self.OUTPUT_BUFFER]},
54            context=context, feedback=feedback, is_child_algorithm=True)
55        buffered = algresult['OUTPUT']
56        return {self.OUTPUT_BUFFER: buffered}

Nach der Durchführung der erforderlichen Importe werden die folgenden QgsProcessingAlgorithm-Funktionen angegeben:

  • name(): Die ID des Algorithmus (Kleinbuchstaben).

  • DisplayName(): Ein von Menschen lesbarer Name für den Algorithmus.

  • createInstance(): Erzeugt eine neue Instanz der Algorithmusklasse.

  • initAlgorithmus(): Konfigurieren Sie die parameterDefinitionen und outputDefinitionen.

    Hier beschreiben Sie die Parameter und die Ausgabe des Algorithmus. In diesem Fall eine Objektquelle für die Eingabe, eine Objektsenke für das Ergebnis und eine Zahl für den Pufferabstand.

  • processAlgorithm(): Erledigt die Arbeit.

    Hier führen wir zuerst den smoothgeometry-Algorithmus aus, um die Geometrie zu glätten, und dann lassen wir den buffer-Algorithmus auf die geglättete Ausgabe laufen. Um Algorithmen innerhalb eines anderen Algorithmus ausführen zu können, müssen wir das Argument is_child_algorithm auf True setzen. Sie können sehen, wie Eingabe- und Ausgabeparameter als Parameter für die Algorithmen smoothgeometry und buffer verwendet werden.

Es gibt eine Reihe von verschiedenen Parametertypen für die Ein- und Ausgabe. Die vollständige Liste finden Sie unter Eingabe- und Ausgabetypen für Verarbeitungsalgorithmen.

Der erste Parameter der Konstruktoren ist der Name des Parameters, der zweite ist die Beschreibung des Parameters (für die Benutzeroberfläche). Der Rest der Konstruktorparameter ist parameterartspezifisch.

Die Eingabe kann in QGIS-Klassen umgewandelt werden, indem man die parameterAs-Funktionen von QgsProcessingAlgorithm benutzt. Zum Beispiel um die Zahl für den Pufferabstand als Double zu erhalten:

self.parameterAsDouble(parameters, self.INPUT_BUFFERDIST, context)).

Die Funktion processAlgorithm sollte ein Wörterbuch zurückgeben, das Werte für jede durch den Algorithmus definierte Ausgabe enthält. Dies ermöglicht den Zugriff auf diese Ausgaben von anderen Algorithmen aus, einschließlich anderer Algorithmen innerhalb desselben Modells.

Gut funktionierende Algorithmen sollten so viele Ausgaben definieren und zurückgeben, wie es sinnvoll ist. Nicht-Feature-Ausgaben wie Zahlen und Strings sind sehr nützlich, wenn Ihr Algorithmus als Teil eines größeren Modells ausgeführt wird, da diese Werte als Eingabeparameter für nachfolgende Algorithmen innerhalb des Modells verwendet werden können. Ziehen Sie in Erwägung, numerische Ausgaben für Dinge wie die Anzahl der verarbeiteten Objekte, die Anzahl der gefundenen ungültigen Objekte, die Anzahl der ausgegebenen Objekte usw. hinzuzufügen. Je mehr Ausgaben Sie zurückgeben, desto nützlicher wird Ihr Algorithmus!

27.7.2.1. Rückmeldungen

Das feedback-Objekt, das an processAlgorithm() übergeben wird, sollte für Benutzer-Feedback / Interaktion verwendet werden. Sie können die Funktion setProgress() des Objekts feedback verwenden, um den Fortschrittsbalken (0 bis 100) zu aktualisieren und den Benutzer über den Fortschritt des Algorithmus zu informieren. Dies ist sehr nützlich, wenn Ihr Algorithmus sehr lange braucht, um abgeschlossen zu werden.

Das Objekt feedback stellt eine Methode isCanceled() zur Verfügung, die überwacht werden sollte, um den Abbruch des Algorithmus durch den Benutzer zu ermöglichen. Die Methode pushInfo() von feedback kann verwendet werden, um Informationen an den Benutzer zu senden, und reportError() ist praktisch, um nicht schwerwiegende Fehler an Benutzer zu senden.

Algorithmen sollten andere Formen der Rückmeldung an den Benutzer, wie z. B. Druckanweisungen oder die Protokollierung in QgsMessageLog, vermeiden und stattdessen immer das Feedback-Objekt verwenden. Dies ermöglicht eine ausführliche Protokollierung für den Algorithmus und ist außerdem thread-sicher (was wichtig ist, da Algorithmen normalerweise in einem Hintergrund-Thread ausgeführt werden).

27.7.2.2. Umgang mit Fehlern

Wenn Ihr Algorithmus auf einen Fehler stößt, der ihn an der Ausführung hindert, z. B. ungültige Eingabewerte oder eine andere Bedingung, von der er sich nicht erholen kann oder soll, dann sollten Sie eine QgsProcessingException auslösen. Z.B.:

if feature['value'] < 20:
  raise QgsProcessingException('Invalid input value {}, must be >= 20'.format(feature['value']))

Versuchen Sie zu vermeiden, QgsProcessingException für nicht-fatale Fehler auszulösen (z.B. wenn ein Objekt eine Null-Geometrie hat), und melden Sie diese Fehler stattdessen einfach über feedback.reportError() und überspringen Sie das Objekt. Dies trägt dazu bei, Ihren Algorithmus „modellfreundlich“ zu machen, da es vermeidet, die Ausführung eines gesamten Algorithmus anzuhalten, wenn ein nicht-fataler Fehler auftritt.

27.7.2.3. Ihre Scripte dokumentieren

Wie bei den Modellen können Sie auch für Ihre Skripte eine zusätzliche Dokumentation erstellen, um zu erklären, was sie tun und wie sie zu verwenden sind.

QgsProcessingAlgorithm bietet die helpString(), shortHelpString() und helpUrl() Funktionen für diesen Zweck. Geben Sie diese Funktionen an oder überschreiben Sie sie, um dem Benutzer mehr Hilfe zu bieten.

shortDescription() wird im Tooltip verwendet, wenn der Mauszeiger über den Algorithmus in der Toolbox bewegt wird.

27.7.3. Skript-Hooks vor und nach der Ausführung

Skripte können auch als Pre- und Post-Execution Hooks verwendet werden, die vor bzw. nach der Ausführung eines Algorithmus ausgeführt werden. Auf diese Weise können Aufgaben automatisiert werden, die bei der Ausführung eines Algorithmus ausgeführt werden sollen.

Die Syntax ist identisch zu der oben erklärten Syntax, es steht aber eine zusätzliche Globalvariable genannt alg zur Verfügung, die den Algorithmus, der gerade ausgeführt wurde (oder ausgeführt wird), repräsentiert.

In der Gruppe Allgemein des Dialogs Verarbeitungsoptionen finden Sie zwei Einträge namens Pre-execution script und Post-execution script, in die Sie die Dateinamen der jeweils auszuführenden Skripte eintragen können.