QGIS API Documentation  3.24.2-Tisler (13c1a02865)
qgseptdecoder.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgseptdecoder.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 QGSEPTDECODER_H
19 #define QGSEPTDECODER_H
20 
21 
22 #include "qgis_core.h"
23 #include "qgis_sip.h"
24 #include "qgspointcloudblock.h"
25 #include "qgspointcloudattribute.h"
26 
27 #include "laz-perf/io.hpp"
28 #include "laz-perf/common/common.hpp"
29 
31 #define SIP_NO_FILE
32 
33 #include <QString>
34 
35 namespace QgsEptDecoder
36 {
37  struct ExtraBytesAttributeDetails
38  {
39  QString attribute;
41  int size;
42  int offset;
43  };
44 
45  QgsPointCloudBlock *decompressBinary( const QString &filename, const QgsPointCloudAttributeCollection &attributes, const QgsPointCloudAttributeCollection &requestedAttributes, const QgsVector3D &scale, const QgsVector3D &offset );
46  QgsPointCloudBlock *decompressBinary( const QByteArray &data, const QgsPointCloudAttributeCollection &attributes, const QgsPointCloudAttributeCollection &requestedAttributes, const QgsVector3D &scale, const QgsVector3D &offset );
47  QgsPointCloudBlock *decompressZStandard( const QString &filename, const QgsPointCloudAttributeCollection &attributes, const QgsPointCloudAttributeCollection &requestedAttributes, const QgsVector3D &scale, const QgsVector3D &offset );
48  QgsPointCloudBlock *decompressZStandard( const QByteArray &data, const QgsPointCloudAttributeCollection &attributes, const QgsPointCloudAttributeCollection &requestedAttributes, const QgsVector3D &scale, const QgsVector3D &offset );
49  QgsPointCloudBlock *decompressLaz( const QString &filename, const QgsPointCloudAttributeCollection &attributes, const QgsPointCloudAttributeCollection &requestedAttributes, const QgsVector3D &scale, const QgsVector3D &offset );
50  QgsPointCloudBlock *decompressLaz( const QByteArray &data, const QgsPointCloudAttributeCollection &attributes, const QgsPointCloudAttributeCollection &requestedAttributes, const QgsVector3D &scale, const QgsVector3D &offset );
51 
53  template<typename FileType>
54  QVector<QgsEptDecoder::ExtraBytesAttributeDetails> readExtraByteAttributes( FileType &file )
55  {
56  if ( !file.good() )
57  return QVector<QgsEptDecoder::ExtraBytesAttributeDetails>();
58 
59  auto pastFilePos = file.tellg();
60 
61  file.seekg( 0 );
62 
63  laszip::io::reader::basic_file<FileType> f( file );
64  int point_record_length = f.get_header().point_record_length;
65 
66  // Read VLR stuff
67 
68  struct VlrHeader
69  {
70  unsigned short reserved;
71  char user_id[16];
72  unsigned short record_id;
73  unsigned short record_length;
74  char desc[32];
75  };
76 
77  struct ExtraByteDescriptor
78  {
79  unsigned char reserved[2]; // 2 bytes
80  unsigned char data_type; // 1 byte
81  unsigned char options; // 1 byte
82  char name[32]; // 32 bytes
83  unsigned char unused[4]; // 4 bytes
84  unsigned char no_data[8]; // 8 bytes
85  unsigned char deprecated1[16]; // 16 bytes
86  unsigned char min[8]; // 8 bytes
87  unsigned char deprecated2[16]; // 16 bytes
88  unsigned char max[8]; // 8 bytes
89  unsigned char deprecated3[16]; // 16 bytes
90  unsigned char scale[8]; // 8 bytes
91  unsigned char deprecated4[16]; // 16 bytes
92  double offset; // 8 bytes
93  unsigned char deprecated5[16]; // 16 bytes
94  char description[32]; // 32 bytes
95  };
96 
97  QVector<ExtraByteDescriptor> extraBytes;
98  QVector<ExtraBytesAttributeDetails> extrabytesAttr;
99 
100  VlrHeader extraBytesVlrHeader;
101  int extraBytesDescriptorsOffset = -1;
102 
103  file.seekg( f.get_header().header_size );
104  for ( unsigned int i = 0; i < f.get_header().vlr_count && file.good() && !file.eof(); ++i )
105  {
106  VlrHeader vlrHeader;
107  file.read( ( char * )&vlrHeader, sizeof( VlrHeader ) );
108  file.seekg( vlrHeader.record_length, std::ios::cur );
109  if ( std::equal( vlrHeader.user_id, vlrHeader.user_id + 9, "LASF_Spec" ) && vlrHeader.record_id == 4 )
110  {
111  extraBytesVlrHeader = vlrHeader;
112  extraBytesDescriptorsOffset = f.get_header().header_size + sizeof( VlrHeader );
113  }
114  }
115 
116  // Read VLR fields
117  if ( extraBytesDescriptorsOffset != -1 )
118  {
119  file.seekg( extraBytesDescriptorsOffset );
120  int n_descriptors = extraBytesVlrHeader.record_length / sizeof( ExtraByteDescriptor );
121  for ( int i = 0; i < n_descriptors; ++i )
122  {
123  ExtraByteDescriptor ebd;
124  file.read( ( char * )&ebd, sizeof( ExtraByteDescriptor ) );
125  extraBytes.push_back( ebd );
126  }
127  }
128 
129  for ( int i = ( int )extraBytes.size() - 1; i >= 0; --i )
130  {
131  ExtraByteDescriptor eb = extraBytes[i];
132  ExtraBytesAttributeDetails ebAtrr;
133  ebAtrr.attribute = QString::fromStdString( eb.name );
134  switch ( eb.data_type )
135  {
136  case 0:
137  ebAtrr.type = QgsPointCloudAttribute::Char;
138  ebAtrr.size = eb.options;
139  break;
140  case 1:
141  ebAtrr.type = QgsPointCloudAttribute::UChar;
142  ebAtrr.size = 1;
143  break;
144  case 2:
145  ebAtrr.type = QgsPointCloudAttribute::Char;
146  ebAtrr.size = 1;
147  break;
148  case 3:
149  ebAtrr.type = QgsPointCloudAttribute::UShort;
150  ebAtrr.size = 2;
151  break;
152  case 4:
153  ebAtrr.type = QgsPointCloudAttribute::Short;
154  ebAtrr.size = 2;
155  break;
156  case 5:
157  ebAtrr.type = QgsPointCloudAttribute::UInt32;
158  ebAtrr.size = 4;
159  break;
160  case 6:
161  ebAtrr.type = QgsPointCloudAttribute::Int32;
162  ebAtrr.size = 4;
163  break;
164  case 7:
165  ebAtrr.type = QgsPointCloudAttribute::UInt64;
166  ebAtrr.size = 8;
167  break;
168  case 8:
169  ebAtrr.type = QgsPointCloudAttribute::Int64;
170  ebAtrr.size = 8;
171  break;
172  case 9:
173  ebAtrr.type = QgsPointCloudAttribute::Float;
174  ebAtrr.size = 4;
175  break;
176  case 10:
177  ebAtrr.type = QgsPointCloudAttribute::Double;
178  ebAtrr.size = 8;
179  break;
180  default:
181  ebAtrr.type = QgsPointCloudAttribute::Char;
182  ebAtrr.size = eb.options;
183  break;
184  }
185  int accOffset = ( extrabytesAttr.empty() ? point_record_length : extrabytesAttr.back().offset ) - ebAtrr.size;
186  ebAtrr.offset = accOffset;
187  extrabytesAttr.push_back( ebAtrr );
188  }
189 
190  file.seekg( pastFilePos );
191 
192  return extrabytesAttr;
193  }
194 };
195 
197 #endif // QGSEPTDECODER_H
Collection of point cloud attributes.
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.
Base class for storing raw data from point cloud nodes.