RDB 2
pointAttributes.hpp
Go to the documentation of this file.
1 /*
2  *******************************************************************************
3  *
4  * Copyright 2021 RIEGL Laser Measurement Systems
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  *
20  *******************************************************************************
21  */
22 /*!
23  *******************************************************************************
24  *
25  * \file pointAttributes.hpp
26  * \author RIEGL LMS GmbH, Austria
27  * \brief Manage point attributes
28  * \version 2015-10-14/AW: Initial version
29  * \version 2016-01-04/AW: Added function to duplicate point attribute data
30  * \version 2016-01-11/AW: Added function to discard point attribute data
31  * \version 2016-11-29/AW: Added function to define a RIEGL point attribute
32  * \version 2017-03-23/AW: Added function to modify point attribute details
33  * \version 2017-11-09/AW: Added function to merge point attribute details
34  * \version 2017-11-24/AW: Constructors declared as "explicit" (#2825)
35  * \version 2019-04-15/AW: Added function to query point attribute group (#3342)
36  * \version 2020-12-02/AW: put() accepts name, title, description & unit (#3750)
37  *
38  *******************************************************************************
39  */
40 
41 #ifndef RIEGL_RDB_POINTCLOUD_POINTATTRIBUTES_HPP
42 #define RIEGL_RDB_POINTCLOUD_POINTATTRIBUTES_HPP
43 
44 //---< INCLUDES >---------------------------------------------------------------
45 
46 #include <memory>
47 #include <string>
48 #include <vector>
52 
53 //---< NAMESPACE >--------------------------------------------------------------
54 
55 namespace riegl {
56 namespace rdb {
57 
58 class Pointcloud; // forward declaration
59 
60 namespace pointcloud {
61 
62 //---< CLASS PointAttributes >--------------------------------------------------
63 /*!
64  * \brief Manage point attributes
65  *
66  * This class allows to manage point attributes (dimensions).
67  *
68  * When creating a new database, each point has at least two attributes:
69  *
70  * - an unique point identifier (ID)
71  * - the primary attribute specified in CreateSettings::primaryAttribute
72  *
73  * Both attributes cannot be deleted or modified in any way.
74  *
75  * The point identifier attribute is always named "id" and is an unsigned 64
76  * bit integer number (see DataTypes::UINT64, pointIDType() and pointIDName()).
77  *
78  * \see riegl::rdb::Pointcloud::pointAttribute()
79  */
81 {
82 public:
83  /*!
84  * \brief Constructor
85  * \note You cannot create new PointAttributes objects directly,
86  * use riegl::rdb::Pointcloud::pointAttribute() instead.
87  */
88  explicit PointAttributes(riegl::rdb::PointcloudData* pointcloud);
89 
90  /*!
91  * \brief Query attribute names
92  *
93  * This function returns the names of the attributes defined in the
94  * database in the order defined by the point attribute group table
95  * (details see group() function).
96  *
97  * \see group()
98  */
99  std::vector<std::string> list() const;
100 
101  /*!
102  * \brief Query default attribute names
103  * \returns a list of built-in RIEGL default attribute names
104  * \note the order of attribute names is undefined
105  */
106  static std::vector<std::string> listDefault(riegl::rdb::Context &context);
107 
108  /*!
109  * \brief Check if attribute exists
110  * \returns true if an attribute with given name exists
111  */
112  bool exists(
113  const std::string &name //!< [in] attribute name
114  ) const;
115 
116  /*!
117  * \brief Add new attribute
118  *
119  * \note All attribute name related functions are case sensitive
120  * (i.e. "xyz" and "XYZ" are different attributes).
121  * \note Attribute names are unique. If an attribute with the same
122  * name already exists in the database, this function fails.
123  */
124  void add(
125  const PointAttribute &attribute //!< [in] attribute information to be added
126  );
127 
128  /*!
129  * \brief Add RIEGL attribute
130  *
131  * If the given name refers to an built-in RIEGL default point attribute,
132  * this function adds the point attribute to the database. Otherwise this
133  * function fails.
134  *
135  * \note All attribute name related functions are case sensitive
136  * (i.e. "xyz" and "XYZ" are different attributes).
137  * \note Attribute names are unique. If an attribute with the same
138  * name already exists in the database, this function fails.
139  */
140  void add(
141  const std::string &name //!< [in] name of a RIEGL point attribute
142  );
143 
144  /*!
145  * \brief Query attribute details
146  *
147  * If the given attribute name could not be found, the function fails.
148  */
149  PointAttribute get(
150  const std::string &name //!< [in] attribute name
151  ) const;
152 
153  /*!
154  * \brief Query attribute group and index
155  *
156  * Since RDB version 2.2 the point attributes are grouped and sorted for
157  * a better overview. The grouping and order is defined by a table which
158  * is stored in the meta data entry "riegl.point_attribute_groups". Each
159  * database is filled with a default table with RIEGL point attributes.
160  *
161  * The list() function returns the names of the attributes actually used
162  * in the order defined by the table. Function group() returns the group
163  * name as well as the table index of a point attribute (index starts at
164  * 1 for the first attribute in the first group and goes up to N for the
165  * last attribute in the last group).
166  *
167  * So unless you want to change the order of the point attributes or add
168  * your own, it is not necessary to access or change the attribute table.
169  *
170  * \see list()
171  */
172  void group(
173  const std::string &name, //!< [in] attribute name
174  std::string &group, //!< [out] attribute group name
175  uint32_t &index //!< [out] attribute index
176  ) const;
177 
178  /*!
179  * \brief Modify attribute details
180  *
181  * This function allows to modify certain point attribute properties.
182  * Thereto the function looks for a point attribute of the given name,
183  * compares the given properties with those stored in the database and
184  * finally updates the modified properties in the database.
185  *
186  * \note Only the modification of `name`, `title`, `description`,
187  * `unitSymbol`, `scaleFactor` and `lodSettings` is supported.
188  * If a point attribute shall be renamed, the `name` property
189  * must contain the old and the new name separated by " -> ".
190  * Example: To rename `riegl.xyz` to `riegl.xyz_socs`, set
191  * `attribute.name` to `riegl.xyz -> riegl.xyz_socs`.
192  */
193  void put(
194  const PointAttribute &attribute //!< [in] attribute information to be modified
195  );
196 
197  /*!
198  * \brief Query default attribute details
199  *
200  * This function is similar to get() but instead of returning the attribute
201  * details defined in the database, it returns the details of the built-in
202  * RIEGL default point attribute.
203  *
204  * If the given attribute name could not be found, the function fails.
205  */
206  static PointAttribute getDefault(
207  riegl::rdb::Context &context, //!< [in] library context
208  const std::string &name //!< [in] attribute name
209  );
210 
211  /*!
212  * \brief Query default attribute group and index
213  *
214  * This function works like group() but returns the group and index from
215  * the built-in RIEGL default attribute table.
216  */
217  static void groupDefault(
218  riegl::rdb::Context &context, //!< [in] library context
219  const std::string &name, //!< [in] attribute name
220  std::string &group, //!< [out] attribute group name
221  uint32_t &index //!< [out] attribute index
222  );
223 
224  /*!
225  * \brief Merge attribute details
226  *
227  * This function returns the details (description) of a point attribute by
228  * analyzing two or more point clouds. If the attribute details are not the
229  * same in all point clouds (e.g. a typo was fixed or the minimum, maximum,
230  * resolution or default value has changed), merged details that cover all
231  * variants are returned. However, some changes can not be merged, e.g.
232  * changes to the vector length, the unit symbol or changes to the minimum,
233  * maximum and resolution values that would require unsupported data types
234  * (see riegl::rdb::pointcloud::DataType). In this case an exception with
235  * error code riegl::rdb::Error::PointAttributeNotMergeable is thrown.
236  * It is not required that the point attribute exists in all point clouds.
237  *
238  * This function might be helpful when merging point clouds, i.e. when
239  * reading points from multiple databases and storing them in a single
240  * database. In this case one needs to define the point attributes in the
241  * target database. If the source databases were generated by different
242  * software applications (or different versions of the same application),
243  * the details of the same attribute may slightly differ (see above), which
244  * makes the definition of the attribute in the target database quite hard.
245  * So instead of defining the attributes by using a hard-coded table, one
246  * can use this function to generate the attribute description at runtime.
247  *
248  * __Examples (simplified, fake attributes):__
249  *
250  * | Example 1 | Attribute | Description | Resolution | Minimum | Maximum |
251  * | -------------- | ----------- | ---------------- |----------: | ------: | ------: |
252  * | Point cloud A | amplitude | signal amplitude | 0.01 | 0.00 | 655.35 |
253  * | Point cloud B | amplitude | signal amplitude | 0.01 | -327.68 | 327.67 |
254  * | Merged details | amplitude | signal amplitude | 0.01 | -327.68 | 655.35 |
255  *
256  * | Example 2 | Attribute | Description | Resolution | Minimum | Maximum |
257  * | -------------- | ----------- | ------------------- | ---------: | ------: | ------: |
258  * | Point cloud A | temperature | coarse temperature | 0.50 | -100.00 | 500.00 |
259  * | Point cloud B | temperature | precise temperature | 0.01 | -100.00 | 1000.00 |
260  * | Merged details | temperature | precise temperature | 0.01 | -100.00 | 1000.00 |
261  *
262  * In both examples the value range (minimum/maximum) of the attribute has
263  * changed, so the result range is the combination (disjunction) of both
264  * ranges.
265  *
266  * In the second example the resolution is different too. The example
267  * shows that always the higher resolution (lower value) is returned.
268  *
269  * If the description text changes, then the result is the text that is
270  * stored in the younger database (the database that was created last).
271  * In example 2, "Point cloud B" is the younger database.
272  */
273  static PointAttribute getMerged(
274  riegl::rdb::Context &context, //!< [in] library context
275  const std::vector<riegl::rdb::Pointcloud*> &pointclouds, //!< [in] list of point clouds
276  const std::string &name //!< [in] attribute name
277  );
278 
279  /*!
280  * \brief Merge attribute details
281  *
282  * Same as the overloaded version above, but instead of merging one point
283  * attribute, this function merges all point attributes of all given point
284  * clouds.
285  */
286  static std::vector<PointAttribute> getMerged(
287  riegl::rdb::Context &context, //!< [in] library context
288  const std::vector<riegl::rdb::Pointcloud*> &pointclouds //!< [in] list of point clouds
289  );
290 
291  /*!
292  * \brief Delete attribute
293  *
294  * If the given attribute name could not be found, this function does not fail.
295  *
296  * \note The primary point attribute (see CreateSettings::primaryAttribute)
297  * and the unique point identifier (ID) cannot be deleted.
298  */
299  void remove(
300  const std::string &name //!< [in] attribute name
301  );
302 
303  /*!
304  * \brief Duplicate attribute data
305  *
306  * Use this function to duplicate the current point attribute *data* (but
307  * not the point attribute description). This can e.g. be used to make a
308  * backup of point attribute data.
309  *
310  * \note The source and target attributes must exist and be compatible (i.e.
311  * attribute minimum, maximum, resolution and length are identical).
312  *
313  * \note The primary point attribute and the point ID attribute cannot be
314  * used as target attribute.
315  */
316  void duplicate(
317  const std::string &source, //!< [in] source attribute name
318  const std::string &target //!< [in] target attribute name
319  );
320 
321  /*!
322  * \brief Discard attribute data
323  *
324  * Use this function to delete the current point attribute *data* (but
325  * not the point attribute description). This is equivalent to a newly
326  * created point attribute, i.e. all points will have the default value.
327  *
328  * \note The primary point attribute (see CreateSettings::primaryAttribute)
329  * and the unique point identifier (ID) data cannot be discarded.
330  */
331  void discard(
332  const std::string &name //!< [in] attribute name
333  );
334 
335 public:
336  typedef uint64_t PointID; //!< Point identifier data type
337  static std::string pointIDName(); //!< Point identifier attribute name
338  static std::string pointIDUnit(); //!< Point identifier attribute unit
339  static DataType pointIDType(); //!< Point identifier data type enum
340 
341  std::string primaryAttributeName() const; //!< Name of primary point attribute
342 
343 private:
344  riegl::rdb::PointcloudData *data;
345 };
346 
347 }}} // namespace riegl::rdb::pointcloud
348 
349 #endif // RIEGL_RDB_POINTCLOUD_POINTATTRIBUTES_HPP
PointAttributes(riegl::rdb::PointcloudData *pointcloud)
Constructor.
DataType
Point attribute access data type.
Definition: dataTypes.hpp:55
Library context.
Definition: context.hpp:70
void put(const PointAttribute &attribute)
Modify attribute details.
static std::vector< std::string > listDefault(riegl::rdb::Context &context)
Query default attribute names.
static std::string pointIDUnit()
Point identifier attribute unit.
static PointAttribute getMerged(riegl::rdb::Context &context, const std::vector< riegl::rdb::Pointcloud *> &pointclouds, const std::string &name)
Merge attribute details.
void discard(const std::string &name)
Discard attribute data.
static DataType pointIDType()
Point identifier data type enum.
static std::string pointIDName()
Point identifier attribute name.
RIEGL Laser Measurement Systems GmbH, Austria.
Definition: context.hpp:48
void group(const std::string &name, std::string &group, uint32_t &index) const
Query attribute group and index.
Point attribute description.
Point attribute description.
static void groupDefault(riegl::rdb::Context &context, const std::string &name, std::string &group, uint32_t &index)
Query default attribute group and index.
bool exists(const std::string &name) const
Check if attribute exists.
void add(const PointAttribute &attribute)
Add new attribute.
std::vector< std::string > list() const
Query attribute names.
Point attribute access data types.
Pointcloud class implementation details.
std::string primaryAttributeName() const
Name of primary point attribute.
static PointAttribute getDefault(riegl::rdb::Context &context, const std::string &name)
Query default attribute details.
void duplicate(const std::string &source, const std::string &target)
Duplicate attribute data.
uint64_t PointID
Point identifier data type.