1#!/usr/local/bin/python3.8
2
3"""
4MODULE:    r.mapcalc.simple
5
6AUTHOR(S): Vaclav Petras <wenzeslaus gmail com>
7           R. Brunzema <r.brunzema web de> (original 5.0 version)
8           Michael Barton <michael.barton asu edu> (update to GRASS 5.7)
9           Huidae Cho <grass4u gmail com> (removed bashism)
10
11PURPOSE:   Provides wrapper friendly wrapper to r.mapcalc
12
13COPYRIGHT: (C) 2018 by Vaclav Petras and the GRASS Development Team
14
15This program is free software under the GNU General Public
16License (>=v2). Read the file COPYING that comes with GRASS
17for details.
18"""
19
20#%module
21#% description: Calculates a new raster map from a simple r.mapcalc expression.
22#% keyword: raster
23#% keyword: algebra
24#% keyword: simple
25#%end
26#%option
27#% key: expression
28#% type: string
29#% description: Formula (e.g. A-B or A*C+B)
30#% required : yes
31#%end
32#%option G_OPT_R_INPUT
33#% key: a
34#% description: Name of input A raster map
35#% required : no
36#% guisection: Input maps
37#%end
38#%option G_OPT_R_INPUT
39#% key: b
40#% description: Name of input B raster map
41#% required : no
42#% guisection: Input maps
43#%end
44#%option G_OPT_R_INPUT
45#% key: c
46#% description: Name of input C raster map
47#% required : no
48#% guisection: Input maps
49#%end
50#%option G_OPT_R_INPUT
51#% key: d
52#% description: Name of input D raster map
53#% required : no
54#% guisection: Input maps
55#%end
56#%option G_OPT_R_INPUT
57#% key: e
58#% description: Name of input E raster map
59#% required : no
60#% guisection: Input maps
61#%end
62#%option G_OPT_R_INPUT
63#% key: f
64#% description: Name of input F raster map
65#% required : no
66#% guisection: Input maps
67#%end
68#%option G_OPT_R_OUTPUT
69#%end
70#%option
71#% key: seed
72#% type: integer
73#% required: no
74#% multiple: no
75#% description: Seed for rand() function
76#% guisection: Random
77#%end
78#%flag
79#% key: s
80#% description: Generate random seed (result is non-deterministic)
81#% guisection: Random
82#%end
83#%flag
84#% key: q
85#% description: Quote the map names
86#% guisection: Input maps
87#%end
88#%flag
89#% key: c
90#% description: Case sensitive variable names
91#%end
92
93import sys
94import re
95
96import grass.script as gs
97
98
99def name_quote(name):
100    return '"{}"'.format(name)
101
102
103def main():
104    options, flags = gs.parser()
105    expr = options['expression']
106    if not expr:
107        gs.fatal(_("The expression is an empty string"))
108    output = options['output']
109    quote = flags['q']
110    re_flags = 0
111    if flags['c']:
112        re_flags = re.IGNORECASE
113
114    if quote:
115        output = name_quote(output)
116
117    seed = None
118    if options['seed']:
119        seed = options['seed']
120    elif flags['s']:
121        seed = 'auto'
122
123    variables = []
124    for key in "ABCDEF":
125        name = options[key.lower()]
126        if name:
127            if quote:
128                name = name_quote(name)
129            variables.append((key, name))
130
131    for key, name in variables:
132        find = r'([^a-zA-Z0-9]|^){key}([^a-zA-Z0-9]|$)'.format(key=key)
133        replace = r'\1{}\2'.format(name)
134        # we need to do the substitution twice because we are matching
135        # also the char before and after which fails when there is only
136        # one char between the two usages of the same var (e.g. A*A)
137        expr = re.sub(find, replace, expr, flags=re_flags)
138        expr = re.sub(find, replace, expr, flags=re_flags)
139
140    expr = '{lhs} = {rhs}'.format(lhs=output, rhs=expr)
141    gs.verbose(_("Expression: {}").format(expr))
142    gs.mapcalc(expr, seed=seed)
143    # g.message -e "Calculating $GIS_OPT_OUTFILE. Try expert mode."
144
145    return 0
146
147
148if __name__ == "__main__":
149    sys.exit(main())
150
151