OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimBandSeparateHandler.cpp
Go to the documentation of this file.
1 //*************************************************************************************************
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: Oscar Kramer
8 //
9 // Description:
10 //
11 // Image handler used when the multi-band image has each band represented by a different disk file.
12 // This is the case for some Ikonos imagery.
13 //
14 //*************************************************************************************************
15 // $Id: ossimBandSeparateHandler.cpp 2644 2011-05-26 15:20:11Z oscar.kramer $
16 
21 #include <ossim/base/ossimNotify.h>
25 #include <algorithm>
26 
27 RTTI_DEF1(ossimBandSeparateHandler, "ossimBandSeparateHandler", ossimImageHandler)
28 
29 //*************************************************************************************************
31 //*************************************************************************************************
33 { }
34 
35 //*************************************************************************************************
37 //*************************************************************************************************
39 {
40  close();
41 }
42 
43 //*************************************************************************************************
44 // Opens multiple band-files based on info in metadata file.
45 //*************************************************************************************************
47 {
48  if (isOpen())
49  close();
50 
51  // Fetch the list of band filenames:
52  vector<ossimFilename> file_names;
53  getBandFileNames(file_names);
54 
55  // There should be a list of filenames populated:
56  if (file_names.size() == 0)
57  return false;
58 
61  for (ossim_uint32 band=0; band<file_names.size(); ++band)
62  {
63  // Open input band file:
64  handler = ossimImageHandlerRegistry::instance()->open(file_names[band], true, false);
65  if (!handler.valid())
66  {
67  ossimNotify(ossimNotifyLevel_WARN)<<"ossimBandSeparateHandler::open() -- "
68  "Expected to find band file at <"<<file_names[band]<<"> but could not open file."
69  " Image not opened."<<endl;
70  close();
71  return false;
72  }
73 
74  // Add this band file to the merge source:
75  m_bandFiles.push_back(handler);
76  m_mergeSource->connectMyInputTo(band, handler.get());
77  }
78 
79  completeOpen();
80  return true;
81 }
82 
83 //*************************************************************************************************
86 //*************************************************************************************************
88 {
89  vector<ossimRefPtr<ossimImageHandler> >::iterator iter = m_bandFiles.begin();
90  while (iter != m_bandFiles.end())
91  {
92  (*iter)->close();
93  *iter = 0;
94  ++iter;
95  }
96  m_bandFiles.clear();
97  m_mergeSource = 0;
98 }
99 
100 //*************************************************************************************************
103 //*************************************************************************************************
105 {
106  if (m_bandFiles.size() > 0)
107  return true;
108 
109  return false;
110 }
111 
112 //*************************************************************************************************
114 //*************************************************************************************************
116  ossim_uint32 resLevel)
117 {
118  // First verify that there are band-files available:
119  if ((m_bandFiles.size() == 0) || !m_mergeSource.valid())
121 
122  // Check if res level represents data in the overview:
123  if (theOverview.valid() && (resLevel > 0))
124  return theOverview->getTile(tile_rect, resLevel);
125 
126  // Just pass getTile call on to contained bandMergeSource:
127  return m_mergeSource->getTile(tile_rect, resLevel);
128 }
129 
130 //*************************************************************************************************
134 //*************************************************************************************************
136 {
137  if ((m_bandFiles.size() == 0))
138  return 0;
139 
140  // Using simple decimation by powers of 2:
141  ossim_uint32 numlines = m_bandFiles[0]->getNumberOfLines() >> resLevel;
142  return numlines;
143 }
144 
145 //*************************************************************************************************
149 //*************************************************************************************************
151 {
152  if ((m_bandFiles.size() == 0))
153  return 0;
154 
155  // Using simple decimation by powers of 2:
156  ossim_uint32 numsamps = m_bandFiles[0]->getNumberOfSamples() >> resLevel;
157  return numsamps;
158 }
159 
160 //*************************************************************************************************
163 //*************************************************************************************************
164 bool ossimBandSeparateHandler::saveState(ossimKeywordlist& kwl, const char* prefix) const
165 {
166  return ossimImageHandler::saveState(kwl, prefix);
167 }
168 
169 //*************************************************************************************************
172 //*************************************************************************************************
173 bool ossimBandSeparateHandler::loadState(const ossimKeywordlist& kwl, const char* prefix)
174 {
175  if (!ossimImageHandler::loadState(kwl, prefix))
176  return false;
177 
178  return open();
179 }
180 
181 //*************************************************************************************************
182 // Returns the number of bands of the first tile since all tiles need to have the same pixel type.
183 //*************************************************************************************************
185 {
186  return (ossim_uint32) m_bandFiles.size();
187 }
188 
189 //*************************************************************************************************
191 //*************************************************************************************************
193 {
194  if ((m_bandFiles.size() == 0) || (!m_bandFiles[0].valid()))
195  return OSSIM_SCALAR_UNKNOWN;
196 
197  return m_bandFiles[0]->getOutputScalarType();
198 }
199 
200 //*************************************************************************************************
202 // Returns TRUE if connection possible
203 //*************************************************************************************************
205  const ossimConnectableObject* obj)
206 {
207  if (!m_mergeSource.valid())
208  return false;
209 
210  return m_mergeSource->canConnectMyOutputTo(index, obj);
211 }
212 
213 //*************************************************************************************************
220 //*************************************************************************************************
221 void ossimBandSeparateHandler::getBandFileNames(vector<ossimFilename>& file_names)
222 {
223  file_names.clear();
224 
225  // Ikonos expects metadata file with text extension:
226  if (theImageFile.ext() != "txt")
227  return;
228 
229  // Attempt to open the metadata file:
230  ifstream is (theImageFile.chars());
231  if (is.fail())
232  {
233  ossimNotify(ossimNotifyLevel_WARN)<<"ossimBandSeparateHandler::open() -- "
234  "Cannot open text file at <"<<theImageFile<<">. Image not opened."<<endl;
235  return;
236  }
237 
238  vector<ossimString> fname_list;
239  const ossimString separator (" ");
240  char line_buf[4096];
241  while (!is.eof())
242  {
243  is.getline(line_buf, 4096);
244  ossimString line_str (line_buf);
245 
246  // Look for mention of multiple band files. It must indicate "separate files". This comes
247  // before the list of band files:
248  if (line_str.contains("Multispectral Files:"))
249  {
250  if (!line_str.contains("Separate Files"))
251  return;
252  }
253 
254  // Look for list of band files:
255  if (line_str.contains("Tile File Name:"))
256  {
257  ossimString file_list_str = line_str.after(":");
258  file_list_str.split(fname_list, separator, true);
259  break;
260  }
261  }
262  is.close();
263 
264  // Set the path of individual band files to match metadata file path:
265  ossimFilename pathName (theImageFile.path());
266  for (size_t i=0; i<fname_list.size(); ++i)
267  {
268  ossimFilename fname (fname_list[i]);
269  fname.setPath(pathName);
270  file_names.push_back(fname);
271  }
272 }
273 
274 //*************************************************************************************************
276 //*************************************************************************************************
278 {
279  if ((m_bandFiles.size() == 0) || (!m_bandFiles[0].valid()))
280  return 0;
281 
282  return m_bandFiles[0]->getImageGeometry();
283 }
ossimFilename theImageFile
virtual ossimImageHandler * open(const ossimFilename &fileName, bool trySuffixFirst=true, bool openOverview=true) const
open that takes a filename.
Represents serializable keyword/value map.
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel)
Fills the requested tile by pulling pixels from multiple file tiles as needed.
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool valid() const
Definition: ossimRefPtr.h:75
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
bool contains(char aChar) const
Definition: ossimString.h:58
ossimFilename & setPath(const ossimString &p)
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
virtual bool isOpen() const
Derived classes must implement this method to be concrete.
virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const
virtual bool open()
Opens multiple band-files based on info in metadata file.
void push_back(char c)
Equivalent to insert(end(), c).
Definition: ossimString.h:905
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
unsigned int ossim_uint32
const char * chars() const
For backward compatibility.
Definition: ossimString.h:77
virtual ossimScalarType getOutputScalarType() const
Returns scalar type of first band (should be the same for all bands)
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const
virtual ossim_int32 connectMyInputTo(ossimConnectableObject *inputObject, bool makeOutputConnection=true, bool createEventFlag=true)
Will try to connect this objects input to the passed in object.
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the geometry of the first band:
ossimScalarType
virtual void completeOpen()
Will complete the opening process.
ossimRefPtr< ossimImageHandler > theOverview
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual ~ossimBandSeparateHandler()
Destructor:
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
This will merge all the bands from the input source list into one contiguous ossimImageData object...
ossimRefPtr< ossimBandMergeSource > m_mergeSource
virtual void getBandFileNames(vector< ossimFilename > &file_names)
Fetches the list of band file names from the header file.
vector< ossimRefPtr< ossimImageHandler > > m_bandFiles
ossimString ext() const
static ossimImageHandlerRegistry * instance()
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual bool canConnectMyOutputTo(ossim_int32 myOutputIndex, const ossimConnectableObject *object) const
default implementation is to allow anyone to connect to us.
virtual bool canConnectMyOutputTo(ossim_int32 index, const ossimConnectableObject *obj)
Overrides base connection method to connect output of merge source.
ossimString after(const ossimString &str, std::string::size_type pos=0) const
METHOD: after(str, pos) Returns string immediately after the token str.
ossimFilename path() const
virtual void close()
Closes all band-files and clears input handler list.
virtual ossim_uint32 getNumberOfInputBands() const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)