31#include <QElapsedTimer> 
   32#include <QTemporaryFile> 
   37#include "lazperf/las.hpp" 
   38#include <lazperf/lazperf.hpp> 
   55      const char val = char( value );
 
   61      const unsigned char val = ( 
unsigned char )( value );
 
   68      short val = short( value );
 
   69      memcpy( s + position, 
reinterpret_cast<char * 
>( &val ), 
sizeof( 
short ) );
 
   74      unsigned short val = 
static_cast< unsigned short>( value );
 
   75      memcpy( s + position, 
reinterpret_cast< char * 
>( &val ), 
sizeof( 
unsigned short ) );
 
   81      qint32 val = qint32( value );
 
   82      memcpy( s + position, 
reinterpret_cast< char * 
>( &val ), 
sizeof( qint32 ) );
 
   87      quint32 val = quint32( value );
 
   88      memcpy( s + position, 
reinterpret_cast< char * 
>( &val ), 
sizeof( quint32 ) );
 
   94      qint64 val = qint64( value );
 
   95      memcpy( s + position, 
reinterpret_cast< char * 
>( &val ), 
sizeof( qint64 ) );
 
  100      quint64 val = quint64( value );
 
  101      memcpy( s + position, 
reinterpret_cast< char * 
>( &val ), 
sizeof( quint64 ) );
 
  107      float val = float( value );
 
  108      memcpy( s + position, 
reinterpret_cast< char * 
>( &val ),  
sizeof( 
float ) );
 
  113      double val = double( value );
 
  114      memcpy( s + position, 
reinterpret_cast< char * 
>( &val ), 
sizeof( 
double ) );
 
  125  if ( outputType == inputType )
 
  127    memcpy( data + outputPosition, input + inputPosition, inputSize );
 
  135      const char val = *( input + inputPosition );
 
  136      return _lazStoreToStream<char>( data, outputPosition, outputType, val );
 
  140      const unsigned char val = *( input + inputPosition );
 
  141      return _lazStoreToStream<unsigned char>( data, outputPosition, outputType, val );
 
  145      const short val = *
reinterpret_cast< const short * 
>( input + inputPosition );
 
  146      return _lazStoreToStream<short>( data, outputPosition, outputType, val );
 
  150      const unsigned short val = *
reinterpret_cast< const unsigned short * 
>( input + inputPosition );
 
  151      return _lazStoreToStream<unsigned short>( data, outputPosition, outputType, val );
 
  155      const qint32 val = *
reinterpret_cast<const qint32 * 
>( input + inputPosition );
 
  156      return _lazStoreToStream<qint32>( data, outputPosition, outputType, val );
 
  160      const quint32 val = *
reinterpret_cast<const quint32 * 
>( input + inputPosition );
 
  161      return _lazStoreToStream<quint32>( data, outputPosition, outputType, val );
 
  165      const qint64 val = *
reinterpret_cast<const qint64 * 
>( input + inputPosition );
 
  166      return _lazStoreToStream<qint64>( data, outputPosition, outputType, val );
 
  170      const quint64 val = *
reinterpret_cast<const quint64 * 
>( input + inputPosition );
 
  171      return _lazStoreToStream<quint64>( data, outputPosition, outputType, val );
 
  175      const float val = *
reinterpret_cast< const float * 
>( input + inputPosition );
 
  176      return _lazStoreToStream<float>( data, outputPosition, outputType, val );
 
  180      const double val = *
reinterpret_cast< const double * 
>( input + inputPosition );
 
  181      return _lazStoreToStream<double>( data, outputPosition, outputType, val );
 
  189std::vector< QgsLazDecoder::RequestedAttributeDetails > __prepareRequestedAttributeDetails( 
const QgsPointCloudAttributeCollection &requestedAttributes, QVector<QgsLazInfo::ExtraBytesAttributeDetails> &extrabytesAttr )
 
  191  const QVector<QgsPointCloudAttribute> requestedAttributesVector = requestedAttributes.
