Skip to content

Commit

Permalink
Graphical modeler: export variables to Python (#3702)
Browse files Browse the repository at this point in the history
  • Loading branch information
landam authored Jun 3, 2024
1 parent d7cce33 commit 50da15e
Showing 1 changed file with 89 additions and 44 deletions.
133 changes: 89 additions & 44 deletions gui/wxpython/gmodeler/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3333,6 +3333,12 @@ def __init__(self, fd, model, grassAPI="script"):
self._writePython()

def _getStandardizedOption(self, string):
"""Return GRASS standardized option based on specified string.
:param string: input string to be converted
:return: GRASS standardized option as a string or None if not converted
"""
if string == "raster":
return "G_OPT_R_MAP"
elif string == "vector":
Expand All @@ -3346,7 +3352,7 @@ def _getStandardizedOption(self, string):
elif string == "region":
return "G_OPT_M_REGION"

return ""
return None

def _writePython(self):
"""Write model to file"""
Expand Down Expand Up @@ -3390,7 +3396,8 @@ def _writePython(self):

modelItems = self.model.GetItems(ModelAction)
for item in modelItems:
for flag in item.GetParameterizedParams()["flags"]:
parametrizedParams = item.GetParameterizedParams()
for flag in parametrizedParams["flags"]:
if flag["label"]:
desc = flag["label"]
else:
Expand All @@ -3414,7 +3421,7 @@ def _writePython(self):
self.fd.write("# % answer: False\n")
self.fd.write("# %end\n")

for param in item.GetParameterizedParams()["params"]:
for param in parametrizedParams["params"]:
if param["label"]:
desc = param["label"]
else:
Expand All @@ -3441,6 +3448,29 @@ def _writePython(self):
self.fd.write("# % answer: {}\n".format(param["value"]))
self.fd.write("# %end\n")

# variables
for vname, vdesc in self.model.GetVariables().items():
self.fd.write("# %option")
optionType = self._getStandardizedOption(vdesc["type"])
if optionType:
self.fd.write(" {}".format(optionType))
self.fd.write("\n")
self.fd.write(
r"""# % key: {param_name}
# % description: {description}
# % required: yes
""".format(
param_name=vname,
description=vdesc.get("description", ""),
)
)
if optionType is None and vdesc["type"]:
self.fd.write("# % type: {}\n".format(vdesc["type"]))

if vdesc["value"]:
self.fd.write("# % answer: {}\n".format(vdesc["value"]))
self.fd.write("# %end\n")

# import modules
self.fd.write(
r"""
Expand Down Expand Up @@ -3489,8 +3519,11 @@ def cleanup():
self.fd.write(" pass\n")

self.fd.write("\ndef main(options, flags):\n")
modelVars = self.model.GetVariables()
for item in self.model.GetItems(ModelAction):
self._writeItem(item, variables=item.GetParameterizedParams())
modelParams = item.GetParameterizedParams()
modelParams["vars"] = modelVars
self._writeItem(item, variables=modelParams)

self.fd.write(" return 0\n")

Expand Down Expand Up @@ -3533,6 +3566,45 @@ def _writePythonAction(self, item, variables={}, intermediates=None):
strcmd + self._getPythonActionCmd(item, task, len(strcmd), variables) + "\n"
)

def _substitutePythonParamValue(
self, value, name, parameterizedParams, variables, item
):
"""Substitute parameterized options or variables.
:param value: parameter value to be substituted
:param name: parameter name
:param parameterizedParams: list of parameterized options
:param variables: list of user-defined variables
:param item: item object
:return: substituted value
"""
foundVar = False
parameterizedValue = value

if name in parameterizedParams:
foundVar = True
parameterizedValue = 'options["{}"]'.format(self._getParamName(name, item))
else:
# check for variables
formattedVar = False
for var in variables["vars"]:
pattern = re.compile("%" + var)
found = pattern.search(value)
if found:
foundVar = True
if found.end() != len(value):
formattedVar = True
parameterizedValue = pattern.sub(
"{options['" + var + "']}", value
)
else:
parameterizedValue = f'options["{var}"]'
if formattedVar:
parameterizedValue = 'f"' + parameterizedValue + '"'

return foundVar, parameterizedValue

def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):
opts = task.get_options()

Expand Down Expand Up @@ -3560,11 +3632,18 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):
value = list(map(float, value))

if (name and value) or (name in parameterizedParams):
foundVar = False

if name in parameterizedParams:
foundVar = True
value = 'options["{}"]'.format(self._getParamName(name, item))
if isinstance(value, list):
foundVar = False
for idx in range(len(value)):
foundVar_, value[idx] = self._substitutePythonParamValue(
value[idx], name, parameterizedParams, variables, item
)
if foundVar_ is True:
foundVar = True
else:
foundVar, value = self._substitutePythonParamValue(
value, name, parameterizedParams, variables, item
)

if (
foundVar
Expand All @@ -3577,7 +3656,7 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):

ret += '"%s"' % task.get_name()
if flags:
ret += ",\n{indent}flags='{fl}'".format(indent=" " * cmdIndent, fl=flags)
ret += ',\n{indent}flags="{fl}"'.format(indent=" " * cmdIndent, fl=flags)
if itemParameterizedFlags:
ret += " + getParameterizedFlags(options, [{}])".format(
itemParameterizedFlags
Expand All @@ -3597,40 +3676,6 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):

return ret

def _substituteVariable(self, string, variable, data):
"""Substitute variable in the string
:param string: string to be modified
:param variable: variable to be substituted
:param data: data related to the variable
:return: modified string
"""
result = ""
ss = re.split(r"\w*(%" + variable + ")w*", string)

if not ss[0] and not ss[-1]:
if data:
return "options['%s']" % variable
else:
return variable

for s in ss:
if not s or s == '"':
continue

if s == "%" + variable:
if data:
result += "+options['%s']+" % variable
else:
result += "+%s+" % variable
else:
result += '"' + s
if not s.endswith("]"): # options
result += '"'

return result.strip("+")


class ModelParamDialog(wx.Dialog):
def __init__(
Expand Down

0 comments on commit 50da15e

Please sign in to comment.