Skip to content
Permalink
Browse files

Move expression context generation out of parameters

  • Loading branch information
nyalldawson committed Jun 5, 2017
1 parent 416770b commit 28f7a8b7e1d7e4c8444155ad715005ecfe6706fe
@@ -120,7 +120,6 @@ def execute(self, parameters, context=None, feedback=None, model=None):
try:
self.setOutputCRS()
self.resolveOutputs()
self.evaluateParameterValues()
self.runPreExecutionScript(feedback)
self.processAlgorithm(parameters, context, feedback)
feedback.setProgress(100)
@@ -229,14 +228,6 @@ def getFormatShortNameFromFilename(self, filename):
return name
return 'GTiff'

def evaluateParameterValues(self):
for param in self.parameters:
try:
param.evaluate(self)
except ValueError as e:
traceback.print_exc()
raise GeoAlgorithmExecutionException(str(e))

def resolveOutputs(self):
"""Sets temporary outputs (output.value = None) with a
temporary file instead. Resolves expressions as well.
@@ -37,10 +37,10 @@
import numbers

from qgis.core import QgsProcessingUtils
from qgis.utils import iface

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinateReferenceSystem,
QgsExpressionContext, QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope,
QgsExpression,
QgsProject,
QgsRectangle,
QgsVectorFileWriter,
@@ -72,25 +72,6 @@ def _createDescriptiveName(s):
return s.replace('_', ' ')


def _expressionContext():
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope(QgsProject.instance()))

if iface.mapCanvas():
context.appendScope(QgsExpressionContextUtils.mapSettingsScope(iface.mapCanvas().mapSettings()))

processingScope = QgsExpressionContextScope()

extent = iface.mapCanvas().fullExtent()
processingScope.setVariable('fullextent_minx', extent.xMinimum())
processingScope.setVariable('fullextent_miny', extent.yMinimum())
processingScope.setVariable('fullextent_maxx', extent.xMaximum())
processingScope.setVariable('fullextent_maxy', extent.yMaximum())
context.appendScope(processingScope)
return context


class Parameter(object):

"""
@@ -139,9 +120,6 @@ def tr(self, string, context=''):
context = 'Parameter'
return QCoreApplication.translate(context, string)

def evaluate(self, alg):
pass


class ParameterBoolean(Parameter):

@@ -726,8 +704,7 @@ def setValue(self, n):

if isinstance(n, str):
try:
v = self._evaluate(n)
self.value = float(v)
self.value = float(n)
if self.isInteger:
self.value = int(math.floor(self.value))
return True
@@ -772,22 +749,6 @@ def fromScriptCode(self, line):
default = None
return ParameterNumber(name, descName, default=default, optional=isOptional)

def _evaluate(self, value):
exp = QgsExpression(value)
if exp.hasParserError():
raise ValueError(self.tr("Error in parameter expression: ") + exp.parserErrorString())
result = exp.evaluate(_expressionContext())
if exp.hasEvalError():
raise ValueError("Error evaluating parameter expression: " + exp.evalErrorString())
if self.isInteger:
return math.floor(result)
else:
return result

def evaluate(self, alg):
if isinstance(self.value, str) and bool(self.value):
self.value = self._evaluate(self.value)

def _layerVariables(self, element, alg=None):
variables = {}
context = dataobjects.createContext()
@@ -827,9 +788,6 @@ def evaluateForModeler(self, value, model):

return value

def expressionContext(self):
return _expressionContext()

def getValueAsCommandLineParameter(self):
if self.value is None:
return str(None)
@@ -1070,7 +1028,6 @@ def __init__(self, name='', description='', default=None, multiline=False,
optional=False, evaluateExpressions=False, metadata={}):
Parameter.__init__(self, name, description, default, optional, metadata)
self.multiline = parseBool(multiline)
self.evaluateExpressions = parseBool(evaluateExpressions)

def setValue(self, obj):
if not bool(obj):
@@ -1118,19 +1075,6 @@ def fromScriptCode(self, line):
else:
return ParameterString(name, descName, multiline=True, optional=isOptional)

