raster.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. ::
  6. from grass.script import raster as grass
  7. grass.raster_history(map)
  8. (C) 2008-2011 by the GRASS Development Team
  9. This program is free software under the GNU General Public
  10. License (>=v2). Read the file COPYING that comes with GRASS
  11. for details.
  12. .. sectionauthor:: Glynn Clements
  13. .. sectionauthor:: Martin Landa <landa.martin gmail.com>
  14. """
  15. import os
  16. import string
  17. import types
  18. import time
  19. from core import *
  20. from utils import float_or_dms, parse_key_val
  21. def raster_history(map):
  22. """Set the command history for a raster map to the command used to
  23. invoke the script (interface to `r.support').
  24. :param str map: map name
  25. :return: True on success
  26. :return: False on failure
  27. """
  28. current_mapset = gisenv()['MAPSET']
  29. if find_file(name=map)['mapset'] == current_mapset:
  30. run_command('r.support', map=map, history=os.environ['CMDLINE'])
  31. return True
  32. warning(_("Unable to write history for <%(map)s>. "
  33. "Raster map <%(map)s> not found in current mapset." % { 'map': map, 'map': map}))
  34. return False
  35. def raster_info(map):
  36. """Return information about a raster map (interface to
  37. `r.info -gre'). Example:
  38. >>> raster_info('elevation') # doctest: +ELLIPSIS
  39. {'creator': '"helena"', 'cols': '1500' ... 'south': 215000.0}
  40. :param str map: map name
  41. :return: parsed raster info
  42. """
  43. def float_or_null(s):
  44. if s == 'NULL':
  45. return None
  46. else:
  47. return float(s)
  48. s = read_command('r.info', flags='gre', map=map)
  49. kv = parse_key_val(s)
  50. for k in ['min', 'max']:
  51. kv[k] = float_or_null(kv[k])
  52. for k in ['north', 'south', 'east', 'west']:
  53. kv[k] = float(kv[k])
  54. for k in ['nsres', 'ewres']:
  55. kv[k] = float_or_dms(kv[k])
  56. return kv
  57. def mapcalc(exp, quiet=False, verbose=False, overwrite=False,
  58. seed=None, env=None, **kwargs):
  59. """Interface to r.mapcalc.
  60. :param str exp: expression
  61. :param bool quiet: True to run quietly (<tt>--q</tt>)
  62. :param bool verbose: True to run verbosely (<tt>--v</tt>)
  63. :param bool overwrite: True to enable overwriting the output (<tt>--o</tt>)
  64. :param seed: an integer used to seed the random-number generator for the
  65. rand() function, or 'auto' to generate a random seed
  66. :param dict env: dictionary of environment variables for child process
  67. :param kwargs:
  68. """
  69. if seed == 'auto':
  70. seed = hash((os.getpid(), time.time())) % (2**32)
  71. t = string.Template(exp)
  72. e = t.substitute(**kwargs)
  73. if write_command('r.mapcalc', file='-', stdin=e, env=env, seed=seed,
  74. quiet=quiet, verbose=verbose, overwrite=overwrite) != 0:
  75. fatal(_("An error occurred while running r.mapcalc"))
  76. def mapcalc_start(exp, quiet=False, verbose=False, overwrite=False,
  77. seed=None, env=None, **kwargs):
  78. """Interface to r.mapcalc, doesn't wait for it to finish, returns Popen object.
  79. >>> output = 'newele'
  80. >>> input = 'elevation'
  81. >>> expr1 = '"%s" = "%s" * 10' % (output, input)
  82. >>> expr2 = '...' # etc.
  83. >>> # launch the jobs:
  84. >>> p1 = mapcalc_start(expr1)
  85. >>> p2 = mapcalc_start(expr2)
  86. ...
  87. >>> # wait for them to finish:
  88. >>> p1.wait()
  89. 0
  90. >>> p2.wait()
  91. 1
  92. >>> run_command('g.remove', rast=output)
  93. :param str exp: expression
  94. :param bool quiet: True to run quietly (<tt>--q</tt>)
  95. :param bool verbose: True to run verbosely (<tt>--v</tt>)
  96. :param bool overwrite: True to enable overwriting the output (<tt>--o</tt>)
  97. :param seed: an integer used to seed the random-number generator for the
  98. rand() function, or 'auto' to generate a random seed
  99. :param dict env: dictionary of environment variables for child process
  100. :param kwargs:
  101. :return: Popen object
  102. """
  103. if seed == 'auto':
  104. seed = hash((os.getpid(), time.time())) % (2**32)
  105. t = string.Template(exp)
  106. e = t.substitute(**kwargs)
  107. p = feed_command('r.mapcalc', file='-', env=env, seed=seed,
  108. quiet=quiet, verbose=verbose, overwrite=overwrite)
  109. p.stdin.write(e)
  110. p.stdin.close()
  111. return p
  112. def raster_what(map, coord, env=None):
  113. """Interface to r.what
  114. >>> raster_what('elevation', [[640000, 228000]])
  115. [{'elevation': {'color': '255:214:000', 'label': '', 'value': '102.479'}}]
  116. :param str map: the map name
  117. :param list coord: a list of list containing all the point that you want
  118. query
  119. :param env:
  120. """
  121. if type(map) in (types.StringType, types.UnicodeType):
  122. map_list = [map]
  123. else:
  124. map_list = map
  125. coord_list = list()
  126. if type(coord) is types.TupleType:
  127. coord_list.append('%f,%f' % (coord[0], coord[1]))
  128. else:
  129. for e, n in coord:
  130. coord_list.append('%f,%f' % (e, n))
  131. sep = '|'
  132. # separator '|' not included in command
  133. # because | is causing problems on Windows
  134. # change separator?
  135. ret = read_command('r.what',
  136. flags='rf',
  137. map=','.join(map_list),
  138. coordinates=','.join(coord_list),
  139. null=_("No data"),
  140. quiet=True,
  141. env=env)
  142. data = list()
  143. if not ret:
  144. return data
  145. labels = (_("value"), _("label"), _("color"))
  146. for item in ret.splitlines():
  147. line = item.split(sep)[3:]
  148. for i, map_name in enumerate(map_list):
  149. tmp_dict = {}
  150. tmp_dict[map_name] = {}
  151. for j in range(len(labels)):
  152. tmp_dict[map_name][labels[j]] = line[i*len(labels)+j]
  153. data.append(tmp_dict)
  154. return data