2

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
  • This is the Next Gen provider, so it requires sagang.
    – jger
    Commented May 6 at 18:55

1 Answer 1

2

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:

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.