i.spectral.py 5.6 KB

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