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