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
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$ '
2013-10-01 20:52:22 +03:00
import sys
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
2016-04-22 10:38:48 +02:00
from qgis . PyQt . QtCore import Qt , QCoreApplication , QObject , pyqtSignal
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
2015-08-20 01:10:43 +02:00
from qgis . core import QgsMessageLog
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
2014-07-14 14:19:09 +02:00
from processing . gui . AlgorithmExecutor import runalg
2013-10-01 20:52:22 +03:00
from processing . tools import dataobjects
2016-05-19 12:25:04 +02:00
from processing . core . alglist import algList
from processing . modeler . ModelerAlgorithmProvider import ModelerAlgorithmProvider
from processing . modeler . ModelerOnlyAlgorithmProvider import ModelerOnlyAlgorithmProvider
from processing . algs . qgis . QGISAlgorithmProvider import QGISAlgorithmProvider
from processing . algs . grass . GrassAlgorithmProvider import GrassAlgorithmProvider
from processing . algs . grass7 . Grass7AlgorithmProvider import Grass7AlgorithmProvider
from processing . algs . lidar . LidarToolsAlgorithmProvider import LidarToolsAlgorithmProvider
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
from processing . script . ScriptAlgorithmProvider import ScriptAlgorithmProvider
from processing . algs . taudem . TauDEMAlgorithmProvider import TauDEMAlgorithmProvider
from processing . preconfigured . PreconfiguredAlgorithmProvider import PreconfiguredAlgorithmProvider
2016-04-27 15:40:56 +03:00
2013-08-12 20:44:27 +02:00
class Processing :
2012-09-15 18:25:25 +03:00
providers = [ ]
2013-10-01 20:52:22 +03:00
2016-05-19 12:25:04 +02:00
# Same structure as algs in algList
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 = [ ]
@staticmethod
2016-05-23 16:57:59 +02:00
def addProvider ( provider , updateList = True ) :
2013-10-01 20:52:22 +03:00
""" Use this method to add algorithms from external providers.
"""
2016-05-19 12:25:04 +02:00
if provider . getName ( ) in [ p . getName for p in algList . providers ] :
2016-04-28 18:27:45 +02:00
return
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 ( )
2016-04-28 18:27:45 +02:00
provider . loadAlgorithms ( )
Processing . actions [ provider . getName ( ) ] = provider . actions
Processing . contextMenuActions . extend ( provider . contextMenuActions )
2016-05-19 12:25:04 +02:00
algList . addProvider ( 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 ,
2014-10-09 10:51:50 +03:00
Processing . tr ( ' Could not load provider: %s \n %s ' )
2016-04-26 08:29:15 +02:00
% ( provider . getDescription ( ) , 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 .
"""
2012-09-15 18:25:25 +03:00
try :
provider . unload ( )
2013-08-12 20:44:27 +02:00
Processing . providers . remove ( provider )
2016-05-19 12:25:04 +02:00
algList . remove ( provider . getName ( ) )
del Processing . actions [ provider . getName ( ) ]
for act in provider . contextMenuActions :
Processing . contextMenuActions . remove ( act )
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
2016-04-28 18:27:45 +02:00
# before I find out how to properly avoid that.
2013-10-01 20:52:22 +03:00
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. """
2016-05-19 12:25:04 +02:00
return algList . getProviderFromName ( name )
2012-09-15 18:25:25 +03:00
@staticmethod
def initialize ( ) :
2016-05-23 16:57:59 +02:00
if Processing . providers :
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-23 16:57:59 +02:00
@staticmethod
def addScripts ( folder ) :
Processing . initialize ( )
provider = Processing . getProviderFromName ( " qgis " )
scripts = ScriptUtils . loadFromFolder ( folder )
print scripts
for script in scripts :
script . allowEdit = False
script . _icon = provider . _icon
script . provider = provider
provider . externalAlgs . extend ( scripts )
Processing . reloadProvider ( " qgis " )
2016-05-24 10:27:38 +02:00
@staticmethod
2016-05-23 16:57:59 +02:00
def removeScripts ( folder ) :
2016-05-24 10:27:38 +02:00
provider = Processing . getProviderFromName ( " qgis " )
for alg in provider . externalAlgs [ : : - 1 ] :
path = os . path . dirname ( alg . descriptionFile )
if path == folder :
provider . externalAlgs . remove ( alg )
Processing . reloadProvider ( " qgis " )
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 .
"""
2016-01-21 09:00:19 +01:00
QApplication . setOverrideCursor ( QCursor ( Qt . WaitCursor ) )
2016-04-28 18:27:45 +02:00
for p in Processing . providers :
Processing . reloadProvider ( p )
2016-01-21 09:00:19 +01:00
QApplication . restoreOverrideCursor ( )
2012-09-15 18:25:25 +03:00
2016-04-28 12:40:50 +02:00
@staticmethod
def reloadProvider ( providerName ) :
2016-05-19 12:25:04 +02:00
algList . reloadProvider ( providerName )
2012-09-15 18:25:25 +03:00
@staticmethod
def getAlgorithm ( name ) :
2016-05-19 12:25:04 +02:00
return algList . getAlgorithm ( name )
2013-05-01 23:45:20 +02:00
2013-04-13 15:05:19 +02:00
@staticmethod
def getAlgorithmFromFullName ( name ) :
2016-05-19 12:25:04 +02:00
return algList . getAlgorithmFromFullName ( name )
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
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 :
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-14 14:12:01 +02:00
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 = [ ]
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-14 14:12:01 +02:00
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 ,
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 :
2015-12-16 17:33:43 +01:00
if not param . setDefaultValue ( ) :
2016-03-21 04:58:12 +01:00
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 ,
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-14 14:12:01 +02:00
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 " ) )
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 ] ) :
2016-03-21 04:58:12 +01:00
print ' Error: Wrong parameter value: ' + unicode ( 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-14 14:12:01 +02:00
print ' Error: Wrong output value: ' + unicode ( 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 :
2016-02-18 14:09:34 +02:00
print ' Unable to execute algorithm \n ' + unicode ( 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 ( ) :
2016-03-21 04:58:12 +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
2014-07-14 14:19:09 +02:00
progress = None
2015-08-14 14:12:01 +02:00
if kwargs is not None and " progress " in kwargs . keys ( ) :
2015-11-10 20:21:10 +00:00
progress = kwargs [ " progress " ]
elif iface is not None :
2015-08-14 14:12:01 +02:00
progress = MessageBarProgress ( )
2015-11-10 20:21:10 +00:00
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
2015-08-20 14:30:12 +02:00
if overrideCursor :
2015-08-22 14:29:41 +02:00
QApplication . restoreOverrideCursor ( )
2015-08-14 14:12:01 +02:00
if isinstance ( progress , MessageBarProgress ) :
2015-08-22 14:29:41 +02:00
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 )