QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
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
19
20#include "qgis.h"
21
23
25 : mName( name )
26 , mType( type )
27{
28 updateSize();
29}
30
32{
33 switch ( mType )
34 {
35 case DataType::UChar:
36 case DataType::Char:
37 case DataType::Short:
40 case DataType::Int32:
41 return QMetaType::Type::Int;
42
44 case DataType::Int64:
45 return QMetaType::Type::LongLong;
46 case DataType::Float:
48 return QMetaType::Type::Double;
49 }
50 return QMetaType::Type::UnknownType;
51}
52
54{
55 switch ( mType )
56 {
57 case DataType::UChar:
58 return QObject::tr( "Unsigned Character" );
59 case DataType::Char:
60 return QObject::tr( "Character" );
61 case DataType::Short:
62 return QObject::tr( "Short" );
64 return QObject::tr( "Unsigned Short" );
65 case DataType::Float:
66 return QObject::tr( "Float" );
67 case DataType::Int32:
68 return QObject::tr( "Integer" );
70 return QObject::tr( "Unsigned Integer" );
71 case DataType::Int64:
72 return QObject::tr( "Long Integer" );
74 return QObject::tr( "Unsigned Long Integer" );
76 return QObject::tr( "Double" );
77 }
78 return QString();
79}
80
82{
83 switch ( type )
84 {
85 case DataType::UChar:
86 case DataType::Char:
87 return false;
88 case DataType::Short:
90 case DataType::Int32:
92 case DataType::Int64:
94 case DataType::Float:
96 return true;
97 }
98 return false;
99}
100
101void QgsPointCloudAttribute::updateSize()
102{
103 switch ( mType )
104 {
105 case DataType::UChar:
106 case DataType::Char:
107 mSize = 1;
108 break;
109 case DataType::Short:
110 case DataType::UShort:
111 mSize = 2;
112 break;
113 case DataType::Float:
114 mSize = 4;
115 break;
116 case DataType::Int32:
117 case DataType::UInt32:
118 mSize = 4;
119 break;
120 case DataType::Int64:
121 case DataType::UInt64:
122 mSize = 8;
123 break;
124 case DataType::Double:
125 mSize = 8;
126 break;
127 }
128}
129
130// //////////////////
131
133
135{
136 mAttributes.reserve( attributes.size() );
137 for ( const QgsPointCloudAttribute &attribute : attributes )
138 {
139 push_back( attribute );
140 }
141}
142
144{
145 mCachedAttributes.insert( attribute.name().toUpper(), CachedAttributeData( mAttributes.size(), mSize ) );
146 mAttributes.push_back( attribute );
147 mSize += attribute.size();
148}
149
150void QgsPointCloudAttributeCollection::extend( const QgsPointCloudAttributeCollection &otherCollection, const QSet<QString> &matchingNames )
151{
152 for ( const auto &attributeName : matchingNames )
153 {
154 if ( indexOf( attributeName ) == -1 )
155 {
156 int offset;
157 const auto attr = otherCollection.find( attributeName, offset );
158 if ( attr )
159 push_back( *attr );
160 }
161 }
162}
163
164QVector<QgsPointCloudAttribute> QgsPointCloudAttributeCollection::attributes() const
165{
166 return mAttributes;
167}
168
169const QgsPointCloudAttribute *QgsPointCloudAttributeCollection::find( const QString &attributeName, int &offset ) const
170{
171 const auto it = mCachedAttributes.constFind( attributeName.toUpper() );
172 if ( it != mCachedAttributes.constEnd() )
173 {
174 offset = it->offset;
175 return &mAttributes.at( it->index );
176 }
177
178 // not found
179 return nullptr;
180}
181
182int QgsPointCloudAttributeCollection::indexOf( const QString &name ) const
183{
184 const auto it = mCachedAttributes.constFind( name.toUpper() );
185 if ( it != mCachedAttributes.constEnd() )
186 {
187 return it->index;
188 }
189
190 // not found
191 return -1;
192}
193
195{
196 QgsFields fields;
197 for ( const QgsPointCloudAttribute &attribute : mAttributes )
198 {
199 fields.append( QgsField( attribute.name(), attribute.variantType(), attribute.displayType() ) );
200 }
201 return fields;
202}
203
204template <typename T>
205void _attribute( const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value )
206{
207 switch ( type )
208 {
210 value = *reinterpret_cast< const unsigned char * >( data + offset );
211 return;
212
214 value = *( data + offset );
215 return;
216
218 value = *reinterpret_cast< const quint32 * >( data + offset );
219 return;
220
222 value = *reinterpret_cast< const qint32 * >( data + offset );
223 return;
224
226 value = *reinterpret_cast< const quint64 * >( data + offset );
227 return;
228
230 value = *reinterpret_cast< const qint64 * >( data + offset );
231 return;
232
234 value = *reinterpret_cast< const short * >( data + offset );
235 return;
236
238 value = *reinterpret_cast< const unsigned short * >( data + offset );
239 return;
240
242 value = static_cast< T >( *reinterpret_cast< const float * >( data + offset ) );
243 return;
244
246 value = *reinterpret_cast< const double * >( data + offset );
247 return;
248 }
250}
251
252double QgsPointCloudAttribute::convertValueToDouble( const char *ptr ) const
253{
254 double val;
255 _attribute( ptr, 0, mType, val );
256 return val;
257}
258
259void QgsPointCloudAttribute::getPointXYZ( const char *ptr, int i, std::size_t pointRecordSize, int xOffset, QgsPointCloudAttribute::DataType xType,
260 int yOffset, QgsPointCloudAttribute::DataType yType,
261 int zOffset, QgsPointCloudAttribute::DataType zType,
262 const QgsVector3D &indexScale, const QgsVector3D &indexOffset, double &x, double &y, double &z )
263{
264 _attribute( ptr, i * pointRecordSize + xOffset, xType, x );
265 x = indexOffset.x() + indexScale.x() * x;
266
267 _attribute( ptr, i * pointRecordSize + yOffset, yType, y );
268 y = indexOffset.y() + indexScale.y() * y;
269
270 _attribute( ptr, i * pointRecordSize + zOffset, zType, z );
271 z = indexOffset.z() + indexScale.z() * z;
272}
273
274QVariantMap QgsPointCloudAttribute::getAttributeMap( const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection )
275{
276 QVariantMap map;
277 const QVector<QgsPointCloudAttribute> attributes = attributeCollection.attributes();
278 for ( const QgsPointCloudAttribute &attr : attributes )
279 {
280 const QString attributeName = attr.name();
281 int attributeOffset;
282 attributeCollection.find( attributeName, attributeOffset );
283 switch ( attr.type() )
284 {
286 {
287 const unsigned char value = *reinterpret_cast< const unsigned char * >( data + recordOffset + attributeOffset );
288 map[ attributeName ] = value;
289 }
290 break;
291
293 {
294 const char value = *( data + recordOffset + attributeOffset );
295 map[ attributeName ] = value;
296 }
297 break;
298
300 {
301 const quint32 value = *reinterpret_cast< const quint32 * >( data + recordOffset + attributeOffset );
302 map[ attributeName ] = value;
303 }
304 break;
306 {
307 const qint32 value = *reinterpret_cast< const qint32 * >( data + recordOffset + attributeOffset );
308 map[ attributeName ] = value;
309 }
310 break;
311
313 {
314 const quint64 value = *reinterpret_cast< const quint64 * >( data + recordOffset + attributeOffset );
315 map[ attributeName ] = value;
316 }
317 break;
319 {
320 const qint64 value = *reinterpret_cast< const qint64 * >( data + recordOffset + attributeOffset );
321 map[ attributeName ] = value;
322 }
323 break;
324
326 {
327 const short value = *reinterpret_cast< const short * >( data + recordOffset + attributeOffset );
328 map[ attributeName ] = value;
329 }
330 break;
331
333 {
334 const unsigned short value = *reinterpret_cast< const unsigned short * >( data + recordOffset + attributeOffset );
335 map[ attributeName ] = value;
336 }
337 break;
338
340 {
341 const float value = *reinterpret_cast< const float * >( data + recordOffset + attributeOffset );
342 map[ attributeName ] = value;
343 }
344 break;
345
347 {
348 const double value = *reinterpret_cast< const double * >( data + recordOffset + attributeOffset );
349 map[ attributeName ] = value;
350 }
351 break;
352 }
353 }
354 return map;
355}
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:54
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:73
A 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.
QMetaType::Type variantType() const
Returns the most suitable equivalent QVariant data type to this attribute type.
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.
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.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:30
double y() const
Returns Y coordinate.
Definition qgsvector3d.h:49
double z() const
Returns Z coordinate.
Definition qgsvector3d.h:51
double x() const
Returns X coordinate.
Definition qgsvector3d.h:47
#define BUILTIN_UNREACHABLE
Definition qgis.h:7208
void _attribute(const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value)