OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimImageCacheTileSource.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: Mingjie Su
8 //
9 //********************************************************************
10 // $Id: ossimImageCacheTileSource.cpp 2644 2011-05-26 15:20:11Z oscar.kramer $
11 #include <algorithm>
12 using namespace std;
13 
15 
22 #include <ossim/base/ossimCommon.h>
28 #include <ossim/base/ossimDatum.h>
29 #include <ossim/base/ossimNotify.h>
32 
33 #include <ossim/base/ossimTrace.h>
35 
36 static ossimTrace traceDebug = ossimTrace("ossimImageCacheTileSource:debug");
37 
38 #ifdef OSSIM_ID_ENABLED
39 static const char OSSIM_ID[] = "$Id: ossimImageCacheTileSource.cpp 2644 2011-05-26 15:20:11Z oscar.kramer $";
40 #endif
41 
42 RTTI_DEF1(ossimImageCacheTileSource, "ossimImageCacheTileSource", ossimImageCacheBase)
43 
45  :
47  m_tile(0),
48  m_imageHandler(0),
49  m_minPixelValue(ossim::nan()),
50  m_maxPixelValue(ossim::nan()),
51  m_nullPixelValue(ossim::nan())
52 {
53 }
54 
56 {
57  if(m_imageHandler.valid())
58  {
59  m_imageHandler = 0;
60  }
61  close();
62 }
63 
65 {
66  return ossimString("ImageCache");
67 }
68 
70 {
71  return ossimString("ImageCache reader");
72 }
73 
74 
76 {
77  deleteAll();
78 }
79 
81 {
82  if(traceDebug())
83  {
84  ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageCacheTileSource::open(): Entered....." << std::endl;
85  }
86 
87  ossimFilename imageFile = theImageFile;
88  bool result = true;
89 
90  if(isOpen() == false)
91  {
92  close();
93  result = false;
94  }
95 
96  if(result)
97  {
98  if (m_fileNames.size() == 0 && m_frameEntryArray.size() == 0)
99  {
100  if (buildFrameEntryArray(imageFile) == false)
101  {
102  return false;
103  }
104  }
105 
106  //---
107  // Adjust image rect so not to go over the -180 to 180 and -90 to 90
108  // bounds.
109  //---
110  setActualImageRect();
111 
112  // Set the base class image file name.
113  theImageFile = imageFile;
114  m_tile = ossimImageDataFactory::instance()->create(this, this);
115  m_tile->initialize();
116  completeOpen();
117  }
118 
119  if(traceDebug())
120  {
121  ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageCacheTileSource::open(): Leaving at line" << __LINE__ << std::endl;
122  }
123 
124  return result;
125 }
126 
128 {
129  static const char MODULE[] = "ossimImageCacheTileSource::buildFrameEntryArray";
130  if ( traceDebug() )
131  {
132  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered..." << endl;
133  }
134 
135  std::ifstream in((imageFile).c_str() );
136  std::string line;
137  ossim_uint32 index = 0; // used throughout
138  ossim_uint32 frameWidth = 0;
139  ossim_uint32 frameHeight = 0;
140  while( in.good() )
141  {
142  // Read in a line.
143  std::getline(in, line);
144  ossimString tmpStr = ossimString(line);
145  if (index == 0)
146  {
147  std::vector<ossimString> box_lat_lon;
148  tmpStr.split(box_lat_lon, "|");
149  if (box_lat_lon.size() == 4)
150  {
151  std::vector<ossimString> pixelInfos = box_lat_lon[3].split(",");
152  if (pixelInfos.size() == 3)
153  {
154  m_minPixelValue = ossimString::toFloat64(pixelInfos[0]);
155  m_maxPixelValue = ossimString::toFloat64(pixelInfos[1]);
156  m_nullPixelValue = ossimString::toFloat64(pixelInfos[2]);
157  }
158  }
159  }
160  else if (index == 1)
161  {
162  std::vector<ossimString> frame_lat_lon = tmpStr.split("|");
163  ossimFilename firstFile = frame_lat_lon[0];
164  if(m_workFrame->parseFile(firstFile) == ossimErrorCodes::OSSIM_ERROR)
165  {
166  m_imageHandler = ossimImageHandlerRegistry::instance()->open(firstFile);
167  if (m_imageHandler.valid())
168  {
169  frameWidth = m_imageHandler->getBoundingRect().width();
170  frameHeight = m_imageHandler->getBoundingRect().height();
171  break;
172  }
173  }
174  else
175  {
176  return false;
177  }
178  }
179  ++index;
180  }
181  in.close();
182 
183  return ossimImageCacheBase::buildFrameEntryArray(imageFile, frameWidth, frameHeight);
184 }
185 
187  const ossimIrect& rect, ossim_uint32 resLevel)
188 {
189  if (m_tile.valid())
190  {
191  // Image rectangle must be set prior to calling getTile.
192  m_tile->setImageRectangle(rect);
193 
194  if ( getTile( m_tile.get(), resLevel ) == false )
195  {
196  if (m_tile->getDataObjectStatus() != OSSIM_NULL)
197  {
198  m_tile->makeBlank();
199  }
200  }
201  }
202 
203  return m_tile;
204 }
205 
207  ossim_uint32 resLevel)
208 {
209  bool status = false;
210 
211  //---
212  // Not open, this tile source bypassed, or invalid res level,
213  // return a blank tile.
214  //---
215  if( isOpen() && isSourceEnabled() && isValidRLevel(resLevel) &&
216  result && (result->getNumberOfBands() == getNumberOfOutputBands()))
217  {
218  if ( resLevel > 0 )
219  {
220  status = getOverviewTile(resLevel, result);
221  }
222 
223  if (!status) // Did not get an overview tile.
224  {
225  status = true;
226 
227  ossimIrect rect = result->getImageRectangle();
228 
229  ossimIrect imageRect = getImageRectangle();
230 
231  if ( rect.intersects(imageRect) )
232  {
233  //---
234  // Start with a blank tile in case there is not total coverage
235  // for rect.
236  //---
237  result->makeBlank();
238 
239  vector<ossimFrameEntryData> frames = getIntersectingEntries(rect);
240  if(frames.size() > 0)
241  {
242  //---
243  // Now lets render each frame. Note we will have to find
244  // subframes
245  // that intersect the rectangle of interest for each frame.
246  //---
247  fillTile(rect, frames, result);
248 
249  // Revalidate tile status.
250  result->validate();
251  }
252  }
253  else
254  {
255  result->makeBlank();
256  }
257  }
258  }
259  return status;
260 }
261 
263  const ossimIrect& tileRect,
264  const vector<ossimFrameEntryData>& framesInvolved,
265  ossimImageData* tile)
266 {
267  ossim_uint32 idx = 0;
268  for(idx = 0; idx < framesInvolved.size(); ++idx)
269  {
270  if (m_imageHandler.valid())
271  {
272  if (m_imageHandler->getFilename() != framesInvolved[idx].theFrameEntry.getFullPath())
273  {
274  m_imageHandler = 0;
275  m_imageHandler = ossimImageHandlerRegistry::instance()->open(framesInvolved[idx].theFrameEntry.getFullPath());
276  }
277  }
278  else
279  {
280  m_imageHandler = ossimImageHandlerRegistry::instance()->open(framesInvolved[idx].theFrameEntry.getFullPath());
281  }
282 
283  if (m_imageHandler.valid())
284  {
285  if (m_imageHandler->isOpen() == false)
286  {
287  m_imageHandler->open(framesInvolved[idx].theFrameEntry.getFullPath());
288  }
289 
290  ossimIrect frameRect(framesInvolved[idx].thePixelCol,
291  framesInvolved[idx].thePixelRow,
292  framesInvolved[idx].thePixelCol + m_frame_width - 1,
293  framesInvolved[idx].thePixelRow + m_frame_height - 1);
294 
295  ossimIrect clipRect = tileRect.clipToRect(frameRect);
296 
297  ossimIpt tempDelta(clipRect.ul().x - framesInvolved[idx].thePixelCol,
298  clipRect.ul().y - framesInvolved[idx].thePixelRow);
299 
300  ossimIrect offsetRect(tempDelta.x,
301  tempDelta.y,
302  tempDelta.x + clipRect.width()-1,
303  tempDelta.y + clipRect.height()-1);
304 
305  //if the current image size is different from the default size, resample the image data
306  if ( ( m_imageHandler->getBoundingRect().width() != m_frame_width ) ||
307  ( m_imageHandler->getBoundingRect().height() != m_frame_height ) )
308  {
309 
310  //calculate the ratio
311  ossim_float64 widthRatio = static_cast<ossim_float64>(m_imageHandler->getBoundingRect().width())/static_cast<ossim_float64>(m_frame_width);
312  ossim_float64 heightRatio = static_cast<ossim_float64>(m_imageHandler->getBoundingRect().height())/static_cast<ossim_float64>(m_frame_height);
313 
314  //initialize the rect bounding for getting image data from image handler
315  ossimDpt ul(offsetRect.ul().x*widthRatio, offsetRect.ul().y*heightRatio);
316  ossimDpt lr(offsetRect.lr().x*widthRatio, offsetRect.lr().y*heightRatio);
317 
318  //---
319  // Floor, ceil to avoid rect size of zero from ul, lr, delta being only fractional
320  // resulting in size of 0 if cast to an int or passed to ossim<int>::round().
321  //---
322  ossimIrect actualOffsetRect(static_cast<ossim_int32>(std::floor(ul.x)),
323  static_cast<ossim_int32>(std::floor(ul.y)),
324  static_cast<ossim_int32>(std::ceil(lr.x)),
325  static_cast<ossim_int32>(std::ceil(lr.y)));
326 
327  //get accurate rect in case the actual rect is larger than the rect of image
328  actualOffsetRect = actualOffsetRect.clipToRect(m_imageHandler->getBoundingRect());
329 
330  ossimRefPtr<ossimImageData> imageData = m_imageHandler->getTile(actualOffsetRect);
331  if (imageData.valid())
332  {
333  ossimFilterResampler* resampler = new ossimFilterResampler();
334 
335  double denominatorY = 1.0;
336  double denominatorX = 1.0;
337  if(clipRect.height() > 2) // Cannot be zero.
338  {
339  denominatorY = clipRect.height()-1.0;
340  }
341  if(clipRect.width() > 2) // Cannot be zero.
342  {
343  denominatorX = clipRect.width()-1.0;
344  }
345 
346  //create a tile and set the rect size
347  ossimRefPtr<ossimImageData> tmpTile = (ossimImageData*)imageData->dup();
348  tmpTile->setImageRectangle(offsetRect);
349  tmpTile->makeBlank();
350 
351  ossimDpt deltaUl(((actualOffsetRect.ll().x - actualOffsetRect.ul().x)/denominatorX),
352  ((actualOffsetRect.ll().y - actualOffsetRect.ul().y)/denominatorY));
353  ossimDpt deltaUr(((actualOffsetRect.lr().x - actualOffsetRect.ur().x)/denominatorX),
354  ((actualOffsetRect.lr().y - actualOffsetRect.ur().y)/denominatorY));
355  ossimDpt length(offsetRect.width(),offsetRect.height());
356 
357  //resample the image data
358  resampler->resample(imageData,
359  tmpTile,
360  actualOffsetRect.ul(),
361  actualOffsetRect.ur(),
362  deltaUl,
363  deltaUr,
364  length);
365 
366  tile->loadTile(tmpTile->getBuf(), clipRect, OSSIM_BSQ);
367 
368  tmpTile = 0;
369  delete resampler;
370  resampler = 0;
371  }
372  }
373  else
374  {
375  ossimRefPtr<ossimImageData> imageData = m_imageHandler->getTile(offsetRect);
376  if (imageData.valid())
377  {
378  tile->loadTile(imageData->getBuf(), clipRect, OSSIM_BSQ);
379  }
380  }
381  }
382  }
383 }
384 
386 {
387  if (m_imageHandler.valid())
388  {
389  return m_imageHandler->getOutputScalarType();
390  }
391  return OSSIM_UCHAR;
392 }
393 
395 {
396  if (ossim::isnan(m_minPixelValue))
397  {
399  }
400  return m_minPixelValue;
401 }
402 
404 {
405  if (ossim::isnan(m_maxPixelValue))
406  {
408  }
409  return m_maxPixelValue;
410 }
411 
413 {
414  if (ossim::isnan(m_nullPixelValue))
415  {
417  }
418  return m_nullPixelValue;
419 }
420 
422 {
423  if (m_imageHandler.valid())
424  {
425  return m_imageHandler->getNumberOfInputBands();
426  }
427  return m_numberOfBands;
428 }
429 
431 {
432  if (m_imageHandler.valid())
433  {
434  return m_imageHandler->getNumberOfInputBands();
435  }
436  return m_numberOfBands;
437 }
virtual bool open()=0
Pure virtual open.
void fillTile(const ossimIrect &tileRect, const vector< ossimFrameEntryData > &framesInvolved, ossimImageData *tile)
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
virtual ossim_uint32 getNumberOfBands() const
bool buildFrameEntryArray(ossimFilename imageFile)
virtual void setImageRectangle(const ossimIrect &rect)
virtual ossimImageHandler * open(const ossimFilename &fileName, bool trySuffixFirst=true, bool openOverview=true) const
open that takes a filename.
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool valid() const
Definition: ossimRefPtr.h:75
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
This code was derived from https://gist.github.com/mshockwave.
Definition: Barrier.h:8
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
Returns a pointer to an ossimImageDataObject given a rectangluar region of interest.
ossim_uint32 height() const
Definition: ossimIrect.h:487
const ossimIpt & ul() const
Definition: ossimIrect.h:274
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 ossimString getShortName() const
This method is defined in the base class ossimObject.
static const ossimErrorCode OSSIM_ERROR
std::istream & getline(std::istream &is, ossimString &str, char delim)
Definition: ossimString.h:916
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
virtual ossim_uint32 getNumberOfInputBands() const
This method allows you to query the number of input bands.
virtual ~ossimImageCacheTileSource()
Destructor.
virtual ossimString getLongName() const
This method is defined in the base class ossimObject.
virtual ossimScalarType getOutputScalarType() const
This method allows you to query the scalar type of the output data.
virtual void initialize()
Initialize the data buffer.
virtual ossimObject * dup() const
virtual bool open()
Pure virtual open.
virtual double getMinPixelValue(ossim_uint32 band=0) const
Retuns the min pixel value.
virtual double getMinPixelValue(ossim_uint32 band=0) const
Retuns the min pixel value.
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
double ossim_float64
virtual void loadTile(const void *src, const ossimIrect &src_rect, ossimInterleaveType il_type)
static ossimImageDataFactory * instance()
virtual ossimDataObjectStatus validate() const
unsigned int ossim_uint32
ossim_float64 toFloat64() const
virtual ossimIrect getImageRectangle() const
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
virtual ossim_uint32 getNumberOfOutputBands() const
This method allows one to query the number of output bands.
ossim_uint32 width() const
Definition: ossimIrect.h:500
ossimIrect clipToRect(const ossimIrect &rect) const
Definition: ossimIrect.cpp:501
ossimScalarType
return status
virtual void makeBlank()
Initializes data to null pixel values.
bool buildFrameEntryArray(ossimFilename imageFile, ossim_uint32 frameWidth, ossim_uint32 frameHeight)
ossim_int32 y
Definition: ossimIpt.h:142
virtual const void * getBuf() const
virtual void resample(const ossimRefPtr< ossimImageData > &input, ossimRefPtr< ossimImageData > &output, const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &deltaUl, const ossimDpt &deltaUr, const ossimDpt &length)
static ossimImageHandlerRegistry * instance()
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
Returns zero-based bounding rectangle of the image.
ossim_int32 x
Definition: ossimIpt.h:141
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual void close()
Closes this image handler and deletes any allocated data.
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
8 bit unsigned iteger
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91