| RDB 2

pointAttributes.hpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************
3 *
4 * Copyright 2025 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
52 #include "riegl/rdb/pointcloud/dataTypes.hpp"
53 #include "riegl/rdb/pointcloud/pointcloudData.hpp"
54 #include "riegl/rdb/pointcloud/pointAttribute.hpp"
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 */
83 class PointAttributes
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 */
175 PointAttribute get(
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::PointAttributes
PointAttributes(riegl::rdb::PointcloudData *pointcloud)
Constructor.
riegl::rdb::pointcloud::PointAttributes
Manage point attributes.
Definition: pointAttributes.hpp:83
riegl::rdb::pointcloud::DataType
DataType
Point attribute access data type.
Definition: dataTypes.hpp:56
riegl::rdb::Context
Library context.
Definition: context.hpp:75
riegl::rdb::pointcloud::PointAttributes::put
void put(const PointAttribute &attribute)
Modify 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::listDefault
static std::vector< std::string > listDefault(riegl::rdb::Context &context)
Query default attribute names.
riegl::rdb::pointcloud::PointAttributes::pointIDUnit
static std::string pointIDUnit()
Point identifier attribute unit.
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::discard
void discard(const std::string &name)
Discard attribute data.
riegl::rdb::pointcloud::PointAttributes::PointID
std::uint64_t PointID
Point identifier data type.
Definition: pointAttributes.hpp:362
riegl::rdb::pointcloud::PointAttributes::pointIDType
static DataType pointIDType()
Point identifier data type enum.
riegl::rdb::pointcloud::PointAttributes::pointIDName
static std::string pointIDName()
Point identifier attribute name.
riegl
RIEGL Laser Measurement Systems GmbH, Austria.
Definition: context.hpp:48
pointAttribute.hpp
Point attribute description.
riegl::rdb::pointcloud::PointAttribute
Point attribute description.
Definition: pointAttribute.hpp:120
riegl::rdb::pointcloud::PointAttributes::exists
bool exists(const std::string &name) const
Check if attribute exists.
riegl::rdb::pointcloud::PointAttributes::add
void add(const PointAttribute &attribute)
Add new attribute.
riegl::rdb::pointcloud::PointAttributes::list
std::vector< std::string > list() const
Query attribute names.
riegl::rdb::pointcloud::PointAttributes::listFiltered
static std::vector< std::string > listFiltered(const std::string &filter, riegl::rdb::Context &context)
Query attribute names of filter.
dataTypes.hpp
Point attribute access data types.
pointcloudData.hpp
Pointcloud class implementation details.
riegl::rdb::pointcloud::PointAttributes::primaryAttributeName
std::string primaryAttributeName() const
Name of primary point attribute.
riegl::rdb::pointcloud::PointAttributes::getDefault
static PointAttribute getDefault(riegl::rdb::Context &context, const std::string &name)
Query default attribute details.
riegl::rdb::pointcloud::PointAttributes::duplicate
void duplicate(const std::string &source, const std::string &target)
Duplicate attribute data.
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.