attributes();
 
  193  std::vector< QgsLazDecoder::RequestedAttributeDetails > requestedAttributeDetails;
 
  194  requestedAttributeDetails.reserve( requestedAttributesVector.size() );
 
  197    if ( requestedAttribute.name().compare( QLatin1String( 
"X" ), Qt::CaseInsensitive ) == 0 )
 
  199      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::X, requestedAttribute.type(), requestedAttribute.size() ) );
 
  201    else if ( requestedAttribute.name().compare( QLatin1String( 
"Y" ), Qt::CaseInsensitive ) == 0 )
 
  203      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::Y, requestedAttribute.type(), requestedAttribute.size() ) );
 
  205    else if ( requestedAttribute.name().compare( QLatin1String( 
"Z" ), Qt::CaseInsensitive ) == 0 )
 
  207      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::Z, requestedAttribute.type(), requestedAttribute.size() ) );
 
  209    else if ( requestedAttribute.name().compare( QLatin1String( 
"Classification" ), Qt::CaseInsensitive ) == 0 )
 
  211      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::Classification, requestedAttribute.type(), requestedAttribute.size() ) );
 
  213    else if ( requestedAttribute.name().compare( QLatin1String( 
"Intensity" ), Qt::CaseInsensitive ) == 0 )
 
  215      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::Intensity, requestedAttribute.type(), requestedAttribute.size() ) );
 
  217    else if ( requestedAttribute.name().compare( QLatin1String( 
"ReturnNumber" ), Qt::CaseInsensitive ) == 0 )
 
  219      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::ReturnNumber, requestedAttribute.type(), requestedAttribute.size() ) );
 
  221    else if ( requestedAttribute.name().compare( QLatin1String( 
"NumberOfReturns" ), Qt::CaseInsensitive ) == 0 )
 
  223      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::NumberOfReturns, requestedAttribute.type(), requestedAttribute.size() ) );
 
  225    else if ( requestedAttribute.name().compare( QLatin1String( 
"ScanDirectionFlag" ), Qt::CaseInsensitive ) == 0 )
 
  227      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::ScanDirectionFlag, requestedAttribute.type(), requestedAttribute.size() ) );
 
  229    else if ( requestedAttribute.name().compare( QLatin1String( 
"EdgeOfFlightLine" ), Qt::CaseInsensitive ) == 0 )
 
  231      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::EdgeOfFlightLine, requestedAttribute.type(), requestedAttribute.size() ) );
 
  233    else if ( requestedAttribute.name().compare( QLatin1String( 
"ScanAngleRank" ), Qt::CaseInsensitive ) == 0 )
 
  235      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::ScanAngleRank, requestedAttribute.type(), requestedAttribute.size() ) );
 
  237    else if ( requestedAttribute.name().compare( QLatin1String( 
"UserData" ), Qt::CaseInsensitive ) == 0 )
 
  239      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::UserData, requestedAttribute.type(), requestedAttribute.size() ) );
 
  241    else if ( requestedAttribute.name().compare( QLatin1String( 
"PointSourceId" ), Qt::CaseInsensitive ) == 0 )
 
  243      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::PointSourceId, requestedAttribute.type(), requestedAttribute.size() ) );
 
  245    else if ( requestedAttribute.name().compare( QLatin1String( 
"GpsTime" ), Qt::CaseInsensitive ) == 0 )
 
  247      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::GpsTime, requestedAttribute.type(), requestedAttribute.size() ) );
 
  249    else if ( requestedAttribute.name().compare( QLatin1String( 
"Red" ), Qt::CaseInsensitive ) == 0 )
 
  251      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::Red, requestedAttribute.type(), requestedAttribute.size() ) );
 
  253    else if ( requestedAttribute.name().compare( QLatin1String( 
"Green" ), Qt::CaseInsensitive ) == 0 )
 
  255      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::Green, requestedAttribute.type(), requestedAttribute.size() ) );
 
  257    else if ( requestedAttribute.name().compare( QLatin1String( 
"Blue" ), Qt::CaseInsensitive ) == 0 )
 
  259      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::Blue, requestedAttribute.type(), requestedAttribute.size() ) );
 
  261    else if ( requestedAttribute.name().compare( QLatin1String( 
"ScannerChannel" ), Qt::CaseInsensitive ) == 0 )
 
  263      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::ScannerChannel, requestedAttribute.type(), requestedAttribute.size() ) );
 
  265    else if ( requestedAttribute.name().compare( QLatin1String( 
"ClassificationFlags" ), Qt::CaseInsensitive ) == 0 )
 
  267      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::ClassificationFlags, requestedAttribute.type(), requestedAttribute.size() ) );
 
  269    else if ( requestedAttribute.name().compare( QLatin1String( 
"Infrared" ), Qt::CaseInsensitive ) == 0 )
 
  271      requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::NIR, requestedAttribute.type(), requestedAttribute.size() ) );
 
  275      bool foundAttr = 
