Skip to content

Commit

Permalink
fix misplaced laszip tiles
Browse files Browse the repository at this point in the history
  • Loading branch information
NEDJIMAbelgacem authored and wonder-sk committed May 4, 2021
1 parent 0c3b3c1 commit 42ce3b6
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 33 deletions.
39 changes: 38 additions & 1 deletion python/core/auto_generated/pointcloud/qgspointcloudblock.sip.in
Expand Up @@ -32,7 +32,7 @@ Base class for storing raw data from point cloud nodes
%Docstring
Ctor
%End
~QgsPointCloudBlock();
virtual ~QgsPointCloudBlock();

const char *data() const;
%Docstring
Expand All @@ -51,6 +51,43 @@ Returns the attributes that are stored in the data block, along with their size

};


class QgsCustomPointCloudBlock : QgsPointCloudBlock
{
%Docstring(signature="appended")
Base class for storing raw data from point cloud nodes that have a custom scale and offset values

.. note::

The API is considered EXPERIMENTAL and can be changed without a notice

.. versionadded:: 3.20
%End

%TypeHeaderCode
#include "qgspointcloudblock.h"
%End
public:
QgsCustomPointCloudBlock( int count,
const QgsPointCloudAttributeCollection &attributes,
const QByteArray &data,
const QgsVector3D &scale,
const QgsVector3D &offset );
%Docstring
Ctor
%End

QgsVector3D scale() const;
%Docstring
Returns the custom scale of the block.
%End

QgsVector3D offset() const;
%Docstring
Returns the custom offset of the block.
%End
};

/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
10 changes: 10 additions & 0 deletions python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in
Expand Up @@ -51,11 +51,21 @@ Returns a reference to the context's render context.
QgsVector3D scale() const;
%Docstring
Returns the scale of the layer's int32 coordinates compared to CRS coords.
%End

void setScale( QgsVector3D scale );
%Docstring
Sets the scale of the layer's int32 coordinates compared to CRS coords.
%End

QgsVector3D offset() const;
%Docstring
Returns the offset of the layer's int32 coordinates compared to CRS coords.
%End

void setOffset( QgsVector3D offset );
%Docstring
Sets the offset of the layer's int32 coordinates compared to CRS coords.
%End

long pointsRendered() const;
Expand Down
61 changes: 40 additions & 21 deletions src/3d/symbols/qgspointcloud3dsymbol_p.cpp
Expand Up @@ -253,9 +253,13 @@ void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *p
const char *ptr = block->data();
int count = block->pointCount();
const std::size_t recordSize = attributes.pointRecordSize();

const QgsVector3D scale = pc->scale();
const QgsVector3D offset = pc->offset();
QgsVector3D blockScale = pc->scale();
QgsVector3D blockOffset = pc->offset();
if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( block.get() ) )
{
blockScale = customBlock->scale();
blockOffset = customBlock->offset();
}
const double zValueScale = context.zValueScale();
const double zValueOffset = context.zValueFixedOffset();
QgsCoordinateTransform coordinateTransform = context.coordinateTransform();
Expand All @@ -270,9 +274,9 @@ void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *p
qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );

double x = offset.x() + scale.x() * ix;
double y = offset.y() + scale.y() * iy;
double z = ( offset.z() + scale.z() * iz ) * zValueScale + zValueOffset;
double x = blockOffset.x() + blockScale.x() * ix;
double y = blockOffset.y() + blockScale.y() * iy;
double z = ( blockOffset.z() + blockScale.z() * iz ) * zValueScale + zValueOffset;
try
{
coordinateTransform.transformInPlace( x, y, z );
Expand Down Expand Up @@ -378,8 +382,13 @@ void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc,
int count = block->pointCount();
const std::size_t recordSize = attributes.pointRecordSize();

const QgsVector3D scale = pc->scale();
const QgsVector3D offset = pc->offset();
QgsVector3D blockScale = pc->scale();
QgsVector3D blockOffset = pc->offset();
if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( block.get() ) )
{
blockScale = customBlock->scale();
blockOffset = customBlock->offset();
}

