Skip to content

Commit dfb4cdd

Browse files
committed
[processing] moved output value evaluation to output object itself
1 parent 2bb6e4c commit dfb4cdd

File tree

5 files changed

+129
-135
lines changed

5 files changed

+129
-135
lines changed

python/plugins/processing/algs/qgis/FieldsCalculator.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,6 @@ def processAlgorithm(self, progress):
8989

9090
output = self.getOutputFromName(self.OUTPUT_LAYER)
9191

92-
if output.value == '':
93-
ext = output.getDefaultFileExtension(self)
94-
output.value = system.getTempFilenameInTempFolder(
95-
output.name + '.' + ext)
96-
9792
fields = layer.fields()
9893
if newField:
9994
fields.append(QgsField(fieldName, fieldType, '', width, precision))

python/plugins/processing/core/GeoAlgorithm.py

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,8 @@ def execute(self, progress=SilentProgress(), model=None):
197197
self.model = model
198198
try:
199199
self.setOutputCRS()
200-
self.resolveTemporaryOutputs()
201-
self.resolveDataObjects()
200+
self.resolveOutputs()
202201
self.evaluateParameterValues()
203-
self.checkOutputFileExtensions()
204202
self.runPreExecutionScript(progress)
205203
self.processAlgorithm(progress)
206204
progress.setPercentage(100)
@@ -328,51 +326,24 @@ def getFormatShortNameFromFilename(self, filename):
328326
return name
329327
return 'GTiff'
330328

331-
def checkOutputFileExtensions(self):
332-
"""Checks if the values of outputs are correct and have one of
333-
the supported output extensions.
334-
335-
If not, it adds the first one of the supported extensions, which
336-
is assumed to be the default one.
337-
"""
338-
for out in self.outputs:
339-
if not out.hidden and out.value is not None:
340-
if not os.path.isabs(out.value):
341-
continue
342-
if isinstance(out, OutputRaster):
343-
exts = dataobjects.getSupportedOutputRasterLayerExtensions()
344-
elif isinstance(out, OutputVector):
345-
exts = dataobjects.getSupportedOutputVectorLayerExtensions()
346-
elif isinstance(out, OutputTable):
347-
exts = dataobjects.getSupportedOutputTableExtensions()
348-
elif isinstance(out, OutputHTML):
349-
exts = ['html', 'htm']
350-
else:
351-
continue
352-
idx = out.value.rfind('.')
353-
if idx == -1:
354-
out.value = out.value + '.' + exts[0]
355-
else:
356-
ext = out.value[idx + 1:]
357-
if ext not in exts + ['dbf']:
358-
out.value = out.value + '.' + exts[0]
359-
360-
361329
def evaluateParameterValues(self):
362330
for param in self.parameters:
363331
try:
364332
param.evaluate(self)
365333
except ValueError, e:
334+
traceback.print_exc()
366335
raise GeoAlgorithmExecutionException(str(e))
367336

368-
def resolveTemporaryOutputs(self):
337+
def resolveOutputs(self):
369338
"""Sets temporary outputs (output.value = None) with a
370-
temporary file instead.
339+
temporary file instead. Resolves expressions as well.
371340
"""
372-
for out in self.outputs:
373-
if not out.hidden and out.value is None:
374-
setTempOutput(out, self)
375-
341+
try:
342+
for out in self.outputs:
343+
out.resolveValue(self)
344+
except ValueError, e:
345+
raise GeoAlgorithmExecutionException(str(e))
346+
376347
def setOutputCRS(self):
377348
layers = dataobjects.getAllLayers()
378349
for param in self.parameters:

python/plugins/processing/core/outputs.py

Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from builtins import range
2121
from builtins import object
2222

23-
2423
__author__ = 'Victor Olaya'
2524
__date__ = 'August 2012'
2625
__copyright__ = '(C) 2012, Victor Olaya'
@@ -29,15 +28,27 @@
2928

3029
__revision__ = '$Format:%H$'
3130

31+
import os
3232
import sys
3333

3434
from qgis.PyQt.QtCore import QCoreApplication, QSettings
3535

3636
from processing.core.ProcessingConfig import ProcessingConfig
37-
from processing.tools.system import isWindows, getTempFilenameInTempFolder
37+
from processing.tools.system import isWindows, getTempFilenameInTempFolder, getTempDirInTempFolder
3838
from processing.tools.vector import VectorWriter, TableWriter
3939
from processing.tools import dataobjects
4040

