Skip to content

Commit

Permalink
Merge branch 'processing_exps' of https://github.com/volaya/QGIS into…
Browse files Browse the repository at this point in the history
… processing_exps

Conflicts:
	python/plugins/processing/gui/NumberInputPanel.py
	python/plugins/processing/gui/OutputSelectionPanel.py
  • Loading branch information
alexbruy committed May 13, 2016
2 parents b51d70a + 2535c0a commit 730c580
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 17 deletions.
26 changes: 22 additions & 4 deletions python/plugins/processing/gui/AlgorithmDialog.py
Expand Up @@ -29,7 +29,7 @@
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QPushButton, QWidget, QVBoxLayout
from qgis.PyQt.QtGui import QCursor, QColor, QPalette

from qgis.core import QgsMapLayerRegistry
from qgis.core import QgsMapLayerRegistry, QgsExpressionContext, QgsExpressionContextUtils, QgsExpression

from processing.core.ProcessingLog import ProcessingLog
from processing.core.ProcessingConfig import ProcessingConfig
Expand Down Expand Up @@ -102,8 +102,8 @@ def setParamValues(self):
continue
if not self.setParamValue(
param, self.mainWidget.valueItems[param.name]):
raise AlgorithmDialogBase.InvalidParameterValue(param,
self.mainWidget.valueItems[param.name])
raise AlgorithmDialogBase.InvalidParameterValue(
param, self.mainWidget.valueItems[param.name])

for param in params:
if isinstance(param, ParameterExtent):
Expand All @@ -121,6 +121,19 @@ def setParamValues(self):

return True

def evaluateExpression(self, text):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope())
exp = QgsExpression(text)
if exp.hasParserError():
raise Exception(exp.parserErrorString())
result = exp.evaluate(context)
if exp.hasEvalError():
raise ValueError(exp.evalErrorString())
return result


def setParamValue(self, param, widget, alg=None):
if isinstance(param, ParameterRaster):
return param.setValue(widget.getValue())
Expand Down Expand Up @@ -159,7 +172,12 @@ def setParamValue(self, param, widget, alg=None):
if param.multiline:
return param.setValue(unicode(widget.toPlainText()))
else:
return param.setValue(unicode(widget.text()))
text = widget.text()
try:
text = self.evaluateExpression(text)
except:
return False
return param.setValue(text)
elif isinstance(param, ParameterGeometryPredicate):
return param.setValue(widget.value())
else:
Expand Down
71 changes: 64 additions & 7 deletions python/plugins/processing/gui/NumberInputPanel.py
Expand Up @@ -29,9 +29,15 @@

from qgis.PyQt import uic
from qgis.PyQt.QtCore import pyqtSignal
from PyQt.QtGui import QDialog

from math import log10, floor
from processing.gui.NumberInputDialog import NumberInputDialog
from qgis.core import (QgsDataSourceURI, QgsCredentials, QgsExpressionContext,
QgsExpressionContextUtils, QgsExpression, QgsRasterLayer,
QgsExpressionContextScope)
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
from qgis.utils import iface
from processing.tools import dataobjects

pluginPath = os.path.split(os.path.dirname(__file__))[0]
WIDGET, BASE = uic.loadUiType(
Expand All @@ -46,6 +52,7 @@ def __init__(self, number, minimum, maximum, isInteger):
super(NumberInputPanel, self).__init__(None)
self.setupUi(self)

self.spnValue.setExpressionsEnabled(True)
self.isInteger = isInteger
if self.isInteger:
self.spnValue.setDecimals(0)
Expand Down Expand Up @@ -74,15 +81,65 @@ def __init__(self, number, minimum, maximum, isInteger):
self.spnValue.setValue(0)
self.spnValue.setClearValue(0)

self.btnCalc.clicked.connect(self.showNumberInputDialog)
self.btnCalc.setFixedHeight(self.spnValue.height())

self.btnCalc.clicked.connect(self.showExpressionsBuilder)

self.spnValue.valueChanged.connect(lambda: self.hasChanged.emit())

def showNumberInputDialog(self):
dlg = NumberInputDialog(self.isInteger)
dlg.exec_()
if dlg.value is not None:
self.spnValue.setValue(dlg.value)
def showExpressionsBuilder(self):
context = self.expressionContext()
dlg = QgsExpressionBuilderDialog(None, self.spnValue.text(), self, "generic", context)
dlg.setWindowTitle(self.tr("Expression based input"));
if dlg.exec_() == QDialog.Accepted:
exp = QgsExpression(dlg.expressionText())
if not exp.hasParserError():
result = exp.evaluate(context)
if not exp.hasEvalError():
try:
self.spnValue.setValue(float(result))
except:
pass

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()
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()
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)
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()
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()
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()
Expand Down
32 changes: 30 additions & 2 deletions python/plugins/processing/gui/OutputSelectionPanel.py
Expand Up @@ -32,8 +32,9 @@
from qgis.PyQt.QtCore import QCoreApplication, QSettings
from qgis.PyQt.QtWidgets import QDialog, QMenu, QAction, QFileDialog
from qgis.PyQt.QtGui import QCursor
from qgis.gui import QgsEncodingFileDialog
from qgis.core import QgsDataSourceURI, QgsCredentials
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
from qgis.core import QgsDataSourceURI, QgsCredentials, QgsExpressionContext,\
QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope

from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.outputs import OutputVector
Expand Down Expand Up @@ -78,6 +79,11 @@ def selectOutput(self):
actionSaveToFile.triggered.connect(self.selectFile)
popupMenu.addAction(actionSaveToFile)

actionShowExpressionsBuilder = QAction(
self.tr('Use expression...'), self.btnSelect)
actionShowExpressionsBuilder.triggered.connect(self.showExpressionsBuilder)
popupMenu.addAction(actionShowExpressionsBuilder)

if isinstance(self.output, OutputVector) \
and self.alg.provider.supportsNonFileBasedOutput():
actionSaveToMemory = QAction(
Expand All @@ -100,6 +106,22 @@ def selectOutput(self):

popupMenu.exec_(QCursor.pos())

def showExpressionsBuilder(self):
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 expressionContext(self):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope())
processingScope = QgsExpressionContextScope()
for param in self.ag.parameters:
processingScope.setVariable("%s_value" % param.name, "")
context.appendScope(processingScope)
return context

def saveToTemporaryFile(self):
self.leText.setText('')

Expand Down Expand Up @@ -202,6 +224,12 @@ def selectDirectory(self):

def getValue(self):
fileName = unicode(self.leText.text())
context = self.expressionContext()
exp = QgsExpression(fileName)
if not exp.hasParserError():
result = exp.evaluate(context)
if not exp.hasEvalError():
fileName = result
if fileName.strip() in ['', self.SAVE_TO_TEMP_FILE]:
value = None
elif fileName.startswith('memory:'):
Expand Down
15 changes: 14 additions & 1 deletion python/plugins/processing/ui/widgetBaseSelector.ui
Expand Up @@ -21,10 +21,23 @@
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="leText"/>
<widget class="QLineEdit" name="leText">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>...</string>
</property>
Expand Down
25 changes: 22 additions & 3 deletions python/plugins/processing/ui/widgetLayerSelector.ui
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>250</width>
<height>23</height>
<width>608</width>
<height>20</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -21,17 +21,36 @@
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="cmbText"/>
<widget class="QComboBox" name="cmbText">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnIterate">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Iterate over this layer</string>
</property>
Expand Down

0 comments on commit 730c580

Please sign in to comment.