RDB 2
queryUpdate.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 queryUpdate.hpp
26  * \author RIEGL LMS GmbH, Austria
27  * \brief Point update 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  *
33  *******************************************************************************
34  */
35 
36 #ifndef RIEGL_RDB_POINTCLOUD_QUERYUPDATE_HPP
37 #define RIEGL_RDB_POINTCLOUD_QUERYUPDATE_HPP
38 
39 //---< INCLUDES >---------------------------------------------------------------
40 
41 #include <memory>
42 #include <string>
43 #include <cstdlib>
44 #include <cstdint>
45 
48 
49 //---< NAMESPACE >--------------------------------------------------------------
50 
51 namespace riegl {
52 namespace rdb {
53 namespace pointcloud {
54 
55 //---< CLASS QueryUpdate >------------------------------------------------------
56 /*!
57  * \brief Point update query
58  *
59  * This class can be used to update (modify) attributes of existing points.
60  *
61  * \see riegl::rdb::Pointcloud::update()
62  *
63  * \note You either must delete the query object or call close()
64  * __before__ the parent Pointcloud instance is closed/deleted!
65  */
67 {
68 public:
69  /*!
70  * \brief Default constructor
71  *
72  * Creates a null query - i.e. the query cannot be used to update points.
73  *
74  * \see riegl::rdb::Pointcloud::update()
75  */
76  explicit QueryUpdate();
77 
78  /*!
79  * \brief Constructor
80  *
81  * Creates a query prepared for updating points.
82  *
83  * \note You cannot create new QueryUpdate objects this way,
84  * use riegl::rdb::Pointcloud::update() instead.
85  */
86  explicit QueryUpdate(riegl::rdb::PointcloudData *pointcloud);
87 
88  /*!
89  * \brief Check if query is not null
90  *
91  * \see valid()
92  */
93  operator bool() const;
94 
95  /*!
96  * \brief Check if query is not null
97  *
98  * A null query cannot be used to update points.
99  */
100  bool valid() const;
101 
102  /*!
103  * \brief Finish query
104  *
105  * Call this function when done with updating points.
106  */
107  void close();
108 
109  /*!
110  * \brief Bind attribute buffer
111  *
112  * Use this function to define a source buffer for a point attribute.
113  * Exactly one buffer can be defined for an attribute (i.e. only the
114  * most recently defined buffer will be used).
115  *
116  * You can but don't need to define a buffer for each attribute. If
117  * no buffer is defined for an attribute, it remains unchanged.
118  *
119  * The buffer is expected to be n*s*d bytes large, where
120  * __n__ is the number of points defined in next(),
121  * __s__ is the size of one element as defined by 'dataType' and
122  * __d__ is the number of attribute dimensions (elements).
123  *
124  * \note This function just stores the buffer pointer - it does
125  * __NOT__ copy the data contained in the buffer. So make
126  * sure that the buffer remains valid until you call next().
127  *
128  * \note This function expects a buffer for the point ID attribute.
129  *
130  * \see riegl::rdb::pointcloud::PointAttributes
131  */
132  void bind(
133  const std::string &attribute, //!< [in] attribute name
134  const DataType dataType, //!< [in] buffer data type
135  const void *buffer, //!< [in] buffer location
136  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
137  );
138 
139  //! \copydoc bind()
140  template <typename ValueType>
142  const std::string &attribute, //!< [in] attribute name
143  const ValueType &buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
144  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
145  )
146  {
147  bind(attribute, dataTypeOf(buffer), dataPointerOf(buffer), stride);
148  }
149 
150  /*!
151  * \brief Bind attribute buffer
152  *
153  * This is a variant of bindBuffer() that allows to bind a member variable
154  * of an object as attribute buffer. The object can be part of a container
155  * that stores the objects contiguously (e.g. std::vector, std::array) and
156  * the stride is automatically derived from the object size.
157  *
158  * \see bindBuffer()
159  */
160  template <typename ObjectType, typename MemberPointer>
162  const std::string &attribute, //!< [in] attribute name
163  const ObjectType &object, //!< [in] e.g. first object of container
164  const MemberPointer member //!< [in] object member variable pointer
165  )
166  {
167  bindBuffer(
168  attribute, object.*member,
169  static_cast<std::int32_t>(sizeof(ObjectType))
170  );
171  }
172 
173  //! \copydoc bindMember()
174  template <typename ObjectType, typename MemberPointer>
176  const std::string &attribute, //!< [in] attribute name
177  const ObjectType &object, //!< [in] e.g. first object of container
178  const MemberPointer member, //!< [in] object member variable pointer
179  const std::size_t index //!< [in] index for array-like object members
180  )
181  {
182  bindBuffer(
183  attribute, (object.*member)[index],
184  static_cast<std::int32_t>(sizeof(ObjectType))
185  );
186  }
187 
188  /*!
189  * \brief Update points
190  *
191  * Use this function to actually read the point attributes from
192  * all defined buffers and update the points in the database.
193  *
194  * Afterwards you may re-fill the buffers or define new buffers
195  * with bind() and call next() again until all points have been
196  * updated.
197  *
198  * \remark It is assumed that the points are given in the exact same order as
199  * returned by the select query (riegl::rdb::pointcloud::QuerySelect).
200  * If the points are given in a different order, the update will still
201  * work but may take more time to finish. Of course it is not required
202  * to update all points (you don't need to provide points that you do
203  * not want to update).
204  *
205  * \note IEEE-754 "NaN" values contained in floating point source
206  * buffers are ignored and the attribute's default value is
207  * used instead. Furthermore IEEE-754 "Infinity" values will
208  * always cause next() to fail with error code 10414, i.e.
209  * riegl::rdb::Error::QueryAttributeValueOutOfRange.
210  *
211  * \note Since version 2.4.2, unit vector point attributes (e.g.
212  * "riegl.direction") are automatically normalized (divided
213  * by the vector length) on insertion. This is done for all
214  * point attributes that meet the following requirements:
215  * `length` is 3, `minimumValue` is -1, `maximumValue` is 1,
216  * `resolution` is not 1, `scaleFactor` is 1, `unitSymbol` is
217  * empty, `invalidValue` is undefined and `tags` contains the
218  * "direction" tag but not the "do-not-normalize" tag.
219  *
220  * \warning If you want to modify the primary point attribute (usually
221  * the point coordinates), you __must__ either read __all__ points
222  * with a select query (class QuerySelect) first and update them
223  * later, or use two different instances of riegl::rdb::Pointcloud
224  * on the same database and use one instance to read (select) and
225  * the other instance to write (update) the points. In other words:
226  * It is not allowed to alternately call next() on an instance of
227  * QuerySelect and an instance of QueryUpdate if both were started
228  * on the same Pointcloud instance and the goal is to modify the
229  * primary point attribute.
230  *
231  * \returns the number of points updated
232  */
233  std::uint32_t next(
234  std::uint32_t count //!< [in] size of source buffers in terms of points
235  );
236 
237 private:
238  struct Private;
239  std::shared_ptr<Private> data;
240 };
241 
242 }}} // namespace riegl::rdb::pointcloud
243 
244 #endif // RIEGL_RDB_POINTCLOUD_QUERYUPDATE_HPP
riegl::rdb::pointcloud::QueryUpdate::bindBuffer
void bindBuffer(const std::string &attribute, const ValueType &buffer, const std::int32_t stride=0)
Bind attribute buffer.
Definition: queryUpdate.hpp:141
riegl::rdb::pointcloud::QueryUpdate::valid
bool valid() const
Check if query is not null.
riegl::rdb::pointcloud::QueryUpdate::bind
void bind(const std::string &attribute, const DataType dataType, const void *buffer, const std::int32_t stride=0)
Bind attribute buffer.
riegl
RIEGL Laser Measurement Systems GmbH, Austria.
Definition: context.hpp:48
riegl::rdb::pointcloud::dataTypeOf
DataType dataTypeOf()
Convenience wrapper for DataTypeOf class.
Definition: dataTypes.hpp:147
riegl::rdb::pointcloud::QueryUpdate::close
void close()
Finish query.
riegl::rdb::pointcloud::QueryUpdate::bindMember
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member, const std::size_t index)
Bind attribute buffer.
Definition: queryUpdate.hpp:175
riegl::rdb::pointcloud::QueryUpdate::next
std::uint32_t next(std::uint32_t count)
Update points.
dataTypes.hpp
Point attribute access data types.
riegl::rdb::pointcloud::dataPointerOf
ValueType * dataPointerOf(ValueType *const value)
Get pointer to variable or to data in a std::array or vector container.
Definition: dataTypes.hpp:176
riegl::rdb::pointcloud::QueryUpdate
Point update query.
Definition: queryUpdate.hpp:66
riegl::rdb::pointcloud::QueryUpdate::bindMember
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member)
Bind attribute buffer.
Definition: queryUpdate.hpp:161
pointcloudData.hpp
Pointcloud class implementation details.
riegl::rdb::pointcloud::QueryUpdate::QueryUpdate
QueryUpdate()
Default constructor.
riegl::rdb::pointcloud::DataType
DataType
Point attribute access data type.
Definition: dataTypes.hpp:56