OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimPdalReader.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$
9 
10 #include "ossimPdalReader.h"
12 #include <ossim/base/ossimNotify.h>
13 #include <ossim/base/ossimGpt.h>
16 #include <pdal/PointViewIter.hpp>
17 
19 
20 using namespace pdal;
21 using namespace pdal::Dimension;
22 
24 : m_currentPV (0),
25  m_currentPvOffset (0),
26  m_pdalPipe (0),
27  m_availableFields(0)
28 {
29  // create unity-transform, geographic geometry. derived classes may overwrite this later
31 }
32 
35 {
36  delete m_pdalPipe;
37 }
38 
40 {
42  if (m_pvs.size())
43  m_currentPV = *(m_pvs.begin());
44  else
45  m_currentPV = 0;
46  m_currentPID = 0;
47 }
48 
50 {
51  ossim_uint32 field_code = block.getFieldCode();
52  while (m_currentPvOffset < m_currentPV->size())
53  {
54  if (block.size() == maxNumPoints)
55  break;
56 
57  // Convert point data to OSSIM-friendly format:
58 #ifdef NORMALIZE_FIELDS
59  ossim_float32 minI, delI, minC, delC;
60  bool hasIntensity = false;
61  bool hasRGB = false;
62  if (field_code & ossimPointRecord::Intensity)
63  {
64  hasIntensity = true;
67  }
69  if ((field_code & rgb_code) == rgb_code)
70  {
71  hasRGB = true;
74  }
75 #endif
76 
77  // cout << "ossimPdalReader::parsePointView() -- point_id = "<< point_id<<endl;
78 
79  // Reads directly from the PDAL point buffer:
80  ossimRefPtr<ossimPointRecord> opr = new ossimPointRecord(field_code);
81  parsePoint(opr.get());
82 
83  // Normalize intensity and color:
84 #ifdef NORMALIZE_FIELDS
85  if (hasIntensity)
86  {
87  float normI = (opr->getField(ossimPointRecord::Intensity) - minI) / delI;
89  }
90  if (hasRGB)
91  {
92  float normC = (opr->getField(ossimPointRecord::Red) - minC) / delC;
93  opr->setField(ossimPointRecord::Red, normC);
94  normC = (opr->getField(ossimPointRecord::Green) - minC) / delC;
95  opr->setField(ossimPointRecord::Green, normC);
96  normC = (opr->getField(ossimPointRecord::Blue) - minC) / delC;
97  opr->setField(ossimPointRecord::Blue, normC);
98  }
99 #endif
100 
101  // Add this point to the output block:
102  opr->setPointId(m_currentPID++);
103  block.addPoint(opr.get());
105  }
106 }
107 
109 {
110  if (!point)
111  return;
112 
113  ossimDpt3d dpt3d;
114  ossim_uint8 I8;
115  float F32;
116 
117  // The ossimPointRecord should already be initialized with the desired fields set to default
118  // values (i.e., their NULL values):
119  const IdList& idList = m_currentPV->dims();
120  IdList::const_iterator dim_iter = idList.begin();
121  while (dim_iter != idList.end())
122  {
123  Id::Enum id = *dim_iter;
124  switch (id)
125  {
126  case Id::Enum::X: // always do position
127  dpt3d.x = m_currentPV->getFieldAs<double>(Id::Enum::X, m_currentPvOffset);
128  break;
129  case Id::Enum::Y: // always do position
130  dpt3d.y = m_currentPV->getFieldAs<double>(Id::Enum::Y, m_currentPvOffset);
131  break;
132  case Id::Enum::Z: // always do position
133  dpt3d.z = m_currentPV->getFieldAs<double>(Id::Enum::Z, m_currentPvOffset);
134  break;
135  case Id::Enum::ReturnNumber:
137  {
138  I8 = m_currentPV->getFieldAs<uint8_t>(Id::Enum::ReturnNumber, m_currentPvOffset);
140  }
141  break;
142  case Id::Enum::NumberOfReturns:
144  {
145  I8 = m_currentPV->getFieldAs<uint8_t>(Id::Enum::NumberOfReturns, m_currentPvOffset);
147  }
148  break;
149  case Id::Enum::Intensity:
151  {
152  F32 = m_currentPV->getFieldAs<float>(Id::Enum::Intensity, m_currentPvOffset);
154  }
155  break;
156  case Id::Enum::Red:
157  if (point->hasFields(ossimPointRecord::Red))
158  {
159  F32 = m_currentPV->getFieldAs<float>(Id::Enum::Red, m_currentPvOffset);
161  }
162  break;
163  case Id::Enum::Green:
165  {
166  F32 = m_currentPV->getFieldAs<float>(Id::Enum::Green, m_currentPvOffset);
168  }
169  break;
170  case Id::Enum::Blue:
171  if (point->hasFields(ossimPointRecord::Blue))
172  {
173  F32 = m_currentPV->getFieldAs<float>(Id::Enum::Blue, m_currentPvOffset);
175  }
176  break;
177  case Id::Enum::Infrared:
179  {
180  F32 = m_currentPV->getFieldAs<float>(Id::Enum::Infrared, m_currentPvOffset);
182  }
183  break;
184  case Id::Enum::GpsTime:
186  {
187  F32 = m_currentPV->getFieldAs<float>(Id::Enum::GpsTime, m_currentPvOffset);
189  }
190  break;
191  default:
192  break;
193  }
194  ++dim_iter;
195  }
196 
197  // Need to convert X, Y, Z to geographic point (if necessary).
198  ossimGpt pos;
199  m_geometry->convertPos(dpt3d, pos);
200  point->setPosition(pos);
201 }
202 
204 {
205  rewind();
206 
207  PointViewSet::iterator pvs_iter = m_pvs.begin();
208  if ((pvs_iter == m_pvs.end()) || (*pvs_iter)->empty())
209  return;
210 
211  if (!m_minRecord.valid())
212  {
215  }
216 
217  // Latch first point:
218  m_currentPV = *pvs_iter;
221  ossimGpt minPos (m_minRecord->getPosition());
222  ossimGpt maxPos (minPos);
223 
224  // Set up loop over all point view sets:
226  while (pvs_iter != m_pvs.end())
227  {
228  // Set up loop over points in each PointView:
229  m_currentPV = *pvs_iter;
230  m_currentPvOffset = 0;
231 
232  // Now loop over all points in PV to latch min/max:
233  PointViewIter pv_iter = m_currentPV->begin();
234  while (pv_iter != m_currentPV->end())
235  {
236  parsePoint(opr.get());
237 
238  if (opr->getPosition().lat < minPos.lat)
239  minPos.lat = opr->getPosition().lat;
240  if (opr->getPosition().lon < minPos.lon)
241  minPos.lon = opr->getPosition().lon;
242  if (opr->getPosition().hgt < minPos.hgt)
243  minPos.hgt = opr->getPosition().hgt;
244 
245  if (opr->getPosition().lat > maxPos.lat)
246  maxPos.lat = opr->getPosition().lat;
247  if (opr->getPosition().lon > maxPos.lon)
248  maxPos.lon = opr->getPosition().lon;
249  if (opr->getPosition().hgt > maxPos.hgt)
250  maxPos.hgt = opr->getPosition().hgt;
251 
252  std::map<ossimPointRecord::FIELD_CODES, ossim_float32>::const_iterator field =
253  opr->getFieldMap().begin();
254  while (field != opr->getFieldMap().end())
255  {
256  if (field->second < m_minRecord->getField(field->first))
257  m_minRecord->setField(field->first, field->second);
258  else if (field->second > m_maxRecord->getField(field->first))
259  m_maxRecord->setField(field->first, field->second);
260  ++field;
261  }
262  ++pv_iter;
264  }
265  ++pvs_iter;
266  }
267 
268  m_minRecord->setPosition(minPos);
269  m_maxRecord->setPosition(maxPos);
270 
271  // Latch overall min and max color band to avoid color distortion when normalizing:
275  if (m_minRecord->hasFields(R|G|B))
276  {
280  float c = std::min(r, std::min(g, b));
281  m_minRecord->setField(R, c);
282  m_minRecord->setField(G, c);
283  m_minRecord->setField(B, c);
284 
285  r = m_maxRecord->getField(R);
286  g = m_maxRecord->getField(G);
287  b = m_maxRecord->getField(B);
288  c = std::max(r, std::max(g, b));
289  m_maxRecord->setField(R, c);
290  m_maxRecord->setField(G, c);
291  m_maxRecord->setField(B, c);
292  }
293 
294  rewind();
295 }
296 
298 {
299  ossim_uint32 numPoints = 0;
300 
301  PointViewSet::iterator pvs_iter = m_pvs.begin();
302  while (pvs_iter != m_pvs.end())
303  {
304  numPoints += (*pvs_iter)->size();
305  ++pvs_iter;
306  }
307 
308  return numPoints;
309 }
310 
312 {
313  m_availableFields = 0;
314  if (!m_currentPV)
315  return;
316 
317  if (m_currentPV->hasDim(Id::Enum::Intensity))
319  if (m_currentPV->hasDim(Id::Enum::ReturnNumber))
321  if (m_currentPV->hasDim(Id::Enum::NumberOfReturns))
323  if (m_currentPV->hasDim(Id::Enum::Red))
325  if (m_currentPV->hasDim(Id::Enum::Green))
327  if (m_currentPV->hasDim(Id::Enum::Blue))
329  if (m_currentPV->hasDim(Id::Enum::GpsTime))
331  if (m_currentPV->hasDim(Id::Enum::Infrared))
333 }
334 
335 
ossimRefPtr< ossimPointRecord > m_maxRecord
const std::map< FIELD_CODES, ossim_float32 > & getFieldMap() const
pdal::Stage * m_pdalPipe
virtual ossim_uint32 getNumPoints() const
Returns number of points in the data file.
ossim_uint32 getFieldCode() const
Returns OR&#39;d mash-up of ossimPointRecord field codes being stored (or desired to be stored) ...
ossim_uint32 m_currentPvOffset
bool valid() const
Definition: ossimRefPtr.h:75
float ossim_float32
ossim_float32 getField(FIELD_CODES fc) const
Return the float value of the requested field.
pdal::PointViewPtr m_currentPV
virtual void establishAvailableFields()
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
void parsePointView(ossimPointBlock &block, ossim_uint32 maxNumPoints=0xFFFFFFFF) const
The current point ID (pid) gets updated.
virtual ossim_uint32 getFieldCode() const
Fetches the data fields ids available from this source, OR&#39;d together for testing against specific fi...
virtual void addPoint(ossimPointRecord *point)
Adds single point to the tail of the list.
ossim_uint32 m_availableFields
double z
Definition: ossimDpt3d.h:145
void parsePoint(ossimPointRecord *precord) const
Need to pass allocated ossimPointRecord with field code set to desired fields.
yy_size_t size
ossim_float64 lon
Definition: ossimGpt.h:266
unsigned int ossim_uint32
virtual bool hasFields(ossim_uint32 code_mashup) const
Argument can be mash-up of OR&#39;d codes for check of multiple fields.
virtual ossim_uint32 size() const
Returns allocated size.
void convertPos(const ossimDpt3d &stored_pos, ossimGpt &converted_gpos) const
Method converts a generic 3D point as stored in the argument ossim3Dpt object, and converts it to an ...
#define max(a, b)
Definition: auxiliary.h:76
virtual ~ossimPdalReader()
virtual destructor
virtual ossim_uint32 getFieldCode() const
Returns mash-up of OR&#39;d codes of multiple fields being stored.
double x
Definition: ossimDpt3d.h:143
virtual void rewind() const
bool hasRGB() const
Special for convenience.
virtual void establishMinMax()
Computes min and max records using points in the current PointViewSet.
const ossimGpt & getPosition() const
Returns the 3D position vector in the dataset&#39;s coodinate reference system (available from the ossimP...
ossim_float64 lat
Definition: ossimGpt.h:265
void setField(FIELD_CODES fc, ossim_float32 value)
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
double y
Definition: ossimDpt3d.h:144
ossimRefPtr< ossimPointCloudGeometry > m_geometry
Base class for all point-cloud file readers.
void setPosition(const ossimGpt &p)
ossimRefPtr< ossimPointRecord > m_minRecord
unsigned char ossim_uint8
void setPointId(ossim_uint32 id)
pdal::PointViewSet m_pvs
ossimPdalReader()
default constructor
#define min(a, b)
Definition: auxiliary.h:75