i.spectral.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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, raster, multispectral
  24. #%End
  25. #%option
  26. #% key: group
  27. #% type: string
  28. #% gisprompt: old,group
  29. #% description: group input
  30. #% required : no
  31. #%end
  32. #%option
  33. #% key: raster
  34. #% type: string
  35. #% gisprompt: old,cell,raster
  36. #% description: raster input maps
  37. #% multiple : yes
  38. #% required : no
  39. #%end
  40. #%option
  41. #% key: output
  42. #% type: string
  43. #% gisprompt: new_file,file,PNG
  44. #% description: write output to PNG image
  45. #% multiple : no
  46. #% required : no
  47. #%end
  48. #%option
  49. #% key: coords
  50. #% type: double
  51. #% key_desc: east,north
  52. #% description: coordinates
  53. #% multiple : yes
  54. #% required : yes
  55. #%end
  56. #%flag
  57. #%key: c
  58. #%description: label with coordinates instead of numbering
  59. #%end
  60. import sys
  61. import os
  62. import subprocess
  63. import atexit
  64. import glob
  65. import grass
  66. def cleanup():
  67. grass.try_remove('spectrum.gnuplot')
  68. for name in glob.glob('data_[0-9]*'):
  69. if name[5:].isdigit():
  70. grass.try_remove(name)
  71. def main():
  72. group = options['group']
  73. raster = options['raster']
  74. output = options['output']
  75. coords = options['coords']
  76. label = flags['c']
  77. if not group and not raster:
  78. grass.fatal("Either group= or raster= is required")
  79. if group and raster:
  80. grass.fatal("group= and raster= are mutually exclusive")
  81. #check if present
  82. if not grass.find_program('gnuplot', ['-V']):
  83. grass.fatal("gnuplot required, please install first")
  84. tmp1 = grass.tempfile()
  85. tmp2 = grass.tempfile()
  86. # get y-data for gnuplot-data file
  87. # get data from group files and set the x-axis labels
  88. if group:
  89. # ## PARSES THE GROUP FILES - gets rid of ugly header info from group list output
  90. maps = []
  91. s = grass.read_command('i.group', flags='l', group = group, quiet = True)
  92. active = False
  93. for l in s.splitlines():
  94. if l == '-------------':
  95. active = not active
  96. continue
  97. if not active:
  98. continue
  99. f = l.replace(' in ','@').split()
  100. maps += f
  101. rastermaps = maps
  102. else:
  103. # ## get data from list of files and set the x-axis labels
  104. rastermaps = raster.split(',')
  105. xlabels = ["'%s' %d" % (n, i) for i, n in enumerate(rastermaps)]
  106. xlabels = ','.join(xlabels)
  107. numbands = len(rastermaps)
  108. what = []
  109. s = grass.read_command('r.what', input = rastermaps, east_north = coords, quiet = True)
  110. for l in s.splitlines():
  111. f = l.split('|')
  112. for i, v in enumerate(f):
  113. if v in ['', '*']:
  114. f[i] = 0
  115. else:
  116. f[i] = float(v)
  117. what.append(f)
  118. numclicks = len(what)
  119. start = 0
  120. num = numbands
  121. # build data files
  122. for i, row in enumerate(what):
  123. outfile = 'data_%d' % i
  124. outf = file(outfile, 'w')
  125. for j, val in enumerate(row[3:]):
  126. outf.write("%s %s\n" % (j, val))
  127. outf.close()
  128. xrange = numbands + 1
  129. # build gnuplot script
  130. lines = []
  131. if output:
  132. lines += [
  133. "set term png large",
  134. "set output '%s'" % output
  135. ]
  136. lines += [
  137. "set xtics (%s)" % xlabels,
  138. "set grid",
  139. "set title 'Spectral signatures'",
  140. "set xrange [0:%s]" % xrange,
  141. "set noclabel",
  142. "set xlabel 'Bands'",
  143. "set ylabel 'DN Value'",
  144. "set data style lines"
  145. ]
  146. cmd = []
  147. for i, row in enumerate(what):
  148. if not label:
  149. title = str(i)
  150. else:
  151. title = str(tuple(row[0:2]))
  152. cmd.append("'data_%d' title '%s'" % (i, title))
  153. cmd = ','.join(cmd)
  154. cmd = ' '.join(['plot', cmd, "with linespoints pt 779"])
  155. lines.append(cmd)
  156. plotfile = 'spectrum.gnuplot'
  157. plotf = file(plotfile, 'w')
  158. for line in lines:
  159. plotf.write(line + '\n')
  160. plotf.close()
  161. if output:
  162. subprocess.call(['gnuplot', plotfile])
  163. else:
  164. subprocess.call(['gnuplot', '-persist', plotfile])
  165. if __name__ == "__main__":
  166. options, flags = grass.parser()
  167. atexit.register(cleanup)
  168. main()