mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[processing] moved script syntax from script algorithm class to parameters classes
This commit is contained in:
parent
a69b358aa7
commit
8cc9a50a52
@ -30,6 +30,7 @@ __revision__ = '$Format:%H$'
|
||||
|
||||
import sys
|
||||
import os
|
||||
import inspect
|
||||
|
||||
from qgis.PyQt.QtCore import QCoreApplication
|
||||
from qgis.core import QgsRasterLayer, QgsVectorLayer
|
||||
@ -37,19 +38,23 @@ from processing.tools.vector import resolveFieldIndex, features
|
||||
from processing.tools.system import isWindows
|
||||
from processing.tools import dataobjects
|
||||
|
||||
|
||||
def getParameterFromString(s):
|
||||
tokens = s.split("|")
|
||||
params = [t if str(t) != str(None) else None for t in tokens[1:]]
|
||||
clazz = getattr(sys.modules[__name__], tokens[0])
|
||||
return clazz(*params)
|
||||
|
||||
|
||||
def parseBool(s):
|
||||
if s is None or s == str(None).lower():
|
||||
return None
|
||||
return str(s).lower() == str(True).lower()
|
||||
|
||||
def _splitParameterOptions(line):
|
||||
tokens = line.split('=', 1)
|
||||
if tokens[1].lower().strip().startswith('optional'):
|
||||
isOptional = True
|
||||
definition = tokens[1].strip()[len('optional') + 1:]
|
||||
else:
|
||||
isOptional = False
|
||||
definition = tokens[1]
|
||||
return isOptional, tokens[0], definition
|
||||
|
||||
def _createDescriptiveName(s):
|
||||
return s.replace('_', ' ')
|
||||
|
||||
class Parameter(object):
|
||||
|
||||
@ -128,8 +133,7 @@ class Parameter(object):
|
||||
if context == '':
|
||||
context = 'Parameter'
|
||||
return QCoreApplication.translate(context, string)
|
||||
|
||||
|
||||
|
||||
class ParameterBoolean(Parameter):
|
||||
|
||||
default_metadata = {
|
||||
@ -158,6 +162,20 @@ class ParameterBoolean(Parameter):
|
||||
param_type += 'optional '
|
||||
param_type += 'boolean '
|
||||
return '##' + self.name + '=' + param_type + str(self.default)
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
if definition.startswith("boolean"):
|
||||
descName = _createDescriptiveName(name)
|
||||
default = definition.strip()[len('boolean') + 1:]
|
||||
if default:
|
||||
param = ParameterBoolean(name, descName, default)
|
||||
else:
|
||||
param = ParameterBoolean(name, descName)
|
||||
param.optional = isOptional
|
||||
return param
|
||||
|
||||
|
||||
|
||||
class ParameterCrs(Parameter):
|
||||
@ -194,6 +212,16 @@ class ParameterCrs(Parameter):
|
||||
param_type += 'crs '
|
||||
return '##' + self.name + '=' + param_type + str(self.default)
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
if definition.startswith("crs"):
|
||||
descName = _createDescriptiveName(name)
|
||||
default = definition.strip()[len('crs') + 1:]
|
||||
if default:
|
||||
return ParameterCrs(name, descName, default, isOptional)
|
||||
else:
|
||||
return ParameterCrs(name, descName, None, isOptional)
|
||||
|
||||
class ParameterDataObject(Parameter):
|
||||
|
||||
@ -243,6 +271,14 @@ class ParameterExtent(Parameter):
|
||||
param_type += 'optional '
|
||||
param_type += 'extent'
|
||||
return '##' + self.name + '=' + param_type
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
if definition.startswith("extent"):
|
||||
descName = _createDescriptiveName(name)
|
||||
default = definition.strip()[len('extent') + 1:] or None
|
||||
return ParameterExtent(name, descName, default, isOptional)
|
||||
|
||||
|
||||
class ParameterPoint(Parameter):
|
||||
@ -279,6 +315,14 @@ class ParameterPoint(Parameter):
|
||||
param_type += 'point'
|
||||
return '##' + self.name + '=' + param_type
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
if definition.startswith("point"):
|
||||
descName = _createDescriptiveName(name)
|
||||
default = definition.strip()[len('point') + 1:] or None
|
||||
return ParameterPoint(name, descName, default, isOptional)
|
||||
|
||||
|
||||
class ParameterFile(Parameter):
|
||||
|
||||
@ -318,6 +362,13 @@ class ParameterFile(Parameter):
|
||||
param_type += 'file'
|
||||
return '##' + self.name + '=' + param_type
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
if definition.startswith("file") or definition.startswith("folder"):
|
||||
descName = _createDescriptiveName(name)
|
||||
return ParameterFile(name, descName, definition.startswith("folder"), isOptional)
|
||||
|
||||
|
||||
class ParameterFixedTable(Parameter):
|
||||
|
||||
@ -356,6 +407,14 @@ class ParameterFixedTable(Parameter):
|
||||
tablestring = tablestring[:-1]
|
||||
return tablestring
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
if definition.startswith("point"):
|
||||
descName = _createDescriptiveName(name)
|
||||
default = definition.strip()[len('point') + 1:] or None
|
||||
return ParameterPoint(name, descName, default, isOptional)
|
||||
|
||||
|
||||
class ParameterMultipleInput(ParameterDataObject):
|
||||
|
||||
@ -542,6 +601,17 @@ class ParameterMultipleInput(ParameterDataObject):
|
||||
param_type += 'multiple vector'
|
||||
return '##' + self.name + '=' + param_type
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip() == 'multiple raster':
|
||||
return ParameterMultipleInput(name, descName,
|
||||
dataobjects.TYPE_RASTER, isOptional)
|
||||
elif definition.lower().strip() == 'multiple vector':
|
||||
return ParameterMultipleInput(name, definition,
|
||||
dataobjects.TYPE_VECTOR_ANY, isOptional)
|
||||
|
||||
|
||||
class ParameterNumber(Parameter):
|
||||
|
||||
@ -599,6 +669,13 @@ class ParameterNumber(Parameter):
|
||||
param_type += 'number'
|
||||
return '##' + self.name + '=' + param_type + str(self.default)
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip().startswith('number'):
|
||||
default = definition.strip()[len('number') + 1:] or None
|
||||
return ParameterNumber(name, descName, default=default, optional=isOptional)
|
||||
|
||||
class ParameterRange(Parameter):
|
||||
|
||||
@ -701,6 +778,13 @@ class ParameterRaster(ParameterDataObject):
|
||||
param_type += 'raster'
|
||||
return '##' + self.name + '=' + param_type
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
print isOptional, name, definition
|
||||
if definition.lower().strip().startswith('raster'):
|
||||
return ParameterRaster(name, descName, optional=isOptional)
|
||||
|
||||
class ParameterSelection(Parameter):
|
||||
|
||||
@ -744,7 +828,18 @@ class ParameterSelection(Parameter):
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip().startswith('selectionfromfile'):
|
||||
options = definition.strip()[len('selectionfromfile '):].split(';')
|
||||
return ParameterSelection(name, descName, options, isSource=True, optional=isOptional)
|
||||
elif definition.lower().strip().startswith('selection'):
|
||||
options = definition.strip()[len('selection '):].split(';')
|
||||
return ParameterSelection(name, descName, options, optional=isOptional)
|
||||
|
||||
|
||||
class ParameterString(Parameter):
|
||||
|
||||
NEWLINE = '\n'
|
||||
@ -781,6 +876,22 @@ class ParameterString(Parameter):
|
||||
param_type += 'string'
|
||||
return '##' + self.name + '=' + param_type + self.default
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip().startswith('string'):
|
||||
default = definition.strip()[len('string') + 1:]
|
||||
if default:
|
||||
return ParameterString(name, descName, default, optional=isOptional)
|
||||
else:
|
||||
return ParameterString(name, descName, optional=isOptional)
|
||||
elif definition.lower().strip().startswith('longstring'):
|
||||
default = definition.strip()[len('longstring') + 1:]
|
||||
if default:
|
||||
return ParameterString(name, descName, default, multiline=True, optional=isOptional)
|
||||
else:
|
||||
return ParameterString(name, descName, multiline=True, optional=isOptional)
|
||||
|
||||
class ParameterTable(ParameterDataObject):
|
||||
|
||||
@ -853,6 +964,13 @@ class ParameterTable(ParameterDataObject):
|
||||
param_type += 'table'
|
||||
return '##' + self.name + '=' + param_type
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip().startswith('table'):
|
||||
return ParameterTable(name, descName, isOptional)
|
||||
|
||||
|
||||
class ParameterTableField(Parameter):
|
||||
|
||||
@ -908,6 +1026,24 @@ class ParameterTableField(Parameter):
|
||||
return '##' + self.name + '=' + param_type + self.parent
|
||||
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip().startswith('field'):
|
||||
if definition.lower().strip().startswith('field number'):
|
||||
parent = definition.strip()[len('field number') + 1:]
|
||||
datatype = ParameterTableField.DATA_TYPE_NUMBER
|
||||
elif definition.lower().strip().startswith('field string'):
|
||||
parent = definition.strip()[len('field string') + 1:]
|
||||
datatype = ParameterTableField.DATA_TYPE_STRING
|
||||
else:
|
||||
parent = definition.strip()[len('field') + 1:]
|
||||
datatype = ParameterTableField.DATA_TYPE_ANY
|
||||
|
||||
return ParameterTableField(name, descName, parent, datatype, isOptional)
|
||||
|
||||
|
||||
class ParameterTableMultipleField(Parameter):
|
||||
|
||||
"""A parameter representing several table fields.
|
||||
@ -974,6 +1110,23 @@ class ParameterTableMultipleField(Parameter):
|
||||
param_type += 'multiple field '
|
||||
return '##' + self.name + '=' + param_type + self.parent
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
if definition.lower().strip().startswith('multiple field'):
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip().startswith('multiple field number'):
|
||||
field = definition.strip()[len('multiple field number') + 1:]
|
||||
datatype = ParameterTableMultipleField.DATA_TYPE_NUMBER
|
||||
elif definition.lower().strip().startswith('multiple field string'):
|
||||
field = definition.strip()[len('multiple field string') + 1:]
|
||||
datatype = ParameterTableMultipleField.DATA_TYPE_STRING
|
||||
else:
|
||||
field = definition.strip()[len('multiple field') + 1:]
|
||||
datatype = ParameterTableMultipleField.DATA_TYPE_ANY
|
||||
|
||||
return ParameterTableMultipleField(name, descName, field, datatype, isOptional)
|
||||
|
||||
|
||||
class ParameterVector(ParameterDataObject):
|
||||
|
||||
@ -1050,6 +1203,22 @@ class ParameterVector(ParameterDataObject):
|
||||
param_type += 'vector'
|
||||
return '##' + self.name + '=' + param_type
|
||||
|
||||
@classmethod
|
||||
def fromScriptCode(self, line):
|
||||
isOptional, name, definition = _splitParameterOptions(line)
|
||||
descName = _createDescriptiveName(name)
|
||||
if definition.lower().strip() == 'vector':
|
||||
return ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_ANY], isOptional)
|
||||
elif definition.lower().strip() == 'vector point':
|
||||
return ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_POINT], isOptional)
|
||||
elif definition.lower().strip() == 'vector line':
|
||||
return ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_LINE], isOptional)
|
||||
elif definition.lower().strip() == 'vector polygon':
|
||||
return ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_POLYGON], isOptional)
|
||||
|
||||
class ParameterGeometryPredicate(Parameter):
|
||||
|
||||
@ -1089,3 +1258,23 @@ class ParameterGeometryPredicate(Parameter):
|
||||
else:
|
||||
self.value = value
|
||||
return True
|
||||
|
||||
|
||||
paramClasses = [c for c in sys.modules[__name__].__dict__.values() if inspect.isclass(c) and issubclass(c, Parameter)]
|
||||
|
||||
def getParameterFromString(s):
|
||||
print s
|
||||
#Try the parameter definitions used in description files
|
||||
if '|' in s:
|
||||
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)
|
||||
else: #try script syntax
|
||||
for paramClass in paramClasses:
|
||||
try:
|
||||
param = paramClass.fromScriptCode(s)
|
||||
if param is not None:
|
||||
return param
|
||||
except AttributeError:
|
||||
pass
|
||||
|
@ -146,12 +146,6 @@ class ScriptAlgorithm(GeoAlgorithm):
|
||||
out = None
|
||||
line = line.replace('#', '')
|
||||
|
||||
# If the line is in the format of the text description files for
|
||||
# normal algorithms, then process it using parameter and output
|
||||
# factories
|
||||
if '|' in line:
|
||||
self.processDescriptionParameterLine(line)
|
||||
return
|
||||
if line == "nomodeler":
|
||||
self.showInModeler = False
|
||||
return
|
||||
@ -170,15 +164,8 @@ class ScriptAlgorithm(GeoAlgorithm):
|
||||
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])
|
||||
param = getParameterFromString(line)
|
||||
|
||||
if param is not None:
|
||||
self.addParameter(param)
|
||||
@ -191,125 +178,11 @@ class ScriptAlgorithm(GeoAlgorithm):
|
||||
self.tr('Could not load script: %s.\n'
|
||||
'Problem with line "%s"', 'ScriptAlgorithm') % (self.descriptionFile or '', line))
|
||||
|
||||
def processInputParameterToken(self, token, name):
|
||||
param = None
|
||||
|
||||
descName = self.createDescriptiveName(name)
|
||||
|
||||
if token.lower().strip() == 'raster':
|
||||
param = ParameterRaster(name, descName, False)
|
||||
elif token.lower().strip() == 'vector':
|
||||
param = ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_ANY])
|
||||
elif token.lower().strip() == 'vector point':
|
||||
param = ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_POINT])
|
||||
elif token.lower().strip() == 'vector line':
|
||||
param = ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_LINE])
|
||||
elif token.lower().strip() == 'vector polygon':
|
||||
param = ParameterVector(name, descName,
|
||||
[dataobjects.TYPE_VECTOR_POLYGON])
|
||||
elif token.lower().strip() == 'table':
|
||||
param = ParameterTable(name, descName, False)
|
||||
elif token.lower().strip() == 'multiple raster':
|
||||
param = ParameterMultipleInput(name, descName,
|
||||
dataobjects.TYPE_RASTER)
|
||||
param.optional = False
|
||||
elif token.lower().strip() == 'multiple vector':
|
||||
param = ParameterMultipleInput(name, descName,
|
||||
dataobjects.TYPE_VECTOR_ANY)
|
||||
param.optional = False
|
||||
elif token.lower().strip().startswith('selectionfromfile'):
|
||||
options = token.strip()[len('selectionfromfile '):].split(';')
|
||||
param = ParameterSelection(name, descName, options, isSource=True)
|
||||
elif token.lower().strip().startswith('selection'):
|
||||
options = token.strip()[len('selection '):].split(';')
|
||||
param = ParameterSelection(name, descName, options)
|
||||
elif token.lower().strip().startswith('boolean'):
|
||||
default = token.strip()[len('boolean') + 1:]
|
||||
if default:
|
||||
param = ParameterBoolean(name, descName, default)
|
||||
else:
|
||||
param = ParameterBoolean(name, descName)
|
||||
elif token.lower().strip() == 'extent':
|
||||
param = ParameterExtent(name, descName)
|
||||
elif token.lower().strip() == 'point':
|
||||
param = ParameterPoint(name, descName)
|
||||
elif token.lower().strip() == 'file':
|
||||
param = ParameterFile(name, descName, False)
|
||||
elif token.lower().strip() == 'folder':
|
||||
param = ParameterFile(name, descName, True)
|
||||
elif token.lower().strip().startswith('number'):
|
||||
default = token.strip()[len('number') + 1:]
|
||||
if default:
|
||||
param = ParameterNumber(name, descName, default=default)
|
||||
else:
|
||||
param = ParameterNumber(name, descName)
|
||||
elif token.lower().strip().startswith('field'):
|
||||
if token.lower().strip().startswith('field number'):
|
||||
field = token.strip()[len('field number') + 1:]
|
||||
datatype = ParameterTableField.DATA_TYPE_NUMBER
|
||||
elif token.lower().strip().startswith('field string'):
|
||||
field = token.strip()[len('field string') + 1:]
|
||||
datatype = ParameterTableField.DATA_TYPE_STRING
|
||||
else:
|
||||
field = token.strip()[len('field') + 1:]
|
||||
datatype = ParameterTableField.DATA_TYPE_ANY
|
||||
found = False
|
||||
for p in self.parameters:
|
||||
if p.name == field:
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
param = ParameterTableField(
|
||||
name=name,
|
||||
description=descName,
|
||||
parent=field,
|
||||
datatype=datatype
|
||||
)
|
||||
elif token.lower().strip().startswith('multiple field'):
|
||||
if token.lower().strip().startswith('multiple field number'):
|
||||
field = token.strip()[len('multiple field number') + 1:]
|
||||
datatype = ParameterTableMultipleField.DATA_TYPE_NUMBER
|
||||
elif token.lower().strip().startswith('multiple field string'):
|
||||
field = token.strip()[len('multiple field string') + 1:]
|
||||
datatype = ParameterTableMultipleField.DATA_TYPE_STRING
|
||||
else:
|
||||
field = token.strip()[len('multiple field') + 1:]
|
||||
datatype = ParameterTableMultipleField.DATA_TYPE_ANY
|
||||
found = False
|
||||
for p in self.parameters:
|
||||
if p.name == field:
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
param = ParameterTableMultipleField(
|
||||
name=name,
|
||||
description=descName,
|
||||
parent=field,
|
||||
datatype=datatype
|
||||
)
|
||||
elif token.lower().strip().startswith('string'):
|
||||
default = token.strip()[len('string') + 1:]
|
||||
if default:
|
||||
param = ParameterString(name, descName, default)
|
||||
else:
|
||||
param = ParameterString(name, descName)
|
||||
elif token.lower().strip().startswith('longstring'):
|
||||
default = token.strip()[len('longstring') + 1:]
|
||||
if default:
|
||||
param = ParameterString(name, descName, default, multiline=True)
|
||||
else:
|
||||
param = ParameterString(name, descName, multiline=True)
|
||||
elif token.lower().strip().startswith('crs'):
|
||||
default = token.strip()[len('crs') + 1:]
|
||||
if default:
|
||||
param = ParameterCrs(name, descName, default)
|
||||
else:
|
||||
param = ParameterCrs(name, descName)
|
||||
|
||||
return param
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user