mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-28 00:05:33 -04:00
Merge branch 'processing_exps' of https://github.com/volaya/QGIS into processing_exps
Conflicts: python/plugins/processing/gui/NumberInputPanel.py python/plugins/processing/gui/OutputSelectionPanel.py
This commit is contained in:
commit
730c5806aa
@ -29,7 +29,7 @@ from qgis.PyQt.QtCore import Qt
|
|||||||
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QPushButton, QWidget, QVBoxLayout
|
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QPushButton, QWidget, QVBoxLayout
|
||||||
from qgis.PyQt.QtGui import QCursor, QColor, QPalette
|
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.ProcessingLog import ProcessingLog
|
||||||
from processing.core.ProcessingConfig import ProcessingConfig
|
from processing.core.ProcessingConfig import ProcessingConfig
|
||||||
@ -102,8 +102,8 @@ class AlgorithmDialog(AlgorithmDialogBase):
|
|||||||
continue
|
continue
|
||||||
if not self.setParamValue(
|
if not self.setParamValue(
|
||||||
param, self.mainWidget.valueItems[param.name]):
|
param, self.mainWidget.valueItems[param.name]):
|
||||||
raise AlgorithmDialogBase.InvalidParameterValue(param,
|
raise AlgorithmDialogBase.InvalidParameterValue(
|
||||||
self.mainWidget.valueItems[param.name])
|
param, self.mainWidget.valueItems[param.name])
|
||||||
|
|
||||||
for param in params:
|
for param in params:
|
||||||
if isinstance(param, ParameterExtent):
|
if isinstance(param, ParameterExtent):
|
||||||
@ -121,6 +121,19 @@ class AlgorithmDialog(AlgorithmDialogBase):
|
|||||||
|
|
||||||
return True
|
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):
|
def setParamValue(self, param, widget, alg=None):
|
||||||
if isinstance(param, ParameterRaster):
|
if isinstance(param, ParameterRaster):
|
||||||
return param.setValue(widget.getValue())
|
return param.setValue(widget.getValue())
|
||||||
@ -159,7 +172,12 @@ class AlgorithmDialog(AlgorithmDialogBase):
|
|||||||
if param.multiline:
|
if param.multiline:
|
||||||
return param.setValue(unicode(widget.toPlainText()))
|
return param.setValue(unicode(widget.toPlainText()))
|
||||||
else:
|
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):
|
elif isinstance(param, ParameterGeometryPredicate):
|
||||||
return param.setValue(widget.value())
|
return param.setValue(widget.value())
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -29,9 +29,15 @@ import os
|
|||||||
|
|
||||||
from qgis.PyQt import uic
|
from qgis.PyQt import uic
|
||||||
from qgis.PyQt.QtCore import pyqtSignal
|
from qgis.PyQt.QtCore import pyqtSignal
|
||||||
|
from PyQt.QtGui import QDialog
|
||||||
|
|
||||||
from math import log10, floor
|
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]
|
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||||
WIDGET, BASE = uic.loadUiType(
|
WIDGET, BASE = uic.loadUiType(
|
||||||
@ -46,6 +52,7 @@ class NumberInputPanel(BASE, WIDGET):
|
|||||||
super(NumberInputPanel, self).__init__(None)
|
super(NumberInputPanel, self).__init__(None)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
|
self.spnValue.setExpressionsEnabled(True)
|
||||||
self.isInteger = isInteger
|
self.isInteger = isInteger
|
||||||
if self.isInteger:
|
if self.isInteger:
|
||||||
self.spnValue.setDecimals(0)
|
self.spnValue.setDecimals(0)
|
||||||
@ -74,15 +81,65 @@ class NumberInputPanel(BASE, WIDGET):
|
|||||||
self.spnValue.setValue(0)
|
self.spnValue.setValue(0)
|
||||||
self.spnValue.setClearValue(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())
|
self.spnValue.valueChanged.connect(lambda: self.hasChanged.emit())
|
||||||
|
|
||||||
def showNumberInputDialog(self):
|
def showExpressionsBuilder(self):
|
||||||
dlg = NumberInputDialog(self.isInteger)
|
context = self.expressionContext()
|
||||||
dlg.exec_()
|
dlg = QgsExpressionBuilderDialog(None, self.spnValue.text(), self, "generic", context)
|
||||||
if dlg.value is not None:
|
dlg.setWindowTitle(self.tr("Expression based input"));
|
||||||
self.spnValue.setValue(dlg.value)
|
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):
|
def getValue(self):
|
||||||
return self.spnValue.value()
|
return self.spnValue.value()
|
||||||
|
|||||||
@ -32,8 +32,9 @@ from qgis.PyQt import uic
|
|||||||
from qgis.PyQt.QtCore import QCoreApplication, QSettings
|
from qgis.PyQt.QtCore import QCoreApplication, QSettings
|
||||||
from qgis.PyQt.QtWidgets import QDialog, QMenu, QAction, QFileDialog
|
from qgis.PyQt.QtWidgets import QDialog, QMenu, QAction, QFileDialog
|
||||||
from qgis.PyQt.QtGui import QCursor
|
from qgis.PyQt.QtGui import QCursor
|
||||||
from qgis.gui import QgsEncodingFileDialog
|
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
|
||||||
from qgis.core import QgsDataSourceURI, QgsCredentials
|
from qgis.core import QgsDataSourceURI, QgsCredentials, QgsExpressionContext,\
|
||||||
|
QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope
|
||||||
|
|
||||||
from processing.core.ProcessingConfig import ProcessingConfig
|
from processing.core.ProcessingConfig import ProcessingConfig
|
||||||
from processing.core.outputs import OutputVector
|
from processing.core.outputs import OutputVector
|
||||||
@ -78,6 +79,11 @@ class OutputSelectionPanel(BASE, WIDGET):
|
|||||||
actionSaveToFile.triggered.connect(self.selectFile)
|
actionSaveToFile.triggered.connect(self.selectFile)
|
||||||
popupMenu.addAction(actionSaveToFile)
|
popupMenu.addAction(actionSaveToFile)
|
||||||
|
|
||||||
|
actionShowExpressionsBuilder = QAction(
|
||||||
|
self.tr('Use expression...'), self.btnSelect)
|
||||||
|
actionShowExpressionsBuilder.triggered.connect(self.showExpressionsBuilder)
|
||||||
|
popupMenu.addAction(actionShowExpressionsBuilder)
|
||||||
|
|
||||||
if isinstance(self.output, OutputVector) \
|
if isinstance(self.output, OutputVector) \
|
||||||
and self.alg.provider.supportsNonFileBasedOutput():
|
and self.alg.provider.supportsNonFileBasedOutput():
|
||||||
actionSaveToMemory = QAction(
|
actionSaveToMemory = QAction(
|
||||||
@ -100,6 +106,22 @@ class OutputSelectionPanel(BASE, WIDGET):
|
|||||||
|
|
||||||
popupMenu.exec_(QCursor.pos())
|
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):
|
def saveToTemporaryFile(self):
|
||||||
self.leText.setText('')
|
self.leText.setText('')
|
||||||
|
|
||||||
@ -202,6 +224,12 @@ class OutputSelectionPanel(BASE, WIDGET):
|
|||||||
|
|
||||||
def getValue(self):
|
def getValue(self):
|
||||||
fileName = unicode(self.leText.text())
|
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]:
|
if fileName.strip() in ['', self.SAVE_TO_TEMP_FILE]:
|
||||||
value = None
|
value = None
|
||||||
elif fileName.startswith('memory:'):
|
elif fileName.startswith('memory:'):
|
||||||
|
|||||||
@ -21,10 +21,23 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnSelect">
|
<widget class="QToolButton" name="btnSelect">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>250</width>
|
<width>608</width>
|
||||||
<height>23</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -21,10 +21,23 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnSelect">
|
<widget class="QToolButton" name="btnSelect">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
@ -32,6 +45,12 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnIterate">
|
<widget class="QToolButton" name="btnIterate">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Iterate over this layer</string>
|
<string>Iterate over this layer</string>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user