Viktigt

Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.

23.7. Använda bearbetningsalgoritmer från konsolen

Konsolen gör det möjligt för avancerade användare att öka sin produktivitet och utföra komplexa operationer som inte kan utföras med hjälp av något av de andra GUI-elementen i bearbetningsramverket. Modeller som innehåller flera algoritmer kan definieras med hjälp av kommandoradsgränssnittet och ytterligare operationer som loopar och villkorliga meningar kan läggas till för att skapa mer flexibla och kraftfulla arbetsflöden.

Det finns ingen bearbetningskonsol i QGIS, men alla bearbetningskommandon är istället tillgängliga från QGIS inbyggda Python-konsol. Det innebär att du kan införliva dessa kommandon i ditt konsolarbete och ansluta bearbetningsalgoritmer till alla andra funktioner (inklusive metoder från QGIS API) som finns tillgängliga därifrån.

Den kod som du kan exekvera från Python-konsolen, även om den inte anropar någon specifik bearbetningsmetod, kan konverteras till en ny algoritm som du senare kan anropa från verktygslådan, den grafiska modelleraren eller någon annan komponent, precis som du gör med vilken annan algoritm som helst. Faktum är att vissa algoritmer som du kan hitta i verktygslådan är enkla skript.

I det här avsnittet ska vi se hur man använder bearbetningsalgoritmer från QGIS Python-konsolen, och även hur man skriver algoritmer med Python.

23.7.1. Anropa algoritmer från Python-konsolen

Det första du måste göra är att importera bearbetningsfunktionerna med följande rad:

>>> from qgis import processing

Nu finns det i princip bara en (intressant) sak du kan göra med det från konsolen: exekvera en algoritm. Det görs med metoden run(), som tar namnet på den algoritm som ska köras som sin första parameter och sedan ett varierande antal ytterligare parametrar beroende på algoritmens krav. Så det första du behöver veta är namnet på den algoritm som ska köras. Det är inte det namn som du ser i verktygslådan, utan snarare ett unikt kommandoradsnamn. För att hitta rätt namn för din algoritm kan du använda processingRegistry. Skriv följande rad i din konsol:

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

Du kommer att se något liknande detta (med några extra streck tillagda för att förbättra läsbarheten).

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

Det är en lista över alla tillgängliga algoritm-ID:n, sorterade efter leverantörsnamn och algoritmnamn, tillsammans med deras motsvarande namn.

När du vet kommandoradsnamnet på algoritmen är nästa sak att bestämma rätt syntax för att exekvera den. Det innebär att du måste veta vilka parametrar som behövs när du anropar metoden run().

Det finns en metod för att beskriva en algoritm i detalj, som kan användas för att få en lista över de parametrar som en algoritm kräver och de utdata som den kommer att generera. För att få den här informationen kan du använda metoden algorithmHelp(id_of_the_algorithm). Använd algoritmens ID, inte det fullständiga beskrivande namnet.

Om man anropar metoden med native:buffer som parameter (qgis:buffer är ett alias för native:buffer och fungerar också) får man följande beskrivning:

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

Nu har du allt du behöver för att köra en algoritm. Som vi redan har nämnt kan algoritmer köras med hjälp av: run(). Dess syntax är som följer:

>>> processing.run(name_of_the_algorithm, parameters)

Där parametrar är en ordlista med parametrar som beror på den algoritm du vill köra, och är exakt den lista som metoden algorithmHelp() ger dig.

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'})

Om en parameter är valfri och du inte vill använda den, ska du inte ta med den i ordlistan.

Om en parameter inte anges kommer standardvärdet att användas.

