Browse Source

r.mapcalc.simple: added from https://svn.osgeo.org/grass/sandbox/wenzeslaus/r.mapcalculator as r.mapcalc.simple (trac https://trac.osgeo.org/grass/ticket/3431)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@73791 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Neteler 6 years ago
parent
commit
ccb0aeb3c8

+ 1 - 0
scripts/Makefile

@@ -40,6 +40,7 @@ SUBDIRS = \
 	r.in.aster \
 	r.in.srtm \
 	r.in.wms \
+	r.mapcalc.simple \
 	r.mask \
 	r.out.xyz \
 	r.pack \

+ 7 - 0
scripts/r.mapcalc.simple/Makefile

@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.mapcalc.simple
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script

+ 121 - 0
scripts/r.mapcalc.simple/r.mapcalc.simple.html

@@ -0,0 +1,121 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.mapcalc.simple</em> provides a wrapper to <em>r.mapcalc</em>.
+Up to 6 maps can be combined using simple expressions.
+
+<p>
+The general syntax for the <b>expression</b> follows
+<em><a href="r.mapcalc.html">r.mapcalc</a></em> expression format,
+for example, <tt>A + B</tt> or <tt>exp(A + B)</tt> are valid.
+The variables A, B, ..., F represent raster maps which are provided
+as options <b>a</b>, <b>b</b>, ..., <b>f</b>.
+
+<p>
+The result name, i.e. the output raster map, is provided using the
+option <b>output</b> and, unlike <em>r.mapcalc</em> it is not part
+of the expression.
+
+<p>
+This module is meant for convenience (for users and programmers) while
+the <em>r.mapcalc</em> module is a better choice for more complex
+expressions and advanced usage.
+
+
+<h2>NOTES</h2>
+
+Differences to <em>r.mapcalc</em> module:
+
+<ul>
+    <li>The input raster map names and the output map raster name are
+        separate from the expression (formula) which uses generic
+        variable names (A, B, C, ...).
+    <li>The output raster name is not included in the expression.
+    <li>The expression is expected to be a single short one liner
+        without the function <tt>eval()</tt>.
+</ul>
+
+Differences to <em>r.mapcalc.simple</em> module in GRASS GIS 5 and 6:
+
+<ul>
+    <li>The primary purpose is not being a GUI front end to
+        <em>r.mapcalc</em>, but a wrapper which allows easy building of
+        interfaces to <em>r.mapcalc</em> (including GUIs).
+    <li>Whitespace (most notably spaces) are allowed
+        (in the same way as for <em>r.mapcalc</em>).
+    <li>The variable names are case-insensitive to allow the original
+        uppercase as well as lowercase as in option names
+        (unless the <b>-c</b> flag is used).
+    <li>Option names for each map are just one letter (not amap, etc.).
+    <li>Output option name is <b>output</b> as for other modules
+        (not outfile).
+    <li>Raster map names can be optionally quoted (the <b>-q</b> flag).
+    <li>There is no expert mode
+        (which was just running <em>r.mapcalc</em>).
+    <li>The <b>expression</b> option is first, so it is possible to
+        omit its name in the command line
+        (just like with <em>r.mapcalc</em>).
+    <li>Overwriting of outputs is done in the same way as with other
+        modules, so there is no flag to not overwrite outputs.
+</ul>
+
+
+<h2>EXAMPLES</h2>
+
+
+<h3>Basic examples</h3>
+
+<div class="code"><pre>
+r.mapcalc.simple expression="0" output=zeros
+r.mapcalc.simple expression="1" output=ones
+r.mapcalc.simple expression="2" output=twos
+</pre></div>
+
+<div class="code"><pre>
+r.mapcalc.simple expression="A + B + C" a=zeros b=ones c=twos output=result1
+</pre></div>
+
+<div class="code"><pre>
+r.mapcalc.simple expression="(A * B) / 2 + 3 * C" a=zeros b=ones c=twos output=result2
+</pre></div>
+
+
+<h3>Example expressions</h3>
+
+Addition:
+
+<div class="code"><pre>
+A + B
+</pre></div>
+
+No spaces around operators are not recommended for readability,
+but allowed in the expression:
+
+<div class="code"><pre>
+A+B
+</pre></div>
+
+More complex expression with a function:
+
+<p>
+<div class="code"><pre>
+exp(A+C)+(B-2)*7
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.mapcalc.html">r.mapcalc</a>,
+<a href="r3.mapcalc.html">r3.mapcalc</a>,
+<a href="t.rast.mapcalc.html">t.rast.mapcalc</a>,
+<a href="g.region.html">g.region</a>
+</em>
+
+
+<h2>AUTHORS</h2>
+
+Vaclav Petras, <a href="https://geospatial.ncsu.edu/geoforall/">NCSU GeoForAll Lab</a><br>
+Michael Barton, Arizona State University (updated to GRASS 5.7)<br>
+R. Brunzema (original 5.0 Bash version)
+
+<p><i>Last changed: $Date$</i>

+ 143 - 0
scripts/r.mapcalc.simple/r.mapcalc.simple.py

