RDB 2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
std::map< long long int, std::string > NamedValuesMap
Map of VALUE=NAME pairs.
nothing special, just use default compression algorithm
static void decodeDescriptor(const std::string &descriptor, std::string &name, std::int32_t &index)
Get attribute name and vector index from attribute descriptor.
DataType
Point attribute access data type.
Definition: dataTypes.hpp:56
Library context.
Definition: context.hpp:75
shuffle bytes of point attribute values
std::uint8_t compressionOptions
options additional to default compression
std::string name
unique attribute name (for queries)
double minimumValue
theoretical minimum value
calculate differences and shuffle bytes
double scaleFactor
optional scale factor applied to real numbers (i.e. resolution not equal to 1.0)
double defaultValue
default value (minimum <= default <= maximum)
std::string lodSettings
Level of detail settings.
RDB library context.
std::string description
attribute description (for display), string size limits: [0, 5000]
void load(const std::string &json)
Load settings from JSON string.
void assign(PointAttribute &target) const
Copy assignment.
std::string tags
attribute tags (comma separated, e.g. "position, transform"), string size limits: [0...
std::string save() const
Save settings to JSON string.
value can change from time to time
riegl::rdb::pointcloud::DataType dataType() const
Get buffer data type.
Point attribute description.
std::string namedValues
list of VALUE=NAME pairs separated by a single line feed character (LF, ASCII 0x0A), string size limits: [0, 1000000]
double invalidValue
invalid value (minimum <= invalid <= maximum, use "not-a-number" if there is no invalid value) ...
calculate differences between two consecutive values
std::uint8_t storageClass
storage class
std::uint32_t length
number of dimensions/elements (1: scalar, >1: vector, e.g. 3 for point coordinates) ...
value is likely to be changed often
std::string unitSymbol
physical unit symbol (e.g. "m", "rad", "K"), string size limits: [0, 100]
std::string title
attribute title (for display), string size limits: [1, 100]
CompressionOptions
Data Compression Options.
Point attribute access data types.
void setNamedValues(const NamedValuesMap &map)
Set named values string from map.
PointAttribute & operator=(const PointAttribute &attribute)
Assignment operator.
NamedValuesMap getNamedValues() const
Get map from named values string.
double maximumValue
theoretical maximum value
double resolution
expected value resolution
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.