Implement z range filtering for point clouds

This commit is contained in:
Nyall Dawson 2020-11-24 12:58:24 +10:00
parent 0f2a967f49
commit 775320e095
4 changed files with 46 additions and 3 deletions

View File

@ -89,6 +89,8 @@ 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;
@ -96,6 +98,17 @@ Returns the offset for the x value in a point record.
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:

View File

@ -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 )

View File

@ -111,6 +111,7 @@ class CORE_EXPORT QgsPointCloudRenderContext
* Returns the offset for the x value in a point record.
*
* \see yOffset()
* \see zOffset()
*/
int xOffset() const { return mXOffset; }
@ -118,9 +119,18 @@ class CORE_EXPORT QgsPointCloudRenderContext
* 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 );
@ -134,6 +144,7 @@ class CORE_EXPORT QgsPointCloudRenderContext
int mPointRecordSize = 0;
int mXOffset = 0;
int mYOffset = 0;
int mZOffset = 0;
};

View File

@ -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;
@ -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 ) ) )
{
@ -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