[processing] improvements for scripts and R scripts

This commit is contained in:
volaya 2016-09-08 10:30:30 +02:00
parent efd73a491f
commit 01f380863f
4 changed files with 65 additions and 197 deletions

View File

@ -56,6 +56,8 @@ from processing.core.outputs import OutputVector
from processing.core.outputs import OutputRaster
from processing.core.outputs import OutputHTML
from processing.core.outputs import OutputFile
from processing.core.parameters import getParameterFromString
from processing.core.outputs import getOutputFromString
from processing.tools import dataobjects
from processing.tools.system import isWindows
from processing.script.WrongScriptException import WrongScriptException
@ -148,7 +150,6 @@ class RAlgorithm(GeoAlgorithm):
def processParameterLine(self, line):
param = None
out = None
line = line.replace('#', '')
if line.lower().strip().startswith('showplots'):
self.showPlots = True
@ -169,133 +170,24 @@ class RAlgorithm(GeoAlgorithm):
self.name = self.i18n_name = tokens[0]
return
if tokens[1].lower().strip().startswith('output'):
outToken = tokens[1].strip()[len('output') + 1:]
out = self.processOutputParameterToken(outToken)
elif tokens[1].lower().strip().startswith('optional'):
optToken = tokens[1].strip()[len('optional') + 1:]
param = self.processInputParameterToken(optToken, tokens[0])
if param:
param.optional = True
else:
param = self.processInputParameterToken(tokens[1], tokens[0])
out = getOutputFromString(line)
if out is None:
param = getParameterFromString(line)
if param is not None:
self.addParameter(param)
elif out is not None:
out.name = tokens[0]
out.description = tokens[0]
out.description = desc
self.addOutput(out)
else:
raise WrongScriptException(
self.tr('Could not load script: %s.\n'
'Problem with line "%s"', 'ScriptAlgorithm') % (self.descriptionFile or '', line))
raise WrongScriptException(
self.tr('Could not load R script: %s.\n Problem with line %s' % (self.descriptionFile, line)))
def processInputParameterToken(self, token, name):
param = None
desc = self.createDescriptiveName(name)
if token.lower().strip().startswith('raster'):
param = ParameterRaster(name, desc, False)
elif token.lower().strip() == 'vector':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_ANY])
elif token.lower().strip() == 'vector point':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_POINT])
elif token.lower().strip() == 'vector line':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_LINE])
elif token.lower().strip() == 'vector polygon':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_POLYGON])
elif token.lower().strip() == 'table':
param = ParameterTable(name, desc, False)
elif token.lower().strip().startswith('multiple raster'):
param = ParameterMultipleInput(name, desc,
dataobjects.TYPE_RASTER)
param.optional = False
elif token.lower().strip() == 'multiple vector':
param = ParameterMultipleInput(name, desc,
dataobjects.TYPE_VECTOR_ANY)
param.optional = False
elif token.lower().strip().startswith('selection'):
options = token.strip()[len('selection'):].split(';')
param = ParameterSelection(name, desc, options)
elif token.lower().strip().startswith('boolean'):
default = token.strip()[len('boolean') + 1:]
if default:
param = ParameterBoolean(name, desc, default)
else:
param = ParameterBoolean(name, desc)
elif token.lower().strip().startswith('number'):
default = token.strip()[len('number') + 1:]
if default:
param = ParameterNumber(name, desc, default=default)
else:
param = ParameterNumber(name, desc)
elif token.lower().strip().startswith('field'):
field = token.strip()[len('field') + 1:]
found = False
for p in self.parameters:
if p.name == field:
found = True
break
if found:
param = ParameterTableField(name, desc, field)
elif token.lower().strip().startswith('multiple field'):
field = token.strip()[len('multiple field') + 1:]
found = False
for p in self.parameters:
if p.name == field:
found = True
break
if found:
param = ParameterTableMultipleField(token, desc, field)
elif token.lower().strip() == 'extent':
param = ParameterExtent(name, desc)
elif token.lower().strip() == 'point':
param = ParameterPoint(name, desc)
elif token.lower().strip() == 'file':
param = ParameterFile(name, desc, False)
elif token.lower().strip() == 'folder':
param = ParameterFile(name, desc, True)
elif token.lower().strip().startswith('string'):
default = token.strip()[len('string') + 1:]
if default:
param = ParameterString(name, desc, default)
else:
param = ParameterString(name, desc)
elif token.lower().strip().startswith('longstring'):
default = token.strip()[len('longstring') + 1:]
if default:
param = ParameterString(name, desc, default, multiline=True)
else:
param = ParameterString(name, desc, multiline=True)
elif token.lower().strip() == 'crs':
default = token.strip()[len('crs') + 1:]
if default:
param = ParameterCrs(name, desc, default)
else:
param = ParameterCrs(name, desc)
return param
def processOutputParameterToken(self, token):
out = None
if token.lower().strip().startswith('raster'):
out = OutputRaster()
elif token.lower().strip().startswith('vector'):
out = OutputVector()
elif token.lower().strip().startswith('table'):
out = OutputTable()
elif token.lower().strip().startswith('file'):
out = OutputFile()
return out
def processAlgorithm(self, progress):
if isWindows():

View File

