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  auto block = std::make_unique< QgsPointCloudBlock >(
 
   84  const bool filterIsValid = filterExpression.isValid();
 
   85  if ( !filterExpression.prepare( block.get() ) && filterIsValid )
 
   88    block->setPointCount( 0 );
 
   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 );
 
  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 );
 
A 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.
 
A rectangle specified with double values.
 
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
 
void setYMinimum(double y)
Set the minimum y value.
 
void setXMinimum(double x)
Set the minimum x value.
 
void setYMaximum(double y)
Set the maximum y value.
 
void setXMaximum(double x)
Set the maximum x value.
 
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
 
double y() const
Returns Y coordinate.
 
double x() const
Returns X coordinate.