RDB 2
pointAttribute.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 pointAttribute.hpp
26  * \author RIEGL LMS GmbH, Austria
27  * \brief Point attribute description
28  * \version 2015-10-14/AW: Initial version
29  * \version 2016-11-28/AW: Compression options added (#2423)
30  * \version 2016-12-20/AW: New functions to load/save settings from/to JSON
31  * \version 2017-03-22/AW: Point attribute scale factor added (#2552)
32  * \version 2017-03-28/AW: Documentation of JSON load/save functions updated
33  * \version 2017-11-09/AW: New function to suggest buffer data type (#2587)
34  * \version 2017-11-24/AW: Constructors declared as "explicit" (#2825)
35  * \version 2018-03-09/AW: New attribute property "invalid value" added (#3047)
36  * \version 2018-06-22/AW: Attribute length type changed to uint32 (#3117)
37  * \version 2018-07-05/AW: Add string conversion operator function
38  * \version 2019-01-21/AW: New attribute property "lod settings" added
39  * \version 2019-02-15/AW: Fix C++ API wrapper of PointAttribute class
40  * \version 2020-02-21/AW: Class 'PointAttribute' is now context-free (#3544)
41  * \version 2022-01-26/AW: Add optional point attribute tags (#4128)
42  * \version 2022-03-18/AW: Add optional list of named values (#4128)
43  * \version 2023-10-04/AW: Add attribute definition string size limits (#4790)
44  *
45  *******************************************************************************
46  */
47 
48 #ifndef RIEGL_RDB_POINTCLOUD_POINTATTRIBUTE_HPP
49 #define RIEGL_RDB_POINTCLOUD_POINTATTRIBUTE_HPP
50 
51 //---< INCLUDES >---------------------------------------------------------------
52 
53 #include <map>
54 #include <limits>
55 #include <string>
56 #include <cstdlib>
57 #include <cstdint>
58 
59 #include "riegl/rdb/context.hpp"
61 
62 //---< NAMESPACE >--------------------------------------------------------------
63 
64 namespace riegl {
65 namespace rdb {
66 namespace pointcloud {
67 
68 //---< CLASS PointAttribute >---------------------------------------------------
69 /*!
70  * \brief Point attribute description
71  *
72  * This class describes a point attribute. The database uses this
73  * information for internal attribute representation and compression.
74  *
75  * While the name is a unique identifier, the description holds some
76  * text that client programs might display the user in some way. Also
77  * the physical unit is not used by the database but can be presented
78  * to the user (see PointAttribute::unitSymbol).
79  *
80  * To avoid point attribute name conflicts, the names (not the titles)
81  * shall contain a namespace prefix. Namespace and attribute name are
82  * separated by a dot (".", e.g. "riegl.xyz"). The default namespace
83  * "riegl" is used if no namespace is given.
84  *
85  * \remarks
86  *
87  * If the attribute is a vector (i.e. length > 1), then you might append
88  * a zero-based vector element index to the attribute name when inserting,
89  * updating or selecting points. Example: use "rgb[0]" to access the red
90  * color component (0), the green (1) and blue (2) components are not read
91  * or modified in this case.
92  *
93  * Furthermore, the minimum, maximum and default values are applied to all
94  * elements of vectors and the vector length must be in the range [1..100000].
95  *
96  * PointAttribute::defaultValue is returned when reading a point attribute
97  * that has never been written before. The value must be between minimum and
98  * maximum (both inclusive).
99  *
100  * PointAttribute::invalidValue may be used to define a value that represents
101  * an invalid/undefined/unknown value. The value must be between minimum and
102  * maximum (both inclusive) and must be a multiple of the resolution value.
103  * The value may be equal to the default value and you may use "NaN" (not a
104  * number) to signal that there is no "invalid value".
105  *
106  * \note
107  *
108  * Attribute names may only contain following ASCII characters:
109  *
110  * - a-z
111  * - A-Z
112  * - 0-9
113  * - .
114  * - _
115  *
116  * Attribute title, description and unit symbol may contain any UTF-8 character.
117  *
118  * \see riegl::rdb::pointcloud::PointAttributes
119  */
121 {
122 public:
123  /*!
124  * \brief Data Storage Class
125  *
126  * The storage class gives a hint about how often a point attribute
127  * is expected to change. This might be helpful for the database to
128  * optimize data structures for speed or file size.
129  */
131  {
132  CONSTANT = 1, //!< value cannot be changed
133  VARIABLE = 2, //!< value can change from time to time
134  DYNAMIC = 3 //!< value is likely to be changed often
135  };
136 
137  /*!
138  * \brief Data Compression Options
139  *
140  * The data of all point attributes is compressed with the settings defined
141  * during the database creation (see class CreateSettings). Additionally,
142  * the data may be pre-processed using one or more of the following methods:
143  */
145  {
146  DEFAULT = 0, //!< nothing special, just use default compression algorithm
147  DELTA = 1, //!< calculate differences between two consecutive values
148  SHUFFLE = 2, //!< shuffle bytes of point attribute values
149  DELTA_SHUFFLE = 3 //!< calculate differences and shuffle bytes
150  };
151 
152  std::string name; //!< unique attribute name (for queries) \see details of class PointAttribute, string size limits: [1, 100]
153  std::string title; //!< attribute title (for display), string size limits: [1, 100]
154  std::string tags; //!< attribute tags (comma separated, e.g. "position, transform"), string size limits: [0, 5000]
155  std::string description; //!< attribute description (for display), string size limits: [0, 5000]
156  std::string unitSymbol; //!< physical unit symbol (e.g. "m", "rad", "K"), string size limits: [0, 100]
157  std::uint32_t length; //!< number of dimensions/elements (1: scalar, >1: vector, e.g. 3 for point coordinates)
158  double resolution; //!< expected value resolution
159  double minimumValue; //!< theoretical minimum value
160  double maximumValue; //!< theoretical maximum value
161  double defaultValue; //!< default value (minimum <= default <= maximum)
162  double invalidValue; //!< invalid value (minimum <= invalid <= maximum, use "not-a-number" if there is no invalid value)
163  std::string namedValues; //!< list of VALUE=NAME pairs separated by a single line feed character (LF, ASCII 0x0A), string size limits: [0, 1000000]
164  std::uint8_t storageClass; //!< storage class \see enum StorageClass
165  std::uint8_t compressionOptions; //!< options additional to default compression
166 
167  /*!
168  * \brief Level of detail settings
169  *
170  * This field defines the method to be used to generate level of detail
171  * data (LOD) for this point attribute. Depending on the LOD mode defined
172  * during database creation (see CreateSettings::LodMode), several LOD
173  * methods are available. A list of all methods and their settings can
174  * be found in file "/manual/riegl_rdb_lod_methods.json" in the RDB SDK.
175  *
176  * String size limits: [0, 50000]
177  */
178  std::string lodSettings;
179 
180  /*!
181  * \brief optional scale factor applied to real numbers (i.e. resolution not equal to 1.0)
182  *
183  * - reading points: resultValue = originalValue * scaleFactor
184  * - writing points: storedValue = givenValue / scaleFactor
185  */
186  double scaleFactor;
187 
188  /*!
189  * \brief Map of VALUE=NAME pairs
190  *
191  * \see namedValues
192  * \see getNamedValues()
193  * \see setNamedValues()
194  */
195  typedef std::map<long long int, std::string> NamedValuesMap;
196 
197 public:
198  ~PointAttribute();
199 
200  /*!
201  * \brief Default constructor
202  *
203  * All properties are set to default values.
204  */
205  explicit PointAttribute(
206  const std::string &name = "none",
207  const std::string &title = "none",
208  const std::string &description = "",
209  const std::string &unitSymbol = "",
210  const std::uint32_t &length = 0,
211  const double &resolution = 1.0,
212  const double &minimumValue = 0.0,
213  const double &maximumValue = 0.0,
214  const double &defaultValue = 0.0,
215  const std::uint8_t &storageClass = CONSTANT,
216  const std::uint8_t &compressionOptions = DEFAULT,
217  const double &scaleFactor = 1.0,
218  const double &invalidValue = std::numeric_limits<double>::quiet_NaN(),
219  const std::string &lodSettings = "default",
220  const std::string &tags = "",
221  const std::string &namedValues = ""
222  );
223 
224  /// \deprecated since 2.2.3 - use the context-free constructors instead
225  explicit PointAttribute(riegl::rdb::Context &context);
226 
227  /*!
228  * \brief Copy constructor
229  *
230  * All properties are copied from the given attribute object.
231  */
232  PointAttribute(const PointAttribute &attribute);
233 
234  /*!
235  * \brief Assignment operator
236  *
237  * All properties are copied from the given attribute object.
238  */
239  PointAttribute& operator=(const PointAttribute &attribute);
240 
241  //__________________________________________________________________________
242  /*!
243  * \brief Copy assignment
244  *
245  * This function is mainly for backward compatibility reasons. You may
246  * also use the copy constructor or copy assignment operator instead.
247  */
248  void assign(PointAttribute &target) const
249  {
250  target = *this;
251  }
252 
253  //__________________________________________________________________________
254  /*!
255  * \brief Get attribute name and vector index from attribute descriptor
256  *
257  * This function decodes the given attribute descriptor into attribute name and attribute
258  * vector index. The optional vector index is enclosed in square brackets and follows the
259  * point attribute name. If no vector index is given, then index -1 is returned. If the
260  * vector index cannot be interpreted as a single positive integer value, then an empty
261  * name and index -2 is returned.
262  *
263  * Examples:
264  * descriptor | name | index
265  * ------------|-------|-------
266  * "xyz" | "xyz" | -1
267  * "xyz[0]" | "xyz" | 0
268  * "rgb[1]" | "rgb" | 1
269  */
270  static void decodeDescriptor(
271  const std::string &descriptor, //!< [in] attribute descriptor, e.g. "xyz", "rgb[1]"
272  std::string &name, //!< [out] attribute name, e.g. "xyz", "rgb"
273  std::int32_t &index //!< [out] attribute vector index, e.g. -1, 1
274  );
275 
276  //__________________________________________________________________________
277  /*!
278  * \brief Get map from named values string
279  *
280  * This function decodes the `namedValues` string into a map.
281  *
282  * \see namedValues
283  * \see NamedValuesMap
284  * \see setNamedValues()
285  */
287 
288  //__________________________________________________________________________
289  /*!
290  * \brief Set named values string from map
291  *
292  * This function generates the `namedValues` string from a map.
293  *
294  * \see namedValues
295  * \see NamedValuesMap
296  * \see getNamedValues()
297  */
298  void setNamedValues(const NamedValuesMap &map);
299 
300  /*!
301  * \brief Load settings from JSON string
302  *
303  * This function parses the given JSON string and applies all available
304  * properties - missing properties are silently ignored (i.e. the value
305  * remains unchanged). When parsing the JSON string fails, an exception
306  * is thrown.
307  *
308  * Example JSON string:
309  *
310  * {
311  * "name": "riegl.reflectance",
312  * "title": "Reflectance",
313  * "tags": "",
314  * "description": "Target surface reflectance",
315  * "unit_symbol": "dB",
316  * "length": 1,
317  * "resolution": 0.01,
318  * "minimum_value": -327.68,
319  * "maximum_value": 327.67,
320  * "default_value": 0.0,
321  * "invalid_value": null,
322  * "named_values": {},
323  * "storage_class": "variable",
324  * "compression_options": "shuffle",
325  * "lod_settings": "default",
326  * "scale_factor": 1.0
327  * }
328  */
329  void load(const std::string &json);
330 
331  /*!
332  * \brief Save settings to JSON string
333  * \see load()
334  */
335  std::string save() const;
336 
337  /*!
338  * \brief Get buffer data type
339  *
340  * This function suggests a data type that is suitable to
341  * construct a buffer for storing values of this attribute.
342  *
343  * The suggestion is based on the resolution, minimumValue
344  * and maximumValue properties, all others are ignored.
345  */
347 
348  //! \brief Get attribute name
349  operator const std::string&() const { return name; }
350 
351 private:
352  friend class PointAttributeWrapper;
353  void *data;
354 };
355 
356 }}} // namespace riegl::rdb::pointcloud
357 
358 #endif // RIEGL_RDB_POINTCLOUD_POINTATTRIBUTE_HPP
riegl::rdb::pointcloud::PointAttribute::DELTA
calculate differences between two consecutive values
Definition: pointAttribute.hpp:147
riegl::rdb::pointcloud::PointAttribute::~PointAttribute
~PointAttribute()
riegl::rdb::pointcloud::PointAttribute
Point attribute description.
Definition: pointAttribute.hpp:120
riegl::rdb::pointcloud::PointAttribute::NamedValuesMap
std::map< long long int, std::string > NamedValuesMap
Map of VALUE=NAME pairs.
Definition: pointAttribute.hpp:195
riegl::rdb::pointcloud::PointAttribute::PointAttribute
PointAttribute(const std::string &name="none", const std::string &title="none", const std::string &description="", const std::string &unitSymbol="", const std::uint32_t &length=0, const double &resolution=1.0, const double &minimumValue=0.0, const double &maximumValue=0.0, const double &defaultValue=0.0, const std::uint8_t &storageClass=CONSTANT, const std::uint8_t &compressionOptions=DEFAULT, const double &scaleFactor=1.0, const double &invalidValue=std::numeric_limits< double >::quiet_NaN(), const std::string &lodSettings="default", const std::string &tags="", const std::string &namedValues="")
Default constructor.
riegl::rdb::pointcloud::PointAttribute::DEFAULT
nothing special, just use default compression algorithm
Definition: pointAttribute.hpp:146
riegl::rdb::pointcloud::PointAttribute::SHUFFLE
shuffle bytes of point attribute values
Definition: pointAttribute.hpp:148
riegl::rdb::pointcloud::PointAttribute::invalidValue
double invalidValue
invalid value (minimum <= invalid <= maximum, use "not-a-number" if there is no invalid value)
Definition: pointAttribute.hpp:162
riegl::rdb::pointcloud::PointAttribute::minimumValue
double minimumValue
theoretical minimum value
Definition: pointAttribute.hpp:159
context.hpp
RDB library context.
riegl::rdb::pointcloud::PointAttribute::assign
void assign(PointAttribute &target) const
Copy assignment.
Definition: pointAttribute.hpp:248
riegl::rdb::pointcloud::PointAttribute::scaleFactor
double scaleFactor
optional scale factor applied to real numbers (i.e. resolution not equal to 1.0)
Definition: pointAttribute.hpp:186
riegl
RIEGL Laser Measurement Systems GmbH, Austria.
Definition: context.hpp:48
riegl::rdb::pointcloud::PointAttribute::defaultValue
double defaultValue
default value (minimum <= default <= maximum)
Definition: pointAttribute.hpp:161
riegl::rdb::pointcloud::PointAttribute::storageClass
std::uint8_t storageClass
storage class
Definition: pointAttribute.hpp:164
riegl::rdb::pointcloud::PointAttribute::unitSymbol
std::string unitSymbol
physical unit symbol (e.g. "m", "rad", "K"), string size limits: [0, 100]
Definition: pointAttribute.hpp:156
riegl::rdb::pointcloud::PointAttribute::CONSTANT
value cannot be changed
Definition: pointAttribute.hpp:132
riegl::rdb::pointcloud::PointAttribute::compressionOptions
std::uint8_t compressionOptions
options additional to default compression
Definition: pointAttribute.hpp:165
riegl::rdb::pointcloud::PointAttribute::DELTA_SHUFFLE
calculate differences and shuffle bytes
Definition: pointAttribute.hpp:149
riegl::rdb::pointcloud::PointAttribute::decodeDescriptor
static void decodeDescriptor(const std::string &descriptor, std::string &name, std::int32_t &index)
Get attribute name and vector index from attribute descriptor.
riegl::rdb::pointcloud::PointAttribute::load
void load(const std::string &json)
Load settings from JSON string.
riegl::rdb::pointcloud::PointAttribute::CompressionOptions
CompressionOptions
Data Compression Options.
Definition: pointAttribute.hpp:144
riegl::rdb::pointcloud::PointAttribute::save
std::string save() const
Save settings to JSON string.
riegl::rdb::pointcloud::PointAttribute::VARIABLE
value can change from time to time
Definition: pointAttribute.hpp:133
riegl::rdb::pointcloud::PointAttribute::tags
std::string tags
attribute tags (comma separated, e.g. "position, transform"), string size limits: [0,...
Definition: pointAttribute.hpp:154
dataTypes.hpp
Point attribute access data types.
riegl::rdb::pointcloud::PointAttribute::getNamedValues
NamedValuesMap getNamedValues() const
Get map from named values string.
riegl::rdb::pointcloud::PointAttribute::resolution
double resolution
expected value resolution
Definition: pointAttribute.hpp:158
riegl::rdb::pointcloud::PointAttribute::namedValues
std::string namedValues
list of VALUE=NAME pairs separated by a single line feed character (LF, ASCII 0x0A),...
Definition: pointAttribute.hpp:163
riegl::rdb::pointcloud::PointAttribute::DYNAMIC
value is likely to be changed often
Definition: pointAttribute.hpp:134
riegl::rdb::pointcloud::PointAttribute::length
std::uint32_t length
number of dimensions/elements (1: scalar, >1: vector, e.g. 3 for point coordinates)
Definition: pointAttribute.hpp:157
riegl::rdb::pointcloud::PointAttribute::StorageClass
StorageClass
Data Storage Class.
Definition: pointAttribute.hpp:130
riegl::rdb::pointcloud::PointAttribute::title
std::string title
attribute title (for display), string size limits: [1, 100]
Definition: pointAttribute.hpp:153
riegl::rdb::pointcloud::PointAttribute::dataType
riegl::rdb::pointcloud::DataType dataType() const
Get buffer data type.
riegl::rdb::pointcloud::PointAttribute::operator=
PointAttribute & operator=(const PointAttribute &attribute)
Assignment operator.
riegl::rdb::pointcloud::PointAttribute::description
std::string description
attribute description (for display), string size limits: [0, 5000]
Definition: pointAttribute.hpp:155
riegl::rdb::pointcloud::PointAttribute::maximumValue
double maximumValue
theoretical maximum value
Definition: pointAttribute.hpp:160
riegl::rdb::pointcloud::PointAttribute::lodSettings
std::string lodSettings
Level of detail settings.
Definition: pointAttribute.hpp:178
riegl::rdb::pointcloud::DataType
DataType
Point attribute access data type.
Definition: dataTypes.hpp:56
riegl::rdb::pointcloud::PointAttribute::setNamedValues
void setNamedValues(const NamedValuesMap &map)
Set named values string from map.
riegl::rdb::pointcloud::PointAttribute::name
std::string name
unique attribute name (for queries)
Definition: pointAttribute.hpp:152
riegl::rdb::Context
Library context.
Definition: context.hpp:75
riegl::rdb::pointcloud::PointAttribute::PointAttributeWrapper
friend class PointAttributeWrapper
Definition: pointAttribute.hpp:352