41+
from qgis.core import QgsExpressionContext, QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope
42+
43+
def _expressionContext(alg):
44+
context = QgsExpressionContext()
45+
context.appendScope(QgsExpressionContextUtils.globalScope())
46+
context.appendScope(QgsExpressionContextUtils.projectScope())
47+
processingScope = QgsExpressionContextScope()
48+
for param in alg.parameters:
49+
processingScope.setVariable('%s_value' % param.name, '')
50+
context.appendScope(processingScope)
51+
return context
4152

4253
class Output(object):
4354

@@ -82,6 +93,44 @@ def setValue(self, value):
8293
return True
8394
except:
8495
return False
96+
97+
def _resolveTemporary(self, alg):
98+
ext = self.getDefaultFileExtension()
99+
return getTempFilenameInTempFolder(self.name + '.' + ext)
100+
101+
def _supportedExtensions(self):
102+
return []
103+
104+
def resolveValue(self, alg):
105+
if not self.hidden and not bool(self.value):
106+
self.value = self._resolveTemporary(alg)
107+
else:
108+
exp = QgsExpression(self.value)
109+
if exp.hasParserError():
110+
raise ValueError(self.tr("Error in output expression: ") + exp.parserErrorString())
111+
self.value = exp.evaluate(_expressionContext(alg))
112+
if exp.hasEvalError():
113+
raise ValueError("Error evaluating output expression: " + exp.evalErrorString())
114+
115+
116+
117+
print self.value
118+
if ":" not in self.value:
119+
if not os.path.isabs(self.value):
120+
self.value = os.path.join(ProcessingConfig.getSetting(ProcessingConfig.OUTPUT_FOLDER),
121+
self.value)
122+
supported = self._supportedExtensions()
123+
if supported:
124+
idx = self.value.rfind('.')
125+
if idx == -1:
126+
self.value = self.value + '.' + self.getDefaultFileExtension()
127+
else:
128+
ext = self.value[idx + 1:]
129+
if ext not in supported:
130+
self.value = self.value + '.' + self.getDefaultFileExtension()
131+
132+
def expressionContext(self, alg):
133+
return _expressionContext(alg)
85134

86135
def typeName(self):
87136
return self.__class__.__name__.replace('Output', '').lower()
@@ -93,7 +142,9 @@ def tr(self, string, context=''):
93142

94143

95144
class OutputDirectory(Output):
96-
directory = True
145+
146+
def resolveValue(self, alg):
147+
self.value = getTempDirInTempFolder()
97148

98149

99150
class OutputExtent(Output):
@@ -118,10 +169,7 @@ def setValue(self, value):
118169
class OutputCrs(Output):
119170

120171
def __init__(self, name='', description=''):
121-
self.name = name
122-
self.description = description
123-
self.value = None
124-
self.hidden = True
172+
Output.__init__(self, name, description, True)
125173

126174

127175
class OutputFile(Output):
@@ -136,7 +184,7 @@ def getFileFilter(self, alg):
136184
else:
137185
return self.tr('%s files(*.%s)', 'OutputFile') % (self.ext, self.ext)
138186

139-
def getDefaultFileExtension(self, alg):
187+
def getDefaultFileExtension(self):
140188
return self.ext or 'file'
141189

142190

@@ -145,17 +193,14 @@ class OutputHTML(Output):
145193
def getFileFilter(self, alg):
146194
return self.tr('HTML files(*.html)', 'OutputHTML')
147195

148-
def getDefaultFileExtension(self, alg):
196+
def getDefaultFileExtension(self):
149197
return 'html'
150198

151199

152200
class OutputNumber(Output):
153201

154202
def __init__(self, name='', description=''):
155-
self.name = name
156-
self.description = description
157-
self.value = None
158-
self.hidden = True
203+
Output.__init__(self, name, description, True)
159204

160205

161206
class OutputRaster(Output):
@@ -168,11 +213,8 @@ def getFileFilter(self, alg):
168213
exts[i] = self.tr('%s files (*.%s)', 'OutputVector') % (exts[i].upper(), exts[i].lower())
169214
return ';;'.join(exts)
170215

