OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimUsgsDemTileSource.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 // Description:
8 //
9 // Contains class declaration for ossimUsgsDemTileSource.
10 //
11 //********************************************************************
12 // $Id: ossimUsgsDemTileSource.cpp 19640 2011-05-25 15:58:00Z oscarkramer $
13 
14 #include <iostream>
15 #include <fstream>
18 #include <ossim/base/ossimCommon.h>
19 #include <ossim/base/ossimNotify.h>
21 #include <ossim/base/ossimTrace.h>
33 
34 RTTI_DEF1(ossimUsgsDemTileSource, "ossimUsgsDemTileSource", ossimImageHandler)
35 
36 // Static trace for debugging
37 static ossimTrace traceDebug("ossimUsgsDemTileSource:debug");
38 
39 static const char DEM_TYPE_KW[] = "dem_type";
40 static const char USGS_DEM_KW[] = "usgs_dem";
41 
42 
44  :
46  theDem(0),
47  theTile(0),
48  theNullValue(0.0),
49  theMinHeight(0.0),
50  theMaxHeight(0.0),
51  theFeetFlag(false),
52  theIsDemFlag(false),
53  theScalarType(OSSIM_SINT16)
54 {
55  // Construction not complete. Users should call "open" method.
56 }
57 
59 {
60  if (theDem)
61  {
62  delete theDem;
63  theDem = 0;
64  }
65  theTile = 0;
66 }
67 
69  const ossimIrect& tile_rect, ossim_uint32 resLevel)
70 {
71  if (theTile.valid())
72  {
73  // Image rectangle must be set prior to calling getTile.
74  theTile->setImageRectangle(tile_rect);
75 
76  if ( getTile( theTile.get(), resLevel ) == false )
77  {
79  {
80  theTile->makeBlank();
81  }
82  }
83  }
84 
85  return theTile;
86 }
87 
89  ossim_uint32 resLevel)
90 {
91  bool status = false;
92 
93  //---
94  // Not open, this tile source bypassed, or invalid res level,
95  // return a blank tile.
96  //---
97  if( isOpen() && isSourceEnabled() && isValidRLevel(resLevel) &&
98  result && (result->getNumberOfBands() == getNumberOfOutputBands()) )
99  {
100  result->ref(); // Increment ref count.
101 
102  //---
103  // Check for overview tile. Some overviews can contain r0 so always
104  // call even if resLevel is 0. Method returns true on success, false
105  // on error.
106  //---
107  status = getOverviewTile(resLevel, result);
108 
109  if (status) // From old code. Not sure if still needed.
110  {
114  }
115 
116  if (!status) // Did not get an overview tile.
117  {
118  status = true;
119 
120  ossimIrect tile_rect = result->getImageRectangle();
121 
122  ossimIrect image_rect = getImageRectangle(resLevel);
123 
124  //---
125  // See if any point of the requested tile is in the image.
126  //---
127  if ( tile_rect.intersects(image_rect) )
128  {
129  ossimIrect clip_rect = tile_rect.clipToRect(image_rect);
130 
131  if ( !tile_rect.completely_within(clip_rect) )
132  {
133  // Start with a blank tile.
134  result->makeBlank();
135  }
136 
137  // Load the tile buffer with data from the dem cell.
139  {
141  tile_rect,
142  clip_rect,
143  result);
144  }
145  else
146  {
148  tile_rect,
149  clip_rect,
150  result);
151  }
152  if (status == true)
153  {
154  result->validate();
155  }
156  }
157  else // No intersection: if ( tile_rect.intersects(image_rect) )
158  {
159  result->makeBlank();
160  }
161  }
162 
163  result->unref(); // Decrement ref count.
164  }
165 
166  return status;
167 }
168 
169 //*******************************************************************
170 // Private Method:
171 //*******************************************************************
172 template <class T>
174  const ossimIrect& tile_rect,
175  const ossimIrect& clip_rect,
176  ossimImageData* tile)
177 {
178  const ossim_uint32 TILE_WIDTH = tile->getWidth();
179 
180  T* d = static_cast<T*>(tile->getBuf());
181 
182  ossim_float32 spatialResZ = theDem->getHeader().getSpatialResZ();
183  if (spatialResZ == 0.0) spatialResZ = 1.0;
184 
185  // Compute the starting offset.
186  ossim_uint32 offset = (clip_rect.ul().y - tile_rect.ul().y) * TILE_WIDTH +
187  clip_rect.ul().x - tile_rect.ul().x;
188 
189  for (ossim_int32 line = clip_rect.ul().y; line <= clip_rect.lr().y; ++line)
190  {
191  // Loop in the longitude or sample direction.
192  int samp_offset = 0;
193  for (ossim_int32 samp = clip_rect.ul().x; samp <= clip_rect.lr().x; ++samp)
194  {
195  ossim_float32 p = theDem->getElevation(samp, line);
196  if (p != theNullValue)
197  {
198  p *= spatialResZ;
199  if (theFeetFlag) p = p * MTRS_PER_FT;
200  }
201  d[offset + samp_offset] = static_cast<T>(p);
202  ++samp_offset;
203  }
204  offset += TILE_WIDTH;
205  }
206 
207  return true;
208 }
209 
212 {
213  return ossimIrect(0,
214  0,
215  getNumberOfSamples(reduced_res_level) - 1,
216  getNumberOfLines(reduced_res_level) - 1);
217 }
218 
220 {
221  static const char MODULE[] = "ossimUsgsDemTileSource::open";
222 
223  if (traceDebug())
224  {
225  CLOG << "DEBUG:"
226  << "\nAttempting to parse file: " << theImageFile.c_str()
227  << std::endl;
228  }
229 
231 
232  if (theIsDemFlag)
233  {
234  // Open up the file for reading.
236  std::ios_base::in | std::ios_base::binary);
237  if (is.good())
238  {
239  // Start out with a fresh dem.
240  if (theDem) delete theDem;
241 
242  //---
243  // Set the null to -32768. This will also be the missing data values.
244  //---
246 
247  //---
248  // Read the dem.
249  //
250  // NOTE: This defines the missing data value. It should be the
251  // same as null for mosaicing and min/max calculations.
252  //---
254  theDem->read(is);
255 
256  is.close();
257  }
258  else
259  {
260  theIsDemFlag = false;
261  }
262  }
263 
264  if (theIsDemFlag)
265  {
267  true : false;
268 
273 
274  completeOpen();
275 
276  //---
277  // Set up the tiles. Note the blank tile will not get initialized to
278  // save memory. This includes setting the min and max pixel value
279  // gathered from the statistics.
280  //---
282  theTile->initialize();
283 
284  if (traceDebug())
285  {
286  CLOG << setiosflags(ios::fixed) << setprecision(5) << "DEBUG:"
287  << "\nNull pix: " << (theTile->getNullPix(0))
288  << "\nMin pix: " << (theTile->getMinPix(0))
289  << "\nMax pix: " << (theTile->getMaxPix(0))
290  << "\nlines: " << theDem->getHeight()
291  << "\nsamples: " << theDem->getWidth()
292  << std::endl;
293  }
294  }
295 
296  return theIsDemFlag;
297 }
298 
300  const char* prefix) const
301 {
302  // Save of the dem type keyword.
303  kwl.add(prefix, DEM_TYPE_KW, USGS_DEM_KW, true);
304 
305  // Save the scalar type.
306  kwl.add(prefix,
308  ossimScalarTypeLut::instance()->getEntryString(theScalarType));
309 
310  return ossimImageHandler::saveState(kwl, prefix);
311 }
312 
314  const char* prefix)
315 {
316  if (ossimImageHandler::loadState(kwl, prefix))
317  {
318  //***
319  // Look for "dem_type: usgs_dem" key value pair.
320  // Note: If not in the keyword list the "open" will look for it on
321  // disk.
322  //***
323  const char* lookup = kwl.find(prefix, DEM_TYPE_KW);
324  if (lookup)
325  {
326  ossimString s = lookup;
327  s.downcase();
328  if (s == USGS_DEM_KW) theIsDemFlag = true;
329  }
330 
331  //---
332  // Look for scalar type override.
333  //
334  // Note: We only allow float or signed 16 bit.
335  //---
336  lookup = kwl.find(prefix, ossimKeywordNames::SCALAR_TYPE_KW);
337  if (lookup)
338  {
339  ossimScalarType st =
341  getEntryNumber(lookup));
342  if ( (st == OSSIM_FLOAT32) || (st == OSSIM_SINT16))
343  {
344  theScalarType = st;
345  }
346  else
347  {
348  if (traceDebug())
349  {
351  << "ossimUsgsDemTileSource::loadState WARNING:"
352  << "\nInvalid scalar type: "
354  getEntryString(st)
355  << std::endl;
356  }
357  }
358  }
359 
360  if (open())
361  {
362  return true;
363  }
364  }
365 
366  return false;
367 }
368 
370 {
371  if ( !theGeometry )
372  {
373  // Check for external geom:
375 
376  if ( !theGeometry )
377  {
378  // Check the internal geometry first to avoid a factory call.
380 
381  // At this point it is assured theGeometry is set.
382 
383  //---
384  // WARNING:
385  // Must create/set theGeometry at this point or the next call to
386  // ossimImageGeometryRegistry::extendGeometry will put us in an infinite loop
387  // as it does a recursive call back to ossimImageHandler::getImageGeometry().
388  //---
389 
390  // Check for set projection.
391  if ( !theGeometry->getProjection() )
392  {
393  // Try factories for projection.
395  }
396  }
397 
398  // Set image things the geometry object should know about.
400  }
401 
402  return theGeometry;
403 }
404 
405 
407 {
409 
410  if (theDem)
411  {
412  const ossimDemHeader HDR = theDem->getHeader();
413  if (traceDebug())
414  {
416  << "ossimUsgsDemTileSource::getInternalImageGeometry DEBUG:"
417  << "\nDEM Header:"
418  << std::endl;
420  }
421 
422  // The DEM's image geometry is a map projection, obtained here via KWL:
423  ossimKeywordlist proj_kwl;
424  if ( HDR.getImageGeometry(proj_kwl) )
425  {
426  if (traceDebug())
427  {
429  << "ossimUsgsDemTileSource::getInternalImageGeometry DEBUG:"
430  << "keyword list:\n" << proj_kwl
431  << std::endl;
432  }
433 
434  // Capture for next time.
437  createProjection(proj_kwl);
438  if ( proj.valid() )
439  {
440  geom->setProjection(proj.get());
441  }
442  }
443  }
444 
445  return geom;
446 }
447 
449 {
450  return theScalarType;
451 }
452 
454 {
455  return ( theTile.valid() ? theTile->getWidth() : 0 );
456 }
457 
459 {
460  return ( theTile.valid() ? theTile->getHeight() : 0 );
461 }
462 
464 {
465  ossim_uint32 result = 0;
466  if (reduced_res_level == 0)
467  {
468  if (theDem)
469  {
470  result = theDem->getHeight();
471  }
472  }
473  else if (theOverview.valid())
474  {
475  result = theOverview->getNumberOfLines(reduced_res_level);
476  }
477  return result;
478 }
479 
481 {
482  ossim_uint32 result = 0;
483  if (reduced_res_level == 0)
484  {
485  if (theDem)
486  {
487  result = theDem->getWidth();
488  }
489  }
490  else if (theOverview.valid())
491  {
492  result = theOverview->getNumberOfSamples(reduced_res_level);
493  }
494  return result;
495 }
496 
498 {
499  return 0;
500 }
501 
503 {
504  return 0;
505 }
506 
508 {
509  return ossimString("usgs dem");
510 }
511 
513 {
514  return ossimString("usgs dem reader");
515 }
516 
518 {
519  return 1;
520 }
521 
523 {
524  return 1;
525 }
526 
528 {
529  return theNullValue;
530 }
531 
533 {
534  if(band < theMetaData.getNumberOfBands())
535  {
536  return theMetaData.getMinPix(band);
537  }
538  return theMinHeight;
539 }
540 
542 {
544  {
545  return theMetaData.getMaxPix(band);
546  }
547  return theMaxHeight;
548 }
549 
551 {
552  return (theDem ? true : false );
553 }
554 
556 {
557  return rhs;
558 }
559 
561 {
562 }
ossimScalarType theScalarType
This can be either OSSIM_SINT16 or OSSIM_FLOAT32.
virtual ossim_uint32 getWidth() const
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
virtual ossimString getShortName() const
static ossimImageGeometryRegistry * instance()
virtual ossimRefPtr< ossimImageGeometry > getInternalImageGeometry() const
Initializes theGeometry from USGS DEM header.
ossimRefPtr< ossimImageGeometry > theGeometry
ossim_int32 getElevationUnits() const
virtual bool open()
Returns true if the "theImageFile can be opened.
virtual const ossim_float64 * getMaxPix() const
void setProjection(ossimProjection *projection)
Sets the projection to be used for local-to-world coordinate transformation.
virtual ossim_uint32 getNumberOfBands() const
#define CLOG
Definition: ossimTrace.h:23
ossimFilename theImageFile
virtual ossim_uint32 getTileHeight() const
Returns the height of the output tile.
virtual void setImageRectangle(const ossimIrect &rect)
const ossimUsgsDemTileSource & operator=(const ossimUsgsDemTileSource &rhs)
double getMinPix(ossim_uint32 band) const
long getWidth() const
Represents serializable keyword/value map.
virtual ossim_uint32 getNumberOfInputBands() const
Returns the number of bands in the image.
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
#define OSSIM_DEFAULT_NULL_PIX_SINT16
double getMinimumElev() const
ossimRefPtr< ossimImageData > theTile
float ossim_float32
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
double getMaxPix(ossim_uint32 band) const
16 bit signed integer
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
virtual ossim_uint32 getImageTileWidth() const
Returns the tile width of the image or 0 if the image is not tiled.
32 bit floating point
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
virtual double getMinPixelValue(ossim_uint32 band=0) const
Retuns the min pixel value.
virtual bool extendGeometry(ossimImageHandler *handler) const
virtual void initialize()
Initialize the data buffer.
void ref() const
increment the reference count by one, indicating that this object has another pointer which is refere...
ossim_uint32 getNumberOfBands() const
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tile_rect, ossim_uint32 resLevel=0)
virtual bool isValidRLevel(ossim_uint32 resLevel) const
Determines if the passed in reslution level is valid.
virtual bool isOpen() const
Derived classes must implement this method to be concrete.
bool completely_within(const ossimIrect &rect) const
Definition: ossimIrect.cpp:425
virtual ossim_uint32 getTileWidth() const
Returns the width of the output tile.
virtual ossim_uint32 getImageTileHeight() const
Returns the tile width of the image or 0 if the image is not tiled.
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual ossimString getLongName() const
static ossimScalarTypeLut * instance()
Returns the static instance of an ossimScalarTypeLut object.
virtual void setNullPix(ossim_float64 null_pix)
virtual bool getOverviewTile(ossim_uint32 resLevel, ossimImageData *result)
Method to get an overview tile.
static ossimImageDataFactory * instance()
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
static bool isUsgsDem(const ossimFilename &file)
Does basic sanity checks to see if file is a dem.
virtual ossimDataObjectStatus validate() const
signed short ossim_sint16
long getHeight() const
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
virtual ossimIrect getImageRectangle() const
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
const ossimIpt & lr() const
Definition: ossimIrect.h:276
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
void initImageParameters(ossimImageGeometry *geom) const
Convenience method to set things needed in the image geometry from the image handler.
ossimIrect clipToRect(const ossimIrect &rect) const
Definition: ossimIrect.cpp:501
virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level=0) const
Returns the number of lines in the image.
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
ossimScalarType
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level=0) const
Returns the number of samples in the image.
void unref() const
decrement the reference count by one, indicating that a pointer to this object is referencing it...
static ossimProjectionFactoryRegistry * instance()
virtual const ossim_float64 * getMinPix() const
long read(ossim::istream &dem, bool incrementalRead=false)
virtual ossimRefPtr< ossimImageGeometry > getExternalImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
#define MTRS_PER_FT
return status
virtual void makeBlank()
Initializes data to null pixel values.
const ossimProjection * getProjection() const
Access methods for projection (may be NULL pointer).
virtual void completeOpen()
Will complete the opening process.
ossimImageMetaData theMetaData
ossimRefPtr< ossimImageHandler > theOverview
virtual void setMaxPix(ossim_float64 max_pix)
This class defines an abstract Handler which all image handlers(loaders) should derive from...
double getSpatialResZ() const
bool fillBuffer(T, const ossimIrect &tile_rect, const ossimIrect &clip_rect, ossimImageData *tile)
Returns true on success, false on error.
ossim_int32 y
Definition: ossimIpt.h:142
virtual const void * getBuf() const
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
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
static const char * SCALAR_TYPE_KW
ossimDemHeader const & getHeader() const
virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level=0) const
Returns the zero based image rectangle for the reduced resolution data set (rrds) passed in...
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
double getMaximumElev() const
ossim_int32 x
Definition: ossimIpt.h:141
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Override base-class method to make sure the internal geometry is explored before extending.
ossim_float32 getElevation(long x, long y) const
virtual void setMinPix(ossim_float64 min_pix)
std::ostream & print(std::ostream &out) const
Print method.
virtual ossimScalarType getOutputScalarType() const
Returns the output pixel type of the tile source.
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
bool getImageGeometry(ossimKeywordlist &kwl, const char *prefix=NULL) const