@ -39,13 +39,6 @@ from processing.tools.vector import VectorWriter, TableWriter
from processing.tools import dataobjects
def getOutputFromString(s):
tokens = s.split("|")
params = [t if str(t) != "None" else None for t in tokens[1:]]
clazz = getattr(sys.modules[__name__], tokens[0])
return clazz(*params)
class Output(object):
def __init__(self, name='', description='', hidden=False):
@ -351,3 +344,49 @@ class OutputVector(Output):
def dataType(self):
return dataobjects.vectorDataType(self)
def getOutputFromString(s):
try:
if "|" in s:
tokens = s.split("|")
params = [t if unicode(t) != "None" else None for t in tokens[1:]]
clazz = getattr(sys.modules[__name__], tokens[0])
return clazz(*params)
else:
tokens = s.split("=")
token = tokens[1].strip()[len('output') + 1:]
out = None
if token.lower().strip().startswith('raster'):
out = OutputRaster()
elif token.lower().strip() == 'vector':
out = OutputVector()
elif token.lower().strip() == 'vector point':
out = OutputVector(datatype=[dataobjects.TYPE_VECTOR_POINT])
elif token.lower().strip() == 'vector line':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_LINE])
elif token.lower().strip() == 'vector polygon':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_POLYGON])
elif token.lower().strip().startswith('table'):
out = OutputTable()
elif token.lower().strip().startswith('html'):
out = OutputHTML()
elif token.lower().strip().startswith('file'):
out = OutputFile()
subtokens = token.split(' ')
if len(subtokens) > 2:
out.ext = subtokens[2]
elif token.lower().strip().startswith('directory'):
out = OutputDirectory()
elif token.lower().strip().startswith('number'):
out = OutputNumber()
elif token.lower().strip().startswith('string'):
out = OutputString()
elif token.lower().strip().startswith('extent'):
out = OutputExtent()
return out
except:
return None

View File

@ -1360,13 +1360,17 @@ class ParameterGeometryPredicate(Parameter):
paramClasses = [c for c in sys.modules[__name__].__dict__.values() if isclass(c) and issubclass(c, Parameter)]
def getParameterFromString(s):
print s
# Try the parameter definitions used in description files
if '|' in s:
isAdvanced = False
if s.startswith("*"):
s = s[1:]
isAdvanced = True
tokens = s.split("|")
params = [t if unicode(t) != unicode(None) else None for t in tokens[1:]]
clazz = getattr(sys.modules[__name__], tokens[0])
return clazz(*params)
param = clazz(*params)
param.isAdvanced = isAdvanced
else: # try script syntax
for paramClass in paramClasses:
try:

View File

@ -33,21 +33,11 @@ from qgis.core import QgsExpressionContextUtils, QgsExpressionContext
from qgis.PyQt.QtGui import QIcon
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.gui.Help2Html import getHtmlFromHelpFile
from processing.core.parameters import getParameterFromString, paramClasses
from processing.core.outputs import OutputTable
from processing.core.outputs import OutputVector
from processing.core.outputs import OutputRaster
from processing.core.outputs import OutputNumber
from processing.core.outputs import OutputString
from processing.core.outputs import OutputHTML
from processing.core.outputs import OutputFile
from processing.core.outputs import OutputDirectory
from processing.core.parameters import getParameterFromString
from processing.core.outputs import getOutputFromString
from processing.core.ProcessingLog import ProcessingLog
from processing.script.WrongScriptException import WrongScriptException
from processing.tools import dataobjects
pluginPath = os.path.split(os.path.dirname(__file__))[0]
@ -128,7 +118,6 @@ class ScriptAlgorithm(GeoAlgorithm):
def processParameterLine(self, line):
param = None
out = None
line = line.replace('#', '')
if line == "nomodeler":
@ -146,10 +135,8 @@ class ScriptAlgorithm(GeoAlgorithm):
self.name = self.i18n_name = tokens[0]
return
if tokens[1].lower().strip().startswith('output'):
outToken = tokens[1].strip()[len('output') + 1:]
out = self.processOutputParameterToken(outToken)
else:
out = getOutputFromString(line)
if out is None:
param = getParameterFromString(line)
if param is not None:
@ -163,60 +150,6 @@ class ScriptAlgorithm(GeoAlgorithm):
self.tr('Could not load script: %s.\n'
'Problem with line "%s"', 'ScriptAlgorithm') % (self.descriptionFile or '', line))
def processInputParameterLine(self, line):
for paramClass in paramClasses:
param = paramClass.fromScriptCode(line)
if param is not None:
return param
def processOutputParameterToken(self, token):
out = None
if token.lower().strip().startswith('raster'):
out = OutputRaster()
elif token.lower().strip() == 'vector':
out = OutputVector()
elif token.lower().strip() == 'vector point':
out = OutputVector(datatype=[dataobjects.TYPE_VECTOR_POINT])
elif token.lower().strip() == 'vector line':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_LINE])
elif token.lower().strip() == 'vector polygon':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_POLYGON])
elif token.lower().strip().startswith('table'):
out = OutputTable()
elif token.lower().strip().startswith('html'):
out = OutputHTML()
elif token.lower().strip().startswith('file'):
out = OutputFile()
subtokens = token.split(' ')
if len(subtokens) > 2:
out.ext = subtokens[2]
elif token.lower().strip().startswith('directory'):
out = OutputDirectory()
elif token.lower().strip().startswith('number'):
out = OutputNumber()
elif token.lower().strip().startswith('string'):
out = OutputString()
elif token.lower().strip().startswith('extent'):
out = OutputExtent()
return out
def processDescriptionParameterLine(self, line):
try:
if line.startswith('Parameter'):
self.addParameter(getParameterFromString(line))
elif line.startswith('*Parameter'):
param = getParameterFromString(line[1:])
param.isAdvanced = True
self.addParameter(param)
else:
self.addOutput(getOutputFromString(line))
except Exception:
raise WrongScriptException(
self.tr('Could not load script: %s.\n'
'Problem with line %d', 'ScriptAlgorithm') % (self.descriptionFile or '', line))
def processAlgorithm(self, progress):
ns = {}
ns['progress'] = progress