i.spectral.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 atexit
  63. import glob
  64. import grass
  65. def cleanup():
  66. grass.try_remove('spectrum.gnuplot')
  67. for name in glob.glob('data_[0-9]*'):
  68. if name[5:].isdigit():
  69. grass.try_remove(name)
  70. def main():
  71. group = options['group']
  72. raster = options['raster']
  73. output = options['output']
  74. coords = options['coords']
  75. label = flags['c']
  76. if not group and not raster:
  77. grass.fatal("Either group= or raster= is required")
  78. if group and raster:
  79. grass.fatal("group= and raster= are mutually exclusive")
  80. #check if present
  81. if not grass.find_program('gnuplot', ['-V']):
  82. grass.fatal("gnuplot required, please install first")
  83. tmp1 = grass.tempfile()
  84. tmp2 = grass.tempfile()
  85. # get y-data for gnuplot-data file
  86. # get data from group files and set the x-axis labels
  87. if group:
  88. # ## PARSES THE GROUP FILES - gets rid of ugly header info from group list output
  89. maps = []
  90. s = grass.read_command('i.group', flags='l', group = group, quiet = True)
  91. active = False
  92. for l in s.splitlines():
  93. if l == '-------------':
  94. active = not active
  95. continue
  96. if not active:
  97. continue
  98. f = l.replace(' in ','@').split()
  99. maps += f
  100. rastermaps = maps
  101. else:
  102. # ## get data from list of files and set the x-axis labels
  103. rastermaps = raster.split(',')
  104. xlabels = ["'%s' %d" % (n, i) for i, n in enumerate(rastermaps)]
  105. xlabels = ','.join(xlabels)
  106. numbands = len(rastermaps)
  107. what = []
  108. s = grass.read_command('r.what', input = rastermaps, east_north = coords, quiet = True)
  109. for l in s.splitlines():
  110. f = l.split('|')
  111. for i, v in enumerate(f):
  112. if v in ['', '*']:
  113. f[i] = 0
  114. else:
  115. f[i] = float(v)
  116. what.append(f)
  117. numclicks = len(what)
  118. start = 0
  119. num = numbands
  120. # build data files
  121. for i, row in enumerate(what):
  122. outfile = 'data_%d' % i
  123. outf = file(outfile, 'w')
  124. for j, val in enumerate(row[3:]):
  125. outf.write("%s %s\n" % (j, val))
  126. outf.close()
  127. xrange = numbands + 1
  128. # build gnuplot script
  129. lines = []
  130. if output:
  131. lines += [
  132. "set term png large",
  133. "set output '%s'" % output
  134. ]
  135. lines += [
  136. "set xtics (%s)" % xlabels,
  137. "set grid",
  138. "set title 'Spectral signatures'",
  139. "set xrange [0:%s]" % xrange,
  140. "set noclabel",
  141. "set xlabel 'Bands'",
  142. "set ylabel 'DN Value'",
  143. "set data style lines"
  144. ]
  145. cmd = []
  146. for i, row in enumerate(what):
  147. if not label:
  148. title = str(i)
  149. else:
  150. title = str(tuple(row[0:2]))
  151. cmd.append("'data_%d' title '%s'" % (i, title))
  152. cmd = ','.join(cmd)
  153. cmd = ' '.join(['plot', cmd, "with linespoints pt 779"])
  154. lines.append(cmd)
  155. plotfile = 'spectrum.gnuplot'
  156. plotf = file(plotfile, 'w')
  157. for line in lines:
  158. plotf.write(line + '\n')
  159. plotf.close()
  160. if output:
  161. grass.call(['gnuplot', plotfile])
  162. else:
  163. grass.call(['gnuplot', '-persist', plotfile])
  164. if __name__ == "__main__":
  165. options, flags = grass.parser()
  166. atexit.register(cleanup)
  167. main()