OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimMG4LidarReader.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: Class definition for MRSID MG4 reader.
8 //
9 // Author: Mingjie Su
10 //
11 //----------------------------------------------------------------------------
12 // $Id: ossimMG4LidarReader.cpp 2645 2011-05-26 15:21:34Z oscar.kramer $
13 
14 #include <fstream>
15 #include <iostream>
16 #include <string>
17 
18 //ossim includes
19 #include <ossim/base/ossimCommon.h>
20 #include <ossim/base/ossimDpt.h>
21 #include <ossim/base/ossimEndian.h>
25 #include <ossim/base/ossimNotify.h>
27 #include <ossim/base/ossimTrace.h>
29 
32 
37 
39 #include <ogr_spatialref.h>
40 
41 #include "ossimMG4LidarReader.h"
42 
43 #ifdef OSSIM_ID_ENABLED
44 static const char OSSIM_ID[] = "$Id";
45 #endif
46 
47 // Resolution Ratio between adjacent levels.
48 
49 static double maxRasterSize = 2048.0;
50 static double maxBlockSideSize = 1024.0;
51 
52 static ossimTrace traceDebug("ossimMG4LidarReader:debug");
53 static ossimTrace traceDump("ossimMG4LidarReader:dump");
54 //static ossimOgcWktTranslator wktTranslator;
55 
57  "ossimMG4LidarReader",
59 
62  m_reader(NULL),
63  m_imageRect(),
64  m_numberOfSamples(0),
65  m_numberOfLines(0),
66  m_scalarType(OSSIM_SCALAR_UNKNOWN),
67  m_tile(0)
68 {
69 }
70 
72 {
73  closeEntry();
74 }
75 
77 {
78  return ossimString("ossim_mg4_lidar_reader");
79 }
80 
82 {
83  return ossimString("ossim mg4 lidar reader");
84 }
85 
87 {
88  return ossimString("ossimMG4LidarReader");
89 }
90 
92 {
93  ossim_uint32 result = 1; // Add r0
94 
95  if (theOverview.valid())
96  {
97  //---
98  // Add external overviews.
99  //---
101  }
102 
103  return result;
104 }
105 
107  ossim_uint32 resLevel) const
108 {
109  if (theOverview.valid())
110  {
111  return theOverview->getNumberOfSamples(resLevel);
112  }
113  return m_numberOfLines;
114 }
115 
117  ossim_uint32 resLevel) const
118 {
119  if (theOverview.valid())
120  {
121  return theOverview->getNumberOfSamples(resLevel);
122  }
123  return m_numberOfSamples;
124 }
125 
127 {
128  static const char MODULE[] = "ossimMG4LidarReader::open";
129 
130  if (traceDebug())
131  {
133  << MODULE << " entered...\n"
134  << "image: " << theImageFile << "\n";
135  }
136 
137  bool result = false;
138 
139  if(isOpen())
140  {
141  closeEntry();
142  }
143 
144  int gen = 0;
145  bool raster = false;
146  result = Version::getMrSIDFileVersion(theImageFile.c_str(), gen, raster);
147  if (result == false)
148  {
149  return result;
150  }
151 
152  m_reader = MG4PointReader::create();
153  m_reader->init(theImageFile.c_str());
154  m_bounds = m_reader->getBounds();
155 
156  int numPoints = m_reader->getNumPoints();
157  m_numberOfSamples = m_bounds.x.length();
158  m_numberOfLines = m_bounds.y.length();
159 
160  double pts_per_area = ((double)m_reader->getNumPoints())/(m_bounds.x.length()*m_bounds.y.length());
161  double average_pt_spacing = sqrt(1.0 / pts_per_area) ;
162  double cell_side = average_pt_spacing;
163  maxRasterSize = std::max(m_bounds.x.length()/cell_side, m_bounds.y.length()/cell_side);
164  //openZoomLevel(0);
165 
166  //get data type from X channel as default
167  getDataType(0);
168 
170  {
172 
173  m_tile->initialize();
174 
175  // Call the base complete open to pick up overviews.
176  completeOpen();
177 
178  result = true;
179  }
180 
181  if (result == false)
182  {
183  closeEntry();
184  }
185 
186  if (traceDebug())
187  {
189  << MODULE << " exit status = " << (result?"true":"false\n")
190  << std::endl;
191  }
192 
193  return result;
194 }
195 
197 {
198  // geo dimensions
199  const double gWidth = m_reader->getBounds().x.length() ;
200  const double gHeight = m_reader->getBounds().y.length() ;
201 
202  // geo res
203  double xRes = pow(2.0, zoom) * gWidth / maxRasterSize ;
204  double yRes = pow(2.0, zoom) * gHeight / maxRasterSize ;
205  xRes = yRes = std::max(xRes, yRes);
206 
207  // pixel dimensions
208  m_numberOfSamples = static_cast<int>(gWidth / xRes + 0.5);
209  m_numberOfLines = static_cast<int>(gHeight / yRes + 0.5);
210 }
211 
213 {
214  return m_tile.get();
215 }
216 
218 {
219  m_tile = 0;
220 
221  if (m_reader)
222  {
223  RELEASE(m_reader);
224  m_reader = 0;
225  }
227 }
228 
230  const ossimIrect& rect, ossim_uint32 resLevel)
231 {
232  // This tile source bypassed, or invalid res level, return null tile.
233  if(!isSourceEnabled() || !isOpen() || !isValidRLevel(resLevel))
234  {
236  }
237 
238  ossimIrect imageBound = getBoundingRect(resLevel);
239  if(!rect.intersects(imageBound))
240  {
242  }
243 
244  // Check for overview.
245  if( resLevel > 0 )
246  {
247  if(theOverview.valid())
248  {
249  ossimRefPtr<ossimImageData> tileData = theOverview->getTile(rect, resLevel);
250  tileData->setScalarType(getOutputScalarType());
251  return tileData;
252  }
253  }
254 
255  m_tile->setImageRectangle(rect);
256 
257  // Compute clip rectangle with respect to the image bounds.
258  ossimIrect clipRect = rect.clipToRect(imageBound);
259 
260  if (rect.completely_within(clipRect) == false)
261  {
262  // Not filling whole tile so blank it out first.
263  m_tile->makeBlank();
264  }
265 
266  // access the point cloud with PointSource::read()
267  const ossimDpt UL_PT(m_bounds.x.min + clipRect.ul().x, m_bounds.y.min + clipRect.ul().y);
268  const ossimDpt LR_PT(m_bounds.x.min + clipRect.ul().x + clipRect.width(), m_bounds.y.min + clipRect.ul().y + clipRect.height());
269 
270  Bounds bounds(UL_PT.lon, LR_PT.lon,
271  UL_PT.lat, LR_PT.lat,
272  -HUGE_VAL, +HUGE_VAL);
273 
274  ossim_float32 fraction = 1.0/pow(2.0, (double)resLevel);
275 
276  PointIterator* iter = m_reader->createIterator(bounds, fraction, m_reader->getPointInfo(), NULL);
277 
278  // create a buffer to store the point data
279  PointData points;
280  points.init(m_reader->getPointInfo(), clipRect.width()*clipRect.height());
281 
282  size_t count = 0;
283  ossimDpt lasPt;
284  double* dataValues = new double[clipRect.width()*clipRect.height()];
285  while((count = iter->getNextPoints(points)) != 0)
286  {
287  //loop through each point
288  for(size_t i = 0; i < count; i += 1)
289  {
290  const ChannelData* channelX = points.getChannel(CHANNEL_NAME_X);
291  const ChannelData* channelY = points.getChannel(CHANNEL_NAME_Y);
292  const ChannelData* channelZ = points.getChannel(CHANNEL_NAME_Z);
293 
294  const void *dataX = channelX->getData();
295  const void *dataY = channelY->getData();
296  const void *dataZ = channelZ->getData();
297 
298  lasPt.x = static_cast<const double*>(dataX)[i];
299  lasPt.y = static_cast<const double*>(dataY)[i];
300 
301  ossim_int32 line = static_cast<ossim_int32>(lasPt.y - UL_PT.y);
302  ossim_int32 samp = static_cast<ossim_int32>(lasPt.x - UL_PT.x);
303  ossim_int32 bufIndex = line * clipRect.width() + samp;
304 
305  if (bufIndex < clipRect.width()*clipRect.height())
306  {
307  dataValues[bufIndex] = static_cast<const double*>(dataZ)[i];
308  }
309  }
310  }
311  RELEASE(iter);
312 
313  m_tile->loadBand((void*)dataValues, clipRect, 0);
314  m_tile->validate();
315 
316  delete[] dataValues;
317 
318  return m_tile;
319 }
320 
322 {
323  return 1;
324 }
325 
327 {
328  return 1;
329 }
330 
332 {
333  return 0;
334 }
335 
337 {
338  return 0;
339 }
340 
342 {
343  return m_scalarType;
344 }
345 
347 {
348  if ( !theGeometry )
349  {
350  //---
351  // Check for external geom:
352  //---
354 
355  if ( !theGeometry )
356  {
357  //---
358  // Check the internal geometry first to avoid a factory call.
359  //---
361 
362  // At this point it is assured theGeometry is set.
363 
364  // Check for set projection.
365  if ( !theGeometry->getProjection() )
366  {
367  // Try factories for projection.
369  }
370  }
371 
372  // Set image things the geometry object should know about.
374  }
375 
376  return theGeometry;
377 }
378 
380 {
381  static const char MODULE[] = "ossimMG4LidarReader::getInternalImageGeometry";
382  if (traceDebug())
383  {
384  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
385  }
386 
388 
389  // Must cast away constness.
390  ossimMG4LidarReader* th = const_cast<ossimMG4LidarReader*>(this);
392 
393  geom->setProjection(proj.get());
394 
395  return geom;
396 }
397 
399  const char* prefix)
400 {
401  bool result = false;
402 
403  if ( ossimImageHandler::loadState(kwl, prefix) )
404  {
405  result = open();
406  }
407 
408  return result;
409 }
410 
412 {
413  if (m_reader)
414  {
415  DataType pixelType = m_reader->getChannel(channelId).getDataType();
416  switch (pixelType)
417  {
418  case DATATYPE_UINT8:
419  {
421  break;
422  }
423  case DATATYPE_SINT8:
424  {
426  break;
427  }
428  case DATATYPE_UINT16:
429  {
431  break;
432  }
433  case DATATYPE_SINT16:
434  {
436  break;
437  }
438  case DATATYPE_UINT32:
439  {
441  break;
442  }
443  case DATATYPE_SINT32:
444  {
446  break;
447  }
448  case DATATYPE_FLOAT32:
449  {
451  break;
452  }
453  case DATATYPE_FLOAT64:
454  {
456  break;
457  }
458  default:
459  {
461  break;
462  }
463  }
464  }
465 }
466 
468 {
469  ossimProjection* proj = NULL;
470  if (m_reader)
471  {
472  const char* wkt = m_reader->getWKT();
473  if (wkt)
474  {
475  OGRSpatialReferenceH hSRS = NULL;
476 
477  //Translate the WKT into an OGRSpatialReference.
478  hSRS = OSRNewSpatialReference(NULL);
479  if(OSRImportFromWkt( hSRS, (char**)&wkt) != OGRERR_NONE)
480  {
481  OSRDestroySpatialReference( hSRS );
482  return NULL;
483  }
484 
485  //Determine if State Plane Coordinate System
486  const char* epsg_code = OSRGetAttrValue(hSRS, "AUTHORITY", 1);
488 
489  //get unit type
490  ossimUnitType unitType = OSSIM_METERS;
491  const char* units = OSRGetAttrValue(hSRS, "UNIT", 0);
492  bool bGeog = OSRIsGeographic(hSRS);
493  if (bGeog == false)
494  {
495  if ( units != NULL )
496  {
497  // Down case to avoid case mismatch.
498  ossimString s = units;
499  s.downcase();
500 
501  if( ( s == ossimString("us survey foot") ) ||
502  ( s == ossimString("u.s. foot") ) ||
503  ( s == ossimString("foot_us") ) )
504  {
505  unitType = OSSIM_US_SURVEY_FEET;
506  }
507  else if( s == ossimString("degree") )
508  {
509  unitType = OSSIM_DEGREES;
510  }
511  else if( s == ossimString("feet") )
512  {
513  unitType = OSSIM_FEET;
514  }
515  }
516  }
517  else
518  {
519  unitType = OSSIM_DEGREES;
520  }
521 
522  //set ul tie point and gsd
523  ossimMapProjection* mapProj = dynamic_cast<ossimMapProjection*>(proj);
524  if (mapProj)
525  {
526  double xMin = m_reader->getBounds().x.min;
527  double yMax = m_reader->getBounds().y.max;
528  double xRes = m_reader->getBounds().x.length()/m_numberOfSamples;
529  double yRes = m_reader->getBounds().y.length()/m_numberOfLines;
530  ossimDpt gsd(xRes, yRes);
531  if (mapProj->isGeographic())
532  {
533  ossimGpt tie(yMax, xMin);
534  mapProj->setUlTiePoints(tie);
535  mapProj->setDecimalDegreesPerPixel(gsd);
536  }
537  else
538  {
539  ossimDpt tie(xMin, yMax);
540  if ( unitType == OSSIM_US_SURVEY_FEET)
541  {
542  gsd = gsd * US_METERS_PER_FT;
543  tie = tie * US_METERS_PER_FT;
544  }
545  else if ( unitType == OSSIM_FEET )
546  {
547  gsd = gsd * MTRS_PER_FT;
548  tie = tie * MTRS_PER_FT;
549  }
550  mapProj->setUlTiePoints(tie);
551  mapProj->setMetersPerPixel(gsd);
552  }
553  }
554  return proj;
555  }
556  }
557  return proj;
558 }
559 
560 template<typename DTYPE>
561 const DTYPE ossimMG4LidarReader::getChannelElement(const ChannelData* channel, size_t idx)
562 {
563  DTYPE retval = static_cast<DTYPE>(0);
564  switch (channel->getDataType())
565  {
566  case (DATATYPE_FLOAT64):
567  retval = static_cast<DTYPE>(static_cast<const double*>(channel->getData())[idx]);
568  break;
569  case (DATATYPE_FLOAT32):
570  retval = static_cast<DTYPE>(static_cast<const float *>(channel->getData())[idx]);
571  break;
572  case (DATATYPE_SINT32):
573  retval = static_cast<DTYPE>(static_cast<const long *>(channel->getData())[idx]);
574  break;
575  case (DATATYPE_UINT32):
576  retval = static_cast<DTYPE>(static_cast<const unsigned long *>(channel->getData())[idx]);
577  break;
578  case (DATATYPE_SINT16):
579  retval = static_cast<DTYPE>(static_cast<const short *>(channel->getData())[idx]);
580  break;
581  case (DATATYPE_UINT16):
582  retval = static_cast<DTYPE>(static_cast<const unsigned short *>(channel->getData())[idx]);
583  break;
584  case (DATATYPE_SINT8):
585  retval = static_cast<DTYPE>(static_cast<const char *>(channel->getData())[idx]);
586  break;
587  case (DATATYPE_UINT8):
588  retval = static_cast<DTYPE>(static_cast<const unsigned char *>(channel->getData())[idx]);
589  break;
590  case (DATATYPE_SINT64):
591  retval = static_cast<DTYPE>(static_cast<const GIntBig *>(channel->getData())[idx]);
592  break;
593  case (DATATYPE_UINT64):
594  retval = static_cast<DTYPE>(static_cast<const GUIntBig *>(channel->getData())[idx]);
595  break;
596  default:
597  break;
598  }
599  return retval;
600 }
601 
virtual ossim_uint32 getNumberOfDecimationLevels() const
Returns the number of decimation levels.
virtual void loadBand(const void *src, const ossimIrect &src_rect, ossim_uint32 band)
8 bit signed integer
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
virtual ossim_uint32 getImageTileWidth() const
Returns the tile width of the image or 0 if the image is not tiled.
static ossimImageGeometryRegistry * instance()
ossimRefPtr< ossimImageGeometry > theGeometry
void setProjection(ossimProjection *projection)
Sets the projection to be used for local-to-world coordinate transformation.
64 bit floating point
ossimFilename theImageFile
virtual void setImageRectangle(const ossimIrect &rect)
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 bool open()
Open method.
16 bit unsigned integer
ossimUnitType
Represents serializable keyword/value map.
virtual ossimString getClassName() const
Returns class name.
bool valid() const
Definition: ossimRefPtr.h:75
RTTI_DEF1_INST(ossimMG4LidarReader, "ossimMG4LidarReader", ossimImageHandler) ossimMG4LidarReader
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.
double y
Definition: ossimDpt.h:165
ossim_uint32 height() const
Definition: ossimIrect.h:487
virtual void closeEntry()
Method to close current entry.
virtual bool isOpen() const
Method to test for open file stream.
virtual bool isGeographic() const
16 bit signed integer
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual void setDecimalDegreesPerPixel(const ossimDpt &gsd)
virtual ossimScalarType getOutputScalarType() const
Returns the output pixel type of the tile source.
32 bit floating point
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
32 bit unsigned integer
ossimScalarType m_scalarType
virtual bool extendGeometry(ossimImageHandler *handler) const
virtual void initialize()
Initialize the data buffer.
virtual void setMetersPerPixel(const ossimDpt &gsd)
virtual ossim_uint32 getNumberOfDecimationLevels() const
This returns the total number of decimation levels.
virtual bool isValidRLevel(ossim_uint32 resLevel) const
Determines if the passed in reslution level is valid.
bool completely_within(const ossimIrect &rect) const
Definition: ossimIrect.cpp:425
virtual ossimRefPtr< ossimImageGeometry > getInternalImageGeometry() const
#define US_METERS_PER_FT
ossim_uint32 m_numberOfSamples
Has sub image offset.
static ossimImageDataFactory * instance()
ossimProjection * getGeoProjection()
ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const
Gets the number of samples for res level.
void getDataType(ossim_int32 channelId)
virtual ossimDataObjectStatus validate() const
32 bit signed integer
unsigned int ossim_uint32
virtual ossimString getShortName() const
Returns short name.
virtual void close()
Deletes the overview and clears the valid image vertices.
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
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 ~ossimMG4LidarReader()
virtural destructor
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if non defined...
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
ossimScalarType
virtual ossim_uint32 getNumberOfInputBands() const
Returns the number of bands in the image.
static ossimProjectionFactoryRegistry * instance()
virtual ossimRefPtr< ossimImageGeometry > getExternalImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
#define MTRS_PER_FT
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.
ossimRefPtr< ossimImageHandler > theOverview
void openZoomLevel(ossim_int32 zoom)
ossimRefPtr< ossimImageData > m_tile
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual ossim_uint32 getImageTileHeight() const
Returns the tile width of the image or 0 if the image is not tiled.
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
#define max(a, b)
Definition: auxiliary.h:76
ossim_int32 y
Definition: ossimIpt.h:142
double x
Definition: ossimDpt.h:164
virtual ossimString getLongName() const
Returns long name.
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
virtual void setUlTiePoints(const ossimGpt &gpt)
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
Returns zero-based bounding rectangle of the image.
ossim_int32 x
Definition: ossimIpt.h:141
8 bit unsigned integer
virtual void setScalarType(ossimScalarType type)
See ossimScalarType in ossimConstants for a full list.
ossimMG4LidarReader()
default construtor
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
Method to grab a tile(rectangle) from image.
MG4PointReader * m_reader
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
const DTYPE getChannelElement(const ChannelData *channel, size_t idx)
virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const
Gets number of lines for res level.