OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimQbTileFilesHandler.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: Image handler used for tiled Quickbird imagery.
10 //
11 //*************************************************************************************************
12 // $Id: ossimQbTileFilesHandler.cpp 2814 2011-07-05 13:40:16Z oscar.kramer $
13 
16 #include <ossim/base/ossimRegExp.h>
17 #include <ossim/base/ossimRefPtr.h>
21 #include <ossim/base/ossimNotify.h>
24 #include <ossim/base/ossimTrace.h>
34 #include <algorithm>
35 
36 RTTI_DEF1(ossimQbTileFilesHandler, "ossimQbTileFilesHandler", ossimTiledImageHandler)
37 
38 // Static trace for debugging
39 static ossimTrace traceDebug("ossimQbTileFilesHandler:debug");
40 
41 //*************************************************************************************************
43 //*************************************************************************************************
45 {
46 }
47 
48 //*************************************************************************************************
50 //*************************************************************************************************
52 {
53 }
54 
55 //*************************************************************************************************
60 //*************************************************************************************************
62 {
63  static const char* MODULE = "ossimQbTileFilesHandler::open() -- ";
64  if (traceDebug())
65  {
67  <<MODULE << "Entering...\nimage: " << theImageFile << "\n";
68  }
69 
70  // Test for extension: image.til
72  if ( ext == "ovr" )
73  {
74  return false; // Don't try to open overviews.
75  }
76 
77  ossimRegExp regExp("^[t|T][i|I][l|L]");
78  if ( regExp.find( ext.c_str() ) )
79  {
80  if (!theImageFile.exists())
81  {
82  return false;
83  }
84  }
85 
86  // Use ossimQuickbirdTile object for parsing the TIL file and fetching the data structure
87  // containing tile-file info:
88  if (traceDebug())
89  ossimNotify(ossimNotifyLevel_INFO)<<MODULE<<"OPENING ossimQuickbirdTile..."<<std::endl;
90 
92  bool success = qbt.open(theImageFile);
93  if (!success)
94  return false;
95 
96  // Populate our own data structure given the QBT map:
97  ossimFilename image_dir (theImageFile.path());
98  const ossimQuickbirdTile::TileMap& qbtTileMap = qbt.getMap();
99 
101  ossimIrect subImageRect;
102  ossimQuickbirdTile::TileMap::const_iterator qbt_iter = qbtTileMap.begin();
104  while (qbt_iter != qbtTileMap.end())
105  {
106  ossimQuickbirdTileInfo info ((*qbt_iter).second);
107  ossimTileFile tilefile;
108  tilefile.tileFilename = (*qbt_iter).second.theFilename;
109  tilefile.tileFilename.setPath(image_dir);
110  if (traceDebug())
111  {
112  ossimNotify(ossimNotifyLevel_INFO)<<MODULE<<"Using factory to open <"
113  <<tilefile.tileFilename<<">"<<std::endl;
114  }
115 
116  // Now open up the handlers for this tile-file:
117  tilefile.imageHandler = factory->open(tilefile.tileFilename);
118  if (tilefile.imageHandler.valid())
119  {
120  // Valid handler, populate remaining items of interest and push it on our list...
121  // Fetch image coordinates in full-view:
122  subImageRect.set_ulx((*qbt_iter).second.theUlXOffset);
123  subImageRect.set_uly((*qbt_iter).second.theUlYOffset);
124  subImageRect.set_lrx((*qbt_iter).second.theLrXOffset);
125  subImageRect.set_lry((*qbt_iter).second.theLrYOffset);
126  tilefile.subImageRects.push_back(subImageRect);
127 
128  // Update bounding image rectangle:
129  m_fullImgRect = m_fullImgRect.combine(subImageRect);
130  m_tileFiles.push_back(tilefile);
131  if (traceDebug())
132  {
133  ossimNotify(ossimNotifyLevel_INFO)<<MODULE<<"Pushed <"<<tilefile.tileFilename<<"> on"
134  "to tile-files list."<<std::endl;
135  }
136  }
137  else
138  {
139  ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"TIL file listed <"
140  <<tilefile.tileFilename<<"> as one of the tiles, but the file could not be opened. "
141  <<"This is being ignored but may cause a problem downstream."<<std::endl;
142  }
143 
144  ++qbt_iter;
145  }
146 
147  // Need to check the full-image rect for validity. May need to explore the .IMD file if this
148  // was not properly initialized:
149  if (m_fullImgRect.hasNans())
150  {
151  if (!computeImageRects())
152  {
153  if (traceDebug())
154  {
155  ossimNotify(ossimNotifyLevel_INFO)<<MODULE<<"Could not establish image rectangles."
156  <<std::endl;
157  }
158  return false;
159  }
160  }
161 
162  if (traceDebug())
163  ossimNotify(ossimNotifyLevel_INFO)<<MODULE<<"Finished loading tiles."<<std::endl;
164 
165  bool open_good = false;
166  if ((m_tileFiles.size() != 0) && m_tileFiles[0].imageHandler.valid())
167  {
168  completeOpen();
169  open_good = true;
170 
171  if (traceDebug())
172  ossimNotify(ossimNotifyLevel_INFO)<<MODULE<<"Open successful."<<std::endl;
173  }
174 
175  if (traceDebug())
176  {
177  ossimNotify(ossimNotifyLevel_INFO)<<MODULE<<"Returning with <"
178  <<ossimString::toString(open_good)<<">"<<std::endl;
179  }
180  return open_good;
181 }
182 
183 //*************************************************************************************************
185 //*************************************************************************************************
187 {
188  if ( !theGeometry )
189  {
190  // Try external geom first:
192 
193  if ( !theGeometry )
194  {
196 
197  // The dataset is expected to have an RPC model associated with it:
199  if (!model->getErrorStatus())
200  {
201  theGeometry->setProjection(model.get());
202  }
203  else
204  {
205  // Check for map projected data:
206  ossimFilename imd_file = theImageFile;
207  imd_file.setExtension("IMD");
208  if ( imd_file.exists() == false )
209  {
210  imd_file.setExtension("imd");
211  }
212 
213  if ( imd_file.exists() )
214  {
216  ossimKeywordlist kwl;
217  if ( md.getMapProjectionKwl( imd_file, kwl ) == true )
218  {
220  createProjection( kwl, 0 );
221  if ( proj.valid() == true )
222  {
223  theGeometry->setProjection( proj.get() );
224  }
225  }
226  }
227  }
228 
229  if ( (m_fullImgRect.ul().x != 0) || (m_fullImgRect.ul().y != 0) )
230  {
231  // Set sub image offset.
234  theGeometry->setTransform( xfrm.get() );
235  }
236  }
237 
238  // Set image things the geometry object should know about.
240  }
241 
242  return theGeometry;
243 }
244 
245 //*************************************************************************************************
248 //*************************************************************************************************
250 {
251  try
252  {
254  if (!oqmd.open(theImageFile))
255  throw 1;
256 
257  ossimIpt image_size (oqmd.getImageSize());
258  if (image_size.hasNans())
259  throw 2;
260 
261  ossimIpt full_image_lr (image_size.x-1, image_size.y-1);
264  m_fullImgRect.set_lr(full_image_lr);
265 
266  // Now consider the subrects for each tile. It is assumed that all tiles (except right
267  // and bottom) will be of uniform size. The TIL file should have at least provided the row
268  // and column offsets for each tile into the full image. This is equivalent to the UL corner.
269  // It is presumed that the TIL failed to provide the LR corner since this method was called.
270  int dx=0, dy=0, i=0;
271  int num_tiles = (int) m_tileFiles.size();
272  while (((dx == 0) || (dy == 0)) && (i < num_tiles-1))
273  {
274  if (dx == 0)
275  dx = m_tileFiles[i+1].subImageRects[0].ul().x - m_tileFiles[i].subImageRects[0].ul().x;
276  if (dy == 0)
277  dy = m_tileFiles[i+1].subImageRects[0].ul().y - m_tileFiles[i].subImageRects[0].ul().y;
278  ++i;
279  }
280 
281  // We should have the nominal tile size now. Check this is so:
282  if ((dx == 0) || (dy == 0))
283  {
284  // Prior scheme failed for establishing the tile dimensions. Final resort is to open the first
285  // available tile file and query its dimensions:
286  if (num_tiles == 0)
287  throw 3;
288  if (m_tileFiles[0].imageHandler.valid())
289  {
290  // we have an open handler, so just query it:
291  dy = m_tileFiles[0].imageHandler->getNumberOfLines();
292  dx = m_tileFiles[0].imageHandler->getNumberOfSamples();
293  }
294  else
295  {
296  // Struck out, just assume the tile is square:
297  if ((dx == 0) && (dy == 0))
298  throw 4;
299  if (dy == 0)
300  dy = dx;
301  else
302  dx = dy;
303  }
304  }
305 
306  // Loop over all tiles to properly assign their image rectangles:
307  for (i=0; i<num_tiles; i++)
308  {
309  ossimIpt ul (m_tileFiles[i].subImageRects[0].ul());
310  ossimIpt lr (ul.x + dx - 1, ul.y + dy - 1);
311 
312  // Check to make sure we don't exceed extents of full image:
313  if (lr.x > full_image_lr.x)
314  lr.x = full_image_lr.x;
315  if (lr.y > full_image_lr.y)
316  lr.y = full_image_lr.y;
317 
318  m_tileFiles[i].subImageRects[0].set_lr(lr);
319  }
320  }
321 
322  catch (...)
323  {
324  // Could not establish the rectangles:
325  return false;
326  }
327 
328  return true;
329 }
330 
void set_uly(ossim_int32 y)
Definition: ossimIrect.h:666
ossimRefPtr< ossimImageGeometry > theGeometry
ossimRefPtr< ossimImageHandler > imageHandler
void setProjection(ossimProjection *projection)
Sets the projection to be used for local-to-world coordinate transformation.
ossimFilename theImageFile
virtual ossimImageHandler * open(const ossimFilename &fileName, bool trySuffixFirst=true, bool openOverview=true) const
open that takes a filename.
bool open(const ossimFilename tileFile)
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
ossimFilename & setPath(const ossimString &p)
static ossimString toString(bool aValue)
Numeric to string methods.
const ossimIpt & ul() const
Definition: ossimIrect.h:274
const std::map< std::string, ossimQuickbirdTileInfo > & getMap() const
bool getMapProjectionKwl(const ossimFilename &imd_file, ossimKeywordlist &kwl)
This class defines an abstract Handler which all image handlers(loaders) should derive from...
ossimImageHandlerRegistry supports the new state cache.
bool exists() const
virtual ~ossimQbTileFilesHandler()
Destructor:
virtual bool open()
Opens the image file given entry index.
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
void initImageParameters(ossimImageGeometry *geom) const
Convenience method to set things needed in the image geometry from the image handler.
std::map< std::string, ossimQuickbirdTileInfo > TileMap
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Fetch the tile-files common RPC data file and create the projection for this image.
static ossimProjectionFactoryRegistry * instance()
virtual ossimRefPtr< ossimImageGeometry > getExternalImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
void set_lrx(ossim_int32 x)
Definition: ossimIrect.h:693
Class for record of one tile file:
virtual void completeOpen()
Will complete the opening process.
void set_lr(const ossimIpt &pt)
Definition: ossimIrect.h:623
virtual ossimErrorCode getErrorStatus() const
void set_lry(ossim_int32 y)
Definition: ossimIrect.h:702
ossim_int32 y
Definition: ossimIpt.h:142
void makeNan()
Definition: ossimIrect.h:329
void setTransform(ossim2dTo2dTransform *transform)
Sets the transform to be used for local-to-full-image coordinate transformation.
Image handler used for tiled Quickbird imagery.
bool open(const ossimFilename &imageFile)
Open method that takes the image file, derives the metadata, header and rpc files, then calls parse methods parseMetaData, parseHdrData, and parseRpcData.
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
const ossimIpt & getImageSize() const
bool hasNans() const
Definition: ossimIrect.h:337
vector< ossimTileFile > m_tileFiles
ossimString ext() const
static ossimImageHandlerRegistry * instance()
ossim_int32 x
Definition: ossimIpt.h:141
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
ossimFilename & setExtension(const ossimString &e)
Sets the extension of a file name.
ossimQbTileFilesHandler()
Constructor (default):
ossimIrect combine(const ossimIrect &rect) const
Definition: ossimIrect.cpp:543
bool find(const char *)
ossimFilename path() const
bool computeImageRects()
Initializes tile image rects by considering adjacent row/col offsets.
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void set_ulx(ossim_int32 x)
Definition: ossimIrect.h:657