false;
 
  278        if ( requestedAttribute.name().compare( eba.attribute.trimmed() ) == 0 )
 
  280          requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::ExtraBytes, eba.type, eba.size, eba.offset ) );
 
  288        requestedAttributeDetails.emplace_back( QgsLazDecoder::RequestedAttributeDetails( QgsLazDecoder::LazAttribute::MissingOrUnknown, requestedAttribute.type(), requestedAttribute.size() ) );
 
  292  return requestedAttributeDetails;
 
  295void decodePoint( 
char *buf, 
int lasPointFormat, 
char *dataBuffer, std::size_t &outputOffset, std::vector< QgsLazDecoder::RequestedAttributeDetails > &requestedAttributeDetails )
 
  297  lazperf::las::point10 p10;
 
  298  lazperf::las::gpstime gps;
 
  299  lazperf::las::rgb rgb;
 
  300  lazperf::las::nir14 nir;
 
  301  lazperf::las::point14 p14;
 
  303  bool isLas14 = ( lasPointFormat == 6 || lasPointFormat == 7 || lasPointFormat == 8 );
 
  305  switch ( lasPointFormat )
 
  313      gps.unpack( buf + 
sizeof( lazperf::las::point10 ) );
 
  317      rgb.unpack( buf + 
sizeof( lazperf::las::point10 ) );
 
  321      gps.unpack( buf + 
sizeof( lazperf::las::point10 ) );
 
  322      rgb.unpack( buf + 
sizeof( lazperf::las::point10 ) + 
sizeof( lazperf::las::gpstime ) );
 
  331      rgb.unpack( buf + 
sizeof( lazperf::las::point14 ) );
 
  335      rgb.unpack( buf + 
sizeof( lazperf::las::point14 ) );
 
  336      nir.unpack( buf + 
sizeof( lazperf::las::point14 ) + 
sizeof( lazperf::las::rgb ) );
 
  343  for ( 
const QgsLazDecoder::RequestedAttributeDetails &requestedAttribute : requestedAttributeDetails )
 
  345    switch ( requestedAttribute.attribute )
 
  347      case QgsLazDecoder::LazAttribute::X:
 
  348        _lazStoreToStream<qint32>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.x() : p10.x );
 
  350      case QgsLazDecoder::LazAttribute::Y:
 
  351        _lazStoreToStream<qint32>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.y() : p10.y );
 
  353      case QgsLazDecoder::LazAttribute::Z:
 
  354        _lazStoreToStream<qint32>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.z() : p10.z );
 
  356      case QgsLazDecoder::LazAttribute::Classification:
 
  357        _lazStoreToStream<unsigned char>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.classification() : p10.classification );
 
  359      case QgsLazDecoder::LazAttribute::Intensity:
 
  360        _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.intensity() : p10.intensity );
 
  362      case QgsLazDecoder::LazAttribute::ReturnNumber:
 
  363        _lazStoreToStream<unsigned char>( dataBuffer,  outputOffset, requestedAttribute.type, isLas14 ? p14.returnNum() : p10.return_number );
 
  365      case QgsLazDecoder::LazAttribute::NumberOfReturns:
 
  366        _lazStoreToStream<unsigned char>( dataBuffer,  outputOffset, requestedAttribute.type, isLas14 ? p14.numReturns() : p10.number_of_returns_of_given_pulse );
 
  368      case QgsLazDecoder::LazAttribute::ScanDirectionFlag:
 
  369        _lazStoreToStream<unsigned char>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.scanDirFlag() : p10.scan_direction_flag );
 
  371      case QgsLazDecoder::LazAttribute::EdgeOfFlightLine:
 
  372        _lazStoreToStream<unsigned char>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.eofFlag() : p10.edge_of_flight_line );
 
  374      case QgsLazDecoder::LazAttribute::ScanAngleRank:
 
  375        _lazStoreToStream<char>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.scanAngle() : p10.scan_angle_rank );
 
  377      case QgsLazDecoder::LazAttribute::UserData:
 
  378        _lazStoreToStream<unsigned char>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.userData() : p10.user_data );
 
  380      case QgsLazDecoder::LazAttribute::PointSourceId:
 
  381        _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.pointSourceID() : p10.point_source_ID );
 
  383      case QgsLazDecoder::LazAttribute::GpsTime:
 
  385        _lazStoreToStream<double>( dataBuffer, outputOffset, requestedAttribute.type,
 
  386                                   isLas14 ? p14.gpsTime() : *
reinterpret_cast<const double *
>( 
reinterpret_cast<const void *
>( &gps.value ) ) );
 
  388      case QgsLazDecoder::LazAttribute::Red:
 
  389        _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, rgb.r );
 
  391      case QgsLazDecoder::LazAttribute::Green:
 
  392        _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, rgb.g );
 
  394      case QgsLazDecoder::LazAttribute::Blue:
 
  395        _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, rgb.b );
 
  397      case QgsLazDecoder::LazAttribute::ScannerChannel:
 
  398        _lazStoreToStream<char>( dataBuffer, outputOffset, requestedAttribute.type, p14.scannerChannel() );
 
  400      case QgsLazDecoder::LazAttribute::ClassificationFlags:
 
  401        _lazStoreToStream<char>( dataBuffer, outputOffset, requestedAttribute.type, p14.classFlags() );
 
  403      case QgsLazDecoder::LazAttribute::NIR:
 
  405        if ( lasPointFormat == 8 || lasPointFormat == 10 )
 
  407          _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, nir.val );
 
  412          _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, 0 );
 
  417      case QgsLazDecoder::LazAttribute::ExtraBytes:
 
  419        switch ( requestedAttribute.type )
 
  422            _lazStoreToStream<char>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<char * 
