1 //----------------------------------------------------------------------------
2 //
3 // License:  LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author:  David Burken
8 //
9 // Description: Class definition for ossimWavelength.
10 //
11 //----------------------------------------------------------------------------
12 
13 #include <ossim/support_data/ossimWavelength.h>
14 #include <ossim/base/ossimString.h>
15 #include <ossim/support_data/ossimEnviHeader.h>
16 #include <cmath>
17 
ossimWavelength()18 ossimWavelength::ossimWavelength()
19    : m_map()
20 {}
21 
ossimWavelength(const ossimWavelength & obj)22 ossimWavelength::ossimWavelength( const ossimWavelength& obj )
23    : m_map( obj.m_map )
24 {}
25 
operator =(const ossimWavelength & rhs)26 const ossimWavelength& ossimWavelength::operator=( const ossimWavelength& rhs )
27 {
28    if ( this != &rhs )
29    {
30       m_map = rhs.m_map;
31    }
32    return *this;
33 }
34 
~ossimWavelength()35 ossimWavelength::~ossimWavelength()
36 {
37 }
38 
getMap() const39 const ossimWavelength::WavelengthMap& ossimWavelength::getMap() const
40 {
41    return m_map;
42 }
43 
getMap()44 ossimWavelength::WavelengthMap& ossimWavelength::getMap()
45 {
46    return m_map;
47 }
48 
initialize(const ossimEnviHeader & hdr)49 bool ossimWavelength::initialize( const ossimEnviHeader& hdr )
50 {
51    //---
52    // Example envi wavelength format:
53    // wavelength = { 374.323608,  382.530487,  390.737427 }
54    //---
55    ossimString value;
56 
57    // Check the units...
58    ossimString key = "wavelength units";
59    if ( hdr.getValue( key, value ) )
60    {
61       if ( value.downcase() == "nanometers" )
62       {
63          // Check for wavelength key:
64          key = "wavelength";
65          if ( hdr.getValue( key, value ) )
66          {
67             if ( value.size() )
68             {
69                // Split into array.
70                value.trim( ossimString("{}") );
71                std::vector<ossimString> list;
72                value.split( list, ossimString(","), true );
73 
74                if ( list.size() )
75                {
76                   // Initialize the map:
77 
78                   std::vector<ossimString>::const_iterator i = list.begin();
79                   ossim_uint32 band = 0;
80                   ossim_float32 wavelength = 0.0;
81 
82                   while ( i != list.end() )
83                   {
84                      wavelength = (*i).toFloat64();
85                      m_map.insert( std::make_pair( wavelength, band ) );
86                      ++band;
87                      ++i;
88                   }
89                }
90             }
91          }
92       }
93    }
94 
95    return ( m_map.size() ? true : false);
96 
97 } // End: bool ossimWavelength::initialize(const ossimEnviHeader&)
98 
99 using namespace std;
findClosestIterator(const ossim_float64 & requestedWavelength,const ossim_float64 & thresholdFromCenter) const100 ossimWavelength::WavelengthMap::const_iterator ossimWavelength::findClosestIterator(
101    const ossim_float64& requestedWavelength,
102    const ossim_float64& thresholdFromCenter  ) const
103 {
104    WavelengthMap::const_iterator result = m_map.lower_bound( requestedWavelength );
105    if ( result != m_map.end() )
106    {
107       if ( result != m_map.begin() ) //  && (result->first > requestedWavelength) )
108       {
109          // Somewhere in the middle.
110          WavelengthMap::const_iterator lower = result;
111          --lower;
112 
113          ossim_float64 t = (requestedWavelength - lower->first) / (result->first -lower->first);
114          if ( t < 0.5 )
115          {
116             result = lower;
117          }
118       }
119    }
120    else
121    {
122       --result;
123    }
124 
125    if ( result != m_map.end() )
126    {
127       // Within threshold check.
128       if ( std::fabs( result->first - requestedWavelength) > thresholdFromCenter )
129       {
130          result = m_map.end();
131       }
132 
133    } // if ( result != m_map.end() )
134 
135    return result;
136 
137 } // End: WavelengthMap::const_iterator ossimWavelength::findClosestIterator
138 
findClosestIndex(const ossim_float64 & requestedWavelength,const ossim_float64 & thresholdFromCenter) const139 ossim_int32 ossimWavelength::findClosestIndex(
140    const ossim_float64& requestedWavelength, const ossim_float64& thresholdFromCenter  ) const
141 {
142    ossim_int32 result = -1;
143    WavelengthMap::const_iterator i =
144       findClosestIterator( requestedWavelength, thresholdFromCenter );
145    if ( i != m_map.end() )
146    {
147       result = (*i).second;
148    }
149    return result;
150 
151 } // End: ossim_int32 ossimWavelength::findClosestIndex(...
152 
getRgbBands(std::vector<ossim_uint32> & bands) const153 bool ossimWavelength::getRgbBands( std::vector<ossim_uint32>& bands ) const
154 {
155    bool result = false;
156 
157    if ( m_map.size() )
158    {
159       //---
160       // Attempt to find bands with closest rgb wavelengths.
161       // red:   620 - 750 nm
162       // green: 495 - 570 nm
163       // blue:  450 - 495 nm
164       //---
165       //const ossim_float32 RED_WAVELENGTH              = 439.978577; // 442.0;
166       //const ossim_float32 GREEN_WAVELENGTH            = 546.666504; // 546.0;
167       //const ossim_float32 BLUE_WAVELENGTH             = 636.941406; // 637.0;
168       const ossim_float32 RED_WAVELENGTH              = 685.0;
169       const ossim_float32 GREEN_WAVELENGTH            = 532.5;
170       const ossim_float32 BLUE_WAVELENGTH             = 472.5;
171       const ossim_float32 RED_THRESHOLD_FROM_CENTER   =  65.0;
172       const ossim_float32 GREEN_THRESHOLD_FROM_CENTER =  37.5;
173       const ossim_float32 BLUE_THRESHOLD_FROM_CENTER  =  22.5;
174 
175       WavelengthMap::const_iterator r =
176          findClosestIterator( RED_WAVELENGTH, RED_THRESHOLD_FROM_CENTER );
177       WavelengthMap::const_iterator g =
178          findClosestIterator( GREEN_WAVELENGTH, GREEN_THRESHOLD_FROM_CENTER );
179       WavelengthMap::const_iterator b =
180          findClosestIterator( BLUE_WAVELENGTH, BLUE_THRESHOLD_FROM_CENTER );
181 
182       if ( (r != m_map.end()) && (g != m_map.end()) && (b != m_map.end()) )
183       {
184          bands.resize(3);
185          bands[0] = (*r).second;
186          bands[1] = (*g).second;
187          bands[2] = (*b).second;
188          result = true;
189       }
190    }
191    return result;
192 
193 } // bool ossimWavelength::getRgbBands( std::vector<ossim_uint32>& ) const
194 
end() const195 ossimWavelength::WavelengthMap::const_iterator ossimWavelength::end() const
196 {
197    return m_map.end();
198 }
199 
end()200 ossimWavelength::WavelengthMap::iterator ossimWavelength::end()
201 {
202    return m_map.end();
203 }
204