2

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?

0

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.

|improve this answer|||||
  • my script worked for u? – AN10 Sep 3 '19 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 Sep 4 '19 at 6:21
  • so should i just add a main that returns the output ? – AN10 Sep 4 '19 at 21:29
  • @AN10 yes I guess – Djedouas Sep 6 '19 at 6:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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