>( &buf[requestedAttribute.offset] ) );
 
  425            _lazStoreToStream<unsigned char>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<unsigned char * 
>( &buf[requestedAttribute.offset] ) );
 
  428            _lazStoreToStream<qint16>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<qint16 * 
>( &buf[requestedAttribute.offset] ) );
 
  431            _lazStoreToStream<quint16>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<quint16 * 
>( &buf[requestedAttribute.offset] ) );
 
  434            _lazStoreToStream<qint32>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<qint32 * 
>( &buf[requestedAttribute.offset] ) );
 
  437            _lazStoreToStream<quint32>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<quint32 * 
>( &buf[requestedAttribute.offset] ) );
 
  440            _lazStoreToStream<qint64>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<qint64 * 
>( &buf[requestedAttribute.offset] ) );
 
  443            _lazStoreToStream<quint64>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<quint64 * 
>( &buf[requestedAttribute.offset] ) );
 
  446            _lazStoreToStream<float>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<float * 
>( &buf[requestedAttribute.offset] ) );
 
  449            _lazStoreToStream<double>( dataBuffer, outputOffset, requestedAttribute.type, *
reinterpret_cast<double * 
>( &buf[requestedAttribute.offset] ) );
 
  454      case QgsLazDecoder::LazAttribute::MissingOrUnknown:
 
  456        _lazStoreToStream<unsigned short>( dataBuffer, outputOffset, requestedAttribute.type, 0 );
 
  460    outputOffset += requestedAttribute.size;
 
  464template<
