[processing] better expression context building

This commit is contained in:
volaya 2016-04-26 08:33:57 +02:00
parent e9a3089670
commit 2535c0a9c1
3 changed files with 39 additions and 35 deletions

View File

@ -123,6 +123,7 @@ class AlgorithmDialog(AlgorithmDialogBase):
def evaluateExpression(self, text):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope())
exp = QgsExpression(text)
if exp.hasParserError():

View File

@ -33,7 +33,8 @@ from PyQt.QtGui import QDialog
from math import log10, floor
from qgis.core import (QgsDataSourceURI, QgsCredentials, QgsExpressionContext,
QgsExpressionContextUtils, QgsExpression, QgsRasterLayer)
QgsExpressionContextUtils, QgsExpression, QgsRasterLayer,
QgsExpressionContextScope)
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
from qgis.utils import iface
from processing.tools import dataobjects
@ -87,11 +88,7 @@ class NumberInputPanel(BASE, WIDGET):
self.spnValue.valueChanged.connect(lambda: self.hasChanged.emit())
def showExpressionsBuilder(self):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
scope = QgsExpressionContextUtils.projectScope()
self.addVariablesToScope(scope)
context.appendScope(scope)
context = self.expressionContext()
dlg = QgsExpressionBuilderDialog(None, self.spnValue.text(), self, "generic", context)
dlg.setWindowTitle(self.tr("Expression based input"));
if dlg.exec_() == QDialog.Accepted:
@ -104,40 +101,45 @@ class NumberInputPanel(BASE, WIDGET):
except:
pass
def addVariablesToScope(self, scope):
def expressionContext(self):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope())
processingScope = QgsExpressionContextScope()
layers = dataobjects.getAllLayers()
for layer in layers:
name = layer.name()
scope.setVariable("%s_minx" % name, layer.extent().xMinimum())
scope.setVariable("%s_miny" % name, layer.extent().yMinimum())
scope.setVariable("%s_maxx" % name, layer.extent().xMaximum())
scope.setVariable("%s_maxy" % name, layer.extent().yMaximum())
processingScope.setVariable("%s_minx" % name, layer.extent().xMinimum())
processingScope.setVariable("%s_miny" % name, layer.extent().yMinimum())
processingScope.setVariable("%s_maxx" % name, layer.extent().xMaximum())
processingScope.setVariable("%s_maxy" % name, layer.extent().yMaximum())
if isinstance(layer, QgsRasterLayer):
cellsize = (layer.extent().xMaximum()
- layer.extent().xMinimum()) / layer.width()
scope.setVariable("%s_cellsize" % name, cellsize)
processingScope.setVariable("%s_cellsize" % name, cellsize)
layers = dataobjects.getRasterLayers()
for layer in layers:
for i in range(layer.bandCount()):
stats = layer.dataProvider().bandStatistics(i + 1)
scope.setVariable("%s_band%i_avg" % (name, i + 1), stats.mean)
scope.setVariable("%s_band%i_stddev" % (name, i + 1), stats.stdDev)
scope.setVariable("%s_band%i_min" % (name, i + 1), stats.minimumValue)
scope.setVariable("%s_band%i_max" % (name, i + 1), stats.maximumValue)
processingScope.setVariable("%s_band%i_avg" % (name, i + 1), stats.mean)
processingScope.setVariable("%s_band%i_stddev" % (name, i + 1), stats.stdDev)
processingScope.setVariable("%s_band%i_min" % (name, i + 1), stats.minimumValue)
processingScope.setVariable("%s_band%i_max" % (name, i + 1), stats.maximumValue)
extent = iface.mapCanvas().extent()
scope.setVariable("canvasextent_minx", extent.xMinimum())
scope.setVariable("canvasextent_miny", extent.yMinimum())
scope.setVariable("canvasextent_maxx", extent.xMaximum())
scope.setVariable("canvasextent_maxy", extent.yMaximum())
processingScope.setVariable("canvasextent_minx", extent.xMinimum())
processingScope.setVariable("canvasextent_miny", extent.yMinimum())
processingScope.setVariable("canvasextent_maxx", extent.xMaximum())
processingScope.setVariable("canvasextent_maxy", extent.yMaximum())
extent = iface.mapCanvas().fullExtent()
scope.setVariable("fullextent_minx", extent.xMinimum())
scope.setVariable("fullextent_miny", extent.yMinimum())
scope.setVariable("fullextent_maxx", extent.xMaximum())
scope.setVariable("fullextent_maxy", extent.yMaximum())
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 getValue(self):
return self.spnValue.value()

View File

@ -34,7 +34,7 @@ from PyQt.QtWidgets import QDialog, QMenu, QAction, QFileDialog
from PyQt.QtGui import QCursor
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
from qgis.core import QgsDataSourceURI, QgsCredentials, QgsExpressionContext,\
QgsExpressionContextUtils, QgsExpression
QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.outputs import OutputVector
@ -107,18 +107,20 @@ class OutputSelectionPanel(BASE, WIDGET):
popupMenu.exec_(QCursor.pos())
def showExpressionsBuilder(self):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
scope = QgsExpressionContextUtils.projectScope()
self.addVariablesToScope(scope)
dlg = QgsExpressionBuilderDialog(None, self.leText.text(), self, "generic", context)
dlg = QgsExpressionBuilderDialog(None, self.leText.text(), self, "generic", self.expressionContext())
dlg.setWindowTitle(self.tr("Expression based output"));
if dlg.exec_() == QDialog.Accepted:
self.leText.setText(dlg.expressionText())
def addVariablesToScope(self, scope):
def expressionContext(self):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope())
processingScope = QgsExpressionContextScope()
for param in self.ag.parameters:
scope.setVariable("%s_value" % param.name, "")
processingScope.setVariable("%s_value" % param.name, "")
context.appendScope(processingScope)
return context
def saveToTemporaryFile(self):
self.leText.setText('')
@ -222,8 +224,7 @@ class OutputSelectionPanel(BASE, WIDGET):
def getValue(self):
fileName = unicode(self.leText.text())
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.projectScope())
context = self.expressionContext()
exp = QgsExpression(fileName)
if not exp.hasParserError():
result = exp.evaluate(context)