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