Geographic Information Systems Asked by alphabetasoup on May 7, 2021
Inspired by this question, but for QGIS 3 (and therefore Python 3), I would like to use the QGIS processing algorithms in a standalone Python script without a GUI, with a standard installation of Ubuntu Linux.
A simple import processing
is insufficient:
import processing
processing.run(
"qgis:rasterlayerstatistics",
{
'INPUT': .'/somefile.tif',
'BAND': 1,
'OUTPUT_HTML_FILE': './result.html'
}
)
Results in:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'processing'
How do you get access to the QGIS processing
module to use the QGIS processing algorithms in a standalone Python script (not the QGIS interpreter)?
This is an example of getting access to processing
to run the QGIS "raster statistics" process, which returns useful information about a raster layer. In particular, raster statistics is useful for obtaining the sum of all values in a raster, which (AFAIK) cannot be done in GDAL alone.
#!/usr/bin/env python3
import os
import sys
import warnings
from functools import wraps
def ignore_warnings(f):
@wraps(f)
def inner(*args, **kwargs):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("ignore")
response = f(*args, **kwargs)
return response
return inner
def import_qgis_processing():
sys.path.append('/usr/lib/qgis')
sys.path.append('/usr/share/qgis/python/plugins')
from qgis.core import QgsApplication, QgsProcessingFeedback, QgsRasterLayer
app = QgsApplication([], False)
feedback = QgsProcessingFeedback()
return (app, feedback, QgsRasterLayer)
app, feedback, QgsRasterLayer = import_qgis_processing()
app.initQgis()
@ignore_warnings # Ignored because we want the output of this script to be a single value, and "import processing" is noisy
def initialise_processing(app):
from qgis.analysis import QgsNativeAlgorithms
import processing
from processing.core.Processing import Processing
Processing.initialize()
app.processingRegistry().addProvider(QgsNativeAlgorithms())
return (app, processing,)
def check_input_validity(QgsRasterLayer):
raster = QgsRasterLayer(sys.argv[1], 'raster', 'gdal')
if not raster.isValid():
raise Exception('Invalid raster')
def raster_stats():
params = {
'INPUT': sys.argv[1],
'BAND': 1
}
return processing.run(
"qgis:rasterlayerstatistics",
params, feedback=feedback
)
def get_raster_stat(stat='SUM'):
return raster_stats().get(stat)
app, processing = initialise_processing(app)
check_input_validity(QgsRasterLayer)
print(get_raster_stat(stat=sys.argv[2]))
app.exitQgis()
The ignore_warnings
wrapper function is included because without it there are three deprecation warnings emitted when importing processing
, and I wanted the script to have a simple output to stdout. You can leave that out if desired.
Importing modules within functions is done to control the order of import, and to stop linters (e.g. autopep8
) from attempting to move all import statements to the top.
The key places to include in sys.path
are:
/usr/lib/qgis
/usr/share/qgis/python/plugins
These would be different on different operating systems, and probably in different Linux distributions.
This script can be run like: ./rasterstats.py ./somefile.tif SUM
, and it would output the sum of all values in the raster to stdout (ignoring no-data values if present). MAX
, MIN
, etc. work also.
The key functions are import_qgis_processing
and initialise_processing
.
Correct answer by alphabetasoup on May 7, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP