mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[processing] added native raster calculator algorithm
Conflicts: python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
This commit is contained in:
parent
fcc343724e
commit
a7f9018e11
@ -552,3 +552,18 @@ qgis:voronoipolygons: >
|
||||
|
||||
qgis:zonalstatistics:
|
||||
|
||||
qgis:rastercalculator: >
|
||||
This algorithm allows to perform algebraic operations using raster layers.
|
||||
|
||||
The resulting layer will have its values computed according to an expression. The expression can contain numerical values, operators and references to any of the layers in the current project. The following functions are also supported:
|
||||
|
||||
- sin(), cos(), tan(), atan2(), ln(), log10()
|
||||
|
||||
The extent and cellsize can be defined by the user. If the extent is not specified, the minimum extent that covers the input layers will be used. If the cellsize is not specified, the minimum cellsize of all input layers will be used.
|
||||
|
||||
The cellsize is assumed to be the same in both X and Y axes.
|
||||
|
||||
Layers are refered by their name as displayed in the layer list and the number of the band to use (based on 1), using the pattern 'layer_name@band number'. For instance, the first band from a layer named DEM will be referred as DEM@1.
|
||||
|
||||
When using the calculator in the batch interface or from the console, the files to use have to be specified. The corresponding layers are refered using the base name of the file (without the full path). For instance, is using a layer at path/to/my/rasterfile.tif, the first band of that layer will be refered as rasterfile.tif@1.
|
||||
|
||||
|
@ -178,6 +178,7 @@ from .ExtractSpecificNodes import ExtractSpecificNodes
|
||||
from .GeometryByExpression import GeometryByExpression
|
||||
from .SnapGeometries import SnapGeometriesToLayer
|
||||
from .PoleOfInaccessibility import PoleOfInaccessibility
|
||||
from .RasterCalculator import RasterCalculator
|
||||
from .CreateAttributeIndex import CreateAttributeIndex
|
||||
from .DropGeometry import DropGeometry
|
||||
from .BasicStatistics import BasicStatisticsForField
|
||||
@ -245,7 +246,7 @@ class QGISAlgorithmProvider(AlgorithmProvider):
|
||||
RemoveNullGeometry(), ExtractByExpression(), ExtendLines(),
|
||||
ExtractSpecificNodes(), GeometryByExpression(), SnapGeometriesToLayer(),
|
||||
PoleOfInaccessibility(), CreateAttributeIndex(), DropGeometry(),
|
||||
BasicStatisticsForField()
|
||||
BasicStatisticsForField(), RasterCalculator()
|
||||
]
|
||||
|
||||
if hasMatplotlib:
|
||||
|
164
python/plugins/processing/algs/qgis/RasterCalculator.py
Normal file
164
python/plugins/processing/algs/qgis/RasterCalculator.py
Normal file
@ -0,0 +1,164 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
RasterLayerCalculator.py
|
||||
---------------------
|
||||
Date : November 2016
|
||||
Copyright : (C) 2016 by Victor Olaya
|
||||
Email : volayaf at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
from processing.modeler.ModelerAlgorithm import ValueFromInput, ValueFromOutput
|
||||
import os
|
||||
|
||||
|
||||
__author__ = 'Victor Olaya'
|
||||
__date__ = 'November 2016'
|
||||
__copyright__ = '(C) 2016, Victor Olaya'
|
||||
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import math
|
||||
from processing.core.GeoAlgorithm import GeoAlgorithm
|
||||
from processing.core.parameters import ParameterMultipleInput, ParameterExtent, ParameterString, ParameterRaster, ParameterNumber
|
||||
from processing.core.outputs import OutputRaster
|
||||
from processing.tools import dataobjects
|
||||
from processing.algs.gdal.GdalUtils import GdalUtils
|
||||
from qgis.core import QgsRectangle
|
||||
from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
from processing.algs.qgis.ui.RasterCalculatorWidgets import LayersListWidgetWrapper, ExpressionWidgetWrapper
|
||||
|
||||
class RasterCalculator(GeoAlgorithm):
|
||||
|
||||
LAYERS = 'LAYERS'
|
||||
EXTENT = 'EXTENT'
|
||||
CELLSIZE = 'CELLSIZE'
|
||||
EXPRESSION = 'EXPRESSION'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def defineCharacteristics(self):
|
||||
self.name, self.i18n_name = self.trAlgorithm('Raster calculator')
|
||||
self.group, self.i18n_group = self.trAlgorithm('Raster')
|
||||
|
||||
self.addParameter(ParameterMultipleInput(self.LAYERS,
|
||||
self.tr('Input layers'),
|
||||
datatype=dataobjects.TYPE_RASTER,
|
||||
optional=True,
|
||||
metadata = {'widget_wrapper': LayersListWidgetWrapper}))
|
||||
class ParameterExpression(ParameterString):
|
||||
def evaluateForModeler(self, value, model):
|
||||
#print value
|
||||
for i in list(model.inputs.values()):
|
||||
param = i.param
|
||||
if isinstance(param, ParameterRaster):
|
||||
new = "%s@" % os.path.basename(param.value)
|
||||
old = "%s@" % param.name
|
||||
value = value.replace(old, new)
|
||||
|
||||
for alg in list(model.algs.values()):
|
||||
for out in alg.algorithm.outputs:
|
||||
print out, out.value
|
||||
if isinstance(out, OutputRaster):
|
||||
if out.value:
|
||||
new = "%s@" % os.path.basename(out.value)
|
||||
old = "%s:%s@" % (alg.name, out.name)
|
||||
value = value.replace(old, new)
|
||||
return value
|
||||
|
||||
self.addParameter(ParameterExpression(self.EXPRESSION, self.tr('Expression'),
|
||||
multiline=True,
|
||||
metadata = {'widget_wrapper': ExpressionWidgetWrapper}))
|
||||
self.addParameter(ParameterNumber(self.CELLSIZE,
|
||||
self.tr('Cellsize (use 0 or empty to set it automatically)'),
|
||||
minValue=0.0, default=0.0, optional=True))
|
||||
self.addParameter(ParameterExtent(self.EXTENT,
|
||||
self.tr('Output extent'),
|
||||
optional=True))
|
||||
self.addOutput(OutputRaster(self.OUTPUT, self.tr('Output')))
|
||||
|
||||
|
||||
def processAlgorithm(self, progress):
|
||||
expression = self.getParameterValue(self.EXPRESSION)
|
||||
layersValue = self.getParameterValue(self.LAYERS)
|
||||
layersDict = {}
|
||||
if layersValue:
|
||||
layers = [dataobjects.getObjectFromUri(f) for f in layersValue.split(";")]
|
||||
layersDict = {os.path.basename(lyr.source()): lyr for lyr in layers}
|
||||
|
||||
for lyr in dataobjects.getRasterLayers():
|
||||
name = lyr.name()
|
||||
if (name + "@") in expression:
|
||||
layersDict[name] = lyr
|
||||
|
||||
entries = []
|
||||
for name, lyr in layersDict.iteritems():
|
||||
for n in xrange(lyr.bandCount()):
|
||||
entry = QgsRasterCalculatorEntry()
|
||||
entry.ref = '%s@%i' % (name, n + 1)
|
||||
entry.raster = lyr
|
||||
entry.bandNumber = n + 1
|
||||
entries.append(entry)
|
||||
|
||||
output = self.getOutputValue(self.OUTPUT)
|
||||
extentValue = self.getParameterValue(self.EXTENT)
|
||||
|
||||
if extentValue:
|
||||
extent = extentValue.split(',')
|
||||
bbox = QgsRectangle(float(extent[0]), float(extent[2]),
|
||||
float(extent[1]), float(extent[3]))
|
||||
else:
|
||||
if layersDict:
|
||||
bbox = layersDict.values()[0].extent()
|
||||
for lyr in layersDict.values():
|
||||
bbox.combineExtentWith(lyr.extent())
|
||||
else:
|
||||
raise GeoAlgorithmExecutionException(self.tr("No layers selected"))
|
||||
def _cellsize(layer):
|
||||
return (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width()
|
||||
cellsize = self.getParameterValue(self.CELLSIZE) or min([_cellsize(lyr) for lyr in layersDict.values()])
|
||||
width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize)
|
||||
height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize)
|
||||
driverName = GdalUtils.getFormatShortNameFromFilename(output)
|
||||
calc = QgsRasterCalculator(expression,
|
||||
output,
|
||||
driverName,
|
||||
bbox,
|
||||
width,
|
||||
height,
|
||||
entries)
|
||||
|
||||
res = calc.processCalculation()
|
||||
if res == QgsRasterCalculator.ParserError:
|
||||
raise GeoAlgorithmExecutionException(self.tr("Error parsing formula"))
|
||||
|
||||
def processBeforeAddingToModeler(self, algorithm, model):
|
||||
values = []
|
||||
expression = algorithm.params[self.EXPRESSION]
|
||||
for i in list(model.inputs.values()):
|
||||
param = i.param
|
||||
if isinstance(param, ParameterRaster) and "%s@" % param.name in expression:
|
||||
values.append(ValueFromInput(param.name))
|
||||
|
||||
if algorithm.name:
|
||||
dependent = model.getDependentAlgorithms(algorithm.name)
|
||||
else:
|
||||
dependent = []
|
||||
for alg in list(model.algs.values()):
|
||||
if alg.name not in dependent:
|
||||
for out in alg.algorithm.outputs:
|
||||
if (isinstance(out, OutputRaster)
|
||||
and "%s:%s@" % (alg.name, out.name) in expression):
|
||||
values.append(ValueFromOutput(alg.name, out.name))
|
||||
|
||||
algorithm.params[self.LAYERS] = values
|
372
python/plugins/processing/algs/qgis/ui/ExpressionWidget.ui
Normal file
372
python/plugins/processing/algs/qgis/ui/ExpressionWidget.ui
Normal file
@ -0,0 +1,372 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>644</width>
|
||||
<height>296</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="verticalGroupBox">
|
||||
<property name="title">
|
||||
<string>Layers (double-click to add)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="buttonsGroupBox">
|
||||
<property name="title">
|
||||
<string>Values and operators</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="2" column="9">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="button7">
|
||||
<property name="text">
|
||||
<string>7</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="button4">
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="button2">
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QPushButton" name="mOpenBracketPushButton">
|
||||
<property name="text">
|
||||
<string>(</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="button1">
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="button5">
|
||||
<property name="text">
|
||||
<string>5</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QPushButton" name="button8">
|
||||
<property name="text">
|
||||
<string>8</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QPushButton" name="mSqrtButton">
|
||||
<property name="text">
|
||||
<string>sqrt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="8">
|
||||
<widget class="QPushButton" name="mCloseBracketPushButton">
|
||||
<property name="text">
|
||||
<string>)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="button3">
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QPushButton" name="mExpButton">
|
||||
<property name="text">
|
||||
<string>^</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QPushButton" name="mMinusPushButton">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QPushButton" name="mDividePushButton">
|
||||
<property name="text">
|
||||
<string>/</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QPushButton" name="button0">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="6">
|
||||
<widget class="QPushButton" name="mGreaterButton">
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QPushButton" name="mMultiplyPushButton">
|
||||
<property name="text">
|
||||
<string>*</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="7">
|
||||
<widget class="QPushButton" name="mAndButton">
|
||||
<property name="text">
|
||||
<string>AND</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="4">
|
||||
<widget class="QPushButton" name="mLesserEqualButton">
|
||||
<property name="text">
|
||||
<string><=</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<widget class="QPushButton" name="mLessButton">
|
||||
<property name="text">
|
||||
<string><</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="6">
|
||||
<widget class="QPushButton" name="mGreaterEqualButton">
|
||||
<property name="text">
|
||||
<string>>=</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="8">
|
||||
<widget class="QPushButton" name="mOrButton">
|
||||
<property name="text">
|
||||
<string>OR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="8">
|
||||
<widget class="QPushButton" name="mEqualButton">
|
||||
<property name="text">
|
||||
<string>=</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="button6">
|
||||
<property name="text">
|
||||
<string>6</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QPushButton" name="buttonDot">
|
||||
<property name="text">
|
||||
<string>.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="7">
|
||||
<widget class="QPushButton" name="mNotEqualButton">
|
||||
<property name="text">
|
||||
<string>!=</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="mPlusPushButton">
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QPushButton" name="button9">
|
||||
<property name="text">
|
||||
<string>9</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Expression</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="text">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -0,0 +1,135 @@
|
||||
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_BATCH
|
||||
from processing.tools import dataobjects
|
||||
from processing.gui.BatchInputSelectionPanel import BatchInputSelectionPanel
|
||||
from qgis.PyQt.QtWidgets import QListWidget, QLineEdit, QPushButton
|
||||
from qgis.PyQt.QtGui import QTextCursor
|
||||
from processing.core.outputs import OutputRaster
|
||||
from processing.core.parameters import ParameterRaster
|
||||
from processing.gui.wrappers import InvalidParameterValue
|
||||
import os
|
||||
from qgis.PyQt import uic
|
||||
from functools import partial
|
||||
|
||||
pluginPath = os.path.dirname(__file__)
|
||||
WIDGET, BASE = uic.loadUiType(
|
||||
os.path.join(pluginPath, 'ExpressionWidget.ui'))
|
||||
|
||||
|
||||
class ExpressionWidget(BASE, WIDGET):
|
||||
|
||||
def __init__(self, options):
|
||||
super(ExpressionWidget, self).__init__(None)
|
||||
self.setupUi(self)
|
||||
|
||||
self.setList(options)
|
||||
|
||||
def doubleClicked(item):
|
||||
self.text.insertPlainText(self.options[item.text()])
|
||||
def addButtonText(text):
|
||||
if any(c for c in text if c.islower()):
|
||||
self.text.insertPlainText(" %s()" % text)
|
||||
self.text.moveCursor(QTextCursor.PreviousCharacter, QTextCursor.MoveAnchor)
|
||||
else:
|
||||
self.text.insertPlainText(" %s " % text)
|
||||
buttons = [b for b in self.buttonsGroupBox.children()if isinstance(b, QPushButton)]
|
||||
for button in buttons:
|
||||
button.clicked.connect(partial(addButtonText, button.text()))
|
||||
self.listWidget.itemDoubleClicked.connect(doubleClicked)
|
||||
|
||||
def setList(self, options):
|
||||
self.options = options
|
||||
self.listWidget.clear()
|
||||
for opt in options.keys():
|
||||
self.listWidget.addItem(opt)
|
||||
|
||||
def setValue(self, value):
|
||||
self.text.setPlainText(value)
|
||||
|
||||
def value(self):
|
||||
return self.text.toPlainText()
|
||||
|
||||
|
||||
class ExpressionWidgetWrapper(WidgetWrapper):
|
||||
|
||||
def _panel(self, options):
|
||||
return ExpressionWidget(options)
|
||||
|
||||
def createWidget(self):
|
||||
if self.dialogType == DIALOG_STANDARD:
|
||||
layers = dataobjects.getRasterLayers(sorting=False)
|
||||
options = {}
|
||||
for lyr in layers:
|
||||
for n in xrange(lyr.bandCount()):
|
||||
name = '%s@%i' % (lyr.name(), n + 1)
|
||||
options[name] = name
|
||||
return self._panel(options)
|
||||
elif self.dialogType == DIALOG_BATCH:
|
||||
return QLineEdit()
|
||||
else:
|
||||
layers = self.dialog.getAvailableValuesOfType(ParameterRaster, OutputRaster)
|
||||
options = {self.dialog.resolveValueDescription(lyr): "%s@1" % lyr for lyr in layers}
|
||||
return self._panel(options)
|
||||
|
||||
def refresh(self):
|
||||
layers = dataobjects.getRasterLayers()
|
||||
options = {}
|
||||
for lyr in layers:
|
||||
for n in xrange(lyr.bandCount()):
|
||||
options[lyr.name()] = '%s@%i' % (lyr.name(), n + 1)
|
||||
self.widget.setList(options)
|
||||
|
||||
def setValue(self, value):
|
||||
if self.dialogType == DIALOG_STANDARD:
|
||||
pass # TODO
|
||||
elif self.dialogType == DIALOG_BATCH:
|
||||
return self.widget.setText(value)
|
||||
else:
|
||||
self.widget.setValue(value)
|
||||
|
||||
def value(self):
|
||||
if self.dialogType in DIALOG_STANDARD:
|
||||
return self.widget.value()
|
||||
elif self.dialogType == DIALOG_BATCH:
|
||||
return self.widget.text()
|
||||
else:
|
||||
return self.widget.value()
|
||||
|
||||
|
||||
class LayersListWidgetWrapper(WidgetWrapper):
|
||||
|
||||
def createWidget(self):
|
||||
if self.dialogType == DIALOG_BATCH:
|
||||
widget = BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
|
||||
widget.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
|
||||
return widget
|
||||
else:
|
||||
return None
|
||||
|
||||
def setValue(self, value):
|
||||
if self.dialogType == DIALOG_BATCH:
|
||||
return self.widget.setText(value)
|
||||
|
||||
|
||||
def value(self):
|
||||
if self.dialogType == DIALOG_STANDARD:
|
||||
if self.param.datatype == dataobjects.TYPE_FILE:
|
||||
return self.param.setValue(self.widget.selectedoptions)
|
||||
else:
|
||||
if self.param.datatype == dataobjects.TYPE_RASTER:
|
||||
options = dataobjects.getRasterLayers(sorting=False)
|
||||
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
|
||||
options = dataobjects.getVectorLayers(sorting=False)
|
||||
else:
|
||||
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
|
||||
return [options[i] for i in self.widget.selectedoptions]
|
||||
elif self.dialogType == DIALOG_BATCH:
|
||||
return self.widget.getText()
|
||||
else:
|
||||
options = self._getOptions()
|
||||
values = [options[i] for i in self.widget.selectedoptions]
|
||||
if len(values) == 0 and not self.param.optional:
|
||||
raise InvalidParameterValue()
|
||||
return values
|
||||
|
||||
|
||||
|
@ -200,7 +200,7 @@ class ValueFromOutput(object):
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return self.alg + "," + self.output
|
||||
return self.alg + ":" + self.output
|
||||
|
||||
def asPythonParameter(self):
|
||||
return "outputs_%s['%s']" % (self.alg, self.output)
|
||||
|
Loading…
x
Reference in New Issue
Block a user