171-
def getDefaultFileExtension(self, alg):
172-
supported = alg.provider.getSupportedOutputRasterLayerExtensions()
173-
default = ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT)
174-
ext = default if default in supported else supported[0]
175-
return ext
216+
def getDefaultFileExtension(self):
217+
return ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT)
176218

177219
def getCompatibleFileName(self, alg):
178220
"""
@@ -189,18 +231,17 @@ def getCompatibleFileName(self, alg):
189231
return self.value
190232
else:
191233
if self.compatible is None:
192-
self.compatible = getTempFilenameInTempFolder(
193-
self.name + '.' + self.getDefaultFileExtension(alg))
234+
supported = alg.provider.getSupportedOutputRasterLayerExtensions()
235+
default = ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT)
236+
ext = default if default in supported else supported[0]
237+
self.compatible = getTempFilenameInTempFolder(self.name + '.' + ext)
194238
return self.compatible
195239

196240

197241
class OutputString(Output):
198242

199243
def __init__(self, name='', description=''):
200-
self.name = name
201-
self.description = description
202-
self.value = None
203-
self.hidden = True
244+
Output.__init__(self, name, description, True)
204245

205246

206247
class OutputTable(Output):
@@ -209,13 +250,13 @@ class OutputTable(Output):
209250
compatible = None
210251

211252
def getFileFilter(self, alg):
212-
exts = ['csv']
253+
exts = ['dbf']
213254
for i in range(len(exts)):
214255
exts[i] = exts[i].upper() + ' files(*.' + exts[i].lower() + ')'
215256
return ';;'.join(exts)
216257

217-
def getDefaultFileExtension(self, alg):
218-
return alg.provider.getSupportedOutputTableExtensions()[0]
258+
def getDefaultFileExtension(self):
259+
return "dbf"
219260

220261
def getCompatibleFileName(self, alg):
221262
"""Returns a filename that is compatible with the algorithm
@@ -233,7 +274,7 @@ def getCompatibleFileName(self, alg):
233274
else:
234275
if self.compatible is None:
235276
self.compatible = getTempFilenameInTempFolder(
236-
self.name + '.' + self.getDefaultFileExtension(alg))
277+
self.name + '.' + alg.provider.getSupportedOutputTableExtensions()[0])
237278
return self.compatible
238279

239280
def getTableWriter(self, fields):
@@ -286,14 +327,13 @@ def getFileFilter(self, alg):
286327
exts[i] = self.tr('%s files (*.%s)', 'OutputVector') % (exts[i].upper(), exts[i].lower())
287328
return ';;'.join(exts)
288329

289-
def getDefaultFileExtension(self, alg):
290-
supported = alg.provider.getSupportedOutputVectorLayerExtensions()
330+
def getDefaultFileExtension(self):
291331
if self.hasGeometry():
292332
default = ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT)
293333
else:
294334
default = 'dbf'
295-
ext = default if default in supported else supported[0]
296-
return ext
335+
return default
336+
297337

298338
def getCompatibleFileName(self, alg):
299339
"""Returns a filename that is compatible with the algorithm
@@ -309,8 +349,10 @@ def getCompatibleFileName(self, alg):
309349
return self.value
310350
else:
311351
if self.compatible is None:
312-
self.compatible = getTempFilenameInTempFolder(
313-
self.name + '.' + self.getDefaultFileExtension(alg))
352+
default = self.getDefaultFileExtension()
353+
supported = alg.provider.getSupportedOutputVectorLayerExtensions()
354+
ext = default if default in supported else supported[0]
355+
self.compatible = getTempFilenameInTempFolder(self.name + '.' + ext)
314356
return self.compatible
315357

316358
def getVectorWriter(self, fields, geomType, crs, options=None):
@@ -345,7 +387,13 @@ def getVectorWriter(self, fields, geomType, crs, options=None):
345387
def dataType(self):
346388
return dataobjects.vectorDataType(self)
347389

348-
390+
def _resolveTemporary(self, alg):
391+
if alg.provider.supportsNonFileBasedOutput():
392+
return "memory:"
393+
else:
394+
ext = self.getDefaultFileExtension()
395+
return getTempFilenameInTempFolder(self.name + '.' + ext)
396+
349397

350398
def getOutputFromString(s):
351399
try:

0 commit comments

Comments
 (0)