OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimPdalFileReader.cpp
Go to the documentation of this file.
1 //**************************************************************************************************
2 //
3 // OSSIM (http://trac.osgeo.org/ossim/)
4 //
5 // License: LGPL -- See LICENSE.txt file in the top level directory for more details.
6 //
7 //**************************************************************************************************
8 // $Id: ossimPdalFileReader.cpp 23401 2015-06-25 15:00:31Z okramer $
9 
10 #include "ossimPdalFileReader.h"
12 #include <ossim/base/ossimNotify.h>
13 #include <ossim/base/ossimGpt.h>
16 #include <pdal/pdal.hpp>
17 #include <pdal/PointViewIter.hpp>
18 #include <pdal/StatsFilter.hpp>
19 #include <pdal/Reader.hpp>
20 #include <pdal/FauxReader.hpp>
21 
22 
23 RTTI_DEF1(ossimPdalFileReader, "ossimPdalFileReader" , ossimPdalReader)
24 
25 using namespace pdal;
26 using namespace pdal::Dimension;
27 
29 {
30 }
31 
34 {
35 }
36 
38 {
39  // PDAL opens the file here.
40  m_inputFilename = fname;
41  pdal::Stage* reader = 0;
42  try
43  {
44  if (m_inputFilename.contains("fauxreader"))
45  {
46  // Debug generated image:
47  reader = new FauxReader;
48  m_pdalPipe = reader;
49  m_pdalOptions.add("mode", "ramp");
50  BOX3D bbox(-0.001, -0.001, -100.0, 0.001, 0.001, 100.0);
51  m_pdalOptions.add("bounds", bbox);
52  m_pdalOptions.add("num_points", "11");
53  m_pdalPipe->setOptions(m_pdalOptions);
54  }
55  else
56  {
57  StageFactory factory;
58  const string driver = factory.inferReaderDriver(m_inputFilename.string());
59  if (driver == "")
60  throw pdal_error("File type not supported by PDAL");
61  reader = factory.createStage(driver);
62  if (!reader)
63  throw pdal_error("No reader created by PDAL");
64 
65  m_pdalOptions.add("filename", m_inputFilename.string());
66  reader->setOptions(m_pdalOptions);
67 
68  // Stick a stats filter in the pipeline:
69  m_pdalPipe = new StatsFilter();
70  m_pdalPipe->setInput(*reader);
71  }
72 
73  m_pointTable = PointTablePtr(new PointTable);
74  m_pdalPipe->prepare(*m_pointTable);
75  m_pvs = m_pdalPipe->execute(*m_pointTable);
76  if (!m_pvs.empty())
77  {
78  m_currentPV = *(m_pvs.begin());
79 
80  // Determine available data fields:
81  establishAvailableFields();
82  }
83 
84  std::string wkt;
85  const SpatialReference& srs = reader->getSpatialReference();
86  wkt = srs.getWKT(SpatialReference::eCompoundOK, false);
87  m_geometry = new ossimPointCloudGeometry(wkt);
88  }
89  catch (std::exception& e)
90  {
91  //ossimNotify() << e.what() << endl;
92  return false;
93  }
94 
95  // Establish the bounds (geographic & radiometric). These are stored in two extreme point records
96  // maintained by the base class:
97  establishMinMax();
98 
99  return true;
100 }
101 
103 {
104  if (!m_currentPV)
105  return 0;
106 
107  return m_currentPV->size();
108 }
109 
110 
112  ossimPointBlock& block,
113  ossim_uint32 requested) const
114 {
115  // A single input file means a single point view coming out of the manager:
116  if (!m_currentPV)
117  {
118  block.clear();
119  return;
120  }
121 
122  ossim_uint32 numPoints = m_currentPV->size();
123 
124  // Expecting the block object passed in to have been allocated to the desired block size before
125  // this call. Interpreting a size = 0 to mean do nothing:
126  if ((requested == 0) || (offset >= numPoints))
127  {
128  block.clear();
129  return;
130  }
131 
132  m_currentPID = offset;
133  parsePointView(block, requested);
134 }
135 
137 {
138  if (!m_pdalPipe || !m_currentPV || !m_geometry.valid())
139  return;
140 
141 #define USE_STATS_FILTER
142 #ifdef USE_STATS_FILTER
143 
144  if (!m_minRecord.valid())
145  {
146  m_minRecord = new ossimPointRecord(getFieldCode());
147  m_maxRecord = new ossimPointRecord(getFieldCode());
148  }
149 
150  // Attempt to cast down to a stats filter for faster min/max access:
151  ossimString filterName(m_pdalPipe->getName());
152  if (!filterName.contains("filters.stats"))
153  {
155  return;
156  }
157  pdal::StatsFilter* stats = (pdal::StatsFilter*) m_pdalPipe;
158 
159  // The ossimPointRecord should already be initialized with the desired fields set to default
160  // values (i.e., their NULL values):
161  ossimDpt3d minPt, maxPt;
162  const IdList& idList = m_currentPV->dims();
163  IdList::const_iterator dim_iter = idList.begin();
164  while (dim_iter != idList.end())
165  {
166  Id::Enum id = *dim_iter;
167  const stats::Summary& summary = stats->getStats(id);
168 
169  switch (id)
170  {
171  case Id::Enum::X: // always do position
172  minPt.x = summary.minimum();
173  maxPt.x = summary.maximum();
174  break;
175  case Id::Enum::Y: // always do position
176  minPt.y = summary.minimum();
177  maxPt.y = summary.maximum();
178  break;
179  case Id::Enum::Z: // always do position
180  minPt.z = summary.minimum();
181  maxPt.z = summary.maximum();
182  break;
183  case Id::Enum::ReturnNumber:
184  if (hasFields(ossimPointRecord::ReturnNumber))
185  {
186  m_minRecord->setField(ossimPointRecord::ReturnNumber, (ossim_float32) summary.minimum());
187  m_maxRecord->setField(ossimPointRecord::ReturnNumber, (ossim_float32) summary.maximum());
188  }
189  break;
190  case Id::Enum::NumberOfReturns:
191  if (hasFields(ossimPointRecord::NumberOfReturns))
192  {
193  m_minRecord->setField(ossimPointRecord::NumberOfReturns, (ossim_float32) summary.minimum());
194  m_maxRecord->setField(ossimPointRecord::NumberOfReturns, (ossim_float32) summary.maximum());
195  }
196  break;
197  case Id::Enum::Intensity:
198  if (hasFields(ossimPointRecord::Intensity))
199  {
200  m_minRecord->setField(ossimPointRecord::Intensity, (ossim_float32) summary.minimum());
201  m_maxRecord->setField(ossimPointRecord::Intensity, (ossim_float32) summary.maximum());
202  }
203  break;
204  case Id::Enum::Red:
205  if (hasFields(ossimPointRecord::Red))
206  {
207  m_minRecord->setField(ossimPointRecord::Red, (ossim_float32) summary.minimum());
208  m_maxRecord->setField(ossimPointRecord::Red, (ossim_float32) summary.maximum());
209  }
210  break;
211  case Id::Enum::Green:
212  if (hasFields(ossimPointRecord::Green))
213  {
214  m_minRecord->setField(ossimPointRecord::Green, (ossim_float32) summary.minimum());
215  m_maxRecord->setField(ossimPointRecord::Green, (ossim_float32) summary.maximum());
216  }
217  break;
218  case Id::Enum::Blue:
219  if (hasFields(ossimPointRecord::Blue))
220  {
221  m_minRecord->setField(ossimPointRecord::Blue, (ossim_float32) summary.minimum());
222  m_maxRecord->setField(ossimPointRecord::Blue, (ossim_float32) summary.maximum());
223  }
224  break;
225  case Id::Enum::Infrared:
226  if (hasFields(ossimPointRecord::Infrared))
227  {
228  m_minRecord->setField(ossimPointRecord::Infrared, (ossim_float32) summary.minimum());
229  m_maxRecord->setField(ossimPointRecord::Infrared, (ossim_float32) summary.maximum());
230  }
231  break;
232  case Id::Enum::GpsTime:
233  if (hasFields(ossimPointRecord::GpsTime))
234  {
235  m_minRecord->setField(ossimPointRecord::GpsTime, (ossim_float32) summary.minimum());
236  m_maxRecord->setField(ossimPointRecord::GpsTime, (ossim_float32) summary.maximum());
237  }
238  break;
239  default:
240  break;
241  }
242  ++dim_iter;
243  }
244 
245  // Need to convert X, Y, Z to geographic point (if necessary).
246  ossimGpt min_gpt, max_gpt;
247  m_geometry->convertPos(minPt, min_gpt);
248  m_minRecord->setPosition(min_gpt);
249  m_geometry->convertPos(maxPt, max_gpt);
250  m_maxRecord->setPosition(max_gpt);
251 
252 #else
253 
255 
256 #endif
257 
258 }
ossimPdalFileReader()
default constructor
float ossim_float32
virtual ossim_uint32 getNumPoints() const
Returns number of points in the data file.
virtual ~ossimPdalFileReader()
virtual destructor
std::shared_ptr< pdal::PointTable > PointTablePtr
virtual bool open(const ossimFilename &fname)
Accepts the name of a point cloud file.
virtual void clear()
Resets any storage to empty.
double z
Definition: ossimDpt3d.h:145
unsigned int ossim_uint32
virtual void getFileBlock(ossim_uint32 offset, ossimPointBlock &block, ossim_uint32 maxNumPoints=0xFFFFFFFF) const
Fetches up to maxNumPoints points at the given dataset <offset> in the order they appear in the data ...
double x
Definition: ossimDpt3d.h:143
virtual void establishMinMax()
Computes min and max records using points in the current PointViewSet.
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
double y
Definition: ossimDpt3d.h:144
virtual void establishMinMax()
Computes min and max records using points in the current PointViewSet.