Skip to content

Commit

Permalink
Implement z range filtering for point clouds
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 28, 2020
1 parent 0f2a967 commit 775320e
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 3 deletions.
13 changes: 13 additions & 0 deletions python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in
Expand Up @@ -89,13 +89,26 @@ Returns the size of a single point record.
Returns the offset for the x value in a point record.

.. seealso:: :py:func:`yOffset`

.. seealso:: :py:func:`zOffset`
%End

int yOffset() const;
%Docstring
Returns the offset for the y value in a point record.

.. seealso:: :py:func:`xOffset`

.. seealso:: :py:func:`zOffset`
%End

int zOffset() const;
%Docstring
Returns the offset for the y value in a point record.

.. seealso:: :py:func:`xOffset`

.. seealso:: :py:func:`yOffset`
%End

private:
Expand Down
3 changes: 2 additions & 1 deletion src/core/pointcloud/qgspointcloudrenderer.cpp
Expand Up @@ -43,9 +43,10 @@ void QgsPointCloudRenderContext::setAttributes( const QgsPointCloudAttributeColl
mAttributes = attributes;
mPointRecordSize = mAttributes.pointRecordSize();

// fetch offset for x/y attributes
// fetch offset for x/y/z attributes
attributes.find( QStringLiteral( "X" ), mXOffset );
attributes.find( QStringLiteral( "Y" ), mYOffset );
attributes.find( QStringLiteral( "Z" ), mZOffset );
}

QgsPointCloudRenderer *QgsPointCloudRenderer::load( QDomElement &element, const QgsReadWriteContext &context )
Expand Down
11 changes: 11 additions & 0 deletions src/core/pointcloud/qgspointcloudrenderer.h
Expand Up @@ -111,16 +111,26 @@ class CORE_EXPORT QgsPointCloudRenderContext
* Returns the offset for the x value in a point record.
*
* \see yOffset()
* \see zOffset()
*/
int xOffset() const { return mXOffset; }

/**
* Returns the offset for the y value in a point record.
*
* \see xOffset()
* \see zOffset()
*/
int yOffset() const { return mYOffset; }

/**
* Returns the offset for the y value in a point record.
*
* \see xOffset()
* \see yOffset()
*/
int zOffset() const { return mZOffset; }

private:
#ifdef SIP_RUN
QgsPointCloudRenderContext( const QgsPointCloudRenderContext &rh );
Expand All @@ -134,6 +144,7 @@ class CORE_EXPORT QgsPointCloudRenderContext
int mPointRecordSize = 0;
int mXOffset = 0;
int mYOffset = 0;
int mZOffset = 0;
};


Expand Down
22 changes: 20 additions & 2 deletions src/core/pointcloud/qgspointcloudrgbrenderer.cpp
Expand Up @@ -92,6 +92,9 @@ void QgsPointCloudRgbRenderer::renderBlock( const QgsPointCloudBlock *block, Qgs
const bool useBlueContrastEnhancement = mBlueContrastEnhancement && mBlueContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement;
const bool useGreenContrastEnhancement = mGreenContrastEnhancement && mGreenContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement;

const QgsDoubleRange zRange = context.renderContext().zRange();
const bool considerZ = !zRange.isInfinite();

int rendered = 0;
double x = 0;
double y = 0;
Expand All @@ -100,6 +103,15 @@ void QgsPointCloudRgbRenderer::renderBlock( const QgsPointCloudBlock *block, Qgs
const bool reproject = ct.isValid();
for ( int i = 0; i < count; ++i )
{
if ( considerZ )
{
// z value filtering is cheapest, if we're doing it...
qint32 iz = *( qint32 * )( ptr + i * context.pointRecordSize() + context.zOffset() );
z = context.offset().z() + context.scale().z() * iz;
if ( !zRange.contains( z ) )
continue;
}

pointXY( context, ptr, i, x, y );
if ( visibleExtent.contains( QgsPointXY( x, y ) ) )
{
Expand Down Expand Up @@ -307,9 +319,15 @@ void QgsPointCloudRgbRenderer::stopRender( QgsPointCloudRenderContext &context )
QgsPointCloudRenderer::stopRender( context );
}

QSet<QString> QgsPointCloudRgbRenderer::usedAttributes( const QgsPointCloudRenderContext & ) const
QSet<QString> QgsPointCloudRgbRenderer::usedAttributes( const QgsPointCloudRenderContext &context ) const
{
return QSet<QString>() << mRedAttribute << mGreenAttribute << mBlueAttribute;
QSet<QString> res;
res << mRedAttribute << mGreenAttribute << mBlueAttribute;

if ( !context.renderContext().zRange().isInfinite() )
res << QStringLiteral( "Z" );

return res;
}

QString QgsPointCloudRgbRenderer::redAttribute() const
Expand Down

0 comments on commit 775320e

Please sign in to comment.