raster.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. """!@package grass.script.raster
  2. @brief GRASS Python scripting module (raster functions)
  3. Raster related functions to be used in Python scripts.
  4. Usage:
  5. @code
  6. from grass.script import raster as grass
  7. grass.raster_history(map)
  8. ...
  9. @endcode
  10. (C) 2008-2011 by the GRASS Development Team
  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. @author Glynn Clements
  15. @author Martin Landa <landa.martin gmail.com>
  16. """
  17. import os
  18. import string
  19. import types
  20. import time
  21. from core import *
  22. from utils import float_or_dms, parse_key_val
  23. # add raster history
  24. def raster_history(map):
  25. """!Set the command history for a raster map to the command used to
  26. invoke the script (interface to `r.support').
  27. @param map map name
  28. @return True on success
  29. @return False on failure
  30. """
  31. current_mapset = gisenv()['MAPSET']
  32. if find_file(name = map)['mapset'] == current_mapset:
  33. run_command('r.support', map = map, history = os.environ['CMDLINE'])
  34. return True
  35. warning(_("Unable to write history for <%(map)s>. "
  36. "Raster map <%(map)s> not found in current mapset." % { 'map' : map, 'map' : map}))
  37. return False
  38. # run "r.info -gre ..." and parse output
  39. def raster_info(map):
  40. """!Return information about a raster map (interface to
  41. `r.info'). Example:
  42. \code
  43. >>> grass.raster_info('elevation')
  44. {'north': 228500.0, 'timestamp': '"none"', 'min': 55.578792572021499,
  45. 'datatype': 'FCELL', 'max': 156.32986450195301, 'ewres': 10.0,
  46. 'vertical_datum': '', 'west': 630000.0, 'units': '',
  47. 'title': 'South-West Wake county: Elevation NED 10m (elev_ned10m)',
  48. 'east': 645000.0, 'nsres': 10.0, 'south': 215000.0}
  49. \endcode
  50. @param map map name
  51. @return parsed raster info
  52. """
  53. def float_or_null(s):
  54. if s == 'NULL':
  55. return None
  56. else:
  57. return float(s)
  58. s = read_command('r.info', flags = 'gre', map = map)
  59. kv = parse_key_val(s)
  60. for k in ['min', 'max']:
  61. kv[k] = float_or_null(kv[k])
  62. for k in ['north', 'south', 'east', 'west']:
  63. kv[k] = float(kv[k])
  64. for k in ['nsres', 'ewres']:
  65. kv[k] = float_or_dms(kv[k])
  66. return kv
  67. # interface to r.mapcalc
  68. def mapcalc(exp, quiet = False, verbose = False, overwrite = False,
  69. seed = None, env = None, **kwargs):
  70. """!Interface to r.mapcalc.
  71. @param exp expression
  72. @param quiet True to run quietly (<tt>--q</tt>)
  73. @param verbose True to run verbosely (<tt>--v</tt>)
  74. @param overwrite True to enable overwriting the output (<tt>--o</tt>)
  75. @param seed an integer used to seed the random-number generator for the rand() function,
  76. or 'auto' to generate a random seed
  77. @param env dictionary of environment variables for child process
  78. @param kwargs
  79. """
  80. if seed == 'auto':
  81. seed = hash((os.getpid(), time.time())) % (2**32)
  82. t = string.Template(exp)
  83. e = t.substitute(**kwargs)
  84. if write_command('r.mapcalc', file = '-', stdin = e,
  85. env = env,
  86. seed = seed,
  87. quiet = quiet,
  88. verbose = verbose,
  89. overwrite = overwrite) != 0:
  90. fatal(_("An error occurred while running r.mapcalc"))
  91. def mapcalc_start(exp, quiet = False, verbose = False, overwrite = False,
  92. seed = None, env = None, **kwargs):
  93. """!Interface to r.mapcalc, doesn't wait for it to finish, returns Popen object.
  94. \code
  95. >>> expr1 = '"%s" = "%s" * 10' % (output, input)
  96. >>> expr2 = '...' # etc.
  97. >>> # launch the jobs:
  98. >>> p1 = grass.mapcalc_start(expr1)
  99. >>> p2 = grass.mapcalc_start(expr2) # etc.
  100. ...
  101. >>> # wait for them to finish:
  102. >>> p1.wait()
  103. >>> p2.wait() # etc.
  104. \endcode
  105. @param exp expression
  106. @param quiet True to run quietly (<tt>--q</tt>)
  107. @param verbose True to run verbosely (<tt>--v</tt>)
  108. @param overwrite True to enable overwriting the output (<tt>--o</tt>)
  109. @param seed an integer used to seed the random-number generator for the rand() function,
  110. or 'auto' to generate a random seed
  111. @param env dictionary of environment variables for child process
  112. @param kwargs
  113. @return Popen object
  114. """
  115. if seed == 'auto':
  116. seed = hash((os.getpid(), time.time())) % (2**32)
  117. t = string.Template(exp)
  118. e = t.substitute(**kwargs)
  119. p = feed_command('r.mapcalc', file = '-',
  120. env = env,
  121. seed = seed,
  122. quiet = quiet,
  123. verbose = verbose,
  124. overwrite = overwrite)
  125. p.stdin.write(e)
  126. p.stdin.close()
  127. return p
  128. # interface to r.what
  129. def raster_what(map, coord, env = None):
  130. """!TODO"""
  131. if type(map) in (types.StringType, types.UnicodeType):
  132. map_list = [map]
  133. else:
  134. map_list = map
  135. coord_list = list()
  136. if type(coord) is types.TupleType:
  137. coord_list.append('%f,%f' % (coord[0], coord[1]))
  138. else:
  139. for e, n in coord:
  140. coord_list.append('%f,%f' % (e, n))
  141. sep = '|'
  142. # separator '|' not included in command
  143. # because | is causing problems on Windows
  144. # change separator?
  145. ret = read_command('r.what',
  146. flags = 'rf',
  147. map = ','.join(map_list),
  148. coordinates = ','.join(coord_list),
  149. null = _("No data"),
  150. quiet = True,
  151. env = env)
  152. data = list()
  153. if not ret:
  154. return data
  155. labels = (_("value"), _("label"), _("color"))
  156. for item in ret.splitlines():
  157. line = item.split(sep)[3:]
  158. for i, map_name in enumerate(map_list):
  159. tmp_dict = {}
  160. tmp_dict[map_name] = {}
  161. for j in range(len(labels)):
  162. tmp_dict[map_name][labels[j]] = line[i*len(labels)+j]
  163. data.append(tmp_dict)
  164. return data