QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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"
19 #include "qgspointcloudattribute.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 
100 void 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 
133 QgsPointCloudAttributeCollection::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 
149 void 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 
163 QVector<QgsPointCloudAttribute> QgsPointCloudAttributeCollection::attributes() const
164 {
165  return mAttributes;
166 }
167 
168 const 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 
181 int 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 
203 template <typename T>
204 void _attribute( const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value )
205 {
206  switch ( type )
207  {
210  value = *( data + offset );
211  return;
212 
214  value = *reinterpret_cast< const quint32 * >( data + offset );
215  return;
216 
218  value = *reinterpret_cast< const qint32 * >( data + offset );
219  return;
220 
222  value = *reinterpret_cast< const quint64 * >( data + offset );
223  return;
224 
226  value = *reinterpret_cast< const qint64 * >( data + offset );
227  return;
228 
230  value = *reinterpret_cast< const short * >( data + offset );
231  return;
232 
234  value = *reinterpret_cast< const unsigned short * >( data + offset );
235  return;
236 
238  value = static_cast< T >( *reinterpret_cast< const float * >( data + offset ) );
239  return;
240 
242  value = *reinterpret_cast< const double * >( data + offset );
243  return;
244  }
246 }
247 
248 double QgsPointCloudAttribute::convertValueToDouble( const char *ptr ) const
249 {
250  double val;
251  _attribute( ptr, 0, mType, val );
252  return val;
253 }
254 
255 void QgsPointCloudAttribute::getPointXYZ( const char *ptr, int i, std::size_t pointRecordSize, int xOffset, QgsPointCloudAttribute::DataType xType,
256  int yOffset, QgsPointCloudAttribute::DataType yType,
257  int zOffset, QgsPointCloudAttribute::DataType zType,
258  const QgsVector3D &indexScale, const QgsVector3D &indexOffset, double &x, double &y, double &z )
259 {
260  _attribute( ptr, i * pointRecordSize + xOffset, xType, x );
261  x = indexOffset.x() + indexScale.x() * x;
262 
263  _attribute( ptr, i * pointRecordSize + yOffset, yType, y );
264  y = indexOffset.y() + indexScale.y() * y;
265 
266  _attribute( ptr, i * pointRecordSize + zOffset, zType, z );
267  z = indexOffset.z() + indexScale.z() * z;
268 }
269 
270 QVariantMap QgsPointCloudAttribute::getAttributeMap( const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection )
271 {
272  QVariantMap map;
273  const QVector<QgsPointCloudAttribute> attributes = attributeCollection.attributes();
274  for ( const QgsPointCloudAttribute &attr : attributes )
275  {
276  const QString attributeName = attr.name();
277  int attributeOffset;
278  attributeCollection.find( attributeName, attributeOffset );
279  switch ( attr.type() )
280  {
283  {
284  const char value = *( data + recordOffset + attributeOffset );
285  map[ attributeName ] = value;
286  }
287  break;
288 
290  {
291  const quint32 value = *reinterpret_cast< const quint32 * >( data + recordOffset + attributeOffset );
292  map[ attributeName ] = value;
293  }
294  break;
296  {
297  const qint32 value = *reinterpret_cast< const qint32 * >( data + recordOffset + attributeOffset );
298  map[ attributeName ] = value;
299  }
300  break;
301 
303  {
304  const quint64 value = *reinterpret_cast< const quint64 * >( data + recordOffset + attributeOffset );
305  map[ attributeName ] = value;
306  }
307  break;
309  {
310  const qint64 value = *reinterpret_cast< const qint64 * >( data + recordOffset + attributeOffset );
311  map[ attributeName ] = value;
312  }
313  break;
314 
316  {
317  const short value = *reinterpret_cast< const short * >( data + recordOffset + attributeOffset );
318  map[ attributeName ] = value;
319  }
320  break;
321 
323  {
324  const unsigned short value = *reinterpret_cast< const unsigned short * >( data + recordOffset + attributeOffset );
325  map[ attributeName ] = value;
326  }
327  break;
328 
330  {
331  const float value = *reinterpret_cast< const float * >( data + recordOffset + attributeOffset );
332  map[ attributeName ] = value;
333  }
334  break;
335 
337  {
338  const double value = *reinterpret_cast< const double * >( data + recordOffset + attributeOffset );
339  map[ attributeName ] = value;
340  }
341  break;
342  }
343  }
344  return map;
345 }
QgsPointCloudAttribute::displayType
QString displayType() const
Returns the type to use when displaying this field.
Definition: qgspointcloudattribute.cpp:52
QgsPointCloudAttribute::DataType
DataType
Systems of unit measurement.
Definition: qgspointcloudattribute.h:44
QgsPointCloudAttributeCollection::find
const QgsPointCloudAttribute * find(const QString &attributeName, int &offset) const
Finds the attribute with the name.
Definition: qgspointcloudattribute.cpp:168
QgsVector3D::y
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:64
QgsVector3D
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
Definition: qgsvector3d.h:31
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsPointCloudAttributeCollection::QgsPointCloudAttributeCollection
QgsPointCloudAttributeCollection()
Ctor.
qgis.h
QgsPointCloudAttribute::convertValueToDouble
double convertValueToDouble(const char *ptr) const
Returns the attribute's value as a double for data pointed to by ptr.
Definition: qgspointcloudattribute.cpp:248
qgspointcloudattribute.h
QgsPointCloudAttribute::UInt32
@ UInt32
Unsigned int32 4 bytes.
Definition: qgspointcloudattribute.h:51
QgsFields::append
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
QgsPointCloudAttribute::name
QString name() const
Returns name of the attribute.
Definition: qgspointcloudattribute.h:64
QgsPointCloudAttribute::Double
@ Double
Double 8 bytes.
Definition: qgspointcloudattribute.h:55
QgsPointCloudAttributeCollection::extend
void extend(const QgsPointCloudAttributeCollection &otherCollection, const QSet< QString > &matchingNames)
Adds specific missing attributes from another QgsPointCloudAttributeCollection.
Definition: qgspointcloudattribute.cpp:149
QgsPointCloudAttribute::isNumeric
static bool isNumeric(DataType type)
Returns true if the specified data type is numeric.
Definition: qgspointcloudattribute.cpp:80
QgsPointCloudAttribute::Short
@ Short
Short int 2 bytes.
Definition: qgspointcloudattribute.h:48
QgsPointCloudAttribute::UInt64
@ UInt64
Unsigned int64 8 bytes.
Definition: qgspointcloudattribute.h:53
QgsPointCloudAttribute::Int32
@ Int32
Int32 4 bytes.
Definition: qgspointcloudattribute.h:50
QgsPointCloudAttributeCollection::attributes
QVector< QgsPointCloudAttribute > attributes() const
Returns all attributes.
Definition: qgspointcloudattribute.cpp:163
QgsPointCloudAttribute::variantType
QVariant::Type variantType() const
Returns the most suitable equivalent QVariant data type to this attribute type.
Definition: qgspointcloudattribute.cpp:30
QgsPointCloudAttribute::UShort
@ UShort
Unsigned short int 2 bytes.
Definition: qgspointcloudattribute.h:49
QgsVector3D::z
double z() const
Returns Z coordinate.
Definition: qgsvector3d.h:66
QgsPointCloudAttributeCollection
Collection of point cloud attributes.
Definition: qgspointcloudattribute.h:141
BUILTIN_UNREACHABLE
#define BUILTIN_UNREACHABLE
Definition: qgis.h:2907
QgsPointCloudAttribute::Char
@ Char
Char 1 byte.
Definition: qgspointcloudattribute.h:46
QgsPointCloudAttribute
Attribute for point cloud data pair of name and size in bytes.
Definition: qgspointcloudattribute.h:40
QgsPointCloudAttribute::getAttributeMap
static QVariantMap getAttributeMap(const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection)
Retrieves all the attributes of a point.
Definition: qgspointcloudattribute.cpp:270
QgsPointCloudAttributeCollection::indexOf
int indexOf(const QString &name) const
Returns the index of the attribute with the specified name.
Definition: qgspointcloudattribute.cpp:181
QgsPointCloudAttribute::Int64
@ Int64
Int64 8 bytes.
Definition: qgspointcloudattribute.h:52
QgsPointCloudAttribute::size
int size() const
Returns size of the attribute in bytes.
Definition: qgspointcloudattribute.h:67
_attribute
void _attribute(const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value)
Definition: qgspointcloudattribute.cpp:204
QgsPointCloudAttributeCollection::toFields
QgsFields toFields() const
Converts the attribute collection to an equivalent QgsFields collection.
Definition: qgspointcloudattribute.cpp:193
QgsPointCloudAttributeCollection::push_back
void push_back(const QgsPointCloudAttribute &attribute)
Adds extra attribute.
Definition: qgspointcloudattribute.cpp:142
QgsPointCloudAttribute::UChar
@ UChar
Unsigned char 1 byte.
Definition: qgspointcloudattribute.h:47
QgsVector3D::x
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:62
QgsPointCloudAttribute::getPointXYZ
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.
Definition: qgspointcloudattribute.cpp:255
QgsPointCloudAttribute::QgsPointCloudAttribute
QgsPointCloudAttribute()
Ctor.
QgsPointCloudAttribute::Float
@ Float
Float 4 bytes.
Definition: qgspointcloudattribute.h:54
QgsPointCloudAttribute::type
DataType type() const
Returns the data type.
Definition: qgspointcloudattribute.h:74
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50