1#!/usr/local/bin/python3.8
2
3# written by Markus Neteler 18. August 1998 / 20. Jan. 1999
4#            neteler geog.uni-hannover.de
5# mosaic code from Felix Gershunov (Felix spsl.nsc.ru)
6# updated for GRASS 5.7 by Michael Barton 2004/04/05
7# converted to Python by Glynn Clements
8#
9# COPYRIGHT:    (C) 1999,2007,2008 by the GRASS Development Team
10#
11#               This program is free software under the GNU General Public
12#               License (>=v2). Read the file COPYING that comes with GRASS
13#               for details.
14#
15# TODO: - implement g.findfile for 3 and 4 maps (currently only current mapset supported)
16#            [done for 2 maps]
17#       - fix isnull() in r.mapcalc for 3 and 4 maps composites
18#            [done for 2 maps]
19#       - fix color table length (currently only 256 cols supported, make
20#         flexible)
21#            [done for 2 maps]
22#--------------------------------------------------
23
24
25#%module
26#% description: Mosaics several images and extends colormap.
27#% keyword: imagery
28#% keyword: geometry
29#% keyword: mosaicking
30#%end
31#%option G_OPT_R_INPUTS
32#%end
33#%option G_OPT_R_OUTPUT
34#%end
35from __future__ import print_function
36
37import grass.script as gscript
38
39
40def copy_colors(fh, map, offset):
41    p = gscript.pipe_command('r.colors.out', map=map)
42    for line in p.stdout:
43        f = gscript.decode(line).rstrip('\r\n').split(' ')
44        if offset:
45            if f[0] in ['nv', 'default']:
46                continue
47            f[0] = str(float(f[0]) + offset)
48        fh.write(gscript.encode(' '.join(f) + '\n'))
49    p.wait()
50
51
52def get_limit(map):
53    return gscript.raster_info(map)['max']
54
55
56def make_expression(i, count):
57    if i > count:
58        return "null()"
59    else:
60        e = make_expression(i + 1, count)
61        return "if(isnull($image%d),%s,$image%d+$offset%d)" % (i, e, i, i)
62
63
64def main():
65    images = options['input'].split(',')
66    output = options['output']
67
68    count = len(images)
69    msg = _('Do not forget to set region properly to cover all images.')
70    gscript.warning(msg)
71
72    offset = 0
73    offsets = []
74    parms = {}
75    for n, img in enumerate(images):
76        offsets.append(offset)
77        parms['image%d' % (n + 1)] = img
78        parms['offset%d' % (n + 1)] = offset
79        offset += get_limit(img) + 1
80
81    gscript.message(_("Mosaicing %d images...") % count)
82
83    gscript.mapcalc("$output = " + make_expression(1, count),
84                    output=output, **parms)
85
86    # modify the color table:
87    p = gscript.feed_command('r.colors', map=output, rules='-')
88    for img, offset in zip(images, offsets):
89        print(img, offset)
90        copy_colors(p.stdin, img, offset)
91    p.stdin.close()
92    p.wait()
93
94    gscript.message(_("Done. Raster map <%s> created.") % output)
95
96    # write cmd history:
97    gscript.raster_history(output)
98
99if __name__ == "__main__":
100    options, flags = gscript.parser()
101    main()
102