1 /******************************************************************************
2 * Copyright (c) 2014,  Hobu Inc., hobu@hobu.co
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following
7 * conditions are met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 *       notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above copyright
12 *       notice, this list of conditions and the following disclaimer in
13 *       the documentation and/or other materials provided
14 *       with the distribution.
15 *     * Neither the name of Hobu, Inc. nor the names of its contributors
16 *       may be used to endorse or promote products derived from this
17 *       software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 * OF SUCH DAMAGE.
31 ****************************************************************************/
32 
33 #include <pdal/DbReader.hpp>
34 #include <pdal/PDALUtils.hpp>
35 
36 namespace pdal
37 {
38 
loadSchema(PointLayoutPtr layout,const std::string & schemaString)39 void DbReader::loadSchema(PointLayoutPtr layout,
40     const std::string& schemaString)
41 {
42     XMLSchema schema(schemaString);
43     loadSchema(layout, schema);
44 }
45 
loadSchema(PointLayoutPtr layout,const XMLSchema & schema)46 void DbReader::loadSchema(PointLayoutPtr layout, const XMLSchema& schema)
47 {
48     m_layout = layout;
49     m_dims = schema.xmlDims();
50 
51     // Always register X, Y and Z.  We will apply any scaling set
52     // before handing it off to PDAL.
53     using namespace Dimension;
54     layout->registerDims( {Id::X, Id::Y, Id::Z} );
55 
56     m_orientation = schema.orientation();
57     m_packedPointSize = 0;
58     for (auto di = m_dims.begin(); di != m_dims.end(); ++di)
59     {
60         di->m_dimType.m_id =
61             layout->registerOrAssignDim(di->m_name, di->m_dimType.m_type);
62         m_packedPointSize += Dimension::size(di->m_dimType.m_type);
63     }
64 }
65 
66 
67 // If we start reading from a DB block with a different schema, reflect that
68 // in the dimensions and size.
updateSchema(const XMLSchema & schema)69 void DbReader::updateSchema(const XMLSchema& schema)
70 {
71     m_dims = schema.xmlDims();
72     m_orientation = schema.orientation();
73     m_packedPointSize = 0;
74     for (auto di = m_dims.begin(); di != m_dims.end(); ++di)
75     {
76         di->m_dimType.m_id = m_layout->findDim(di->m_name);
77         m_packedPointSize += Dimension::size(di->m_dimType.m_type);
78     }
79 }
80 
81 
dbDimTypes() const82 DimTypeList DbReader::dbDimTypes() const
83 {
84     DimTypeList dimTypes;
85 
86     for (auto di = m_dims.begin(); di != m_dims.end(); ++di)
87         dimTypes.push_back(di->m_dimType);
88     return dimTypes;
89 }
90 
91 
dimOffset(Dimension::Id id) const92 size_t DbReader::dimOffset(Dimension::Id id) const
93 {
94     size_t offset = 0;
95     for (auto di = m_dims.begin(); di != m_dims.end(); ++di)
96     {
97         if (di->m_dimType.m_id == id)
98             break;
99         offset += Dimension::size(di->m_dimType.m_type);
100     }
101     return offset;
102 }
103 
104 
writeField(PointRef & point,const char * pos,const DimType & dim)105 void DbReader::writeField(PointRef& point, const char *pos, const DimType &dim)
106 {
107     using namespace Dimension;
108 
109     if (dim.m_id == Id::X || dim.m_id == Id::Y || dim.m_id == Id::Z)
110     {
111         Everything e;
112 
113         memcpy(&e, pos, Dimension::size(dim.m_type));
114         double d = Utils::toDouble(e, dim.m_type);
115         d = (d * dim.m_xform.m_scale.m_val) + dim.m_xform.m_offset.m_val;
116         point.setField(dim.m_id, d);
117     }
118     else
119         point.setField(dim.m_id, dim.m_type, pos);
120 }
121 
122 
123 /// Write a point's packed data into a buffer.
124 /// \param[in] point PointRef to write to.
125 /// \param[in] buf  Pointer to packed DB point data.
writePoint(PointRef & point,const char * buf)126 void DbReader::writePoint(PointRef& point, const char *buf)
127 {
128     for (auto di = m_dims.begin(); di != m_dims.end(); ++di)
129     {
130         writeField(point, buf, di->m_dimType);
131         buf += Dimension::size(di->m_dimType.m_type);
132     }
133 }
134 
135 } // namespace pdal
136