23 #include "qgsconfig.h"
31 #include <QElapsedTimer>
32 #include <QTemporaryFile>
37 #include "lazperf/las.hpp"
45 const std::size_t requestedPointRecordSize = requestedAttributes.
pointRecordSize();
46 const int count = dataUncompressed.size() / pointRecordSize;
48 data.resize( requestedPointRecordSize * count );
49 char *destinationBuffer = data.data();
50 const char *s = dataUncompressed.data();
52 const QVector<QgsPointCloudAttribute> requestedAttributesVector = requestedAttributes.
attributes();
59 : inputOffset( inputOffset )
60 , inputSize( inputSize )
61 , inputType( inputType )
62 , requestedSize( requestedSize )
63 , requestedType( requestedType )
73 std::vector< AttributeData > attributeData;
74 attributeData.reserve( requestedAttributesVector.size() );
77 int inputAttributeOffset;
79 if ( !inputAttribute )
83 attributeData.emplace_back( AttributeData( inputAttributeOffset, inputAttribute->
size(), inputAttribute->
type(),
84 requestedAttribute.size(), requestedAttribute.type() ) );
87 int skippedPoints = 0;
88 std::unique_ptr< QgsPointCloudBlock > block = std::make_unique< QgsPointCloudBlock >(
94 const bool filterIsValid = filterExpression.isValid();
95 if ( !filterExpression.prepare( block.get() ) && filterIsValid )
98 block->setPointCount( 0 );
99 return block.release();
103 size_t outputOffset = 0;
104 for (
int i = 0; i < count; ++i )
106 for (
const AttributeData &attribute : attributeData )
108 _lazSerialize( destinationBuffer, outputOffset,
109 attribute.requestedType, s,
110 attribute.inputType, attribute.inputSize, i * pointRecordSize + attribute.inputOffset );
112 outputOffset += attribute.requestedSize;
119 double eval = filterExpression.evaluate( i - skippedPoints );
120 if ( !eval || std::isnan( eval ) )
123 outputOffset -= requestedPointRecordSize;
128 block->setPointCount( count - skippedPoints );
129 return block.release();
134 if ( ! QFile::exists( filename ) )
138 const bool r = f.open( QIODevice::ReadOnly );
142 const QByteArray dataUncompressed = f.read( f.size() );
143 return _decompressBinary( dataUncompressed, attributes, requestedAttributes, scale, offset, filterExpression );
148 return _decompressBinary( data, attributes, requestedAttributes, scale, offset, filterExpression );
153 QByteArray decompressZtdStream(
const QByteArray &dataCompressed )
158 const int MAXSIZE = 10000000;
159 QByteArray dataUncompressed;
160 dataUncompressed.resize( MAXSIZE );
162 ZSTD_DStream *strm = ZSTD_createDStream();
163 ZSTD_initDStream( strm );
165 ZSTD_inBuffer m_inBuf;
166 m_inBuf.src =
reinterpret_cast<const void *
>( dataCompressed.constData() );
167 m_inBuf.size = dataCompressed.size();
170 ZSTD_outBuffer outBuf {
reinterpret_cast<void *
>( dataUncompressed.data() ), MAXSIZE, 0 };
171 const size_t ret = ZSTD_decompressStream( strm, &outBuf, &m_inBuf );
172 Q_ASSERT( !ZSTD_isError( ret ) );
173 Q_ASSERT( outBuf.pos );
174 Q_ASSERT( outBuf.pos < outBuf.size );
176 ZSTD_freeDStream( strm );
177 dataUncompressed.resize( outBuf.pos );
178 return dataUncompressed;
183 if ( ! QFile::exists( filename ) )
187 const bool r = f.open( QIODevice::ReadOnly );
191 const QByteArray dataCompressed = f.readAll();
192 const QByteArray dataUncompressed = decompressZtdStream( dataCompressed );
193 return _decompressBinary( dataUncompressed, attributes, requestedAttributes, scale, offset, filterExpression );
198 const QByteArray dataUncompressed = decompressZtdStream( data );
199 return _decompressBinary( dataUncompressed, attributes, requestedAttributes, scale, offset, filterExpression );