QGIS API Documentation  3.21.0-Master (909859188c)
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::Char:
35  case DataType::Short:
36  case DataType::UShort:
37  case DataType::Int32:
38  return QVariant::Int;
39 
40  case DataType::Float:
41  case DataType::Double:
42  return QVariant::Double;
43  }
44  return QVariant::Invalid;
45 }
46 
48 {
49  switch ( mType )
50  {
51  case DataType::Char:
52  return QObject::tr( "Character" );
53  case DataType::Short:
54  return QObject::tr( "Short" );
55  case DataType::UShort:
56  return QObject::tr( "Unsigned Short" );
57  case DataType::Float:
58  return QObject::tr( "Float" );
59  case DataType::Int32:
60  return QObject::tr( "Integer" );
61  case DataType::Double:
62  return QObject::tr( "Double" );
63  }
64  return QString();
65 }
66 
68 {
69  switch ( type )
70  {
71  case DataType::Char:
72  return false;
73  case DataType::Short:
74  case DataType::UShort:
75  case DataType::Float:
76  case DataType::Int32:
77  case DataType::Double:
78  return true;
79  }
80  return false;
81 }
82 
83 void QgsPointCloudAttribute::updateSize()
84 {
85  switch ( mType )
86  {
87  case DataType::Char:
88  mSize = 1;
89  break;
90  case DataType::Short:
91  case DataType::UShort:
92  mSize = 2;
93  break;
94  case DataType::Float:
95  mSize = 4;
96  break;
97  case DataType::Int32:
98  mSize = 4;
99  break;
100  case DataType::Double:
101  mSize = 8;
102  break;
103  }
104 }
105 
106 // //////////////////
107 
109 
110 QgsPointCloudAttributeCollection::QgsPointCloudAttributeCollection( const QVector<QgsPointCloudAttribute> &attributes )
111 {
112  mAttributes.reserve( attributes.size() );
113  for ( const QgsPointCloudAttribute &attribute : attributes )
114  {
115  push_back( attribute );
116  }
117 }
118 
120 {
121  mCachedAttributes.insert( attribute.name(), CachedAttributeData( mAttributes.size(), mSize ) );
122  mAttributes.push_back( attribute );
123  mSize += attribute.size();
124 }
125 
126 QVector<QgsPointCloudAttribute> QgsPointCloudAttributeCollection::attributes() const
127 {
128  return mAttributes;
129 }
130 
131 const QgsPointCloudAttribute *QgsPointCloudAttributeCollection::find( const QString &attributeName, int &offset ) const
132 {
133  const auto it = mCachedAttributes.constFind( attributeName );
134  if ( it != mCachedAttributes.constEnd() )
135  {
136  offset = it->offset;
137  return &mAttributes.at( it->index );
138  }
139 
140  // not found
141  return nullptr;
142 }
143 
144 int QgsPointCloudAttributeCollection::indexOf( const QString &name ) const
145 {
146  const auto it = mCachedAttributes.constFind( name );
147  if ( it != mCachedAttributes.constEnd() )
148  {
149  return it->index;
150  }
151 
152  // not found
153  return -1;
154 }
155 
157 {
158  QgsFields fields;
159  for ( const QgsPointCloudAttribute &attribute : mAttributes )
160  {
161  fields.append( QgsField( attribute.name(), attribute.variantType(), attribute.displayType() ) );
162  }
163  return fields;
164 }
165 
166 template <typename T>
167 void _attribute( const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value )
168 {
169  switch ( type )
170  {
172  value = *( data + offset );
173  break;
174 
176  value = *reinterpret_cast< const qint32 * >( data + offset );
177  break;
178 
180  {
181  value = *reinterpret_cast< const short * >( data + offset );
182  }
183  break;
184 
186  value = *reinterpret_cast< const unsigned short * >( data + offset );
187  break;
188 
190  value = static_cast< T >( *reinterpret_cast< const float * >( data + offset ) );
191  break;
192 
194  value = *reinterpret_cast< const double * >( data + offset );
195  break;
196  }
197 }
198 
199 void QgsPointCloudAttribute::getPointXYZ( const char *ptr, int i, std::size_t pointRecordSize, int xOffset, QgsPointCloudAttribute::DataType xType,
200  int yOffset, QgsPointCloudAttribute::DataType yType,
201  int zOffset, QgsPointCloudAttribute::DataType zType,
202  const QgsVector3D &indexScale, const QgsVector3D &indexOffset, double &x, double &y, double &z )
203 {
204  _attribute( ptr, i * pointRecordSize + xOffset, xType, x );
205  x = indexOffset.x() + indexScale.x() * x;
206 
207  _attribute( ptr, i * pointRecordSize + yOffset, yType, y );
208  y = indexOffset.y() + indexScale.y() * y;
209 
210  _attribute( ptr, i * pointRecordSize + zOffset, zType, z );
211  z = indexOffset.z() + indexScale.z() * z;
212 }
213 
214 QVariantMap QgsPointCloudAttribute::getAttributeMap( const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection )
215 {
216  QVariantMap map;
217  const QVector<QgsPointCloudAttribute> attributes = attributeCollection.attributes();
218  for ( const QgsPointCloudAttribute &attr : attributes )
219  {
220  const QString attributeName = attr.name();
221  int attributeOffset;
222  attributeCollection.find( attributeName, attributeOffset );
223  switch ( attr.type() )
224  {
226  {
227  const char value = *( data + recordOffset + attributeOffset );
228  map[ attributeName ] = value;
229  }
230  break;
231 
233  {
234  const qint32 value = *reinterpret_cast< const qint32 * >( data + recordOffset + attributeOffset );
235  map[ attributeName ] = value;
236  }
237  break;
238 
240  {
241  const short value = *reinterpret_cast< const short * >( data + recordOffset + attributeOffset );
242  map[ attributeName ] = value;
243  }
244  break;
245 
247  {
248  const unsigned short value = *reinterpret_cast< const unsigned short * >( data + recordOffset + attributeOffset );
249  map[ attributeName ] = value;
250  }
251  break;
252 
254  {
255  const float value = *reinterpret_cast< const float * >( data + recordOffset + attributeOffset );
256  map[ attributeName ] = value;
257  }
258  break;
259 
261  {
262  const double value = *reinterpret_cast< const double * >( data + recordOffset + attributeOffset );
263  map[ attributeName ] = value;
264  }
265  break;
266  }
267  }
268  return map;
269 }
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.
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)