r.shade.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env python3
  2. #
  3. ############################################################################
  4. #
  5. # MODULE: r.shade
  6. # AUTHOR(S): Hamish Bowman
  7. # Vaclav Petras <wenzeslaus gmail com>
  8. # Inspired by d.shade (formerly d.shadedmap)
  9. # PURPOSE: Uses r.his to drape a color raster over a shaded relief map
  10. # COPYRIGHT: (C) 2014 by Hamish Bowman, and the GRASS Development Team
  11. #
  12. # This program is free software under the GNU General Public
  13. # License (>=v2). Read the file COPYING that comes with GRASS
  14. # for details.
  15. #
  16. #############################################################################
  17. # %module
  18. # % description: Drapes a color raster over an shaded relief or aspect map.
  19. # % keyword: raster
  20. # % keyword: elevation
  21. # % keyword: relief
  22. # % keyword: hillshade
  23. # % keyword: visualization
  24. # %end
  25. # %option G_OPT_R_INPUT
  26. # % key: shade
  27. # % description: Name of shaded relief or aspect raster map
  28. # %end
  29. # %option G_OPT_R_INPUT
  30. # % key: color
  31. # % label: Name of raster to drape over relief raster map
  32. # % description: Typically, this raster is elevation or other colorful raster
  33. # %end
  34. # %option G_OPT_R_OUTPUT
  35. # % description: Name of shaded raster map
  36. # %end
  37. # %option
  38. # % key: brighten
  39. # % type: integer
  40. # % description: Percent to brighten
  41. # % options: -99-99
  42. # % answer: 0
  43. # %end
  44. # %option
  45. # % key: bgcolor
  46. # % type: string
  47. # % key_desc: name
  48. # % label: Color to use instead of NULL values
  49. # % description: Either a standard color name, R:G:B triplet, or "none"
  50. # % gisprompt: old,color_none,color
  51. # %end
  52. # %flag
  53. # % key: c
  54. # % description: Use colors from color tables for NULL values
  55. # %end
  56. # %rules
  57. # % exclusive: bgcolor, -c
  58. # %end
  59. # TODO: bgcolor is not using standard option because it has default white
  60. # using `answer:` will cause `default:` which is not the same as no default
  61. import os
  62. from grass.script import core as gcore
  63. from grass.script import raster as grast
  64. from grass.exceptions import CalledModuleError
  65. def remove(maps):
  66. """Remove raster maps"""
  67. gcore.run_command("g.remove", flags="f", quiet=True, type="rast", name=maps)
  68. def main():
  69. options, flags = gcore.parser()
  70. drape_map = options["color"]
  71. relief_map = options["shade"]
  72. brighten = int(options["brighten"])
  73. output_map = options["output"]
  74. bgcolor = options["bgcolor"]
  75. rhis_extra_args = {}
  76. if bgcolor:
  77. rhis_extra_args["bgcolor"] = bgcolor
  78. if flags["c"]:
  79. rhis_extra_args["flags"] = "c"
  80. to_remove = []
  81. try:
  82. unique_name = "tmp__rshade_%d" % os.getpid()
  83. tmp_base = "%s_drape" % unique_name
  84. tmp_r = tmp_base + ".r"
  85. tmp_g = tmp_base + ".g"
  86. tmp_b = tmp_base + ".b"
  87. if brighten:
  88. # steps taken from r.his manual page
  89. # how much they are similar with d.shade/d.his is unknown
  90. # perhaps even without brightness, there can be some differences
  91. # comparing to d.shade
  92. relief_map_tmp = "%s_relief" % unique_name
  93. # convert [-99, -99] to [0.01, 1.99]
  94. brighten = 1 + brighten / 100.0
  95. grast.mapcalc(
  96. "{n} = {c} * #{o}".format(n=relief_map_tmp, o=relief_map, c=brighten)
  97. )
  98. gcore.run_command("r.colors", map=relief_map_tmp, color="grey255")
  99. relief_map = relief_map_tmp
  100. to_remove.append(relief_map_tmp)
  101. gcore.run_command(
  102. "r.his",
  103. hue=drape_map,
  104. intensity=relief_map,
  105. red=tmp_r,
  106. green=tmp_g,
  107. blue=tmp_b,
  108. **rhis_extra_args,
  109. )
  110. to_remove.extend([tmp_r, tmp_g, tmp_b])
  111. gcore.run_command(
  112. "r.composite", red=tmp_r, green=tmp_g, blue=tmp_b, output=output_map
  113. )
  114. remove(to_remove) # who knows if finally is called when exit
  115. except CalledModuleError as error:
  116. remove(to_remove)
  117. # TODO: implement module name to CalledModuleError
  118. gcore.fatal(_("Module %s failed. Check the above error messages.") % error.cmd)
  119. if __name__ == "__main__":
  120. main()