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.