def evaluate(self, alg):
if isinstance(self.value, str) and bool(self.value) and self.evaluateExpressions:
exp = QgsExpression(self.value)
if exp.hasParserError():
raise ValueError(self.tr("Error in parameter expression: ") + exp.parserErrorString())
result = exp.evaluate(_expressionContext())
if exp.hasEvalError():
raise ValueError("Error evaluating parameter expression: " + exp.evalErrorString())
self.value = result

def expressionContext(self):
return _expressionContext()


class ParameterExpression(Parameter):

@@ -39,6 +39,7 @@
from processing.core.parameters import ParameterNumber, ParameterVector, ParameterRaster
from processing.core.outputs import OutputNumber, OutputVector, OutputRaster
from processing.modeler.ModelerAlgorithm import ValueFromInput, ValueFromOutput, CompoundValue
from processing.tools.dataobjects import createExpressionContext

pluginPath = os.path.split(os.path.dirname(__file__))[0]
NUMBER_WIDGET, NUMBER_BASE = uic.loadUiType(
@@ -48,6 +49,7 @@


class ModellerNumberInputPanel(BASE, WIDGET):

"""
Number input panel for use inside the modeller - this input panel
is based off the base input panel and includes a text based line input
@@ -70,7 +72,7 @@ def __init__(self, param, modelParametersDialog):
self.leText.textChanged.connect(lambda: self.hasChanged.emit())

def showExpressionsBuilder(self):
context = self.param.expressionContext()
context = createExpressionContext()
dlg = QgsExpressionBuilderDialog(None, str(self.leText.text()), self, 'generic', context)

context.popScope()
@@ -138,6 +140,7 @@ def setValue(self, value):


class NumberInputPanel(NUMBER_BASE, NUMBER_WIDGET):

"""
Number input panel for use outside the modeller - this input panel
contains a user friendly spin box for entering values. It also
@@ -195,7 +198,7 @@ def __init__(self, param):
self.spnValue.valueChanged.connect(lambda: self.hasChanged.emit())

def showExpressionsBuilder(self):
context = self.param.expressionContext()
context = createExpressionContext()
dlg = QgsExpressionBuilderDialog(None, str(self.spnValue.value()), self, 'generic', context)

dlg.setWindowTitle(self.tr('Expression based input'))
@@ -230,7 +230,7 @@ def wrapWithExpressionButton(self, basewidget):
return widget

def showExpressionsBuilder(self):
context = self.param.expressionContext()
context = dataobjects.createExpressionContext()
value = self.value()
if not isinstance(value, str):
value = ''
@@ -40,9 +40,13 @@
QgsSettings,
QgsProcessingUtils,
QgsProcessingContext,
QgsFeatureRequest)
QgsFeatureRequest,
QgsExpressionContext,
QgsExpressionContextUtils,
QgsExpressionContextScope)
from qgis.gui import QgsSublayersDialog
from qgis.PyQt.QtCore import QCoreApplication
from qgis.utils import iface

from processing.core.ProcessingConfig import ProcessingConfig
from processing.algs.gdal.GdalUtils import GdalUtils
@@ -91,6 +95,25 @@ def raise_error(f):
return context


def createExpressionContext():
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope(QgsProject.instance()))

if iface.mapCanvas():
context.appendScope(QgsExpressionContextUtils.mapSettingsScope(iface.mapCanvas().mapSettings()))

processingScope = QgsExpressionContextScope()

extent = iface.mapCanvas().fullExtent()
processingScope.setVariable('fullextent_minx', extent.xMinimum())
processingScope.setVariable('fullextent_miny', extent.yMinimum())
processingScope.setVariable('fullextent_maxx', extent.xMaximum())
processingScope.setVariable('fullextent_maxy', extent.yMaximum())
context.appendScope(processingScope)
return context


def getSupportedOutputRasterLayerExtensions():
allexts = []
for exts in list(GdalUtils.getSupportedRasters().values()):

0 comments on commit 28f7a8b

Please sign in to comment.
You can’t perform that action at this time.