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