QGIS API Documentation  3.24.2-Tisler (13c1a02865)
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(), CachedAttributeData( mAttributes.size(), mSize ) );
145  mAttributes.push_back( attribute );
146  mSize += attribute.size();
147 }
148 
149 QVector<QgsPointCloudAttribute> QgsPointCloudAttributeCollection::attributes() const
150 {
151  return mAttributes;
152 }
153 
154 const QgsPointCloudAttribute *QgsPointCloudAttributeCollection::find( const QString &attributeName, int &offset ) const
155 {
156  const auto it = mCachedAttributes.constFind( attributeName );
157  if ( it != mCachedAttributes.constEnd() )
158  {
159  offset = it->offset;
160  return &mAttributes.at( it->index );
161  }
162 
163  // not found
164  return nullptr;
165 }
166 
167 int QgsPointCloudAttributeCollection::indexOf( const QString &name ) const
168 {
169  const auto it = mCachedAttributes.constFind( name );
170  if ( it != mCachedAttributes.constEnd() )
171  {
172  return it->index;
173  }
174 
175  // not found
176  return -1;
177 }
178 
180 {
181  QgsFields fields;
182  for ( const QgsPointCloudAttribute &attribute : mAttributes )
183  {
184  fields.append( QgsField( attribute.name(), attribute.variantType(), attribute.displayType() ) );
185  }
186  return fields;
187 }
188 
189 template <typename T>
190 void _attribute( const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value )
191 {
192  switch ( type )
193  {
196  value = *( data + offset );
197  break;
198 
200  value = *reinterpret_cast< const quint32 * >( data + offset );
201  break;
203  value = *reinterpret_cast< const qint32 * >( data + offset );
204  break;
205 
207  value = *reinterpret_cast< const quint64 * >( data + offset );
208  break;
210  value = *reinterpret_cast< const qint64 * >( data + offset );
211  break;
212 
214  {
215  value = *reinterpret_cast< const short * >( data + offset );
216  }
217  break;
218 
220  value = *reinterpret_cast< const unsigned short * >( data + offset );
221  break;
222 
224  value = static_cast< T >( *reinterpret_cast< const float * >( data + offset ) );
225  break;
226 
228  value = *reinterpret_cast< const double * >( data + offset );
229  break;
230  }
231 }
232 
233 void QgsPointCloudAttribute::getPointXYZ( const char *ptr, int i, std::size_t pointRecordSize, int xOffset, QgsPointCloudAttribute::DataType xType,
234  int yOffset, QgsPointCloudAttribute::DataType yType,
235  int zOffset, QgsPointCloudAttribute::DataType zType,
236  const QgsVector3D &indexScale, const QgsVector3D &indexOffset, double &x, double &y, double &z )
237 {
238  _attribute( ptr, i * pointRecordSize + xOffset, xType, x );
239  x = indexOffset.x() + indexScale.x() * x;
240 
241  _attribute( ptr, i * pointRecordSize + yOffset, yType, y );
242  y = indexOffset.y() + indexScale.y() * y;
243 
244  _attribute( ptr, i * pointRecordSize + zOffset, zType, z );
245  z = indexOffset.z() + indexScale.z() * z;
246 }
247 
248 QVariantMap QgsPointCloudAttribute::getAttributeMap( const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection )
249 {
250  QVariantMap map;
251  const QVector<QgsPointCloudAttribute> attributes = attributeCollection.attributes();
252  for ( const QgsPointCloudAttribute &attr : attributes )
253  {
254  const QString attributeName = attr.name();
255  int attributeOffset;
256  attributeCollection.find( attributeName, attributeOffset );
257  switch ( attr.type() )
258  {
261  {
262  const char value = *( data + recordOffset + attributeOffset );
263  map[ attributeName ] = value;
264  }
265  break;
266 
268  {
269  const quint32 value = *reinterpret_cast< const quint32 * >( data + recordOffset + attributeOffset );
270  map[ attributeName ] = value;
271  }
272  break;
274  {
275  const qint32 value = *reinterpret_cast< const qint32 * >( data + recordOffset + attributeOffset );
276  map[ attributeName ] = value;
277  }
278  break;
279 
281  {
282  const quint64 value = *reinterpret_cast< const quint64 * >( data + recordOffset + attributeOffset );
283  map[ attributeName ] = value;
284  }
285  break;
287  {
288  const qint64 value = *reinterpret_cast< const qint64 * >( data + recordOffset + attributeOffset );
289  map[ attributeName ] = value;
290  }
291  break;
292 
294  {
295  const short value = *reinterpret_cast< const short * >( data + recordOffset + attributeOffset );
296  map[ attributeName ] = value;
297  }
298  break;
299 
301  {
302  const unsigned short value = *reinterpret_cast< const unsigned short * >( data + recordOffset + attributeOffset );
303  map[ attributeName ] = value;
304  }
305  break;
306 
308  {
309  const float value = *reinterpret_cast< const float * >( data + recordOffset + attributeOffset );
310  map[ attributeName ] = value;
311  }
312  break;
313 
315  {
316  const double value = *reinterpret_cast< const double * >( data + recordOffset + attributeOffset );
317  map[ attributeName ] = value;
318  }
319  break;
320  }
321  }
322  return map;
323 }
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
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.
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 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
void _attribute(const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value)