Beroende på typ av parameter introduceras värdena på olika sätt. Nästa lista ger en snabb genomgång av hur man introducerar värden för varje typ av inmatningsparameter:

  • Rasterlager, vektorlager eller tabell. Använd helt enkelt en sträng med namnet som identifierar dataobjektet som ska användas (namnet som det har i QGIS innehållsförteckning) eller ett filnamn (om motsvarande skikt inte är öppnat kommer det att öppnas men inte läggas till i kartbilden). Om du har en instans av ett QGIS-objekt som representerar skiktet kan du också skicka det som parameter.

  • Uppräkning. Om en algoritm har en uppräkningsparameter ska värdet för denna parameter anges med ett heltalsvärde. Om du vill veta vilka alternativ som finns kan du använda kommandot algorithmHelp(), enligt ovan. Till exempel har algoritmen native:buffer en uppräkning som heter 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
    

    I det här fallet har parametern tre alternativ. Observera att ordningen är nollbaserad.

  • Booleansk. Använd True eller False.

  • Flera inmatningar. Värdet är en sträng med indatabeskrivningar åtskilda med semikolon (;). Precis som för enskilda lager eller tabeller kan varje indatabeskrivare vara dataobjektets namn eller dess filsökväg.

  • Tabellfält från XXX. Använd en sträng med namnet på det fält som ska användas. Denna parameter är skiftlägeskänslig.

  • Fast tabell. Skriv in listan över alla tabellvärden separerade med kommatecken (,) och inneslutna mellan citattecken ("). Värdena börjar på den övre raden och går från vänster till höger. Du kan också använda en 2D-array med värden som representerar tabellen.

  • CRS. Ange EPSG-kodnumret för önskad CRS.

  • Utsträckning. Du måste använda en sträng med värdena xmin, xmax, ymin och ymax åtskilda med kommatecken (,).

Booleska, fil-, sträng- och numeriska parametrar behöver inga ytterligare förklaringar.

Inmatningsparametrar som strängar, booleaner eller numeriska värden har standardvärden. Standardvärdet används om motsvarande parameterinmatning saknas.

För objekt med utdatadata skriver du den filsökväg som ska användas för att spara dem, precis som i verktygslådan. Om utdataobjektet inte anges sparas resultatet i en tillfällig fil (eller hoppas över om det är en valfri utdata). Filtillägget avgör vilket filformat som används. Om du anger en filändelse som inte stöds av algoritmen används standardfilformatet för den utdatatypen och motsvarande filändelse läggs till i den angivna filsökvägen.

Till skillnad från när en algoritm exekveras från verktygslådan läggs inte utdata till i kartbilden om du exekverar samma algoritm från Python-konsolen med metoden run(). Den metoden returnerar en ordbok med ett eller flera utdatanamn (de som visas i algoritmbeskrivningen) som nycklar och filsökvägarna för dessa utdata som värden:

 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

Du kan sedan ladda utdata i projektet som vilket vanligt lager som helst:

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

För att omedelbart ladda bearbetningsresultaten i projektet kan du använda metoden runAndLoadResults() i stället för run().

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

Om du vill öppna en algoritmdialog från konsolen kan du använda metoden createAlgorithmDialog. Den enda obligatoriska parametern är algoritmens namn, men du kan också definiera en ordlista med parametrar så att dialogrutan fylls i automatiskt:

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

Metoden execAlgorithmDialog öppnar dialogrutan omedelbart:

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'})

23.7.2. Skapa skript och köra dem från verktygslådan

Du kan skapa dina egna algoritmer genom att skriva Python-kod. Bearbetningsskript utökar QgsProcessingAlgorithm, så du måste lägga till några extra rader kod för att implementera obligatoriska funktioner. Du hittar Create new script (rent skript) och Create New Script from Template (mall som innehåller kod för obligatoriska funktioner i QgsProcessingAlgorithm) under rullgardinsmenyn Scripts högst upp i verktygslådan Processing. Processing Script Editor öppnas och det är där du ska skriva din kod. Om du sparar skriptet därifrån i mappen scripts (standardmappen när du öppnar dialogrutan för att spara filer) med tillägget .py skapas motsvarande algoritm.

Namnet på algoritmen (den som du ser i verktygslådan) definieras i koden.

Låt oss ta en titt på följande kod, som definierar en Processing-algoritm som utför en buffertoperation med ett användardefinierat buffertavstånd på ett vektorlager som anges av användaren, efter att först ha utjämnat lagret.

 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}

Efter att ha gjort de nödvändiga importerna specificeras följande QgsProcessingAlgorithm funktioner:

  • name(): Algoritmens id (gemener).

  • displayName(): Ett mänskligt läsbart namn för algoritmen.

  • createInstance(): Skapa en ny instans av algoritmklassen.

  • initAlgorithm(): Konfigurera parameterDefinitioner och outputDefinitioner.

    Här beskriver du algoritmens parametrar och utdata. I det här fallet en funktionskälla för indata, en funktionssänka för resultatet och ett tal för buffertavståndet.

  • processAlgorithm(): Gör arbetet.

    Här kör vi först algoritmen smoothgeometry för att jämna ut geometrin, och sedan kör vi algoritmen buffer på det utjämnade resultatet. För att kunna köra algoritmer inifrån en annan algoritm måste vi sätta argumentet is_child_algorithm till True. Du kan se hur in- och utparametrar används som parametrar för algoritmerna smoothgeometry och buffer.

