Skip to content

Commit

Permalink
[processing] richer expressions in number parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
volaya committed Oct 5, 2016
1 parent 96406e5 commit bd06316
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 9 deletions.
27 changes: 24 additions & 3 deletions python/plugins/processing/core/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@

from processing.tools.vector import resolveFieldIndex, features
from processing.tools import dataobjects
from processing.core.outputs import OutputNumber
from processing.core.outputs import OutputNumber, OutputRaster, OutputVector
from processing.tools.dataobjects import getObject

def parseBool(s):
if s is None or s == str(None).lower():
Expand Down Expand Up @@ -863,22 +864,42 @@ def evaluate(self, alg):
if isinstance(self.value, basestring):
self.value = self._evaluate(self.value)

def _layerVariables(self, element, alg=None):
variables = {}
layer = getObject(element.value)
if layer is not None:
name = element.name if alg is None else "%s_%s" % (alg.name, element.name)
variables['@%s_minx' % name] = layer.extent().xMinimum()
variables['@%s_miny' % name] = layer.extent().yMinimum()
variables['@%s_maxx' % name] = layer.extent().yMaximum()
variables['@%s_maxy' % name]= layer.extent().yMaximum()
if isinstance(element, (ParameterRaster, OutputRaster)):
stats = layer.dataProvider().bandStatistics(1)
variables['@%s_avg' % name] = stats.mean
variables['@%s_stddev' % name] = stats.stdDev
variables['@%s_min' % name] = stats.minimumValue
variables['@%s_max' % name] = stats.maximumValue
return variables

def evaluateForModeler(self, value, model):
if isinstance(value, numbers.Number):
return value
variables = {}
for param in model.parameters:
if isinstance(param, ParameterNumber):
variables["@" + param.name] = param.value
if isinstance(param, (ParameterRaster, ParameterVector)):
variables.update(self._layerVariables(param))

for alg in model.algs.values():
for out in alg.algorithm.outputs:
if isinstance(out, OutputNumber):
variables["@%s_%s" % (alg.name, out.name)] = out.value
if isinstance(out, (OutputRaster, OutputVector)):
variables.update(self._layerVariables(out, alg))
for k,v in variables.iteritems():
print k,v
value = value.replace(k,unicode(v))

print value
return value

def expressionContext(self):
Expand Down
45 changes: 39 additions & 6 deletions python/plugins/processing/gui/NumberInputPanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
QgsExpressionContextScope)
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
from qgis.utils import iface
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputNumber
from processing.core.parameters import ParameterNumber, ParameterVector, ParameterRaster
from processing.core.outputs import OutputNumber, OutputVector, OutputRaster
from processing.modeler.ModelerAlgorithm import ValueFromInput, ValueFromOutput, CompoundValue

pluginPath = os.path.split(os.path.dirname(__file__))[0]
Expand Down Expand Up @@ -68,12 +68,45 @@ def showExpressionsBuilder(self):
if self.modelParametersDialog is not None:
context.popScope()
values = self.modelParametersDialog.getAvailableValuesOfType(ParameterNumber, OutputNumber)
modelerScope = QgsExpressionContextScope()
variables = {}
for value in values:
name = value.name if isinstance(value, ValueFromInput) else "%s_%s" % (value.alg, value.output)
modelerScope.setVariable(name, 1)
context.appendScope(modelerScope)
if isinstance(value, ValueFromInput):
name = value.name
element = self.modelParametersDialog.model.inputs[name].param
desc = element.description
else:
name = "%s_%s" % (value.alg, value.output)
alg = self.modelParametersDialog.model.algs[value.alg]
out = alg.algorithm.getOutputFromName(value.output)
desc = "Output '%s' from algorithm '%s" % (out.description, alg.description)
variables[name] = desc
values = self.modelParametersDialog.getAvailableValuesOfType(ParameterVector, OutputVector)
values.extend(self.modelParametersDialog.getAvailableValuesOfType(ParameterRaster, OutputRaster))
for value in values:
if isinstance(value, ValueFromInput):
name = value.name
element = self.modelParametersDialog.model.inputs[name].param
desc = element.description
else:
name = "%s_%s" % (value.alg, value.output)
alg = self.modelParametersDialog.model.algs[value.alg]
element = alg.algorithm.getOutputFromName(value.output)
desc = "Output '%s' from algorithm '%s" % (element.description, alg.description)
variables['%s_minx' % name] = "Minimum X of %s" % desc
variables['%s_miny' % name] = "Maximum X of %s" % desc
variables['%s_maxx' % name] = "Minimum Y of %s" % desc
variables['%s_maxy' % name] = "Maximum Y of %s" % desc
if isinstance(element, (ParameterRaster, OutputRaster)):
variables['%s_min' % name] = "Minimum value of %s" % desc
variables['%s_max' % name] = "Maximum value of %s" % desc
variables['%s_avg' % name] = "Mean value of %s" % desc
variables['%s_stddev' % name] = "Standard deviation of %s" % desc

#context.appendScope(modelerScope)
#context.setHighlightedVariables(modelerScope.variableNames())
dlg = QgsExpressionBuilderDialog(None, self.leText.text(), self, 'generic', context)
for variable, desc in variables.iteritems():
dlg.expressionBuilder().registerItem("Modeler", variable, "@" + variable, desc, highlightedItem=True)
dlg.setWindowTitle(self.tr('Expression based input'))
if dlg.exec_() == QDialog.Accepted:
exp = QgsExpression(dlg.expressionText())
Expand Down

0 comments on commit bd06316

Please sign in to comment.