42

I am writing a script which must work outside of QGIS GUI. I call some API functions from qgis.core but I would like to use the processing plugin.

I am able to import processing with sys.path.append() but I cannot run any process. Moreover, all "native" algs are missing in QgsApplication.processingRegistry().algorithms()

Is it possible to run processing that way?

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

I am using QGIS 3.0.1 on Debian 9.

3 Answers 3

64

You can run a QGIS Processing algorithm in standalone (no GUI) mode in this way:

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

# See https://gis.stackexchange.com/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()

# See https://gis.stackexchange.com/a/276979/4972 for a list of algorithms
res = processing.run('qgis:union', params, feedback=feedback)
res['OUTPUT'] # Access your output layer

Note for QGIS versions LESS THAN 3.16.5

If you want to use a native algorithm (i.e., an algorithm from the native provider, whose algorithms are written in C++), you need to add the provider after initializing Processing:

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

# See https://gis.stackexchange.com/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()

# See https://gis.stackexchange.com/a/276979/4972 for a list of algorithms
res = processing.run("native:extractvertices", params, feedback=feedback)
res['OUTPUT'] # Access your output layer

Note: If you actually wrote your own Processing algorithm and would like to run it in a standalone PyQGIS script, see: Using custom Processing algorithm from standalone PyQGIS scripts (outside of GUI)

6
  • @GermánCarrillo Somehow a very similar code dosen't work. See more: gis.stackexchange.com/questions/286281/… Commented Jun 14, 2018 at 5:35
  • I try running a QGIS algorithm in a QGIS Plugin, does this work the same way? Because I can't make it run
    – gHupf
    Commented Nov 12, 2018 at 19:03
  • yes the code work should work with gui but you need a lot of other things to make it run! you should take a look at the Plugin Builder extension
    – vidlb
    Commented Jan 18, 2019 at 19:36
  • 1
    I was able to just copy import processing then the processing.run(. . . ) snippet into my plugin's if result: clause and it ran great :) Thank you!
    – mr.adam
    Commented Apr 2, 2020 at 22:08
  • @GermánCarrillo Great stuff, still when I run the script I get na error qt.qpa.plugin: Could not find the Qt platform plugin "windows" in "C:\OSGEO4~1\apps\Qt5\plugins\platforms , I've read stackoverflow on this but no anwser seems to work, I'm using PyCharm 2020.1 / QGIS 3.12, appreciate help!
    – cincin21
    Commented May 22, 2020 at 14:41
3

I had an error:

NameError: name 'QgsNativeAlgorithms' is not defined

when I tried to use a native algorithm as above, in an OSGeo4W install that included QGIS 3.4.4.

The solution turned out to be a missing import:

from qgis.analysis import QgsNativeAlgorithms

(from QGIS 3.4/3.6 standalone script)

3

For standalone QGIS processing, you can now use qgis_process command line (available since QGIS 3.14, doc at https://docs.qgis.org/3.16/en/docs/user_manual/processing/standalone). Because of this, it's now possible to the following

qgis_process run native:union --INPUT=/path/to/geodata/lines_1.shp --OVERLAY=/path/to/geodata/lines_2.shp --OUTPUT="/tmp/output_layer.gpkg

You will suffer from one limitation at the moment compared to Python standalone approach: you can't specify the layer name output e.g https://github.com/qgis/QGIS/issues/38272

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.