QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
qgspointcloudattribute.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudattribute.cpp
3 -----------------------
4 begin : October 2020
5 copyright : (C) 2020 by Peter Petrik
6 email : zilolv at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgis.h"
20
22
24 : mName( name )
25 , mType( type )
26{
27 updateSize();
28}
29
31{
32 switch ( mType )
33 {
34 case DataType::UChar:
35 case DataType::Char:
36 case DataType::Short:
37 case DataType::UShort:
38 case DataType::UInt32:
39 case DataType::Int32:
40 return QVariant::Int;
41
42 case DataType::UInt64:
43 case DataType::Int64:
44 return QVariant::LongLong;
45 case DataType::Float:
46 case DataType::Double:
47 return QVariant::Double;
48 }
49 return QVariant::Invalid;
50}
51
53{
54 switch ( mType )
55 {
56 case DataType::UChar:
57 return QObject::tr( "Unsigned Character" );
58 case DataType::Char:
59 return QObject::tr( "Character" );
60 case DataType::Short:
61 return QObject::tr( "Short" );
62 case DataType::UShort:
63 return QObject::tr( "Unsigned Short" );
64 case DataType::Float:
65 return QObject::tr( "Float" );
66 case DataType::Int32:
67 return QObject::tr( "Integer" );
68 case DataType::UInt32:
69 return QObject::tr( "Unsigned Integer" );
70 case DataType::Int64:
71 return QObject::tr( "Long Integer" );
72 case DataType::UInt64:
73 return QObject::tr( "Unsigned Long Integer" );
74 case DataType::Double:
75 return QObject::tr( "Double" );
76 }
77 return QString();
78}
79
81{
82 switch ( type )
83 {
84 case DataType::UChar:
85 case DataType::Char:
86 return false;
87 case DataType::Short:
88 case DataType::UShort:
89 case DataType::Int32:
90 case DataType::UInt32:
91 case DataType::Int64:
92 case DataType::UInt64:
93 case DataType::Float:
94 case DataType::Double:
95 return true;
96 }
97 return false;
98}
99
100void QgsPointCloudAttribute::updateSize()
101{
102 switch ( mType )
103 {
104 case DataType::UChar:
105 case DataType::Char:
106 mSize = 1;
107 break;
108 case DataType::Short:
109 case DataType::UShort:
110 mSize = 2;
111 break;
112 case DataType::Float:
113 mSize = 4;
114 break;
115 case DataType::Int32:
116 case DataType::UInt32:
117 mSize = 4;
118 break;
119 case DataType::Int64:
120 case DataType::UInt64:
121 mSize = 8;
122 break;
123 case DataType::Double:
124 mSize = 8;
125 break;
126 }
127}
128
129// //////////////////
130
132
133QgsPointCloudAttributeCollection::QgsPointCloudAttributeCollection( const QVector<QgsPointCloudAttribute> &attributes )
134{
135 mAttributes.reserve( attributes.size() );
136 for ( const QgsPointCloudAttribute &attribute : attributes )
137 {
138 push_back( attribute );
139 }
140}
141
143{
144 mCachedAttributes.insert( attribute.name().toUpper(), CachedAttributeData( mAttributes.size(), mSize ) );
145 mAttributes.push_back( attribute );
146 mSize += attribute.size();
147}
148
149void QgsPointCloudAttributeCollection::extend( const QgsPointCloudAttributeCollection &otherCollection, const QSet<QString> &matchingNames )
150{
151 for ( const auto &attributeName : matchingNames )
152 {
153 if ( indexOf( attributeName ) == -1 )
154 {
155 int offset;
156 const auto attr = otherCollection.find( attributeName, offset );
157 if ( attr )
158 push_back( *attr );
159 }
160 }
161}
162
163QVector<QgsPointCloudAttribute> QgsPointCloudAttributeCollection::attributes() const
164{
165 return mAttributes;
166}
167
168const QgsPointCloudAttribute *QgsPointCloudAttributeCollection::find( const QString &attributeName, int &offset ) const
169{
170 const auto it = mCachedAttributes.constFind( attributeName.toUpper() );
171 if ( it != mCachedAttributes.constEnd() )
172 {
173 offset = it->offset;
174 return &mAttributes.at( it->index );
175 }
176
177 // not found
178 return nullptr;
179}
180
181int QgsPointCloudAttributeCollection::indexOf( const QString &name ) const
182{
183 const auto it = mCachedAttributes.constFind( name.toUpper() );
184 if ( it != mCachedAttributes.constEnd() )
185 {
186 return it->index;
187 }
188
189 // not found
190 return -1;
191}
192
194{
195 QgsFields fields;
196 for ( const QgsPointCloudAttribute &attribute : mAttributes )
197 {
198 fields.append( QgsField( attribute.name(), attribute.variantType(), attribute.displayType() ) );
199 }
200 return fields;
201}
202
203template <typename T>
204void _attribute( const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value )
205{
206 switch ( type )
207 {
209 value = *reinterpret_cast< const unsigned char * >( data + offset );
210 return;
211
213 value = *( data + offset );
214 return;
215
217 value = *reinterpret_cast< const quint32 * >( data + offset );
218 return;
219
221 value = *reinterpret_cast< const qint32 * >( data + offset );
222 return;
223
225 value = *reinterpret_cast< const quint64 * >( data + offset );
226 return;
227
229 value = *reinterpret_cast< const qint64 * >( data + offset );
230 return;
231
233 value = *reinterpret_cast< const short * >( data + offset );
234 return;
235
237 value = *reinterpret_cast< const unsigned short * >( data + offset );
238 return;
239
241 value = static_cast< T >( *reinterpret_cast< const float * >( data + offset ) );
242 return;
243
245 value = *reinterpret_cast< const double * >( data + offset );
246 return;
247 }
249}
250
251double QgsPointCloudAttribute::convertValueToDouble( const char *ptr ) const
252{
253 double val;
254 _attribute( ptr, 0, mType, val );
255 return val;
256}
257
258void QgsPointCloudAttribute::getPointXYZ( const char *ptr, int i, std::size_t pointRecordSize, int xOffset, QgsPointCloudAttribute::DataType xType,
259 int yOffset, QgsPointCloudAttribute::DataType yType,
260 int zOffset, QgsPointCloudAttribute::DataType zType,
261 const QgsVector3D &indexScale, const QgsVector3D &indexOffset, double &x, double &y, double &z )
262{
263 _attribute( ptr, i * pointRecordSize + xOffset, xType, x );
264 x = indexOffset.x() + indexScale.x() * x;
265
266 _attribute( ptr, i * pointRecordSize + yOffset, yType, y );
267 y = indexOffset.y() + indexScale.y() * y;
268
269 _attribute( ptr, i * pointRecordSize + zOffset, zType, z );
270 z = indexOffset.z() + indexScale.z() * z;
271}
272
273QVariantMap QgsPointCloudAttribute::getAttributeMap( const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection )
274{
275 QVariantMap map;
276 const QVector<QgsPointCloudAttribute> attributes = attributeCollection.attributes();
277 for ( const QgsPointCloudAttribute &attr : attributes )
278 {
279 const QString attributeName = attr.name();
280 int attributeOffset;
281 attributeCollection.find( attributeName, attributeOffset );
282 switch ( attr.type() )
283 {
285 {
286 const unsigned char value = *reinterpret_cast< const unsigned char * >( data + recordOffset + attributeOffset );
287 map[ attributeName ] = value;
288 }
289 break;
290
292 {
293 const char value = *( data + recordOffset + attributeOffset );
294 map[ attributeName ] = value;
295 }
296 break;
297
299 {
300 const quint32 value = *reinterpret_cast< const quint32 * >( data + recordOffset + attributeOffset );
301 map[ attributeName ] = value;
302 }
303 break;
305 {
306 const qint32 value = *reinterpret_cast< const qint32 * >( data + recordOffset + attributeOffset );
307 map[ attributeName ] = value;
308 }
309 break;
310
312 {
313 const quint64 value = *reinterpret_cast< const quint64 * >( data + recordOffset + attributeOffset );
314 map[ attributeName ] = value;
315 }
316 break;
318 {
319 const qint64 value = *reinterpret_cast< const qint64 * >( data + recordOffset + attributeOffset );
320 map[ attributeName ] = value;
321 }
322 break;
323
325 {
326 const short value = *reinterpret_cast< const short * >( data + recordOffset + attributeOffset );
327 map[ attributeName ] = value;
328 }
329 break;
330
332 {
333 const unsigned short value = *reinterpret_cast< const unsigned short * >( data + recordOffset + attributeOffset );
334 map[ attributeName ] = value;
335 }
336 break;
337
339 {
340 const float value = *reinterpret_cast< const float * >( data + recordOffset + attributeOffset );
341 map[ attributeName ] = value;
342 }
343 break;
344
346 {
347 const double value = *reinterpret_cast< const double * >( data + recordOffset + attributeOffset );
348 map[ attributeName ] = value;
349 }
350 break;
351 }
352 }
353 return map;
354}
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:52
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
Collection of point cloud attributes.
void push_back(const QgsPointCloudAttribute &attribute)
Adds extra attribute.
const QgsPointCloudAttribute * find(const QString &attributeName, int &offset) const
Finds the attribute with the name.
QgsFields toFields() const
Converts the attribute collection to an equivalent QgsFields collection.
void extend(const QgsPointCloudAttributeCollection &otherCollection, const QSet< QString > &matchingNames)
Adds specific missing attributes from another QgsPointCloudAttributeCollection.
QVector< QgsPointCloudAttribute > attributes() const
Returns all attributes.
int indexOf(const QString &name) const
Returns the index of the attribute with the specified name.
Attribute for point cloud data pair of name and size in bytes.
DataType
Systems of unit measurement.
@ UShort
Unsigned short int 2 bytes.
@ UChar
Unsigned char 1 byte.
@ UInt32
Unsigned int32 4 bytes.
@ UInt64
Unsigned int64 8 bytes.
QVariant::Type variantType() const
Returns the most suitable equivalent QVariant data type to this attribute type.
static void getPointXYZ(const char *ptr, int i, std::size_t pointRecordSize, int xOffset, QgsPointCloudAttribute::DataType xType, int yOffset, QgsPointCloudAttribute::DataType yType, int zOffset, QgsPointCloudAttribute::DataType zType, const QgsVector3D &indexScale, const QgsVector3D &indexOffset, double &x, double &y, double &z)
Retrieves the x, y, z values for the point at index i.
static bool isNumeric(DataType type)
Returns true if the specified data type is numeric.
static QVariantMap getAttributeMap(const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection)
Retrieves all the attributes of a point.
QString displayType() const
Returns the type to use when displaying this field.
int size() const
Returns size of the attribute in bytes.
QString name() const
Returns name of the attribute.
DataType type() const
Returns the data type.
double convertValueToDouble(const char *ptr) const
Returns the attribute's value as a double for data pointed to by ptr.
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:51
double z() const
Returns Z coordinate.
Definition: qgsvector3d.h:53
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:49
#define BUILTIN_UNREACHABLE
Definition: qgis.h:4180
void _attribute(const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value)