Usando algoritmos de processamento QGIS3 a partir de scripts PyQGIS independentes (fora da GUI)

24

Estou escrevendo um script que deve funcionar fora da GUI do QGIS. Eu chamo algumas funções de API do qgis.core, mas gostaria de usar o plugin de processamento.

Consigo importar o processamento com sys.path.append (), mas não consigo executar nenhum processo. Além disso, todos os algs "nativos" estão ausentes nos algoritmos QgsApplication.processingRegistry ().

Então, é possível executar o processamento dessa maneira? O que estou perdendo ?

import os, sys
from qgis.core import *
QgsApplication.setPrefixPath('/usr', True)
qgs = QgsApplication([], False)
qgs.initQgis()

sys.path.append('/usr/share/qgis/python/plugins')
from processing.core.Processing import Processing
Processing.initialize()
import processing

layer1 = QgsVectorLayer('data/ROUTE_PRIMAIRE.SHP')
layer2 = QgsVectorLayer('data/ROUTE_SECONDAIRE.SHP')

processing.run('qgis:union', layer1, layer2, 'test.shp') # returns nothing

Estou no QGIS 3.0.1 - Debian 9

vidlb
fonte

Respostas:

29

Você pode executar um algoritmo de processamento QGIS no modo autônomo (sem GUI) desta maneira:

import sys

from qgis.core import (
     QgsApplication, 
     QgsProcessingFeedback, 
     QgsVectorLayer
)

# See /gis//a/155852/4972 for details about the prefix 
QgsApplication.setPrefixPath('/usr', True)
qgs = QgsApplication([], False)
qgs.initQgis()

# Append the path where processing plugin can be found
sys.path.append('/docs/dev/qgis/build/output/python/plugins')

import processing
from processing.core.Processing import Processing
Processing.initialize()

layer1 = QgsVectorLayer('/path/to/geodata/lines_1.shp', 'layer 1', 'ogr')
layer2 = QgsVectorLayer('/path/to/geodata/lines_2.shp', 'layer 2', 'ogr')

# You can see what parameters are needed by the algorithm  
# using: processing.algorithmHelp("qgis:union")
params = { 
    'INPUT' : layer1,
    'OVERLAY' : layer2, 
    'OUTPUT' : '/path/to/output_layer.gpkg|layername=output'
}
feedback = QgsProcessingFeedback()

res = processing.run('qgis:union', params, feedback=feedback)
res['OUTPUT'] # Access your output layer

Algoritmos Nativos

Agora, se você quiser usar um algoritmo nativo (ou seja, um algoritmo do provedor nativo, cujos algoritmos são escritos em C ++), será necessário adicionar o provedor após a inicialização do Processing:

import sys

from qgis.core import (
     QgsApplication, 
     QgsProcessingFeedback, 
     QgsVectorLayer
)
from qgis.analysis import QgsNativeAlgorithms

# See /gis//a/155852/4972 for details about the prefix 
QgsApplication.setPrefixPath('/usr', True)
qgs = QgsApplication([], False)
qgs.initQgis()

# Append the path where processing plugin can be found
sys.path.append('/docs/dev/qgis/build/output/python/plugins')

import processing
from processing.core.Processing import Processing
Processing.initialize()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())

layer = QgsVectorLayer('/path/to/geodata/lines.shp', 'my layer', 'ogr')

# You can see what parameters are needed by the algorithm  
# using: processing.algorithmHelp("native:extractvertices")
params = {
    'INPUT': layer,
    'OUTPUT': 'memory:'
}
feedback = QgsProcessingFeedback()

res = processing.run("native:extractvertices", params, feedback=feedback)
res['OUTPUT'] # Access your output layer
Germán Carrillo
fonte
Funciona bem, obrigado! Tudo bem gravar a saída no disco ao mesmo tempo, se um caminho for fornecido?
vidlb
Claro, essa é uma opção muito útil também.
Germán Carrillo
1
Isso é pura mágica - Obrigado por compartilhar suas soluções detalhadas!
root676
@ GermánCarrillo De alguma forma, um código muito semelhante não funciona. Veja mais: gis.stackexchange.com/questions/286281/…
Sr. Che
Eu tento executar um algoritmo QGIS em um plug-in QGIS, isso funciona da mesma maneira? Porque eu não posso fazê-lo funcionar
gHupf
1

Ocorreu um erro "NameError: name 'QgsNativeAlgorithms' não está definido" quando tentei usar um algoritmo nativo como acima, em uma instalação do OSGeo4W que incluía o QGIS 3.4.4. A solução acabou sendo uma importação ausente:

from qgis.analysis import QgsNativeAlgorithms

(do script independente do QGIS 3.4 / 3.6 )

Andrew_S
fonte