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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
"""
2014-08-22 11:27:57 +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$ '
2013-10-01 20:52:22 +03:00
import sys
2014-10-03 14:44:01 +03: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
from PyQt4 . QtCore import Qt , QCoreApplication
from PyQt4 . QtGui import QApplication , QCursor
2014-10-03 14:44:01 +03:00
2014-05-20 16:30:59 +02:00
from qgis . utils import iface
2015-08-20 01:10:43 +02:00
from qgis . core import QgsMessageLog
2014-10-03 14:44:01 +03:00
import processing
2015-05-21 16:53:46 +02:00
from processing . gui import AlgorithmClassification
2014-08-22 11:27:57 +02:00
from processing . modeler . ModelerUtils import ModelerUtils
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
2014-07-14 14:19:09 +02:00
from processing . gui . AlgorithmExecutor import runalg
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
from processing . modeler . ModelerAlgorithmProvider import ModelerAlgorithmProvider
from processing . modeler . ModelerOnlyAlgorithmProvider import ModelerOnlyAlgorithmProvider
2014-04-17 01:41:25 +02:00
from processing . algs . qgis . QGISAlgorithmProvider import QGISAlgorithmProvider
from processing . algs . grass . GrassAlgorithmProvider import GrassAlgorithmProvider
from processing . algs . grass7 . Grass7AlgorithmProvider import Grass7AlgorithmProvider
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
from processing . algs . lidar . LidarToolsAlgorithmProvider import LidarToolsAlgorithmProvider
2014-04-17 01:41:25 +02:00
from processing . algs . gdal . GdalOgrAlgorithmProvider import GdalOgrAlgorithmProvider
from processing . algs . otb . OTBAlgorithmProvider import OTBAlgorithmProvider
from processing . algs . r . RAlgorithmProvider import RAlgorithmProvider
from processing . algs . saga . SagaAlgorithmProvider import SagaAlgorithmProvider
2013-08-12 20:44:27 +02:00
from processing . script . ScriptAlgorithmProvider import ScriptAlgorithmProvider
2014-04-17 01:41:25 +02:00
from processing . algs . taudem . TauDEMAlgorithmProvider import TauDEMAlgorithmProvider
2013-10-01 20:52:22 +03:00
from processing . tools import dataobjects
2013-08-12 20:44:27 +02:00
class Processing :
2012-09-15 18:25:25 +03:00
listeners = [ ]
providers = [ ]
2013-10-01 20:52:22 +03:00
# A dictionary of algorithms. Keys are names of providers
# and values are list with all algorithms from that provider
2012-09-15 18:25:25 +03:00
algs = { }
2013-10-01 20:52:22 +03:00
# Same structure as algs
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 = [ ]
modeler = ModelerAlgorithmProvider ( )
@staticmethod
2015-04-11 18:59:27 +01:00
def addProvider ( provider , updateList = True ) :
2013-10-01 20:52:22 +03:00
""" Use this method to add algorithms from external providers.
"""
# Note: this might slow down the initialization process if
# there are many new providers added. Should think of a
# different solution
2013-09-23 13:31:47 +02:00
try :
provider . initializeSettings ( )
Processing . providers . append ( provider )
2014-04-23 18:24:23 +02:00
ProcessingConfig . readSettings ( )
2014-06-13 06:25:50 +02:00
if updateList :
Processing . updateAlgsList ( )
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 ,
2014-10-09 10:51:50 +03:00
Processing . tr ( ' Could not load provider: %s \n %s ' )
2014-10-03 21:56:24 +03:00
% ( provider . getDescription ( ) , unicode ( sys . exc_info ( ) [ 1 ] ) ) )
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 .
"""
2012-09-15 18:25:25 +03:00
try :
provider . unload ( )
2013-08-12 20:44:27 +02:00
Processing . providers . remove ( provider )
2014-04-23 18:24:23 +02:00
ProcessingConfig . readSettings ( )
2014-06-13 06:25:50 +02:00
Processing . updateAlgsList ( )
2012-09-15 18:25:25 +03:00
except :
2013-10-01 20:52:22 +03:00
# This try catch block is here to avoid problems if the
# plugin with a provider is unloaded after the Processing
# framework itself has been unloaded. It is a quick fix
# before I found out how to properly avoid that.
pass
2012-09-15 18:25:25 +03:00
@staticmethod
def getProviderFromName ( name ) :
2014-06-08 00:21:12 +02:00
""" Returns the provider with the given name. """
2013-08-12 20:44:27 +02:00
for provider in Processing . providers :
2012-09-15 18:25:25 +03:00
if provider . getName ( ) == name :
return provider
2013-08-12 20:44:27 +02:00
return Processing . modeler
2012-09-15 18:25:25 +03:00
@staticmethod
def initialize ( ) :
2013-10-01 20:52:22 +03:00
# Add the basic providers
2015-04-11 18:59:27 +01:00
Processing . addProvider ( QGISAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( ModelerOnlyAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( GdalOgrAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( LidarToolsAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( OTBAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( RAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( SagaAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( GrassAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( Grass7AlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( ScriptAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( TauDEMAlgorithmProvider ( ) , updateList = False )
Processing . addProvider ( Processing . modeler , updateList = False )
2013-10-01 20:52:22 +03:00
Processing . modeler . initializeSettings ( )
# And initialize
2015-05-21 16:53:46 +02:00
AlgorithmClassification . loadClassification ( )
AlgorithmClassification . loadDisplayNames ( )
2013-08-12 20:44:27 +02:00
ProcessingLog . startLogging ( )
ProcessingConfig . initialize ( )
2014-04-23 18:24:23 +02:00
ProcessingConfig . readSettings ( )
2013-02-28 22:08:32 +01:00
RenderingStyles . loadStyles ( )
2013-08-12 20:44:27 +02:00
Processing . loadFromProviders ( )
2014-11-30 10:26:17 +01:00
2014-10-06 16:26:49 +02:00
# Inform registered listeners that all providers' algorithms have been loaded
Processing . fireAlgsListHasChanged ( )
2014-11-30 10:26:17 +01:00
2012-09-15 18:25:25 +03:00
@staticmethod
def updateAlgsList ( ) :
2013-10-01 20:52:22 +03:00
""" Call this method when there has been any change that
requires the list of algorithms to be created again from
algorithm providers .
"""
2013-08-12 20:44:27 +02:00
Processing . loadFromProviders ( )
Processing . fireAlgsListHasChanged ( )
2012-09-15 18:25:25 +03:00
@staticmethod
2013-02-07 01:09:39 +01:00
def loadFromProviders ( ) :
2013-08-12 20:44:27 +02:00
Processing . loadAlgorithms ( )
Processing . loadActions ( )
Processing . loadContextMenuActions ( )
2012-09-15 18:25:25 +03:00
@staticmethod
def updateProviders ( ) :
2014-08-22 11:27:57 +02:00
providers = [ p for p in Processing . providers if p . getName ( ) != " model " ]
for provider in providers :
2012-09-15 18:25:25 +03:00
provider . loadAlgorithms ( )
@staticmethod
def addAlgListListener ( listener ) :
2014-06-08 00:21:12 +02:00
"""
Listener should implement a algsListHasChanged ( ) method .
2013-10-01 20:52:22 +03:00
Whenever the list of algorithms changes , that method will be
called for all registered listeners .
"""
2013-08-12 20:44:27 +02:00
Processing . listeners . append ( listener )
2014-11-30 10:26:17 +01:00
2014-10-06 16:26:49 +02:00
@staticmethod
def removeAlgListListener ( listener ) :
try :
Processing . listeners . remove ( listener )
except :
pass
2012-09-15 18:25:25 +03:00
@staticmethod
def fireAlgsListHasChanged ( ) :
2013-08-12 20:44:27 +02:00
for listener in Processing . listeners :
2012-09-15 18:25:25 +03:00
listener . algsListHasChanged ( )
@staticmethod
def loadAlgorithms ( ) :
2013-10-01 20:52:22 +03:00
Processing . algs = { }
2013-08-12 20:44:27 +02:00
Processing . updateProviders ( )
2014-08-22 11:27:57 +02:00
providers = [ p for p in Processing . providers if p . getName ( ) != " model " ]
for provider in providers :
2012-09-15 18:25:25 +03:00
providerAlgs = provider . algs
algs = { }
for alg in providerAlgs :
algs [ alg . commandLineName ( ) ] = alg
2013-08-12 20:44:27 +02:00
Processing . algs [ provider . getName ( ) ] = algs
2013-02-07 01:09:39 +01:00
2012-09-15 18:25:25 +03:00
provs = { }
2013-08-12 20:44:27 +02:00
for provider in Processing . providers :
2012-09-15 18:25:25 +03:00
provs [ provider . getName ( ) ] = provider
2014-08-22 11:27:57 +02:00
2014-06-08 00:21:12 +02:00
ModelerUtils . allAlgs = Processing . algs
ModelerUtils . providers = provs
2012-09-15 18:25:25 +03:00
2014-08-22 11:27:57 +02:00
Processing . modeler . loadAlgorithms ( )
algs = { }
for alg in Processing . modeler . algs :
algs [ alg . commandLineName ( ) ] = alg
Processing . algs [ Processing . modeler . getName ( ) ] = algs
2012-09-15 18:25:25 +03:00
@staticmethod
def loadActions ( ) :
2013-08-12 20:44:27 +02:00
for provider in Processing . providers :
2012-09-15 18:25:25 +03:00
providerActions = provider . actions
actions = list ( )
for action in providerActions :
actions . append ( action )
2013-08-12 20:44:27 +02:00
Processing . actions [ provider . getName ( ) ] = actions
2014-07-02 07:46:03 +02:00
2013-08-12 20:44:27 +02:00
Processing . actions [ provider . getName ( ) ] = actions
2012-09-15 18:25:25 +03:00
@staticmethod
def loadContextMenuActions ( ) :
2013-08-12 20:44:27 +02:00
Processing . contextMenuActions = [ ]
for provider in Processing . providers :
2012-09-15 18:25:25 +03:00
providerActions = provider . contextMenuActions
for action in providerActions :
2013-08-12 20:44:27 +02:00
Processing . contextMenuActions . append ( action )
2012-09-15 18:25:25 +03:00
@staticmethod
def getAlgorithm ( name ) :
2013-08-12 20:44:27 +02:00
for provider in Processing . algs . values ( ) :
2012-09-15 18:25:25 +03:00
if name in provider :
return provider [ name ]
return None
2013-05-01 23:45:20 +02:00
2013-04-13 15:05:19 +02:00
@staticmethod
def getAlgorithmFromFullName ( name ) :
2013-08-12 20:44:27 +02:00
for provider in Processing . algs . values ( ) :
2013-04-13 15:05:19 +02:00
for alg in provider . values ( ) :
if alg . name == name :
return alg
return None
2012-09-15 18:25:25 +03:00
@staticmethod
2012-11-19 08:04:03 +01:00
def getObject ( uri ) :
2014-06-08 00:21:12 +02:00
""" Returns the QGIS object identified by the given URI. """
2013-09-12 13:19:00 +02:00
return dataobjects . getObjectFromUri ( uri )
2012-09-15 18:25:25 +03:00
@staticmethod
2012-11-19 08:04:03 +01:00
def runandload ( name , * args ) :
2014-06-08 23:15:33 +02:00
Processing . runAlgorithm ( name , handleAlgorithmResults , * args )
2012-09-15 18:25:25 +03:00
@staticmethod
def runAlgorithm ( algOrName , onFinish , * args ) :
if isinstance ( algOrName , GeoAlgorithm ) :
alg = algOrName
else :
2013-08-12 20:44:27 +02:00
alg = Processing . getAlgorithm ( algOrName )
2013-10-01 20:52:22 +03:00
if alg is None :
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 = [ ]
for ( name , value ) in args [ 0 ] . items ( ) :
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
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 ,
Processing . tr ( ' Error in %s . Wrong parameter value %s for parameter %s . ' ) % (
2015-08-22 14:29:41 +02:00
alg . name , value , 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
)
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 :
if not param . setValue ( None ) :
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 ,
Processing . tr ( ' Error in %s . Missing parameter value for parameter %s . ' ) % (
2015-08-22 14:29:41 +02: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 ( ) :
2015-08-22 14:29:41 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Wrong number of parameters ' ) , Processing . tr ( " Processing " ) )
2014-06-26 16:09:00 +02:00
processing . alghelp ( algOrName )
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 ] ) :
2015-08-22 14:29:41 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Wrong parameter value: ' ) + unicode ( 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 ] ) :
2015-08-22 14:29:41 +02:00
QgsMessageLog . logMessage ( Processing . tr ( ' Error: Wrong output value: ' ) + unicode ( 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 :
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 ( ) :
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
2014-10-03 10:35:07 +02:00
if iface is not None :
2015-08-22 14:29:41 +02:00
# Don't set the wait cursor twice, because then when you
# restore it, it will still be a wait cursor.
cursor = QApplication . overrideCursor ( )
if cursor is None or cursor == 0 :
QApplication . setOverrideCursor ( QCursor ( Qt . WaitCursor ) )
elif cursor . shape ( ) != Qt . WaitCursor :
QApplication . setOverrideCursor ( QCursor ( Qt . WaitCursor ) )
2012-12-10 00:12:07 +01:00
2014-07-14 14:19:09 +02:00
progress = None
2015-08-22 14:29:41 +02:00
if iface is not None :
2015-06-08 18:27:51 +02:00
progress = MessageBarProgress ( alg . name )
2014-07-14 14:19:09 +02:00
ret = runalg ( alg , progress )
2015-06-23 08:30:17 +02:00
if ret :
if onFinish is not None :
onFinish ( alg , progress )
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
if iface is not None :
2015-08-22 14:29:41 +02:00
QApplication . restoreOverrideCursor ( )
progress . 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 )