Det finns ett antal olika parametertyper tillgängliga för in- och utdata. Du kan hitta hela listan på Inmatnings- och utmatningstyper för bearbetningsalgoritmer.

Den första parametern till konstruktörerna är namnet på parametern och den andra är beskrivningen av parametern (för användargränssnittet). Resten av konstruktörsparametrarna är parametertypspecifika.

Indata kan omvandlas till QGIS-klasser med hjälp av funktionerna parameterAs i QgsProcessingAlgorithm. Till exempel för att få det nummer som anges för buffertavståndet som en dubbel:

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

Funktionen processAlgorithm bör returnera en ordbok som innehåller värden för varje utdata som definieras av algoritmen. Detta gör det möjligt att få tillgång till dessa utdata från andra algoritmer, inklusive andra algoritmer som ingår i samma modell.

Välskötta algoritmer bör definiera och returnera så många utdata som är rimligt. Utdata som inte är funktioner, t.ex. siffror och strängar, är mycket användbara när du kör din algoritm som en del av en större modell, eftersom dessa värden kan användas som inparametrar för efterföljande algoritmer inom modellen. Överväg att lägga till numeriska utdata för saker som antalet bearbetade funktioner, antalet ogiltiga funktioner som påträffats, antalet funktioner som matats ut osv. Ju fler utdata du returnerar, desto mer användbar blir din algoritm!

23.7.2.1. Feedback

Objektet feedback som skickas till processAlgorithm() bör användas för användarens återkoppling/interaktion. Du kan använda funktionen setProgress() i objektet feedback för att uppdatera förloppsindikatorn (0 till 100) för att informera användaren om algoritmens framsteg. Detta är mycket användbart om din algoritm tar lång tid att slutföra.

Objektet feedback tillhandahåller en metod isCanceled() som bör övervakas för att användaren ska kunna avbryta algoritmen. Metoden pushInfo() i feedback kan användas för att skicka information till användaren, och reportError() är praktisk för att skicka icke-fatala fel till användare.

Algoritmer bör undvika att använda andra former av återkoppling till användare, t.ex. utskriftssatser eller loggning till QgsMessageLog, och bör alltid använda feedback-objektet istället. Detta möjliggör utförlig loggning för algoritmen och är även trådsäkert (vilket är viktigt eftersom algoritmer vanligtvis körs i en bakgrundstråd).

23.7.2.2. Hantering av fel

Om din algoritm stöter på ett fel som hindrar den från att köras, t.ex. ogiltiga indatavärden eller något annat tillstånd som den inte kan eller bör återhämta sig från, bör du skapa en QgsProcessingException. T.ex.:

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

Försök att undvika QgsProcessingException för icke-fatala fel (t.ex. när en funktion har en null-geometri), och rapportera istället bara dessa fel via feedback.reportError() och hoppa över funktionen. Detta bidrar till att göra din algoritm ”modellvänlig”, eftersom den undviker att stoppa exekveringen av en hel algoritm när ett icke-fatalt fel påträffas.

23.7.2.3. Dokumentera dina skript

På samma sätt som för modeller kan du skapa ytterligare dokumentation för dina skript för att förklara vad de gör och hur de ska användas.

QgsProcessingAlgorithm tillhandahåller helpString(), shortHelpString() och helpUrl() funktioner för detta ändamål. Ange / åsidosätt dessa för att ge mer hjälp till användaren.

shortDescription() används i verktygstipset när du håller muspekaren över algoritmen i verktygslådan.

23.7.3. Skriptkrokar före och efter utförandet

Skript kan också användas som pre- och post-exekveringskrokar som körs före respektive efter att en algoritm körs. Detta kan användas för att automatisera uppgifter som ska utföras när en algoritm körs.

Syntaxen är identisk med den som förklaras ovan, men det finns ytterligare en global variabel med namnet alg som representerar den algoritm som just har körts (eller ska köras).

I gruppen General i dialogen processing options finns två poster med namnen Pre-execution script och Post-execution script där filnamnen på de skript som ska köras i varje enskilt fall kan anges.