/
Schema.hpp
281 lines (228 loc) · 10.3 KB
/
Schema.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/******************************************************************************
* $Id$
*
* Project: libLAS - http://liblas.org - A BSD library for LAS format data.
* Purpose: LAS Schema implementation for C++ libLAS
* Author: Howard Butler, hobu.inc@gmail.com
*
******************************************************************************
* Copyright (c) 2010, Howard Butler
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the Martin Isenburg or Iowa Department
* of Natural Resources nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/
#ifndef PDAL_SCHEMA_HPP_INCLUDED
#define PDAL_SCHEMA_HPP_INCLUDED
#include <vector>
#include <map>
#include <pdal/pdal_internal.hpp>
#include <pdal/Dimension.hpp>
// boost
#include <boost/cstdint.hpp>
#include <boost/any.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <boost/array.hpp>
#include <boost/optional.hpp>
#include <pdal/third/string_ref.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/functional/hash.hpp>
namespace pdal
{
namespace schema
{
struct name {};
struct position {};
struct index {};
struct uid {};
typedef boost::multi_index::multi_index_container<
Dimension,
boost::multi_index::indexed_by<
// sort by Dimension::operator<
boost::multi_index::ordered_non_unique<boost::multi_index::tag<position>, boost::multi_index::identity<Dimension> >,
// Random access
boost::multi_index::random_access<boost::multi_index::tag<index> >,
// sort by less<string> on GetName
boost::multi_index::hashed_non_unique<boost::multi_index::tag<name>, boost::multi_index::const_mem_fun<Dimension,std::string const&,&Dimension::getName> >,
boost::multi_index::hashed_non_unique<boost::multi_index::tag<uid>, boost::multi_index::const_mem_fun<Dimension,dimension::id const&,&Dimension::getUUID> >
>
> Map;
typedef Map::index<name>::type index_by_name;
typedef Map::index<position>::type index_by_position;
typedef Map::index<index>::type index_by_index;
typedef Map::index<uid>::type index_by_uid;
typedef boost::uint32_t size_type;
typedef std::map<Dimension const*, Dimension const*> DimensionMap;
enum Orientation
{
POINT_INTERLEAVED = 1,
DIMENSION_INTERLEAVED = 2,
UNKNOWN_INTERLEAVED = 256
};
}
/// A pdal::Schema is a composition of pdal::Dimension instances that form
/// a point cloud.
class PDAL_DLL Schema
{
public:
/// @name Constructors
/// An empty constructor with no Dimension instances
Schema();
/// construct an instanct given the order and dimensions in the dimensions vector
/// @param dimensions the list of dimensions (and their order) to use to construct the Schema
Schema(std::vector<Dimension> const& dimensions);
/// Copy constructor
Schema(Schema const& other);
/// Assignment constructor
Schema& operator=(Schema const& rhs);
/// @name Equality
/// Equality
bool operator==(const Schema& other) const;
/// Inequality
bool operator!=(const Schema& other) const;
/// @name Dimension manipulation
/// adds (copies) a Dimension instance to the Schema
/// @param dim a Dimension that is copied and added to the end of the Schema
void appendDimension(Dimension const& dim);
/*! overwrites an existing Dimension with the same name as dim
\param dim the Dimension instance that contains the name and namespace
to overwrite in the Schema.
\verbatim embed:rst
.. note::
If no namespace is given, the *first* dimension with a matching
:cpp:func:`pdal::Dimension::getName()` will be overwritten. To be
sure, have set the namespace of the pdal::Dimension using
:cpp:func:`pdal::Dimension::setNamespace()` beforehand.
\endverbatim
*/
bool setDimension(Dimension const& dim);
/// @return the boost::multi_index map that contains the Dimension instances
inline schema::Map const& getDimensions() const
{
return m_index;
}
/// @name Dimension access
/// @return a const& to a Dimension with the given name and namespace. If
/// no matching dimension is found, pdal::dimension_not_found is thrown.
/// @param name name to use when searching
/// @param ns namespace to use when searching. If none is given, the first
/// matching Dimension instance with name \b name is returned.
const Dimension& getDimension(pdal::string_ref name,
pdal::string_ref ns = string_ref()) const;
/// @return a const& to a Dimension with the given dimension::id. If
/// no matching dimension is found, pdal::dimension_not_found is thrown.
/// @param id id to use when searching
const Dimension& getDimension(dimension::id const& id) const;
/// @return a const& to Dimension with the given index. If the
/// index is out of range, pdal::dimension_not_found is thrown.
/// @param index position index to return.
const Dimension& getDimension(schema::size_type index) const;
/// @return A pointer to a Dimension with the given name and namespace. If
/// no matching dimension is found, the null pointer is returned. The
/// optional errorMsg parameter will be filled with a descriptive error
/// message in the case that the dimension cannot found.
/// @param name name to use when searching
/// @param ns namespace to use when searching. If none is given, the first
/// matching Dimension instance with name \b name is returned.
/// @param errorMsg optional location for storing error messages
const Dimension* getDimensionPtr(string_ref name,
string_ref ns = string_ref(),
std::string* errorMsg = 0) const;
/// @return a boost::optional-wrapped const& to a Dimension with the given name
/// and namespace. If no matching dimension is found, the optional will be empty.
/// @param name name to use when searching
/// @param ns namespace to use when searching. If none is given, the first
/// matching Dimension instance with name \b name is returned.
boost::optional<Dimension const&> getDimensionOptional(string_ref name,
string_ref ns=string_ref()) const;
/// @return a boost::optional-wrapped const& to a Dimension with the given dimension::id.
/// If no matching dimension is found, the optional will be empty.
/// @param id id to use when searching
boost::optional<Dimension const&> getDimensionOptional(dimension::id const& id) const;
/// @return a boost::optional-wrapped const& to a Dimension with the given
/// index. If the index is out of range, the optional will be empty.
/// @param index position index to return.
boost::optional<Dimension const&> getDimensionOptional(schema::size_type index) const;
/// @return the total cumulative byte size of all dimensions
inline schema::size_type const& getByteSize() const
{
return m_byteSize;
}
/// @return the number of dimensions in this Schema instance
inline schema::size_type size() const
{
return m_index.get<schema::name>().size();
}
inline schema::Orientation getOrientation() const
{
return m_orientation;
}
/// @name Summary and serialization
/// @return a boost::property_tree representing the Schema
/*!
\verbatim embed:rst
::
lo:
dimension:
[Dimension ptree]
dimension:
[Dimension ptree]
\endverbatim
*/
boost::property_tree::ptree toPTree() const;
/// @return a schema::DimensionMap instance that maps dimension names
schema::DimensionMap* mapDimensions(Schema const& destination) const;
/// dumps a string representation of the Schema instance to std::cout
void dump() const;
/// Deserialize a Schema instance from the given xml and validate against the
/// given xsd
/// @param xml xml data to ingest
/// @param xsd xsd document to use for validation
static Schema from_xml(std::string const& xml, std::string const& xsd);
/// Deserialize a Schema instance from the given xml
/// @param xml xml data to ingest
static Schema from_xml(std::string const& xml);
/// @return serialized Schema instance as xml
static std::string to_xml(Schema const& schema, boost::property_tree::ptree const* metadata=0);
/// @name Private Attributes
private:
schema::size_type m_byteSize;
schema::Orientation m_orientation;
schema::Map m_index;
};
PDAL_DLL std::ostream& operator<<(std::ostream& os, pdal::Schema const& d);
} // namespace liblas
#endif // PDAL_SCHEMA_HPP_INCLUDED