I am trying run an exported QGIS model as Python script from Anaconda.
I followed Executing a standalone QGIS python script on Windows 10, and I get no error of modules, when running this I get no error nor output but some warnings of deprecation
import os, sys
# Append QGIS Python library to python search path
sys.path.append(r'C:\Program Files\QGIS 3.6\apps\Python37')
# Append location of DLLs to current system PATH envrionment variable
os.environ['PATH'] += r";C:\Program Files\QGIS 3.6\apps\qgis\python;"
print (os.environ['PATH'])
from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterRasterLayer
from qgis.core import QgsProcessingParameterFeatureSink
sys.path.append(r'C:\Program Files\QGIS 3.6\apps\qgis\python\plugins')
import processing
class Trees(QgsProcessingAlgorithm):
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterRasterLayer('dsm', 'DSM', defaultValue="Path/dsm.tif"))
self.addParameter(QgsProcessingParameterRasterLayer('dtm', 'DTM', defaultValue="Path/dtm.tif"))
self.addParameter(QgsProcessingParameterRasterLayer('zone', 'Zone', defaultValue="Path/odm_orthophoto.tif"))
self.addParameter(QgsProcessingParameterFeatureSink('Finaltrees', 'FinalTrees', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue='Path/finaltrees.shp'))
def processAlgorithm(self, parameters, context, model_feedback):
# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
# overall progress through the model
feedback = QgsProcessingMultiStepFeedback(20, model_feedback)
results = {}
outputs = {}
# Heights calculator
alg_params = {
'CELLSIZE': None,
'CRS': None,
'EXPRESSION': '\"DSM@1\" - \"DTM@1\"',
'EXTENT': None,
'LAYERS': parameters['dtm'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['HeightsCalculator'] = processing.run('qgis:rastercalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(1)
if feedback.isCanceled():
return {}
# NDVI calculator
alg_params = {
'CELLSIZE': 0,
'CRS': None,
'EXPRESSION': 'sqrt(256* \"Zone@2\"- 256 * \"Zone@3\")',
'EXTENT': None,
'LAYERS': parameters['dtm'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['NdviCalculator'] = processing.run('qgis:rastercalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(2)
if feedback.isCanceled():
return {}
# NDVI Selector
alg_params = {
'CELLSIZE': 0,
'CRS': None,
'EXPRESSION': '\"\'Output\' from algorithm \'NDVI calculator\'@1\"> 100',
'EXTENT': None,
'LAYERS': outputs['NdviCalculator']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['NdviSelector'] = processing.run('qgis:rastercalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(3)
if feedback.isCanceled():
return {}
# Only NDVI
alg_params = {
'CELLSIZE': 0,
'CRS': None,
'EXPRESSION': '(\"\'Output\' from algorithm \'NDVI Selector\'@1\" =1)*\"\'Output\' from algorithm \'NDVI Selector\'@1\"',
'EXTENT': None,
'LAYERS': outputs['NdviSelector']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['OnlyNdvi'] = processing.run('qgis:rastercalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(4)
if feedback.isCanceled():
return {}
# Build virtual raster
alg_params = {
'ADD_ALPHA': False,
'ASSIGN_CRS': None,
'INPUT': outputs['OnlyNdvi']['OUTPUT'],
'PROJ_DIFFERENCE': False,
'RESAMPLING': 0,
'RESOLUTION': 1,
'SEPARATE': False,
'SRC_NODATA': '0',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['BuildVirtualRaster'] = processing.run('gdal:buildvirtualraster', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(5)
if feedback.isCanceled():
return {}
# True NDVI
alg_params = {
'CELLSIZE': 0,
'CRS': None,
'EXPRESSION': '(\"Zone@4\" -\"Zone@1\" ) /(\"Zone@4\" +\"Zone@1\" )',
'EXTENT': None,
'LAYERS': parameters['zone'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['TrueNdvi'] = processing.run('qgis:rastercalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(6)
if feedback.isCanceled():
return {}
# Polygonize (raster to vector)
alg_params = {
'BAND': 1,
'EIGHT_CONNECTEDNESS': False,
'FIELD': 'Value',
'INPUT': outputs['BuildVirtualRaster']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['PolygonizeRasterToVector'] = processing.run('gdal:polygonize', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(7)
if feedback.isCanceled():
return {}
# Extract by attribute
alg_params = {
'FIELD': 'Value',
'INPUT': outputs['PolygonizeRasterToVector']['OUTPUT'],
'OPERATOR': 0,
'VALUE': '1',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['ExtractByAttribute'] = processing.run('native:extractbyattribute', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(8)
if feedback.isCanceled():
return {}
# Fix geometries
alg_params = {
'INPUT': outputs['ExtractByAttribute']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['FixGeometries'] = processing.run('native:fixgeometries', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(9)
if feedback.isCanceled():
return {}
# JUSTNDVI
alg_params = {
'ALPHA_BAND': False,
'CROP_TO_CUTLINE': True,
'DATA_TYPE': 0,
'INPUT': outputs['TrueNdvi']['OUTPUT'],
'KEEP_RESOLUTION': False,
'MASK': outputs['FixGeometries']['OUTPUT'],
'MULTITHREADING': False,
'NODATA': None,
'OPTIONS': '',
'SET_RESOLUTION': False,
'SOURCE_CRS': None,
'TARGET_CRS': None,
'X_RESOLUTION': None,
'Y_RESOLUTION': None,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['Justndvi'] = processing.run('gdal:cliprasterbymasklayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(10)
if feedback.isCanceled():
return {}
# NDVIValues
alg_params = {
'FIELD_NAME': 'NDVI',
'INPUT_RASTER': outputs['Justndvi']['OUTPUT'],
'RASTER_BAND': 1,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['Ndvivalues'] = processing.run('native:pixelstopoints', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(11)
if feedback.isCanceled():
return {}
# Clip raster by mask layer
alg_params = {
'ALPHA_BAND': False,
'CROP_TO_CUTLINE': True,
'DATA_TYPE': 0,
'INPUT': outputs['HeightsCalculator']['OUTPUT'],
'KEEP_RESOLUTION': False,
'MASK': outputs['FixGeometries']['OUTPUT'],
'MULTITHREADING': False,
'NODATA': None,
'OPTIONS': '',
'SET_RESOLUTION': False,
'SOURCE_CRS': None,
'TARGET_CRS': None,
'X_RESOLUTION': None,
'Y_RESOLUTION': None,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['ClipRasterByMaskLayer'] = processing.run('gdal:cliprasterbymasklayer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(12)
if feedback.isCanceled():
return {}
# Mean NDVI
alg_params = {
'DISCARD_NONMATCHING': False,
'INPUT': outputs['FixGeometries']['OUTPUT'],
'JOIN': outputs['Ndvivalues']['OUTPUT'],
'JOIN_FIELDS': None,
'PREDICATE': 1,
'SUMMARIES': 6,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['MeanNdvi'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(13)
if feedback.isCanceled():
return {}
# Heights
alg_params = {
'FIELD_NAME': 'Height',
'INPUT_RASTER': outputs['ClipRasterByMaskLayer']['OUTPUT'],
'RASTER_BAND': 1,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['Heights'] = processing.run('native:pixelstopoints', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(14)
if feedback.isCanceled():
return {}
# Peaks
alg_params = {
'DISCARD_NONMATCHING': True,
'INPUT': outputs['FixGeometries']['OUTPUT'],
'JOIN': outputs['Heights']['OUTPUT'],
'JOIN_FIELDS': None,
'PREDICATE': 1,
'SUMMARIES': 3,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['Peaks'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(15)
if feedback.isCanceled():
return {}
# PeaksnNDVI
alg_params = {
'DISCARD_NONMATCHING': True,
'INPUT': outputs['Peaks']['OUTPUT'],
'JOIN': outputs['MeanNdvi']['OUTPUT'],
'JOIN_FIELDS': 'NDVI_mean',
'METHOD': 1,
'PREDICATE': 2,
'PREFIX': '',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['Peaksnndvi'] = processing.run('qgis:joinattributesbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(16)
if feedback.isCanceled():
return {}
# Add geometry attributes
alg_params = {
'CALC_METHOD': 0,
'INPUT': outputs['Peaksnndvi']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['AddGeometryAttributes'] = processing.run('qgis:exportaddgeometrycolumns', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(17)
if feedback.isCanceled():
return {}
# Extract by expression
alg_params = {
'EXPRESSION': 'NDVI_mean > 0.2 AND NDVI_mean IS NOT NULL AND Height_max > 1 AND Height_max IS NOT NULL AND area > 1',
'INPUT': outputs['AddGeometryAttributes']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['ExtractByExpression'] = processing.run('native:extractbyexpression', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(18)
if feedback.isCanceled():
return {}
# Join attributes by field value
alg_params = {
'DISCARD_NONMATCHING': True,
'FIELD': 'Height',
'FIELDS_TO_COPY': None,
'FIELD_2': 'Height_max',
'INPUT': outputs['Heights']['OUTPUT'],
'INPUT_2': outputs['ExtractByExpression']['OUTPUT'],
'METHOD': 1,
'PREFIX': '',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['JoinAttributesByFieldValue'] = processing.run('native:joinattributestable', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(19)
if feedback.isCanceled():
return {}
# Delete duplicates by attribute
alg_params = {
'FIELDS': 'NDVI_mean',
'INPUT': outputs['JoinAttributesByFieldValue']['OUTPUT'],
'OUTPUT': parameters['Finaltrees']
}
outputs['DeleteDuplicatesByAttribute'] = processing.run('native:removeduplicatesbyattribute', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
results['Finaltrees'] = outputs['DeleteDuplicatesByAttribute']['OUTPUT']
return results
def name(self):
return 'trees'
def displayName(self):
return 'trees'
def group(self):
return ''
def groupId(self):
return ''
def createInstance(self):
return Trees()
Is this possible?
2 Answers 2
With QGIS 3.4 and Windows 10 I have these deprecation warnings when running my standalone application :
C:\Program Files\QGIS 3.4\apps\qgis-ltr\python\qgis\utils.py:685: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
mod = _builtin_import(name, globals, locals, fromlist, level)
C:\Program Files\QGIS 3.4\apps\qgis-ltr\python\plugins\db_manager\db_plugins\postgis\plugin.py:350: DeprecationWarning: invalid escape sequence \:
uri = u"raster:gdal:%s:%s" % (self.name, re.sub(":", "\:", self.gdalUri()))
C:\PROGRA~1\QGIS3~1.4\apps\Python37\lib\site-packages\PyQt5\uic\objcreator.py:152: DeprecationWarning: 'U' mode is deprecated
plugin = open(filename, 'rU')
And everything works fine.
I guess we can rely on QGis and Pyqt teams to keep their libs up to date before the warnings become errors.
-
my script worked for u?Ayoub Beltarchi– Ayoub Beltarchi2019年09月03日 19:29:27 +00:00Commented Sep 3, 2019 at 19:29
-
@AN10 your script worked for me exactly like you: no error, just deprecation warnings (different warnings than the ones I have though). There is no output because the script does not have a
main
routine.Djedouas– Djedouas2019年09月04日 06:21:21 +00:00Commented Sep 4, 2019 at 6:21 -
so should i just add a
main
that returns the output ?Ayoub Beltarchi– Ayoub Beltarchi2019年09月04日 21:29:18 +00:00Commented Sep 4, 2019 at 21:29 -
Your script has the definition of the processing algorithm class but in order for it to do something you need to instantiate the Trees
class and use it.
Add this at the end of the file and then run it:
trees = Trees()
feedback = QgsProcessingFeedback()
context = QgsProcessingContext()
parameters = {} #add your parameters here
trees.initAlgorithm()
trees.processAlgorithm(parameters, context, feedback)