r.grow.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/usr/bin/env python
  2. #
  3. ############################################################################
  4. #
  5. # MODULE: r.grow
  6. # AUTHOR(S): Glynn Clements
  7. # PURPOSE: Fast replacement for r.grow using r.grow.distance
  8. #
  9. # COPYRIGHT: (C) 2008 by Glynn Clements
  10. #
  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. #
  15. #############################################################################
  16. #%Module
  17. #% description: Generates a raster map layer with contiguous areas grown by one cell.
  18. #% keyword: raster
  19. #%end
  20. #%flag
  21. #% key: m
  22. #% description: Radius is in map units rather than cells
  23. #%end
  24. #%option G_OPT_R_INPUT
  25. #%end
  26. #%option G_OPT_R_OUTPUT
  27. #%end
  28. #%option
  29. #% key: radius
  30. #% type: double
  31. #% required: no
  32. #% multiple: no
  33. #% description: Radius of buffer in raster cells
  34. #% answer: 1.01
  35. #%end
  36. #%option
  37. #% key: metric
  38. #% type: string
  39. #% required: no
  40. #% multiple: no
  41. #% options: euclidean,maximum,manhattan
  42. #% description: Metric
  43. #% answer: euclidean
  44. #%end
  45. #%option
  46. #% key: old
  47. #% type: integer
  48. #% required: no
  49. #% multiple: no
  50. #% description: Value to write for input cells which are non-NULL (-1 => NULL)
  51. #%end
  52. #%option
  53. #% key: new
  54. #% type: integer
  55. #% required: no
  56. #% multiple: no
  57. #% description: Value to write for "grown" cells
  58. #%end
  59. import sys
  60. import os
  61. import atexit
  62. import math
  63. import grass.script as grass
  64. from grass.exceptions import CalledModuleError
  65. # what to do in case of user break:
  66. def cleanup():
  67. for map in [temp_dist, temp_val]:
  68. if map:
  69. grass.run_command('g.remove', flags = 'fb', quiet = True,
  70. type='rast', name = map)
  71. def main():
  72. global temp_dist, temp_val
  73. input = options['input']
  74. output = options['output']
  75. radius = float(options['radius'])
  76. metric = options['metric']
  77. old = options['old']
  78. new = options['new']
  79. mapunits = flags['m']
  80. tmp = str(os.getpid())
  81. temp_dist = "r.grow.tmp.%s.dist" % tmp
  82. if new == '':
  83. temp_val = "r.grow.tmp.%s.val" % tmp
  84. new = temp_val
  85. else:
  86. temp_val = None
  87. if old == '':
  88. old = input
  89. if not mapunits:
  90. kv = grass.region()
  91. scale = math.sqrt(float(kv['nsres']) * float(kv['ewres']))
  92. radius *= scale
  93. if metric == 'euclidean':
  94. metric = 'squared'
  95. radius = radius * radius
  96. #check if input file exists
  97. if not grass.find_file(input)['file']:
  98. grass.fatal(_("Raster map <%s> not found") % input)
  99. try:
  100. grass.run_command('r.grow.distance', input=input, metric=metric,
  101. distance=temp_dist, value=temp_val)
  102. except CalledModuleError:
  103. grass.fatal(_("Growing failed. Removing temporary maps."))
  104. grass.mapcalc(
  105. "$output = if(!isnull($input),$old,if($dist < $radius,$new,null()))",
  106. output = output, input = input, radius = radius,
  107. old = old, new = new, dist = temp_dist)
  108. grass.run_command('r.colors', map = output, raster = input)
  109. # write cmd history:
  110. grass.raster_history(output)
  111. if __name__ == "__main__":
  112. options, flags = grass.parser()
  113. atexit.register(cleanup)
  114. main()