22#include "qgspointcloudexpression.h"
35 const std::size_t requestedPointRecordSize = requestedAttributes.
pointRecordSize();
36 const int count = dataUncompressed.size() / pointRecordSize;
38 data.resize( requestedPointRecordSize * count );
39 char *destinationBuffer = data.data();
40 const char *s = dataUncompressed.data();
42 const QVector<QgsPointCloudAttribute> requestedAttributesVector = requestedAttributes.
attributes();
49 : inputOffset( inputOffset )
50 , inputSize( inputSize )
51 , inputType( inputType )
52 , requestedSize( requestedSize )
53 , requestedType( requestedType )
63 std::vector< AttributeData > attributeData;
64 attributeData.reserve( requestedAttributesVector.size() );
67 int inputAttributeOffset;
69 if ( !inputAttribute )
73 attributeData.emplace_back( AttributeData( inputAttributeOffset, inputAttribute->
size(), inputAttribute->
type(),
74 requestedAttribute.size(), requestedAttribute.type() ) );
77 int skippedPoints = 0;
78 std::unique_ptr< QgsPointCloudBlock > block = std::make_unique< QgsPointCloudBlock >(
84 const bool filterIsValid = filterExpression.isValid();
85 if ( !filterExpression.prepare( block.get() ) && filterIsValid )
88 block->setPointCount( 0 );
89 return block.release();
92 int xAttributeOffset, yAttributeOffset;
95 const bool hasFilterRect = !filterRect.
isEmpty();
98 attributeX = requestedAttributes.
find( QLatin1String(
"X" ), xAttributeOffset );
99 attributeY = requestedAttributes.
find( QLatin1String(
"Y" ), yAttributeOffset );
107 size_t outputOffset = 0;
108 for (
int i = 0; i < count; ++i )
110 for (
const AttributeData &attribute : attributeData )
112 lazSerialize_( destinationBuffer, outputOffset,
113 attribute.requestedType, s,
114 attribute.inputType, attribute.inputSize, i * pointRecordSize + attribute.inputOffset );
116 outputOffset += attribute.requestedSize;
120 bool skipThisPoint =
false;
121 if ( hasFilterRect && attributeX && attributeY )
123 const double x = attributeX->
convertValueToDouble( destinationBuffer + outputOffset - requestedPointRecordSize + xAttributeOffset );
124 const double y = attributeY->
convertValueToDouble( destinationBuffer + outputOffset - requestedPointRecordSize + yAttributeOffset );
126 skipThisPoint =
true;
128 if ( !skipThisPoint && filterIsValid )
131 double eval = filterExpression.evaluate( i - skippedPoints );
132 if ( !eval || std::isnan( eval ) )
133 skipThisPoint =
true;
138 outputOffset -= requestedPointRecordSize;
142 block->setPointCount( count - skippedPoints );
143 return block.release();
148 if ( ! QFile::exists( filename ) )
152 const bool r = f.open( QIODevice::ReadOnly );
156 const QByteArray dataUncompressed = f.read( f.size() );
157 return decompressBinary_( dataUncompressed, attributes, requestedAttributes, scale, offset, filterExpression, filterRect );
162 return decompressBinary_( data, attributes, requestedAttributes, scale, offset, filterExpression, filterRect );
167QByteArray decompressZtdStream(
const QByteArray &dataCompressed )
172 const int MAXSIZE = 10000000;
173 QByteArray dataUncompressed;
174 dataUncompressed.resize( MAXSIZE );
176 ZSTD_DStream *strm = ZSTD_createDStream();
177 ZSTD_initDStream( strm );
179 ZSTD_inBuffer m_inBuf;
180 m_inBuf.src =
reinterpret_cast<const void *
>( dataCompressed.constData() );
181 m_inBuf.size = dataCompressed.size();
184 ZSTD_outBuffer outBuf {
reinterpret_cast<void *
>( dataUncompressed.data() ), MAXSIZE, 0 };
185 const size_t ret = ZSTD_decompressStream( strm, &outBuf, &m_inBuf );
186 Q_ASSERT( !ZSTD_isError( ret ) );
187 Q_ASSERT( outBuf.pos );
188 Q_ASSERT( outBuf.pos < outBuf.size );
190 ZSTD_freeDStream( strm );
191 dataUncompressed.resize( outBuf.pos );
192 return dataUncompressed;
197 if ( ! QFile::exists( filename ) )
201 const bool r = f.open( QIODevice::ReadOnly );
205 const QByteArray dataCompressed = f.readAll();
206 const QByteArray dataUncompressed = decompressZtdStream( dataCompressed );
207 return decompressBinary_( dataUncompressed, attributes, requestedAttributes, scale, offset, filterExpression, filterRect );
212 const QByteArray dataUncompressed = decompressZtdStream( data );
213 return decompressBinary_( dataUncompressed, attributes, requestedAttributes, scale, offset, filterExpression, filterRect );
Collection of point cloud attributes.
int pointRecordSize() const
Returns total size of record.
const QgsPointCloudAttribute * find(const QString &attributeName, int &offset) const
Finds the attribute with the name.
QVector< QgsPointCloudAttribute > attributes() const
Returns all attributes.
Attribute for point cloud data pair of name and size in bytes.
DataType
Systems of unit measurement.
int size() const
Returns size of the attribute in bytes.
DataType type() const
Returns the data type.
double convertValueToDouble(const char *ptr) const
Returns the attribute's value as a double for data pointed to by ptr.
Base class for storing raw data from point cloud nodes.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
bool isEmpty() const
Returns true if the rectangle is empty.
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
double y() const
Returns Y coordinate.
double x() const
Returns X coordinate.