RDB 2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
queryInsert.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 queryInsert.hpp
26  * \author RIEGL LMS GmbH, Austria
27  * \brief Point insert query
28  * \version 2015-10-14/AW: Initial version
29  * \version 2017-11-24/AW: Constructors declared as "explicit" (#2825)
30  * \version 2018-07-05/AW: Wrapper function bindBuffer() added
31  * \version 2020-01-17/AW: Wrapper function bindMember() added (#3497)
32  * \version 2020-02-27/AW: Add bindId() for "riegl.id" data buffers (#3576)
33  *
34  *******************************************************************************
35  */
36 
37 #ifndef RIEGL_RDB_POINTCLOUD_QUERYINSERT_HPP
38 #define RIEGL_RDB_POINTCLOUD_QUERYINSERT_HPP
39 
40 //---< INCLUDES >---------------------------------------------------------------
41 
42 #include <memory>
43 #include <string>
44 #include <cstdlib>
45 #include <cstdint>
46 
49 
50 //---< NAMESPACE >--------------------------------------------------------------
51 
52 namespace riegl {
53 namespace rdb {
54 namespace pointcloud {
55 
56 //---< CLASS QueryInsert >------------------------------------------------------
57 /*!
58  * \brief Point insert query
59  *
60  * This class can be used to insert (new) points into the database.
61  *
62  * \see riegl::rdb::Pointcloud::insert()
63  *
64  * \note You either must delete the query object or call close()
65  * __before__ the parent Pointcloud instance is closed/deleted!
66  */
68 {
69 public:
70  /*!
71  * \brief Default constructor
72  *
73  * Creates a null query - i.e. the query cannot be used to insert points.
74  *
75  * \see riegl::rdb::Pointcloud::insert()
76  */
77  explicit QueryInsert();
78 
79  /*!
80  * \brief Constructor
81  *
82  * Creates a query prepared for inserting points.
83  *
84  * \note You cannot create new QueryInsert objects this way,
85  * use riegl::rdb::Pointcloud::insert() instead.
86  */
87  explicit QueryInsert(riegl::rdb::PointcloudData *pointcloud);
88 
89  /*!
90  * \brief Check if query is not null
91  *
92  * \see valid()
93  */
94  operator bool() const;
95 
96  /*!
97  * \brief Check if query is not null
98  *
99  * A null query cannot be used to insert points.
100  */
101  bool valid() const;
102 
103  /*!
104  * \brief Finish query
105  *
106  * Call this function when done with inserting points.
107  */
108  void close();
109 
110  /*!
111  * \brief Load multi-pass insert settings from JSON string
112  *
113  * This function can be used to change settings for insert queries
114  * in multi-pass insert mode (see 'pointInsertMode' in the database
115  * creation settings). To be applied, the settings must be loaded
116  * before the first call of next(). For settings that have not been
117  * explicitly specified, the default value is used. The settings are
118  * not saved in the database. When parsing the JSON string fails, an
119  * exception is thrown.
120  *
121  * Supported settings:
122  *
123  * - temporary_file_path (string):
124  * Path of the temporary file; if not specified, null or an
125  * empty string, then the database path with suffix ".temp"
126  * is used.
127  * Default: empty
128  *
129  * - points_per_block (integer [1]):
130  * Inserted points are grouped into blocks with this number
131  * of points before they are processed further.
132  * Default: 1048576 (= 16 * 65536)
133  *
134  * - initial_voxel_size (float [m]):
135  * Inserted points are grouped into voxels with this edge
136  * length in meters. The value must be a power of two of the
137  * resolution of the point coordinates (usually 0.00025 m).
138  * After all points have been inserted, voxels are combined
139  * or subdivided to achieve the desired maximum number of
140  * points per voxel set in the database creation settings
141  * (see 'chunkSize').
142  * Default: 2.048 m
143  *
144  * Example JSON string:
145  *
146  * {
147  * "temporary_file_path": "",
148  * "points_per_block": 1048576,
149  * "initial_voxel_size": 2.048
150  * }
151  *
152  * \see riegl::rdb::pointcloud::CreateSettings::pointInsertMode
153  * \see riegl::rdb::pointcloud::CreateSettings::chunkSize
154  */
155  void loadMultiPassSettings(const std::string &json);
156 
157  /*!
158  * \brief Bind attribute buffer
159  *
160  * Use this function to define a source buffer for a point attribute.
161  * Exactly one buffer can be defined for an attribute (i.e. only the
162  * most recently defined buffer will be used).
163  *
164  * You can but don't need to define a buffer for each attribute. If
165  * no buffer is defined for an attribute, the attribute's default
166  * value will be used instead.
167  *
168  * The buffer is expected to be n*s*d bytes large, where
169  * __n__ is the number of points defined in next(),
170  * __s__ is the size of one element as defined by 'dataType' and
171  * __d__ is the number of attribute dimensions (elements).
172  *
173  * \note This function just stores the buffer pointer - it does
174  * __NOT__ copy the data contained in the buffer. So make
175  * sure that the buffer remains valid until you call next().
176  *
177  * \see riegl::rdb::pointcloud::PointAttributes
178  */
179  void bind(
180  const std::string &attribute, //!< [in] attribute name
181  const DataType dataType, //!< [in] buffer data type
182  const void *buffer, //!< [in] buffer location
183  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
184  );
185 
186  /*!
187  * \brief Bind point id buffer
188  *
189  * If you provide a buffer for the point identifier attribute ("riegl.id"),
190  * then it will receive the identifiers of the inserted points (PID). Each
191  * point is assigned a unique PID on insertion. The PID starts at 1 for the
192  * first point and is incremented by 1 for each subsequent point (so that
193  * the PID reflects the insertion order of the points, but only as long as
194  * riegl::rdb::pointcloud::CreateSettings::optimizePointID is set to false).
195  *
196  * \see bind()
197  */
198  void bindId(
199  const DataType dataType, //!< [in] buffer data type
200  void *buffer, //!< [in] buffer location
201  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
202  );
203 
204  //! \copydoc bind()
205  template <typename ValueType>
207  const std::string &attribute, //!< [in] attribute name
208  const ValueType &buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
209  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
210  )
211  {
212  bind(attribute, dataTypeOf(buffer), dataPointerOf(buffer), stride);
213  }
214 
215  /*!
216  * \copydoc bindId()
217  * \see bindBuffer()
218  */
219  template <typename ValueType>
221  ValueType &buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
222  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
223  )
224  {
225  bindId(dataTypeOf(buffer), dataPointerOf(buffer), stride);
226  }
227 
228  /*!
229  * \copydoc bindId()
230  * \see bindBuffer()
231  */
232  template <typename ValueType>
234  ValueType *buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
235  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
236  )
237  {
238  bindId(dataTypeOf(buffer), buffer, stride);
239  }
240 
241  /*!
242  * \brief Bind attribute buffer
243  *
244  * This is a variant of bindBuffer() that allows to bind a member variable
245  * of an object as attribute buffer. The object can be part of a container
246  * that stores the objects contiguously (e.g. std::vector, std::array) and
247  * the stride is automatically derived from the object size.
248  *
249  * \see bindBuffer()
250  */
251  template <typename ObjectType, typename MemberPointer>
253  const std::string &attribute, //!< [in] attribute name
254  const ObjectType &object, //!< [in] e.g. first object of container
255  const MemberPointer member //!< [in] object member variable pointer
256  )
257  {
258  bindBuffer(
259  attribute, object.*member,
260  static_cast<std::int32_t>(sizeof(ObjectType))
261  );
262  }
263 
264  /*!
265  * \copydoc bindId()
266  * \see bindMember()
267  */
268  template <typename ObjectType, typename MemberPointer>
270  ObjectType &object, //!< [in] e.g. first object of container
271  MemberPointer member //!< [in] object member variable pointer
272  )
273  {
274  bindIdBuffer(
275  object.*member,
276  static_cast<std::int32_t>(sizeof(ObjectType))
277  );
278  }
279 
280  //! \copydoc bindMember()
281  template <typename ObjectType, typename MemberPointer>
283  const std::string &attribute, //!< [in] attribute name
284  const ObjectType &object, //!< [in] e.g. first object of container
285  const MemberPointer member, //!< [in] object member variable pointer
286  const std::size_t index //!< [in] index for array-like object members
287  )
288  {
289  bindBuffer(
290  attribute, (object.*member)[index],
291  static_cast<std::int32_t>(sizeof(ObjectType))
292  );
293  }
294 
295  /*!
296  * \copydoc bindId()
297  * \see bindMember()
298  */
299  template <typename ObjectType, typename MemberPointer>
301  ObjectType &object, //!< [in] e.g. first object of container
302  MemberPointer member, //!< [in] object member variable pointer
303  const std::size_t index //!< [in] index for array-like object members
304  )
305  {
306  bindIdBuffer(
307  (object.*member)[index],
308  static_cast<std::int32_t>(sizeof(ObjectType))
309  );
310  }
311 
312  /*!
313  * \brief Insert points
314  *
315  * Use this function to actually read the point attributes from
316  * all defined buffers and insert the points into the database.
317  *
318  * Afterwards you may re-fill the buffers or define new buffers
319  * with bind() and call next() again until all points have been
320  * inserted.
321  *
322  * \note IEEE-754 "NaN" values contained in floating point source
323  * buffers are ignored and the attribute's default value is
324  * used instead. Furthermore IEEE-754 "Infinity" values will
325  * always cause next() to fail with error code 10414, i.e.
326  * riegl::rdb::Error::QueryAttributeValueOutOfRange.
327  *
328  * \note Since version 2.4.2, unit vector point attributes (e.g.
329  * "riegl.direction") are automatically normalized (divided
330  * by the vector length) on insertion. This is done for all
331  * point attributes that meet the following requirements:
332  * `length` is 3, `minimumValue` is -1, `maximumValue` is 1,
333  * `resolution` is not 1, `scaleFactor` is 1, `unitSymbol` is
334  * empty, `invalidValue` is undefined and `tags` contains the
335  * "direction" tag but not the "do-not-normalize" tag.
336  *
337  * \returns the number of points inserted
338  */
339  std::uint32_t next(
340  std::uint32_t count //!< [in] size of source buffers in terms of points
341  );
342 
343 private:
344  struct Private;
345  std::shared_ptr<Private> data;
346 };
347 
348 }}} // namespace riegl::rdb::pointcloud
349 
350 #endif // RIEGL_RDB_POINTCLOUD_QUERYINSERT_HPP
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member)
Bind attribute buffer.
DataType
Point attribute access data type.
Definition: dataTypes.hpp:56
void bind(const std::string &attribute, const DataType dataType, const void *buffer, const std::int32_t stride=0)
Bind attribute buffer.
ValueType * dataPointerOf(ValueType *const value)
Get pointer to variable or to data in a std::array or vector container.
Definition: dataTypes.hpp:176
void bindIdMember(ObjectType &object, MemberPointer member, const std::size_t index)
Bind point id buffer.
bool valid() const
Check if query is not null.
void loadMultiPassSettings(const std::string &json)
Load multi-pass insert settings from JSON string.
DataType dataTypeOf()
Convenience wrapper for DataTypeOf class.
Definition: dataTypes.hpp:147
void bindIdBuffer(ValueType &buffer, const std::int32_t stride=0)
Bind point id buffer.
std::uint32_t next(std::uint32_t count)
Insert points.
void bindIdMember(ObjectType &object, MemberPointer member)
Bind point id buffer.
void bindId(const DataType dataType, void *buffer, const std::int32_t stride=0)
Bind point id buffer.
void bindBuffer(const std::string &attribute, const ValueType &buffer, const std::int32_t stride=0)
Bind attribute buffer.
Point attribute access data types.
Pointcloud class implementation details.
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member, const std::size_t index)
Bind attribute buffer.
void bindIdBuffer(ValueType *buffer, const std::int32_t stride=0)
Bind point id buffer.
QueryInsert()
Default constructor.