File: r.shade.py

package info (click to toggle)
grass 8.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 277,040 kB
  • sloc: ansic: 460,798; python: 227,732; cpp: 42,026; sh: 11,262; makefile: 7,007; xml: 3,637; sql: 968; lex: 520; javascript: 484; yacc: 450; asm: 387; perl: 157; sed: 25; objc: 6; ruby: 4
file content (134 lines) | stat: -rwxr-xr-x 4,156 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
#
############################################################################
#
# MODULE:        r.shade
# AUTHOR(S):     Hamish Bowman
#                Vaclav Petras <wenzeslaus gmail com>
#                Inspired by d.shade (formerly d.shadedmap)
# PURPOSE:       Uses r.his to drape a color raster over a shaded relief map
# COPYRIGHT:     (C) 2014 by Hamish Bowman, 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: Drapes a color raster over an shaded relief or aspect map.
# % keyword: raster
# % keyword: elevation
# % keyword: relief
# % keyword: hillshade
# % keyword: visualization
# %end
# %option G_OPT_R_INPUT
# % key: shade
# % description: Name of shaded relief or aspect raster map
# %end
# %option G_OPT_R_INPUT
# % key: color
# % label: Name of raster to drape over relief raster map
# % description: Typically, this raster is elevation or other colorful raster
# %end
# %option G_OPT_R_OUTPUT
# % description: Name of shaded raster map
# %end
# %option
# % key: brighten
# % type: integer
# % description: Percent to brighten
# % options: -99-99
# % answer: 0
# %end
# %option
# % key: bgcolor
# % type: string
# % key_desc: name
# % label: Color to use instead of NULL values
# % description: Either a standard color name, R:G:B triplet, or "none"
# % gisprompt: old,color_none,color
# %end
# %flag
# % key: c
# % description: Use colors from color tables for NULL values
# %end
# %rules
# % exclusive: bgcolor, -c
# %end

# TODO: bgcolor is not using standard option because it has default white
# using `answer:` will cause `default:` which is not the same as no default


import os
from grass.script import core as gcore
from grass.script import raster as grast
from grass.exceptions import CalledModuleError


def remove(maps):
    """Remove raster maps"""
    gcore.run_command("g.remove", flags="f", quiet=True, type="rast", name=maps)


def main():
    options, flags = gcore.parser()

    drape_map = options["color"]
    relief_map = options["shade"]
    brighten = int(options["brighten"])
    output_map = options["output"]
    bgcolor = options["bgcolor"]

    rhis_extra_args = {}
    if bgcolor:
        rhis_extra_args["bgcolor"] = bgcolor
    if flags["c"]:
        rhis_extra_args["flags"] = "c"

    to_remove = []
    try:
        unique_name = "tmp__rshade_%d" % os.getpid()
        tmp_base = "%s_drape" % unique_name
        tmp_r = tmp_base + ".r"
        tmp_g = tmp_base + ".g"
        tmp_b = tmp_base + ".b"

        if brighten:
            # steps taken from r.his manual page
            # how much they are similar with d.shade/d.his is unknown
            # perhaps even without brightness, there can be some differences
            # comparing to d.shade
            relief_map_tmp = "%s_relief" % unique_name
            # convert [-99, -99] to [0.01, 1.99]
            brighten = 1 + brighten / 100.0
            grast.mapcalc(
                "{n} = {c} * #{o}".format(n=relief_map_tmp, o=relief_map, c=brighten)
            )
            gcore.run_command("r.colors", map=relief_map_tmp, color="grey255")
            relief_map = relief_map_tmp
            to_remove.append(relief_map_tmp)
        gcore.run_command(
            "r.his",
            hue=drape_map,
            intensity=relief_map,
            red=tmp_r,
            green=tmp_g,
            blue=tmp_b,
            **rhis_extra_args,
        )
        to_remove.extend([tmp_r, tmp_g, tmp_b])
        gcore.run_command(
            "r.composite", red=tmp_r, green=tmp_g, blue=tmp_b, output=output_map
        )
        remove(to_remove)  # who knows if finally is called when exit
    except CalledModuleError as error:
        remove(to_remove)
        # TODO: implement module name to CalledModuleError
        gcore.fatal(_("Module %s failed. Check the above error messages.") % error.cmd)


if __name__ == "__main__":
    main()