for ( int i = 0; i < count; ++i )
{
Expand All @@ -390,9 +399,9 @@ void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc,
qint32 iy = *( qint32 * )( ptr + i * recordSize + yOffset );
qint32 iz = *( qint32 * )( ptr + i * recordSize + zOffset );

double x = offset.x() + scale.x() * ix;
double y = offset.y() + scale.y() * iy;
double z = ( offset.z() + scale.z() * iz ) * zValueScale + zValueOffset;
double x = blockOffset.x() + blockScale.x() * ix;
double y = blockOffset.y() + blockScale.y() * iy;
double z = ( blockOffset.z() + blockScale.z() * iz ) * zValueScale + zValueOffset;
try
{
coordinateTransform.transformInPlace( x, y, z );
Expand Down Expand Up @@ -483,8 +492,13 @@ void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const
int count = block->pointCount();
const std::size_t recordSize = attributes.pointRecordSize();

const QgsVector3D scale = pc->scale();
const QgsVector3D offset = pc->offset();
QgsVector3D blockScale = pc->scale();
QgsVector3D blockOffset = pc->offset();
if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( block.get() ) )
{
blockScale = customBlock->scale();
blockOffset = customBlock->offset();
}
const double zValueScale = context.zValueScale();
const double zValueOffset = context.zValueFixedOffset();
QgsCoordinateTransform coordinateTransform = context.coordinateTransform();
Expand All @@ -509,9 +523,9 @@ void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const
qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
double x = offset.x() + scale.x() * ix;
double y = offset.y() + scale.y() * iy;
double z = ( offset.z() + scale.z() * iz ) * zValueScale + zValueOffset;
double x = blockOffset.x() + blockScale.x() * ix;
double y = blockOffset.y() + blockScale.y() * iy;
double z = ( blockOffset.z() + blockScale.z() * iz ) * zValueScale + zValueOffset;
try
{
coordinateTransform.transformInPlace( x, y, z );
Expand Down Expand Up @@ -646,8 +660,13 @@ void QgsClassificationPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex
int count = block->pointCount();
const std::size_t recordSize = attributes.pointRecordSize();

const QgsVector3D scale = pc->scale();
const QgsVector3D offset = pc->offset();
QgsVector3D blockScale = pc->scale();
QgsVector3D blockOffset = pc->offset();
if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( block.get() ) )
{
blockScale = customBlock->scale();
blockOffset = customBlock->offset();
}
const double zValueScale = context.zValueScale();
const double zValueOffset = context.zValueFixedOffset();
QgsCoordinateTransform coordinateTransform = context.coordinateTransform();
Expand All @@ -663,9 +682,9 @@ void QgsClassificationPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex
qint32 iy = *( qint32 * )( ptr + i * recordSize + yOffset );
qint32 iz = *( qint32 * )( ptr + i * recordSize + zOffset );

double x = offset.x() + scale.x() * ix;
double y = offset.y() + scale.y() * iy;
double z = ( offset.z() + scale.z() * iz ) * zValueScale + zValueOffset;
double x = blockOffset.x() + blockScale.x() * ix;
double y = blockOffset.y() + blockScale.y() * iy;
double z = ( blockOffset.z() + blockScale.z() * iz ) * zValueScale + zValueOffset;
try
{
coordinateTransform.transformInPlace( x, y, z );
Expand Down
10 changes: 9 additions & 1 deletion src/app/3d/qgs3dmaptoolidentify.cpp
Expand Up @@ -157,6 +157,14 @@ void Qgs3DMapToolIdentify::mouseReleaseEvent( QMouseEvent *event )
if ( !block )
continue;

QgsVector3D blockScale = index->scale();
QgsVector3D blockOffset = index->offset();
if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( block.get() ) )
{
blockScale = customBlock->scale();
blockOffset = customBlock->offset();
}

const char *ptr = block->data();
QgsPointCloudAttributeCollection blockAttributes = block->attributes();
const std::size_t recordSize = blockAttributes.pointRecordSize();
Expand All @@ -167,7 +175,7 @@ void Qgs3DMapToolIdentify::mouseReleaseEvent( QMouseEvent *event )
for ( int i = 0; i < block->pointCount(); ++i )
{
double x, y, z;
QgsPointCloudAttribute::getPointXYZ( ptr, i, recordSize, xOffset, xType, yOffset, yType, zOffset, zType, index->scale(), index->offset(), x, y, z );
QgsPointCloudAttribute::getPointXYZ( ptr, i, recordSize, xOffset, xType, yOffset, yType, zOffset, zType, blockScale, blockOffset, x, y, z );
QVector3D point( x, y, z );

// check whether point is in front of the ray
Expand Down
14 changes: 8 additions & 6 deletions src/core/pointcloud/qgseptdecoder.cpp
Expand Up @@ -284,6 +284,8 @@ QgsPointCloudBlock *__decompressLaz( FileType &file, const QgsPointCloudAttribut
laszip::io::reader::basic_file<FileType> f( file );

const size_t count = f.get_header().point_count;
QgsVector3D scale( f.get_header().scale.x, f.get_header().scale.y, f.get_header().scale.z );
QgsVector3D offset( f.get_header().offset.x, f.get_header().offset.y, f.get_header().offset.z );
char buf[sizeof( laszip::formats::las::point10 ) + sizeof( laszip::formats::las::gpstime ) + sizeof( laszip::formats::las::rgb ) ]; // a buffer large enough to hold our point

const size_t requestedPointRecordSize = requestedAttributes.pointRecordSize();
Expand Down Expand Up @@ -468,12 +470,12 @@ QgsPointCloudBlock *__decompressLaz( FileType &file, const QgsPointCloudAttribut
float t = common::since( start );
QgsDebugMsgLevel( QStringLiteral( "LAZ-PERF Read through the points in %1 seconds." ).arg( t ), 2 );
#endif

return new QgsPointCloudBlock(
count,
requestedAttributes,
data
);
QgsCustomPointCloudBlock *block = new QgsCustomPointCloudBlock(
count,
requestedAttributes,
data, scale, offset
);
return block;
}

QgsPointCloudBlock *QgsEptDecoder::decompressLaz( const QString &filename,
Expand Down
12 changes: 10 additions & 2 deletions src/core/pointcloud/qgspointcloudblock.cpp
Expand Up @@ -31,8 +31,6 @@ QgsPointCloudBlock::QgsPointCloudBlock(
{
}

QgsPointCloudBlock::~QgsPointCloudBlock() = default;

const char *QgsPointCloudBlock::data() const
{
return mStorage.data();
Expand All @@ -47,3 +45,13 @@ QgsPointCloudAttributeCollection QgsPointCloudBlock::attributes() const
{
return mAttributes;
}

// QgsCustomPointCloudBlock

QgsCustomPointCloudBlock::QgsCustomPointCloudBlock( int count,
const QgsPointCloudAttributeCollection &attributes,
const QByteArray &data,
const QgsVector3D &scale,
const QgsVector3D &offset ) : QgsPointCloudBlock( count, attributes, data ), mScale( scale ), mOffset( offset )
{
}
31 changes: 30 additions & 1 deletion src/core/pointcloud/qgspointcloudblock.h
Expand Up @@ -43,7 +43,7 @@ class CORE_EXPORT QgsPointCloudBlock
const QgsPointCloudAttributeCollection &attributes,
const QByteArray &data );
//! Dtor
~QgsPointCloudBlock();
virtual ~QgsPointCloudBlock() = default;

//! Returns raw pointer to data
const char *data() const;
Expand All @@ -60,4 +60,33 @@ class CORE_EXPORT QgsPointCloudBlock
QByteArray mStorage;
};


/**
* \ingroup core
* \brief Base class for storing raw data from point cloud nodes that have a custom scale and offset values
*
* \note The API is considered EXPERIMENTAL and can be changed without a notice
*
* \since QGIS 3.20
*/
class CORE_EXPORT QgsCustomPointCloudBlock : public QgsPointCloudBlock
{
public:
//! Ctor
QgsCustomPointCloudBlock( int count,
const QgsPointCloudAttributeCollection &attributes,
const QByteArray &data,
const QgsVector3D &scale,
const QgsVector3D &offset );

//! Returns the custom scale of the block.
QgsVector3D scale() const { return mScale; }

//! Returns the custom offset of the block.
QgsVector3D offset() const { return mOffset; }
private:
QgsVector3D mScale, mOffset;

};

#endif // QGSPOINTCLOUDBLOCK_H
10 changes: 9 additions & 1 deletion src/core/pointcloud/qgspointclouddataprovider.cpp
Expand Up @@ -201,6 +201,14 @@ struct MapIndexedPointCloudNode
if ( !block || pointsCount == mPointsLimit )
return acceptedPoints;

QgsVector3D blockScale = mIndexScale;
QgsVector3D blockOffset = mIndexOffset;
if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( block.get() ) )
{
blockScale = customBlock->scale();
blockOffset = customBlock->offset();
}

const char *ptr = block->data();
QgsPointCloudAttributeCollection blockAttributes = block->attributes();
const std::size_t recordSize = blockAttributes.pointRecordSize();
Expand All @@ -213,7 +221,7 @@ struct MapIndexedPointCloudNode
for ( int i = 0; i < block->pointCount() && pointsCount < mPointsLimit; ++i )
{
double x, y, z;
QgsPointCloudAttribute::getPointXYZ( ptr, i, recordSize, xOffset, xType, yOffset, yType, zOffset, zType, mIndexScale, mIndexOffset, x, y, z );
QgsPointCloudAttribute::getPointXYZ( ptr, i, recordSize, xOffset, xType, yOffset, yType, zOffset, zType, blockScale, blockOffset, x, y, z );
QgsPoint point( x, y );

if ( mZRange.contains( z ) && extentEngine->contains( &point ) )
Expand Down
24 changes: 24 additions & 0 deletions src/core/pointcloud/qgspointcloudlayerrenderer.cpp
Expand Up @@ -215,10 +215,21 @@ int QgsPointCloudLayerRenderer::renderNodesSync( const QVector<IndexedPointCloud

if ( !block )
continue;
QgsVector3D contextScale = context.scale();
QgsVector3D contextOffset = context.offset();
if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( block.get() ) )
{
context.setScale( customBlock->scale() );
context.setOffset( customBlock->offset() );
}

context.setAttributes( block->attributes() );

mRenderer->renderBlock( block.get(), context );

context.setScale( contextScale );
context.setOffset( contextOffset );

++nodesDrawn;

// as soon as first block is rendered, we can start showing layer updates.
Expand Down Expand Up @@ -293,9 +304,22 @@ int QgsPointCloudLayerRenderer::renderNodesAsync( const QVector<IndexedPointClou
if ( !blockRequests[ i ]->block() )
continue;

QgsVector3D contextScale = context.scale();
QgsVector3D contextOffset = context.offset();

if ( QgsCustomPointCloudBlock *customBlock = dynamic_cast<QgsCustomPointCloudBlock *>( blockRequests[ i ]->block() ) )
{
context.setScale( customBlock->scale() );
context.setOffset( customBlock->offset() );
}

context.setAttributes( blockRequests[ i ]->block()->attributes() );

mRenderer->renderBlock( blockRequests[ i ]->block(), context );

context.setScale( contextScale );
context.setOffset( contextOffset );

++nodesDrawn;

// as soon as first block is rendered, we can start showing layer updates.
Expand Down

0 comments on commit 42ce3b6

Please sign in to comment.