Does anybody know how to run SAGA Next Gen algorithms in a standalone script? It was possible in QGIS 3.28 when the SAGA provider was a core plugin.
I recently upgraded to 3.36.2 and installed the new SAGA Next Gen provider plugin(1.0) and binaries(9.3.1) and now I get the following error when running the script in PyCharm:
_core.QgsProcessingException: Error: Algorithm sagang:splitlineswithlines not found
Note, I can execute the algorithm by itself in the QGIS Python Console and it works fine like this:
processing.run("sagang:splitlineswithlines", {'LINES':'C:\\temp\\lines.shp','SPLIT':'C:\\temp\\split.shp','INTERSECT':'TEMPORARY_OUTPUT','OUTPUT':1})
Below is the standalone script that I am running (originally taken from this answer) in PyCharm. The interpreter is set to the supplied QGIS bin\python-qgis.bat
file.
# necessary imports
import os
import sys
import json
import pandas as pd
filesDir = 'c:\\temp'
lines = os.path.join(filesDir, 'lines.shp')
split = os.path.join(filesDir, 'split.shp')
# set up system paths
# dumped from within QGIS 3.36.2 python console
qspath = filesDir + '\\qgis_sys_paths.csv'
#provide the path where you saved this file.
paths = pd.read_csv(qspath).paths.tolist()
sys.path += paths
print(sys.path)
# set up environment variables
# dumped from within QGIS 3.36.2 python console
qepath = filesDir + '\\qgis_env.json'
js = json.loads(open(qepath, 'r').read())
for k, v in js.items():
os.environ[k] = v
print(os.environ)
# In special cases, we might also need to map the PROJ_LIB to handle the projections
# for mac OS
#os.environ['PROJ_LIB'] = '/Applications/Qgis.app/Contents/Resources/proj'
# qgis library imports
import PyQt5.QtCore
# import gdal # This import doesn't work for me but you don't need it for process saga tools
import qgis.PyQt.QtCore
from qgis.core import (QgsApplication,
QgsProcessingFeedback,
QgsProcessingRegistry)
from qgis.analysis import QgsNativeAlgorithms
feedback = QgsProcessingFeedback()
# initializing processing module
QgsApplication.setPrefixPath('C:\\OSGeo4W\\apps\\qgis', True)
qgs = QgsApplication([], False)
qgs.initQgis() # use qgs.exitQgis() to exit the processing module at the end of the script.
# initialize processing algorithms
from processing.core.Processing import Processing
Processing.initialize()
import processing
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
# Check QGIS algorithms you can use now
algs = dict()
for alg in QgsApplication.processingRegistry().algorithms():
algs[alg.displayName()] = alg.id()
print(algs)
processing.run("sagang:splitlineswithlines",
{'LINES':lines,
'SPLIT':split,
'INTERSECT':'TEMPORARY_OUTPUT',
'OUTPUT':1})
# Don't forget to exit the processing module at the end of the script
qgs.exitQgis()
Since executing the algorithm using processing.run()
in the QGIS console works and not outside, I think that it might have something to do with the environment setup, but I can't figure out what is missing.
1 Answer 1
As far as I understand, using "Processing Saga NextGen Provider" is the same as exploiting a QGIS plugin in a standalone QGIS application, see this topic for more details: Using Plugin in standalone PyQGIS script.
So, in the end, your code may look like this:
# imports
from sys import path
from qgis.core import QgsApplication, QgsProcessingException
# See https://gis.stackexchange.com/a/155852/4972 for details about the prefix
QgsApplication.setPrefixPath('C:\\OSGeo4W\\apps\\qgis-ltr\\plugins', True)
qgs = QgsApplication([], False)
qgs.initQgis()
# Append the path where processing plugin can be found
path.append('C:\\OSGeo4W\\apps\\qgis-ltr\\python\\plugins')
import processing
from processing.core.Processing import Processing
Processing.initialize()
# appending a path where the Saga NextGen Provider can be found
path.append('C:\\Users\\taras\\AppData\\Roaming\\QGIS\\QGIS3\\profiles\\default\\python\\plugins')
# importing the Saga NextGen Provider
from processing_saga_nextgen.saga_nextgen_plugin import SagaNextGenAlgorithmProvider
# creating the Saga NextGen Provider
provider = SagaNextGenAlgorithmProvider()
# loading all algorithms belonging to the Saga NextGen Provider
provider.loadAlgorithms()
# adding the Saga NextGen processing Provider to the registry.
QgsApplication.processingRegistry().addProvider(provider=provider)
try:
processing.algorithmHelp("sagang:splitlineswithlines")
except QgsProcessingException as e:
print(e)
qgs.exitQgis()
Also, I suggest to implement the Python Try Except blocks to handle errors and exceptions e.g. QgsProcessingException
:
try:
processing.algorithmHelp("sagang:splitlineswithlines")
except QgsProcessingException as e:
print(e)
P.S. I am using QGIS version 3.28.10-Firenze on Windows 11 Pro.
References:
Explore related questions
See similar questions with these tags.