i.spectral.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #!/usr/bin/env python
  2. ############################################################################
  3. #
  4. # MODULE: i.spectral
  5. # AUTHOR(S): Markus Neteler, 18. August 1998
  6. # Converted to Python by Glynn Clements
  7. # PURPOSE: displays spectral response at user specified locations in group or images
  8. # COPYRIGHT: (C) 1999 by the GRASS Development Team
  9. #
  10. # This program is free software under the GNU General Public
  11. # License (>=v2). Read the file COPYING that comes with GRASS
  12. # for details.
  13. #
  14. #############################################################################
  15. # written by Markus Neteler 18. August 1998
  16. # neteler geog.uni-hannover.de
  17. #
  18. # bugfix: 25. Nov.98/20. Jan. 1999
  19. # 3 March 2006: Added multiple images and group support by Francesco Pirotti - CIRGEO
  20. # this script needs gnuplot
  21. #%Module
  22. #% description: Displays spectral response at user specified locations in group or images.
  23. #% keywords: imagery
  24. #% keywords: raster
  25. #% keywords: multispectral
  26. #%End
  27. #%option G_OPT_I_GROUP
  28. #% required : no
  29. #%end
  30. #%option G_OPT_R_INPUTS
  31. #% key: raster
  32. #% required : no
  33. #%end
  34. #%option G_OPT_F_OUTPUT
  35. #% key: output
  36. #% description: Name for output PNG image
  37. #% required : no
  38. #%end
  39. #%option G_OPT_M_COORDS
  40. #% multiple: yes
  41. #% required: yes
  42. ###
  43. #%end
  44. #%flag
  45. #%key: c
  46. #%description: Label with coordinates instead of numbering
  47. #%end
  48. #%flag
  49. #%key: g
  50. #%description: Use gnuplot for display
  51. #%end
  52. import sys
  53. import os
  54. import atexit
  55. import glob
  56. from grass.script import core as grass
  57. def cleanup():
  58. grass.try_remove('spectrum.gnuplot')
  59. for name in glob.glob('data_[0-9]*'):
  60. if name[5:].isdigit():
  61. grass.try_remove(name)
  62. grass.try_remove('data_x')
  63. for name in glob.glob('data_y_[0-9]*'):
  64. if name[7:].isdigit():
  65. grass.try_remove(name)
  66. def draw_gnuplot(what, xlabels, output, label):
  67. xrange = 0
  68. for i, row in enumerate(what):
  69. outfile = 'data_%d' % i
  70. outf = file(outfile, 'w')
  71. xrange = max(xrange, len(row) - 2)
  72. for j, val in enumerate(row[3:]):
  73. outf.write("%d %s\n" % (j + 1, val))
  74. outf.close()
  75. # build gnuplot script
  76. lines = []
  77. if output:
  78. lines += [
  79. "set term png large",
  80. "set output '%s'" % output
  81. ]
  82. lines += [
  83. "set xtics (%s)" % xlabels,
  84. "set grid",
  85. "set title 'Spectral signatures'",
  86. "set xrange [0:%d]" % xrange,
  87. "set noclabel",
  88. "set xlabel 'Bands'",
  89. "set ylabel 'DN Value'",
  90. "set style data lines"
  91. ]
  92. cmd = []
  93. for i, row in enumerate(what):
  94. if not label:
  95. title = str(i + 1)
  96. else:
  97. title = str(tuple(row[0:2]))
  98. cmd.append("'data_%d' title '%s'" % (i, title))
  99. cmd = ','.join(cmd)
  100. cmd = ' '.join(['plot', cmd, "with linespoints pt 779"])
  101. lines.append(cmd)
  102. plotfile = 'spectrum.gnuplot'
  103. plotf = file(plotfile, 'w')
  104. for line in lines:
  105. plotf.write(line + '\n')
  106. plotf.close()
  107. if output:
  108. grass.call(['gnuplot', plotfile])
  109. else:
  110. grass.call(['gnuplot', '-persist', plotfile])
  111. def draw_linegraph(what):
  112. yfiles = []
  113. xfile = 'data_x'
  114. xf = file(xfile, 'w')
  115. for j, val in enumerate(what[0][3:]):
  116. xf.write("%d\n" % (j + 1))
  117. xf.close()
  118. for i, row in enumerate(what):
  119. yfile = 'data_y_%d' % i
  120. yf = file(yfile, 'w')
  121. for j, val in enumerate(row[3:]):
  122. yf.write("%s\n" % val)
  123. yf.close()
  124. yfiles.append(yfile)
  125. sienna = '#%02x%02x%02x' % (160, 82, 45)
  126. coral = '#%02x%02x%02x' % (255, 127, 80)
  127. gp_colors = ['red', 'green', 'blue', 'magenta', 'cyan', sienna, 'orange', coral]
  128. colors = gp_colors
  129. while len(what) > len(colors):
  130. colors += gp_colors
  131. colors = colors[0:len(what)]
  132. grass.run_command('d.linegraph', x_file = xfile, y_file = yfiles,
  133. y_color = colors, title = 'Spectral signatures',
  134. x_title = 'Bands', y_title = 'DN Value')
  135. def main():
  136. group = options['group']
  137. raster = options['raster']
  138. output = options['output']
  139. coords = options['coordinates']
  140. label = flags['c']
  141. gnuplot = flags['g']
  142. if not group and not raster:
  143. grass.fatal(_("Either group= or raster= is required"))
  144. if group and raster:
  145. grass.fatal(_("group= and raster= are mutually exclusive"))
  146. #check if present
  147. if gnuplot and not grass.find_program('gnuplot', ['-V']):
  148. grass.fatal(_("gnuplot required, please install first"))
  149. tmp1 = grass.tempfile()
  150. tmp2 = grass.tempfile()
  151. # get y-data for gnuplot-data file
  152. # get data from group files and set the x-axis labels
  153. if group:
  154. # ## PARSES THE GROUP FILES - gets rid of ugly header info from group list output
  155. s = grass.read_command('i.group', flags='g', group = group, quiet = True)
  156. rastermaps = s.splitlines()
  157. else:
  158. # ## get data from list of files and set the x-axis labels
  159. rastermaps = raster.split(',')
  160. xlabels = ["'%s' %d" % (n, i + 1) for i, n in enumerate(rastermaps)]
  161. xlabels = ','.join(xlabels)
  162. numbands = len(rastermaps)
  163. what = []
  164. s = grass.read_command('r.what', input = rastermaps, coordinates = coords, quiet = True)
  165. for l in s.splitlines():
  166. f = l.split('|')
  167. for i, v in enumerate(f):
  168. if v in ['', '*']:
  169. f[i] = 0
  170. else:
  171. f[i] = float(v)
  172. what.append(f)
  173. # build data files
  174. if gnuplot:
  175. draw_gnuplot(what, xlabels, output, label)
  176. else:
  177. draw_linegraph(what)
  178. if __name__ == "__main__":
  179. options, flags = grass.parser()
  180. atexit.register(cleanup)
  181. main()