typename FileType>
 
  478    lazperf::reader::generic_file f( file );
 
  485    int lasPointFormat = f.header().pointFormat();
 
  486    if ( lasPointFormat != 0 && lasPointFormat != 1 && lasPointFormat != 2 && lasPointFormat != 3 &&
 
  487         lasPointFormat != 6 && lasPointFormat != 7 && lasPointFormat != 8 )
 
  489      QgsDebugMsg( QStringLiteral( 
"Unexpected point format record (%1) - only 0, 1, 2, 3, 6, 7, 8 are supported" ).arg( lasPointFormat ) );
 
  493    const size_t count = f.header().point_count;
 
  494    const QgsVector3D scale( f.header().scale.x, f.header().scale.y, f.header().scale.z );
 
  495    const QgsVector3D offset( f.header().offset.x, f.header().offset.y, f.header().offset.z );
 
  497    QByteArray bufArray( f.header().point_record_length, 0 );
 
  498    char *buf = bufArray.data();
 
  500    const size_t requestedPointRecordSize = requestedAttributes.
pointRecordSize();
 
  502    data.resize( requestedPointRecordSize * count );
 
  503    char *dataBuffer = data.data();
 
  505    std::size_t outputOffset = 0;
 
  507    std::unique_ptr< QgsPointCloudBlock > block = std::make_unique< QgsPointCloudBlock >(
 
  513    int skippedPoints = 0;
 
  514    const bool filterIsValid = filterExpression.isValid();
 
  515    if ( !filterExpression.prepare( block.get() ) && filterIsValid )
 
  518      block->setPointCount( 0 );
 
  519      return block.release();
 
  522    std::vector<char> rawExtrabytes = f.vlrData( 
"LASF_Spec", 4 );
 
  523    QVector<QgsLazInfo::ExtraBytesAttributeDetails> extrabyteAttributesDetails = 
QgsLazInfo::parseExtrabytes( rawExtrabytes.data(), rawExtrabytes.size(), f.header().point_record_length );
 
  524    std::vector< QgsLazDecoder::RequestedAttributeDetails > requestedAttributeDetails = __prepareRequestedAttributeDetails( requestedAttributes, extrabyteAttributesDetails );
 
  526    for ( 
size_t i = 0 ; i < count ; i ++ )
 
  530      decodePoint( buf, lasPointFormat, dataBuffer, outputOffset, requestedAttributeDetails );
 
  536        double eval = filterExpression.evaluate( i - skippedPoints );
 
  537        if ( !eval || std::isnan( eval ) )
 
  540          outputOffset -= requestedPointRecordSize;
 
  547    QgsDebugMsgLevel( QStringLiteral( 
"LAZ-PERF Read through the points in %1 seconds." ).arg( t.elapsed() / 1000. ), 2 );
 
  549    block->setPointCount( count - skippedPoints );
 
  550    return block.release();
 
  552  catch ( std::exception &e )
 
  554    QgsDebugMsg( 
"Error decompressing laz file: " + QString::fromLatin1( e.what() ) );
 
  561    QgsPointCloudExpression &filterExpression )
 
  563  std::ifstream file( toNativePath( filename ), std::ios::binary );
 
  565  return __decompressLaz<std::ifstream>( file, requestedAttributes, filterExpression );
 
  570    QgsPointCloudExpression &filterExpression )
 
  572  std::istringstream file( byteArrayData.toStdString() );
 
  573  return __decompressLaz<std::istringstream>( file, requestedAttributes, filterExpression );
 
  580  if ( lasPointFormat != 6 && lasPointFormat != 7 && lasPointFormat != 8 )
 
  582    QgsDebugMsg( QStringLiteral( 
"Unexpected point format record (%1) - only 6, 7, 8 are supported for COPC format" ).arg( lasPointFormat ) );
 
  588  lazperf::reader::chunk_decompressor decompressor( lasPointFormat, lazInfo.
extrabytesCount(), data.data() );
 
  590  const size_t requestedPointRecordSize = requestedAttributes.
