1 /***************************************************************************
2                          qgspointcloudattribute.h
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 #ifndef QGSPOINTCLOUDATTRIBUTE_H
19 #define QGSPOINTCLOUDATTRIBUTE_H
20 
21 #include "qgis.h"
22 #include "qgis_core.h"
23 #include "qgsfields.h"
24 #include <QString>
25 #include <QVector>
26 
27 #include "qgsvector3d.h"
28 
29 class QgsPointCloudAttributeCollection;
30 
31 /**
32  * \ingroup core
33  *
34  * \brief Attribute for point cloud data
35  * pair of name and size in bytes
36  *
37  * \since QGIS 3.18
38  */
39 class CORE_EXPORT QgsPointCloudAttribute
40 {
41   public:
42     //! Systems of unit measurement
43     enum DataType
44     {
45       Char, //!< Char 1 byte
46       Short, //!< Short int 2 bytes
47       UShort, //!< Unsigned short int 2 bytes
48       Int32, //!< Int32 4 bytes
49       Float, //!< Float 4 bytes
50       Double, //!< Double 8 bytes
51     };
52 
53     //! Ctor
54     QgsPointCloudAttribute();
55     //! Ctor
56     QgsPointCloudAttribute( const QString &name, DataType type );
57 
58     //! Returns name of the attribute
name()59     QString name() const { return mName; }
60 
61     //! Returns size of the attribute in bytes
size()62     int size() const { return mSize; }
63 
64     /**
65      * Returns the data type
66      *
67      * \see variantType()
68      */
type()69     DataType type() const { return mType; }
70 
71     /**
72      * Returns the most suitable equivalent QVariant data type to this attribute type.
73      *
74      * \see type()
75      */
76     QVariant::Type variantType() const;
77 
78     /**
79      * Returns the type to use when displaying this field.
80      *
81      * This will be used when the full datatype with details has to displayed to the user.
82      *
83      * \see type()
84      */
85     QString displayType() const;
86 
87     /**
88      * Returns TRUE if the specified data \a type is numeric.
89      */
90     static bool isNumeric( DataType type );
91 
92 #ifdef SIP_RUN
93     SIP_PYOBJECT __repr__();
94     % MethodCode
95     QString str = QStringLiteral( "<QgsPointCloudAttribute: %1 (%2)>" ).arg( sipCpp->name() ).arg( sipCpp->displayType() );
96     sipRes = PyUnicode_FromString( str.toUtf8().constData() );
97     % End
98 #endif
99 
100     /**
101     * Retrieves the x, y, z values for the point at index \a i.
102     */
103     static void getPointXYZ( const char *ptr, int i, std::size_t pointRecordSize, int xOffset, QgsPointCloudAttribute::DataType xType,
104                              int yOffset, QgsPointCloudAttribute::DataType yType,
105                              int zOffset, QgsPointCloudAttribute::DataType zType,
106                              const QgsVector3D &indexScale, const QgsVector3D &indexOffset, double &x, double &y, double &z ) SIP_SKIP;
107 
108     /**
109     * Retrieves all the attributes of a point
110     */
111     static QVariantMap getAttributeMap( const char *data, std::size_t recordOffset, const QgsPointCloudAttributeCollection &attributeCollection ) SIP_SKIP;
112 
113   private:
114     void updateSize();
115 
116     QString mName;
117     int mSize = 0;
118     DataType mType;
119 };
120 
121 /**
122  * \ingroup core
123  *
124  * \brief Collection of point cloud attributes
125  *
126  * \since QGIS 3.18
127  */
128 class CORE_EXPORT QgsPointCloudAttributeCollection
129 {
130   public:
131     //! Ctor
132     QgsPointCloudAttributeCollection();
133     //! Ctor with given attributes
134     QgsPointCloudAttributeCollection( const QVector<QgsPointCloudAttribute> &attributes );
135     //! Adds extra attribute
136     void push_back( const QgsPointCloudAttribute &attribute );
137 
138     //! Returns all attributes
139     QVector<QgsPointCloudAttribute> attributes() const;
140 
141     /**
142      * Returns the number of attributes present in the collection.
143      */
count()144     int count() const { return mAttributes.size(); }
145 
146     /**
147      * Returns the attribute at the specified \a index.
148      */
at(int index)149     const QgsPointCloudAttribute &at( int index ) const { return mAttributes.at( index ); }
150 
151     /**
152      * Finds the attribute with the name
153      *
154      * Returns NULLPTR if not found.
155      */
156     const QgsPointCloudAttribute *find( const QString &attributeName, int &offset ) const;
157 
158     /**
159      * Returns the index of the attribute with the specified \a name.
160      *
161      * Returns -1 if a matching attribute was not found.
162      */
163     int indexOf( const QString &name ) const;
164 
165     //! Returns total size of record
pointRecordSize()166     int pointRecordSize() const { return mSize; }
167 
168     /**
169      * Converts the attribute collection to an equivalent QgsFields collection.
170      */
171     QgsFields toFields() const;
172 
173   private:
174     int mSize = 0;
175     QVector<QgsPointCloudAttribute> mAttributes;
176 
177     struct CachedAttributeData
178     {
179       int index;
180       int offset;
CachedAttributeDataCachedAttributeData181       CachedAttributeData( int index, int offset )
182         : index( index )
183         , offset( offset )
184       {}
185     };
186 
187     QMap< QString, CachedAttributeData > mCachedAttributes;
188 };
189 
190 #endif // QGSPOINTCLOUDATTRIBUTE_H
191