#!/usr/bin/env python3 # ############################################################################ # # MODULE: r.shade # AUTHOR(S): Hamish Bowman # Vaclav Petras # 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()