2012-10-05 23:28:47 +02:00
# -*- coding: utf-8 -*-
"""
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2013-08-12 20:44:27 +02:00
Processing . py
2012-10-05 23:28:47 +02:00
- - - - - - - - - - - - - - - - - - - - -
Date : August 2012
Copyright : ( C ) 2012 by Victor Olaya
Email : volayaf at gmail dot com
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
"""
2016-08-04 09:10:08 +02:00
from __future__ import print_function
2016-09-21 18:24:26 +02:00
from builtins import str
from builtins import object
2014-08-22 11:27:57 +02:00
2016-05-23 16:57:59 +02:00
2012-10-05 23:28:47 +02:00
__author__ = ' Victor Olaya '
__date__ = ' August 2012 '
__copyright__ = ' (C) 2012, Victor Olaya '
2013-10-01 20:52:22 +03:00
2012-10-05 23:28:47 +02:00
# This will get replaced with a git SHA1 when you do a git archive
2013-10-01 20:52:22 +03:00
2012-10-05 23:28:47 +02:00
__revision__ = ' $Format: % H$ '
2016-05-23 16:57:59 +02:00
import os
2016-04-26 08:29:15 +02:00
import traceback
2014-10-03 14:44:01 +03:00
2017-03-04 19:41:23 +01:00
from qgis . PyQt . QtCore import Qt , QCoreApplication
2016-04-22 10:38:48 +02:00
from qgis . PyQt . QtWidgets import QApplication
from qgis . PyQt . QtGui import QCursor
2014-10-03 14:44:01 +03:00
2014-05-20 16:30:59 +02:00
from qgis . utils import iface
2017-01-09 09:59:35 +10:00
from qgis . core import ( QgsMessageLog ,
QgsApplication )
2014-10-03 14:44:01 +03:00
import processing
2016-04-28 18:27:45 +02:00
from processing . core . AlgorithmProvider import AlgorithmProvider
2016-05-23 16:57:59 +02:00
from processing . script . ScriptUtils import ScriptUtils
2013-08-12 20:44:27 +02:00
from processing . core . ProcessingConfig import ProcessingConfig
from processing . core . GeoAlgorithm import GeoAlgorithm
from processing . core . ProcessingLog import ProcessingLog
2013-10-01 20:52:22 +03:00
from processing . gui . MessageBarProgress import MessageBarProgress
2013-08-12 20:44:27 +02:00
from processing . gui . RenderingStyles import RenderingStyles
2014-06-08 23:15:33 +02:00
from processing . gui . Postprocessing import handleAlgorithmResults
2017-03-22 17:17:14 +02:00
from processing . gui . AlgorithmExecutor import execute
2013-10-01 20:52:22 +03:00
from processing . tools import dataobjects
2016-05-19 12:25:04 +02:00
2017-03-04 19:41:23 +01:00
from processing . modeler . ModelerAlgorithmProvider import ModelerAlgorithmProvider # NOQA
from processing . algs . qgis . QGISAlgorithmProvider import QGISAlgorithmProvider # NOQA
from processing . algs . grass7 . Grass7AlgorithmProvider import Grass7AlgorithmProvider # NOQA
from processing . algs . gdal . GdalAlgorithmProvider import GdalAlgorithmProvider # NOQA
from processing . algs . r . RAlgorithmProvider import RAlgorithmProvider # NOQA
from processing . algs . saga . SagaAlgorithmProvider import SagaAlgorithmProvider # NOQA
from processing . script . ScriptAlgorithmProvider import ScriptAlgorithmProvider # NOQA
from processing . preconfigured . PreconfiguredAlgorithmProvider import PreconfiguredAlgorithmProvider # NOQA
2016-04-27 15:40:56 +03:00
2017-04-04 11:04:36 +10:00
# workaround SIP bindings losing subclasses during transfer to QgsProcessingRegistry
PROVIDERS = [ ]
2016-05-27 19:04:25 +03:00
2016-09-21 18:24:26 +02:00
class Processing ( object ) :
2012-09-15 18:25:25 +03:00
actions = { }
2013-10-01 20:52:22 +03:00
# All the registered context menu actions for the toolbox
2012-09-15 18:25:25 +03:00
contextMenuActions = [ ]
2016-05-28 12:40:32 +02:00
@staticmethod
2017-04-04 11:04:36 +10:00
def addProvider ( provider ) :
2013-10-01 20:52:22 +03:00
""" Use this method to add algorithms from external providers.
"""
2017-04-04 11:04:36 +10:00
if QgsApplication . processingRegistry ( ) . providerById ( provider . id ( ) ) :
2016-04-28 18:27:45 +02:00
return
2013-09-23 13:31:47 +02:00
try :
2017-04-04 09:46:46 +10:00
if provider . load ( ) :
ProcessingConfig . readSettings ( )
provider . refreshAlgorithms ( )
Processing . actions [ provider . id ( ) ] = provider . actions
Processing . contextMenuActions . extend ( provider . contextMenuActions )
2017-04-04 11:04:36 +10:00
QgsApplication . processingRegistry ( ) . addProvider ( provider )
PROVIDERS . append ( provider )
2013-09-23 13:31:47 +02:00
except :
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
ProcessingLog . addToLog (
ProcessingLog . LOG_ERROR ,
2017-03-04 16:23:36 +01:00
Processing . tr ( ' Could not load provider: {0} \n {0} ' ) . format (
provider . name ( ) , traceback . format_exc ( )
)
)
2013-09-23 13:31:47 +02:00
Processing . removeProvider ( provider )
2012-09-15 18:25:25 +03:00
@staticmethod
def removeProvider ( provider ) :
2013-10-01 20:52:22 +03:00
""" Use this method to remove a provider.
This method should be called when unloading a plugin that
contributes a provider .
"""
2017-04-04 11:04:36 +10:00
provider . unload ( )
if provider . id ( ) in Processing . actions :
del Processing . actions [ provider . id ( ) ]
for act in provider . contextMenuActions :
Processing . contextMenuActions . remove ( act )
QgsApplication . processingRegistry ( ) . removeProvider ( provider . id ( ) )
2012-09-15 18:25:25 +03:00
2016-06-02 09:45:20 +02:00
@staticmethod
def activateProvider ( providerOrName , activate = True ) :
2017-01-09 09:18:25 +10:00
provider_id = providerOrName . id ( ) if isinstance ( providerOrName , AlgorithmProvider ) else providerOrName
name = ' ACTIVATE_ ' + provider_id . upper ( ) . replace ( ' ' , ' _ ' )
2016-06-02 09:45:20 +02:00
ProcessingConfig . setSettingValue ( name , activate )
2017-04-04 11:28:28 +10:00
provider = QgsApplication . processingRegistry ( ) . providerById ( provider_id )
if provider :
provider . refreshAlgorithms ( )
2016-06-02 09:45:20 +02:00
2012-09-15 18:25:25 +03:00
@staticmethod
def initialize ( ) :
2017-04-04 11:04:36 +10:00
if " model " in [ p . id ( ) for p in QgsApplication . processingRegistry ( ) . providers ( ) ] :
2016-05-23 16:57:59 +02:00
return
2013-10-01 20:52:22 +03:00
# Add the basic providers
2016-04-28 18:27:45 +02:00
for c in AlgorithmProvider . __subclasses__ ( ) :
Processing . addProvider ( c ( ) )
2013-10-01 20:52:22 +03:00
# And initialize
2013-08-12 20:44:27 +02:00
ProcessingConfig . initialize ( )
2014-04-23 18:24:23 +02:00
ProcessingConfig . readSettings ( )
2013-02-28 22:08:32 +01:00
RenderingStyles . loadStyles ( )
2016-05-27 19:04:25 +03:00
@staticmethod
2016-05-23 16:57:59 +02:00
def addScripts ( folder ) :
Processing . initialize ( )
2017-01-09 09:59:35 +10:00
provider = QgsApplication . processingRegistry ( ) . providerById ( " qgis " )
2016-05-23 16:57:59 +02:00
scripts = ScriptUtils . loadFromFolder ( folder )
2016-08-04 09:10:08 +02:00
# fix_print_with_import
print ( scripts )
2016-05-23 16:57:59 +02:00
for script in scripts :
script . allowEdit = False
script . _icon = provider . _icon
2016-05-27 19:04:25 +03:00
provider . externalAlgs . extend ( scripts )
2017-04-04 11:28:28 +10:00
provider . refreshAlgorithms ( )
2016-05-27 19:04:25 +03:00
2016-05-24 10:27:38 +02:00
@staticmethod
2016-05-23 16:57:59 +02:00
def removeScripts ( folder ) :
2017-01-09 09:59:35 +10:00
provider = QgsApplication . processingRegistry ( ) . providerById ( " qgis " )
2016-05-24 10:27:38 +02:00
for alg in provider . externalAlgs [ : : - 1 ] :
path = os . path . dirname ( alg . descriptionFile )
if path == folder :
2016-05-27 19:04:25 +03:00
provider . externalAlgs . remove ( alg )
2017-04-04 11:28:28 +10:00
provider . refreshAlgorithms ( )
2012-09-15 18:25:25 +03:00
2013-05-01 23:45:20 +02:00
2012-09-15 18:25:25 +03:00
@staticmethod
2015-08-14 14:12:01 +02:00
def runAlgorithm ( algOrName , onFinish , * args , * * kwargs ) :
2012-09-15 18:25:25 +03:00
if isinstance ( algOrName , GeoAlgorithm ) :
alg = algOrName
else :
2017-04-04 11:04:36 +10:00
alg = QgsApplication . processingRegistry ( ) . algorithmById ( algOrName )
2013-10-01 20:52:22 +03:00
if alg is None :
2016-08-04 09:10:08 +02:00
# fix_print_with_import
print ( ' Error: Algorithm not found \n ' )
2015-08-22 14:29:41 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Algorithm {0} not found \n ' ) . format ( algOrName ) , Processing . tr ( " Processing " ) )
2012-09-15 18:25:25 +03:00
return
2013-01-21 23:05:17 +01:00
alg = alg . getCopy ( )
2014-07-02 07:46:03 +02:00
2014-06-26 16:09:00 +02:00
if len ( args ) == 1 and isinstance ( args [ 0 ] , dict ) :
2014-07-02 07:46:03 +02:00
# Set params by name and try to run the alg even if not all parameter values are provided,
2014-06-26 16:09:00 +02:00
# by using the default values instead.
setParams = [ ]
2016-09-21 18:24:26 +02:00
for ( name , value ) in list ( args [ 0 ] . items ( ) ) :
2014-06-26 16:09:00 +02:00
param = alg . getParameterFromName ( name )
if param and param . setValue ( value ) :
setParams . append ( name )
2013-10-01 20:52:22 +03:00
continue
2014-06-26 16:09:00 +02:00
output = alg . getOutputFromName ( name )
if output and output . setValue ( value ) :
2013-10-01 20:52:22 +03:00
continue
2016-08-04 09:10:08 +02:00
# fix_print_with_import
print ( ' Error: Wrong parameter value %s for parameter %s . ' % ( value , name ) )
2015-08-22 14:29:41 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Wrong parameter value {0} for parameter {1} . ' ) . format ( value , name ) , Processing . tr ( " Processing " ) )
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
ProcessingLog . addToLog (
ProcessingLog . LOG_ERROR ,
2017-03-04 16:23:36 +01:00
Processing . tr ( ' Error in {0} . Wrong parameter value {1} for parameter {2} . ' ) . format (
2017-03-29 12:51:59 +10:00
alg . name ( ) , value , name
2017-03-04 16:23:36 +01:00
)
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
)
2012-09-15 18:25:25 +03:00
return
2014-06-26 16:09:00 +02:00
# fill any missing parameters with default values if allowed
for param in alg . parameters :
if param . name not in setParams :
2015-12-16 17:33:43 +01:00
if not param . setDefaultValue ( ) :
2016-08-04 09:10:08 +02:00
# fix_print_with_import
print ( ' Error: Missing parameter value for parameter %s . ' % param . name )
2015-08-22 14:29:41 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Missing parameter value for parameter {0} . ' ) . format ( param . name ) , Processing . tr ( " Processing " ) )
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
ProcessingLog . addToLog (
ProcessingLog . LOG_ERROR ,
2017-03-04 16:23:36 +01:00
Processing . tr ( ' Error in {0} . Missing parameter value for parameter {1} . ' ) . format (
2017-03-29 12:51:59 +10:00
alg . name ( ) , param . name )
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
)
2014-06-26 16:09:00 +02:00
return
2012-09-15 18:25:25 +03:00
else :
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
if len ( args ) != alg . getVisibleParametersCount ( ) + alg . getVisibleOutputsCount ( ) :
2016-08-04 09:10:08 +02:00
# fix_print_with_import
print ( ' Error: Wrong number of parameters ' )
2015-08-22 14:29:41 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Wrong number of parameters ' ) , Processing . tr ( " Processing " ) )
2017-03-22 15:25:12 +02:00
processing . algorithmHelp ( algOrName )
2014-06-26 16:09:00 +02:00
return
2012-09-15 18:25:25 +03:00
i = 0
for param in alg . parameters :
if not param . hidden :
if not param . setValue ( args [ i ] ) :
2016-08-04 09:10:08 +02:00
# fix_print_with_import
2016-09-21 18:24:26 +02:00
print ( ' Error: Wrong parameter value: ' + str ( args [ i ] ) )
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Wrong parameter value: ' ) + str ( args [ i ] ) , Processing . tr ( " Processing " ) )
2012-09-15 18:25:25 +03:00
return
2013-10-01 20:52:22 +03:00
i = i + 1
2012-09-15 18:25:25 +03:00
for output in alg . outputs :
if not output . hidden :
if not output . setValue ( args [ i ] ) :
2016-08-04 09:10:08 +02:00
# fix_print_with_import
2016-09-21 18:24:26 +02:00
print ( ' Error: Wrong output value: ' + str ( args [ i ] ) )
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Wrong output value: ' ) + str ( args [ i ] ) , Processing . tr ( " Processing " ) )
2012-09-15 18:25:25 +03:00
return
2013-10-01 20:52:22 +03:00
i = i + 1
2012-09-15 18:25:25 +03:00
2015-06-23 09:07:20 +02:00
msg = alg . _checkParameterValuesBeforeExecuting ( )
2012-09-15 18:25:25 +03:00
if msg :
2016-08-04 09:10:08 +02:00
# fix_print_with_import
2016-09-21 18:24:26 +02:00
print ( ' Unable to execute algorithm \n ' + str ( msg ) )
2015-09-12 13:27:26 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Unable to execute algorithm \n {0} ' ) . format ( msg ) , Processing . tr ( " Processing " ) )
2013-02-06 21:00:26 +01:00
return
2012-09-15 18:25:25 +03:00
2013-02-06 21:00:26 +01:00
if not alg . checkInputCRS ( ) :
2017-03-04 19:41:23 +01:00
print ( ' Warning: Not all input layers use the same CRS. \n ' +
' This can cause unexpected results. ' )
2015-09-12 13:27:26 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Warning: Not all input layers use the same CRS. \n This can cause unexpected results. ' ) , Processing . tr ( " Processing " ) )
2013-02-07 01:09:39 +01:00
2015-08-20 14:30:12 +02:00
# Don't set the wait cursor twice, because then when you
# restore it, it will still be a wait cursor.
overrideCursor = False
2014-10-03 10:35:07 +02:00
if iface is not None :
2015-08-22 14:29:41 +02:00
cursor = QApplication . overrideCursor ( )
if cursor is None or cursor == 0 :
QApplication . setOverrideCursor ( QCursor ( Qt . WaitCursor ) )
2015-08-14 14:12:01 +02:00
overrideCursor = True
2015-08-22 14:29:41 +02:00
elif cursor . shape ( ) != Qt . WaitCursor :
QApplication . setOverrideCursor ( QCursor ( Qt . WaitCursor ) )
2015-08-14 14:12:01 +02:00
overrideCursor = True
2012-12-10 00:12:07 +01:00
2017-01-06 20:04:00 +10:00
feedback = None
if kwargs is not None and " feedback " in list ( kwargs . keys ( ) ) :
feedback = kwargs [ " feedback " ]
2015-11-10 20:21:10 +00:00
elif iface is not None :
2017-03-29 12:51:59 +10:00
feedback = MessageBarProgress ( alg . displayName ( ) )
2015-11-10 20:21:10 +00:00
2017-03-22 17:17:14 +02:00
ret = execute ( alg , feedback )
2015-06-23 08:30:17 +02:00
if ret :
if onFinish is not None :
2017-01-06 20:04:00 +10:00
onFinish ( alg , feedback )
2015-06-23 08:30:17 +02:00
else :
2015-09-12 13:27:26 +02:00
QgsMessageLog . logMessage ( Processing . tr ( " There were errors executing the algorithm. " ) , Processing . tr ( " Processing " ) )
2014-10-03 10:35:07 +02:00
2015-08-20 14:30:12 +02:00
if overrideCursor :
2015-08-22 14:29:41 +02:00
QApplication . restoreOverrideCursor ( )
2017-01-06 20:04:00 +10:00
if isinstance ( feedback , MessageBarProgress ) :
feedback . close ( )
2012-09-15 18:25:25 +03:00
return alg
2014-10-03 14:44:01 +03:00
2014-10-09 10:51:50 +03:00
@staticmethod
def tr ( string , context = ' ' ) :
2014-10-03 14:44:01 +03:00
if context == ' ' :
context = ' Processing '
2014-10-09 10:51:50 +03:00
return QCoreApplication . translate ( context , string )