r.shaded.relief.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/usr/bin/env python
  2. ############################################################################
  3. #
  4. # MODULE: r.shaded.relief
  5. # AUTHOR(S): CERL
  6. # parameters standardized: Markus Neteler, 2008
  7. # updates: Michael Barton, 2004
  8. # updates: Gordon Keith, 2003
  9. # updates: Andreas Lange, 2001
  10. # updates: David Finlayson, 2001
  11. # updates: Markus Neteler, 2001, 1999
  12. # Converted to Python by Glynn Clements
  13. # PURPOSE: Creates shaded relief map from raster elevation map (DEM)
  14. # COPYRIGHT: (C) 1999 - 2008, 2010 by the GRASS Development Team
  15. #
  16. # This program is free software under the GNU General Public
  17. # License (>=v2). Read the file COPYING that comes with GRASS
  18. # for details.
  19. #
  20. #############################################################################
  21. #
  22. # July 2007 - allow input from other mapsets (Brad Douglas)
  23. #
  24. # May 2005 - fixed wrong units parameter (Markus Neteler)
  25. #
  26. # September 2004 - Added z exaggeration control (Michael Barton)
  27. # April 2004 - updated for GRASS 5.7 by Michael Barton
  28. #
  29. # 9/2004 Adds scale factor input (as per documentation); units set scale only if specified for lat/long regions
  30. # Also, adds option of controlling z-exaggeration.
  31. #
  32. # 6/2003 fixes for Lat/Long Gordon Keith <gordon.keith@csiro.au>
  33. # If n is a number then the ewres and nsres are mulitplied by that scale
  34. # to calculate the shading.
  35. # If n is the letter M (either case) the number of metres is degree of
  36. # latitude is used as the scale.
  37. # If n is the letter f then the number of feet in a degree is used.
  38. # It scales latitude and longitude equally, so it's only approximately
  39. # right, but for shading its close enough. It makes the difference
  40. # between an unusable and usable shade.
  41. #
  42. # 10/2001 fix for testing for dashes in raster file name
  43. # by Andreas Lange <andreas.lange@rhein-main.de>
  44. # 10/2001 added parser support - Markus Neteler
  45. # 9/2001 fix to keep NULLs as is (was value 22 before) - Markus Neteler
  46. # 1/2001 fix for NULL by David Finlayson <david_finlayson@yahoo.com>
  47. # 11/99 updated $ewres to ewres() and $nsres to nsres()
  48. # updated number to FP in r.mapcalc statement Markus Neteler
  49. #% Module
  50. #% description: Creates shaded relief map from an elevation map (DEM).
  51. #% keywords: raster
  52. #% End
  53. #% option
  54. #% key: input
  55. #% type: string
  56. #% gisprompt: old,cell,raster
  57. #% description: Name of input elevation map
  58. #% required : yes
  59. #% end
  60. #% option
  61. #% key: output
  62. #% type: string
  63. #% gisprompt: new,cell,raster
  64. #% description: Name for output shaded relief map
  65. #% required : yes
  66. #% end
  67. #% option
  68. #% key: altitude
  69. #% type: double
  70. #% description: Altitude of the sun in degrees above the horizon
  71. #% required : no
  72. #% options : 0-90
  73. #% answer: 30
  74. #% end
  75. #% option
  76. #% key: azimuth
  77. #% type: double
  78. #% description: Azimuth of the sun in degrees to the east of north
  79. #% required : no
  80. #% options : 0-360
  81. #% answer: 270
  82. #% end
  83. #% option
  84. #% key: zmult
  85. #% type: double
  86. #% description: Factor for exaggerating relief
  87. #% required : no
  88. #% answer: 1
  89. #% end
  90. #% option
  91. #% key: scale
  92. #% type: double
  93. #% description: Scale factor for converting horizontal units to elevation units
  94. #% required : no
  95. #% answer: 1
  96. #% guisection: Scaling
  97. #% end
  98. #% option
  99. #% key: units
  100. #% type: string
  101. #% description: Set scaling factor (applies to lat./long. locations only, none: scale=1)
  102. #% required : no
  103. #% options: none,meters,feet
  104. #% answer: none
  105. #% guisection: Scaling
  106. #% end
  107. import sys
  108. import os
  109. import string
  110. import grass.script as grass
  111. def main():
  112. input = options['input']
  113. output = options['output']
  114. altitude = options['altitude']
  115. azimuth = options['azimuth']
  116. zmult = options['zmult']
  117. scale = float(options['scale'])
  118. units = options['units']
  119. verbose_level = os.getenv('GRASS_VERBOSE')
  120. if verbose_level is None:
  121. verbose_level = 2
  122. if not grass.find_file(input)['file']:
  123. grass.fatal(_("Raster map <%s> not found") % input)
  124. if input == output:
  125. grass.fatal(_("Input elevation map and output relief map must have different names"))
  126. # LatLong locations only:
  127. if units == 'meters':
  128. # scale=111120
  129. scale *= 1852 * 60
  130. # LatLong locations only:
  131. if units == 'feet':
  132. # scale=364567.2
  133. scale *= 6076.12 * 60
  134. #correct azimuth to East (GRASS convention):
  135. # this seems to be backwards, but in fact it works so leave it.
  136. az = float(azimuth) - 90
  137. t = string.Template(
  138. r'''eval( \
  139. x=($zmult*$input[-1,-1] + 2*$zmult*$input[0,-1] + $zmult*$input[1,-1] - \
  140. $zmult*$input[-1,1] - 2*$zmult*$input[0,1] - $zmult*$input[1,1])/(8.*ewres()*$scale), \
  141. y=($zmult*$input[-1,-1] + 2*$zmult*$input[-1,0] + $zmult*$input[-1,1] - \
  142. $zmult*$input[1,-1] - 2*$zmult*$input[1,0] - $zmult*$input[1,1])/(8.*nsres()*$scale), \
  143. slope=90.-atan(sqrt(x*x + y*y)), \
  144. a=round(atan(x,y)), \
  145. a=if(isnull(a),1,a), \
  146. aspect=if(x!=0||y!=0,if(a,a,360.)), \
  147. cang = sin($altitude)*sin(slope) + cos($altitude)*cos(slope) * cos($az-aspect) \
  148. )
  149. $output = if(isnull(cang), null(), 100.*cang)''')
  150. expr = t.substitute(altitude = altitude, az = az, input = input, output = output, scale = scale, zmult = zmult)
  151. p = grass.feed_command('r.mapcalc')
  152. p.stdin.write(expr)
  153. p.stdin.close()
  154. if p.wait() != 0:
  155. grass.fatal(_("In calculation, script aborted."))
  156. if verbose_level < 3:
  157. grass.run_command('r.colors', map = output, color = 'grey', quiet = True)
  158. else:
  159. grass.run_command('r.colors', map = output, color = 'grey')
  160. # record metadata
  161. grass.run_command('r.support', map = output, title = 'Shaded relief of "%s"' % input, history = '')
  162. grass.run_command('r.support', map = output, history = "r.shaded.relief settings:")
  163. t = string.Template("altitude=$altitude azimuth=$azimuth zmult=$zmult scale=$scale")
  164. parms = dict(altitude = altitude, azimuth = azimuth, zmult = zmult, scale = options['scale'])
  165. grass.run_command('r.support', map = output, history = t.substitute(parms))
  166. if units:
  167. grass.run_command('r.support', map = output, history = " units=%s (adjusted scale=%s)" % (units, scale))
  168. # write cmd history:
  169. grass.raster_history(output)
  170. if __name__ == "__main__":
  171. options, flags = grass.parser()
  172. main()