pointRecordSize();
 
  591  QByteArray blockData;
 
  592  blockData.resize( requestedPointRecordSize * pointCount );
 
  593  char *dataBuffer = blockData.data();
 
  595  std::size_t outputOffset = 0;
 
  597  QVector<QgsLazInfo::ExtraBytesAttributeDetails> extrabyteAttributesDetails = lazInfo.
extrabytes();
 
  598  std::vector< RequestedAttributeDetails > requestedAttributeDetails = __prepareRequestedAttributeDetails( requestedAttributes, extrabyteAttributesDetails );
 
  599  std::unique_ptr< QgsPointCloudBlock > block = std::make_unique< QgsPointCloudBlock >(
 
  600        pointCount, requestedAttributes,
 
  604  int skippedPoints = 0;
 
  605  const bool filterIsValid = filterExpression.isValid();
 
  606  if ( !filterExpression.prepare( block.get() ) && filterIsValid )
 
  609    block->setPointCount( 0 );
 
  610    return block.release();
 
  613  for ( 
int i = 0 ; i < pointCount; ++i )
 
  615    decompressor.decompress( decodedData.get() );
 
  616    char *buf = decodedData.get();
 
  618    decodePoint( buf, lasPointFormat, dataBuffer, outputOffset, requestedAttributeDetails );
 
  624      double eval = filterExpression.evaluate( i - skippedPoints );
 
  625      if ( !eval || std::isnan( eval ) )
 
  628        outputOffset -= requestedPointRecordSize;
 
  634  block->setPointCount( pointCount - skippedPoints );
 
  635  return block.release();
 
  639std::wstring QgsLazDecoder::toNativePath( 
const QString &filename )
 
  641  std::wstring_convert< std::codecvt_utf8_utf16< wchar_t > > converter;
 
  642  return converter.from_bytes( filename.toStdString() );
 
  645std::string QgsLazDecoder::toNativePath( 
const QString &filename )
 
  647  return filename.toStdString();
 
Class for extracting information contained in LAZ file such as the public header block and variable l...
 
int extrabytesCount() const
Returns the number of extrabytes contained in the LAZ dataset.
 
QgsVector3D scale() const
Returns the scale of the points coordinates.
 
int pointFormat() const
Returns the point format of the point records contained in the LAZ file.
 
QVector< ExtraBytesAttributeDetails > extrabytes() const
Returns the list of extrabytes contained in the LAZ file.
 
QgsVector3D offset() const
Returns the offset of the points coordinates.
 
int pointRecordLength() const
Returns the length of each point record in bytes.
 
static QVector< ExtraBytesAttributeDetails > parseExtrabytes(char *rawData, int length, int pointRecordLength)
Static function to parse the raw extrabytes VLR into a list of recognizable extrabyte attributes.
 
Collection of point cloud attributes.
 
int pointRecordSize() const
Returns total size of record.
 
QVector< QgsPointCloudAttribute > attributes() const
Returns all attributes.
 
Attribute for point cloud data pair of name and size in bytes.
 
DataType
Systems of unit measurement.
 
@ UShort
Unsigned short int 2 bytes.
 
@ Short
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.
 
#define QgsDebugMsgLevel(str, level)