@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+
+"""
+MODULE:    r.mapcalc.simple
+
+AUTHOR(S): Vaclav Petras <wenzeslaus gmail com>
+           R. Brunzema <r.brunzema web de> (original 5.0 version)
+           Michael Barton <michael.barton asu edu> (update to GRASS 5.7)
+           Huidae Cho <grass4u gmail com> (removed bashism)
+
+PURPOSE:   Provides wrapper friendly wrapper to r.mapcalc
+
+COPYRIGHT: (C) 2018 by Vaclav Petras and the GRASS Development Team
+
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+"""
+
+#%module
+#% description: Calculate new raster map from a r.mapcalc expression
+#% keyword: raster
+#% keyword: algebra
+#%end
+#%option
+#% key: expression
+#% type: string
+#% description: Formula (e.g. A-B or A*C+B)
+#% required : yes
+#%end
+#%option G_OPT_R_INPUT
+#% key: a
+#% description: A
+#% required : no
+#%end
+#%option G_OPT_R_INPUT
+#% key: b
+#% description: B
+#% required : no
+#%end
+#%option G_OPT_R_INPUT
+#% key: c
+#% description: C
+#% required : no
+#%end
+#%option G_OPT_R_INPUT
+#% key: d
+#% description: D
+#% required : no
+#%end
+#%option G_OPT_R_INPUT
+#% key: e
+#% description: E
+#% required : no
+#%end
+#%option G_OPT_R_INPUT
+#% key: f
+#% description: F
+#% required : no
+#%end
+#%option
+#% key: output
+#% description: Name for output raster map
+#% required : yes
+#%end
+#%option
+#% key: seed
+#% type: integer
+#% required: no
+#% multiple: no
+#% description: Seed for rand() function
+#%end
+#%flag
+#% key: s
+#% description: Generate random seed (result is non-deterministic)
+#%end
+#%flag
+#% key: q
+#% description: Quote the map names
+#%end
+#%flag
+#% key: c
+#% description: Case sensitive variable names
+#%end
+
+import sys
+import re
+
+import grass.script as gs
+
+
+def name_quote(name):
+    return '"{}"'.format(name)
+
+
+def main():
+    options, flags = gs.parser()
+    expr = options['expression']
+    if not expr:
+        gs.fatal(_("The expression is an empty string"))
+    output = options['output']
+    quote = flags['q']
+    re_flags = 0
+    if flags['c']:
+        re_flags = re.IGNORECASE
+
+    if quote:
+        output = name_quote(output)
+
+    seed = None
+    if options['seed']:
+        seed = options['seed']
+    elif flags['s']:
+        seed = 'auto'
+
+    variables = []
+    for key in "ABCDEF":
+        name = options[key.lower()]
+        if name:
+            if quote:
+                name = name_quote(name)
+            variables.append((key, name))
+
+    for key, name in variables:
+        find = r'([^a-zA-Z0-9]|^){key}([^a-zA-Z0-9]|$)'.format(key=key)
+        replace = r'\1{}\2'.format(name)
+        # we need to do the substitution twice because we are matching
+        # also the char before and after which fails when there is only
+        # one char between the two usages of the same var (e.g. A*A)
+        expr = re.sub(find, replace, expr, flags=re_flags)
+        expr = re.sub(find, replace, expr, flags=re_flags)
+
+    expr = '{lhs} = {rhs}'.format(lhs=output, rhs=expr)
+    gs.verbose(_("Expression: {}").format(expr))
+    gs.mapcalc(expr, seed=seed)
+    # g.message -e "Calculating $GIS_OPT_OUTFILE. Try expert mode."
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
+

+ 49 - 0
scripts/r.mapcalc.simple/testsuite/test_rmapcalcsimple.py

@@ -0,0 +1,49 @@
+"""
+Name:       r.mapcalc.simple test
+Purpose:    Tests r.mapcalc.simple and its flags/options.
+    
+Author:     Markus Neteler
+Copyright:  (C) 2018 by Markus Neteler and the GRASS Development Team
+Licence:    This program is free software under the GNU General Public
+            License (>=v2). Read the file COPYING that comes with GRASS
+            for details.
+"""
+from grass.gunittest.case import TestCase
+
+class TestReport(TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        """Use temporary region settings"""
+        map_input = 'elevation'
+        cls.runModule("g.region", raster=map_input)
+        cls.use_temp_region()
+
+    @classmethod
+    def tearDownClass(cls):
+        map_output1 = 'test1'
+        map_output2 = 'test2'
+        cls.runModule("g.remove", flags='f', type='raster', name=map_output1)
+        cls.runModule("g.remove", flags='f', type='raster', name=map_output2)
+        cls.del_temp_region()
+
+    def test_rmapcalcsimple(self):
+        """Testing r.mapcalc.simple"""
+        map_input = 'elevation'
+        map_output1 = 'test1'
+        map_output2 = 'test2'
+
+        # test 1
+        self.assertModule('r.mapcalc.simple', expression='0', output=map_output1)
+        self.assertRasterMinMax(map=map_output1, refmin=0, refmax=0,
+                                msg="Result must be 0 for all pixels")
+
+        # test 2
+        formula='if(%s > 2000, 1, 0)' % map_input # expected to be 0
+        self.assertModule('r.mapcalc.simple', expression=formula, output=map_output2)
+        self.assertRasterMinMax(map=map_output2, refmin=0, refmax=0,
+                                msg="Result must be 0 for all pixels")
+
+if __name__ == '__main__':
+    from grass.gunittest.main import test
+    test()