raster.py 6.3 KB

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