Add contrast enhancement options for point cloud RGB renderer

This commit is contained in:
Nyall Dawson 2020-11-13 11:04:26 +10:00
parent 171f435e07
commit bf8ccad89e
11 changed files with 474 additions and 15 deletions

View File

@ -126,6 +126,8 @@ Abstract base class for 2d point cloud renderers.
%End
public:
QgsPointCloudRenderer();
virtual ~QgsPointCloudRenderer();
virtual QString type() const = 0;
@ -139,6 +141,8 @@ Create a deep copy of this renderer. Should be implemented by all subclasses
and generate a proper subclass.
%End
virtual void renderBlock( const QgsPointCloudBlock *block, QgsPointCloudRenderContext &context ) = 0;
%Docstring
Renders a ``block`` of point cloud data using the specified render ``context``.
@ -205,6 +209,8 @@ Calls to :py:func:`~QgsPointCloudRenderer.stopRender` must always be preceded by
Retrieves the x and y coordinate for the point at index ``i``.
%End
private:
QgsPointCloudRenderer( const QgsPointCloudRenderer &other );
};
/************************************************************************

View File

@ -9,6 +9,7 @@
class QgsPointCloudRgbRenderer : QgsPointCloudRenderer
{
%Docstring
@ -26,6 +27,7 @@ An RGB renderer for 2d visualisation of point clouds using embedded red, green a
%Docstring
Constructor for QgsPointCloudRgbRenderer.
%End
virtual QString type() const;
virtual QgsPointCloudRenderer *clone() const;
@ -120,6 +122,78 @@ Sets the ``attribute`` to use for the blue channel.
.. seealso:: :py:func:`setGreenAttribute`
.. seealso:: :py:func:`blueAttribute`
%End
const QgsContrastEnhancement *redContrastEnhancement() const;
%Docstring
Returns the contrast enchancement to use for the red channel.
.. seealso:: :py:func:`setRedContrastEnhancement`
.. seealso:: :py:func:`greenContrastEnhancement`
.. seealso:: :py:func:`blueContrastEnhancement`
%End
void setRedContrastEnhancement( QgsContrastEnhancement *enhancement /Transfer/ );
%Docstring
Sets the contrast ``enchancement`` to use for the red channel.
Ownership of ``enhancement`` is transferred.
.. seealso:: :py:func:`redContrastEnhancement`
.. seealso:: :py:func:`setGreenContrastEnhancement`
.. seealso:: :py:func:`setBlueContrastEnhancement`
%End
const QgsContrastEnhancement *greenContrastEnhancement() const;
%Docstring
Returns the contrast enchancement to use for the green channel.
.. seealso:: :py:func:`setGreenContrastEnhancement`
.. seealso:: :py:func:`redContrastEnhancement`
.. seealso:: :py:func:`blueContrastEnhancement`
%End
void setGreenContrastEnhancement( QgsContrastEnhancement *enhancement /Transfer/ );
%Docstring
Sets the contrast ``enchancement`` to use for the green channel.
Ownership of ``enhancement`` is transferred.
.. seealso:: :py:func:`greenContrastEnhancement`
.. seealso:: :py:func:`setRedContrastEnhancement`
.. seealso:: :py:func:`setBlueContrastEnhancement`
%End
const QgsContrastEnhancement *blueContrastEnhancement() const;
%Docstring
Returns the contrast enchancement to use for the blue channel.
.. seealso:: :py:func:`setBlueContrastEnhancement`
.. seealso:: :py:func:`redContrastEnhancement`
.. seealso:: :py:func:`greenContrastEnhancement`
%End
void setBlueContrastEnhancement( QgsContrastEnhancement *enhancement /Transfer/ );
%Docstring
Sets the contrast ``enchancement`` to use for the blue channel.
Ownership of ``enhancement`` is transferred.
.. seealso:: :py:func:`blueContrastEnhancement`
.. seealso:: :py:func:`setRedContrastEnhancement`
.. seealso:: :py:func:`setGreenContrastEnhancement`
%End
};

View File

@ -14,7 +14,7 @@
class QgsContrastEnhancement
{
%Docstring
Manipulates raster pixel values so that they enhanceContrast or clip into a
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a
specified numerical range according to the specified
ContrastEnhancementAlgorithm.
%End
@ -40,12 +40,12 @@ ContrastEnhancementAlgorithm.
static double maximumValuePossible( Qgis::DataType dataType );
%Docstring
Helper function that returns the maximum possible value for a GDAL data type.
Helper function that returns the maximum possible value for a data type.
%End
static double minimumValuePossible( Qgis::DataType dataType );
%Docstring
Helper function that returns the minimum possible value for a GDAL data type.
Helper function that returns the minimum possible value for a data type.
%End
static QString contrastEnhancementAlgorithmString( ContrastEnhancementAlgorithm algorithm );

View File

@ -45,21 +45,75 @@ QgsMultiBandColorRenderer cannot be copied. Use :py:func:`~QgsMultiBandColorRend
void setBlueBand( int band );
const QgsContrastEnhancement *redContrastEnhancement() const;
%Docstring
Returns the contrast enchancement to use for the red channel.
.. seealso:: :py:func:`setRedContrastEnhancement`
.. seealso:: :py:func:`greenContrastEnhancement`
.. seealso:: :py:func:`blueContrastEnhancement`
%End
void setRedContrastEnhancement( QgsContrastEnhancement *ce /Transfer/ );
%Docstring
Takes ownership
Sets the contrast enchancement to use for the red channel.
Ownership of the enhancement is transferred.
.. seealso:: :py:func:`redContrastEnhancement`
.. seealso:: :py:func:`setGreenContrastEnhancement`
.. seealso:: :py:func:`setBlueContrastEnhancement`
%End
const QgsContrastEnhancement *greenContrastEnhancement() const;
%Docstring
Returns the contrast enchancement to use for the green channel.
.. seealso:: :py:func:`setGreenContrastEnhancement`
.. seealso:: :py:func:`redContrastEnhancement`
.. seealso:: :py:func:`blueContrastEnhancement`
%End
void setGreenContrastEnhancement( QgsContrastEnhancement *ce /Transfer/ );
%Docstring
Takes ownership
Sets the contrast enchancement to use for the green channel.
Ownership of the enhancement is transferred.
.. seealso:: :py:func:`greenContrastEnhancement`
.. seealso:: :py:func:`setRedContrastEnhancement`
.. seealso:: :py:func:`setBlueContrastEnhancement`
%End
const QgsContrastEnhancement *blueContrastEnhancement() const;
%Docstring
Returns the contrast enchancement to use for the blue channel.
.. seealso:: :py:func:`setBlueContrastEnhancement`
.. seealso:: :py:func:`redContrastEnhancement`
.. seealso:: :py:func:`greenContrastEnhancement`
%End
void setBlueContrastEnhancement( QgsContrastEnhancement *ce /Transfer/ );
%Docstring
Takes ownership
Sets the contrast enchancement to use for the blue channel.
Ownership of the enhancement is transferred.
.. seealso:: :py:func:`blueContrastEnhancement`
.. seealso:: :py:func:`setRedContrastEnhancement`
.. seealso:: :py:func:`setGreenContrastEnhancement`
%End
virtual void writeXml( QDomDocument &doc, QDomElement &parentElem ) const;

View File

@ -162,6 +162,8 @@ class CORE_EXPORT QgsPointCloudRenderer
public:
QgsPointCloudRenderer() = default;
virtual ~QgsPointCloudRenderer() = default;
/**
@ -175,6 +177,12 @@ class CORE_EXPORT QgsPointCloudRenderer
*/
virtual QgsPointCloudRenderer *clone() const = 0 SIP_FACTORY;
//! QgsPointCloudRenderer cannot be copied -- use clone() instead
QgsPointCloudRenderer( const QgsPointCloudRenderer &other ) = delete;
//! QgsPointCloudRenderer cannot be copied -- use clone() instead
QgsPointCloudRenderer &operator=( const QgsPointCloudRenderer &other ) = delete;
/**
* Renders a \a block of point cloud data using the specified render \a context.
*/
@ -242,6 +250,10 @@ class CORE_EXPORT QgsPointCloudRenderer
}
private:
#ifdef SIP_RUN
QgsPointCloudRenderer( const QgsPointCloudRenderer &other );
#endif
#ifdef QGISDEBUG
//! Pointer to thread in which startRender was first called
QThread *mThread = nullptr;

View File

@ -17,6 +17,7 @@
#include "qgspointcloudrgbrenderer.h"
#include "qgspointcloudblock.h"
#include "qgscontrastenhancement.h"
QgsPointCloudRgbRenderer::QgsPointCloudRgbRenderer()
{
@ -35,6 +36,20 @@ QgsPointCloudRenderer *QgsPointCloudRgbRenderer::clone() const
res->mRedAttribute = mRedAttribute;
res->mGreenAttribute = mGreenAttribute;
res->mBlueAttribute = mBlueAttribute;
if ( mRedContrastEnhancement )
{
res->setRedContrastEnhancement( new QgsContrastEnhancement( *mRedContrastEnhancement ) );
}
if ( mGreenContrastEnhancement )
{
res->setGreenContrastEnhancement( new QgsContrastEnhancement( *mGreenContrastEnhancement ) );
}
if ( mBlueContrastEnhancement )
{
res->setBlueContrastEnhancement( new QgsContrastEnhancement( *mBlueContrastEnhancement ) );
}
return res.release();
}
@ -72,6 +87,10 @@ void QgsPointCloudRgbRenderer::renderBlock( const QgsPointCloudBlock *block, Qgs
return;
const QgsPointCloudAttribute::DataType blueType = attribute->type();
const bool useRedContrastEnhancement = mRedContrastEnhancement && mRedContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement;
const bool useBlueContrastEnhancement = mBlueContrastEnhancement && mBlueContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement;
const bool useGreenContrastEnhancement = mGreenContrastEnhancement && mGreenContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement;
int rendered = 0;
double x = 0;
double y = 0;
@ -150,6 +169,28 @@ void QgsPointCloudRgbRenderer::renderBlock( const QgsPointCloudBlock *block, Qgs
break;
}
//skip if red, green or blue not in displayable range
if ( ( useRedContrastEnhancement && !mRedContrastEnhancement->isValueInDisplayableRange( red ) )
|| ( useGreenContrastEnhancement && !mGreenContrastEnhancement->isValueInDisplayableRange( green ) )
|| ( useBlueContrastEnhancement && !mBlueContrastEnhancement->isValueInDisplayableRange( blue ) ) )
{
continue;
}
//stretch color values
if ( useRedContrastEnhancement )
{
red = mRedContrastEnhancement->enhanceContrast( red );
}
if ( useGreenContrastEnhancement )
{
green = mGreenContrastEnhancement->enhanceContrast( green );
}
if ( useBlueContrastEnhancement )
{
blue = mBlueContrastEnhancement->enhanceContrast( blue );
}
mapToPixel.transformInPlace( x, y );
pen.setColor( QColor( red, green, blue ) );
@ -172,6 +213,35 @@ QgsPointCloudRenderer *QgsPointCloudRgbRenderer::create( QDomElement &element, c
r->setGreenAttribute( element.attribute( QStringLiteral( "green" ), QStringLiteral( "Green" ) ) );
r->setBlueAttribute( element.attribute( QStringLiteral( "blue" ), QStringLiteral( "Blue" ) ) );
//contrast enhancements
QgsContrastEnhancement *redContrastEnhancement = nullptr;
QDomElement redContrastElem = element.firstChildElement( QStringLiteral( "redContrastEnhancement" ) );
if ( !redContrastElem.isNull() )
{
redContrastEnhancement = new QgsContrastEnhancement( Qgis::UnknownDataType );
redContrastEnhancement->readXml( redContrastElem );
r->setRedContrastEnhancement( redContrastEnhancement );
}
QgsContrastEnhancement *greenContrastEnhancement = nullptr;
QDomElement greenContrastElem = element.firstChildElement( QStringLiteral( "greenContrastEnhancement" ) );
if ( !greenContrastElem.isNull() )
{
greenContrastEnhancement = new QgsContrastEnhancement( Qgis::UnknownDataType );
greenContrastEnhancement->readXml( greenContrastElem );
r->setGreenContrastEnhancement( greenContrastEnhancement );
}
QgsContrastEnhancement *blueContrastEnhancement = nullptr;
QDomElement blueContrastElem = element.firstChildElement( QStringLiteral( "blueContrastEnhancement" ) );
if ( !blueContrastElem.isNull() )
{
blueContrastEnhancement = new QgsContrastEnhancement( Qgis::UnknownDataType );
blueContrastEnhancement->readXml( blueContrastElem );
r->setBlueContrastEnhancement( blueContrastEnhancement );
}
return r.release();
}
@ -186,6 +256,26 @@ QDomElement QgsPointCloudRgbRenderer::save( QDomDocument &doc, const QgsReadWrit
rendererElem.setAttribute( QStringLiteral( "green" ), mGreenAttribute );
rendererElem.setAttribute( QStringLiteral( "blue" ), mBlueAttribute );
//contrast enhancement
if ( mRedContrastEnhancement )
{
QDomElement redContrastElem = doc.createElement( QStringLiteral( "redContrastEnhancement" ) );
mRedContrastEnhancement->writeXml( doc, redContrastElem );
rendererElem.appendChild( redContrastElem );
}
if ( mGreenContrastEnhancement )
{
QDomElement greenContrastElem = doc.createElement( QStringLiteral( "greenContrastEnhancement" ) );
mGreenContrastEnhancement->writeXml( doc, greenContrastElem );
rendererElem.appendChild( greenContrastElem );
}
if ( mBlueContrastEnhancement )
{
QDomElement blueContrastElem = doc.createElement( QStringLiteral( "blueContrastEnhancement" ) );
mBlueContrastEnhancement->writeXml( doc, blueContrastElem );
rendererElem.appendChild( blueContrastElem );
}
return rendererElem;
}
@ -245,3 +335,33 @@ void QgsPointCloudRgbRenderer::setBlueAttribute( const QString &blueAttribute )
{
mBlueAttribute = blueAttribute;
}
const QgsContrastEnhancement *QgsPointCloudRgbRenderer::redContrastEnhancement() const
{
return mRedContrastEnhancement.get();
}
void QgsPointCloudRgbRenderer::setRedContrastEnhancement( QgsContrastEnhancement *enhancement )
{
mRedContrastEnhancement.reset( enhancement );
}
const QgsContrastEnhancement *QgsPointCloudRgbRenderer::greenContrastEnhancement() const
{
return mGreenContrastEnhancement.get();
}
void QgsPointCloudRgbRenderer::setGreenContrastEnhancement( QgsContrastEnhancement *enhancement )
{
mGreenContrastEnhancement.reset( enhancement );
}
const QgsContrastEnhancement *QgsPointCloudRgbRenderer::blueContrastEnhancement() const
{
return mBlueContrastEnhancement.get();
}
void QgsPointCloudRgbRenderer::setBlueContrastEnhancement( QgsContrastEnhancement *enhancement )
{
mBlueContrastEnhancement.reset( enhancement );
}

View File

@ -22,6 +22,8 @@
#include "qgis_core.h"
#include "qgis_sip.h"
class QgsContrastEnhancement;
/**
* \ingroup core
* An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes.
@ -36,6 +38,7 @@ class CORE_EXPORT QgsPointCloudRgbRenderer : public QgsPointCloudRenderer
* Constructor for QgsPointCloudRgbRenderer.
*/
QgsPointCloudRgbRenderer();
QString type() const override;
QgsPointCloudRenderer *clone() const override;
void renderBlock( const QgsPointCloudBlock *block, QgsPointCloudRenderContext &context ) override;
@ -109,7 +112,68 @@ class CORE_EXPORT QgsPointCloudRgbRenderer : public QgsPointCloudRenderer
*/
void setBlueAttribute( const QString &attribute );
/**
* Returns the contrast enchancement to use for the red channel.
*
* \see setRedContrastEnhancement()
* \see greenContrastEnhancement()
* \see blueContrastEnhancement()
*/
const QgsContrastEnhancement *redContrastEnhancement() const;
/**
* Sets the contrast \a enchancement to use for the red channel.
*
* Ownership of \a enhancement is transferred.
*
* \see redContrastEnhancement()
* \see setGreenContrastEnhancement()
* \see setBlueContrastEnhancement()
*/
void setRedContrastEnhancement( QgsContrastEnhancement *enhancement SIP_TRANSFER );
/**
* Returns the contrast enchancement to use for the green channel.
*
* \see setGreenContrastEnhancement()
* \see redContrastEnhancement()
* \see blueContrastEnhancement()
*/
const QgsContrastEnhancement *greenContrastEnhancement() const;
/**
* Sets the contrast \a enchancement to use for the green channel.
*
* Ownership of \a enhancement is transferred.
*
* \see greenContrastEnhancement()
* \see setRedContrastEnhancement()
* \see setBlueContrastEnhancement()
*/
void setGreenContrastEnhancement( QgsContrastEnhancement *enhancement SIP_TRANSFER );
/**
* Returns the contrast enchancement to use for the blue channel.
*
* \see setBlueContrastEnhancement()
* \see redContrastEnhancement()
* \see greenContrastEnhancement()
*/
const QgsContrastEnhancement *blueContrastEnhancement() const;
/**
* Sets the contrast \a enchancement to use for the blue channel.
*
* Ownership of \a enhancement is transferred.
*
* \see blueContrastEnhancement()
* \see setRedContrastEnhancement()
* \see setGreenContrastEnhancement()
*/
void setBlueContrastEnhancement( QgsContrastEnhancement *enhancement SIP_TRANSFER );
private:
int mPenWidth = 1;
int mPainterPenWidth = 1;
@ -117,6 +181,10 @@ class CORE_EXPORT QgsPointCloudRgbRenderer : public QgsPointCloudRenderer
QString mGreenAttribute = QStringLiteral( "Green" );
QString mBlueAttribute = QStringLiteral( "Blue" );
std::unique_ptr< QgsContrastEnhancement > mRedContrastEnhancement;
std::unique_ptr< QgsContrastEnhancement > mGreenContrastEnhancement;
std::unique_ptr< QgsContrastEnhancement > mBlueContrastEnhancement;
};
#endif // QGSPOINTCLOUDRGBRENDERER_H

View File

@ -35,7 +35,7 @@ class QString;
/**
* \ingroup core
* Manipulates raster pixel values so that they enhanceContrast or clip into a
* Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a
* specified numerical range according to the specified
* ContrastEnhancementAlgorithm.
*/
@ -47,8 +47,8 @@ class CORE_EXPORT QgsContrastEnhancement
//! \brief This enumerator describes the types of contrast enhancement algorithms that can be used.
enum ContrastEnhancementAlgorithm
{
NoEnhancement, //this should be the default color scaling algorithm
StretchToMinimumMaximum, //linear histogram enhanceContrast
NoEnhancement, //!< Default color scaling algorithm, no scaling is applied
StretchToMinimumMaximum, //!< Linear histogram
StretchAndClipToMinimumMaximum,
ClipToMinimumMaximum,
UserDefinedEnhancement
@ -61,7 +61,7 @@ class CORE_EXPORT QgsContrastEnhancement
const QgsContrastEnhancement &operator=( const QgsContrastEnhancement & ) = delete;
/**
* Helper function that returns the maximum possible value for a GDAL data type.
* Helper function that returns the maximum possible value for a data type.
*/
static double maximumValuePossible( Qgis::DataType dataType )
{
@ -100,7 +100,7 @@ class CORE_EXPORT QgsContrastEnhancement
}
/**
* Helper function that returns the minimum possible value for a GDAL data type.
* Helper function that returns the minimum possible value for a data type.
*/
static double minimumValuePossible( Qgis::DataType dataType )
{

View File

@ -55,16 +55,64 @@ class CORE_EXPORT QgsMultiBandColorRenderer: public QgsRasterRenderer
int blueBand() const { return mBlueBand; }
void setBlueBand( int band ) { mBlueBand = band; }
/**
* Returns the contrast enchancement to use for the red channel.
*
* \see setRedContrastEnhancement()
* \see greenContrastEnhancement()
* \see blueContrastEnhancement()
*/
const QgsContrastEnhancement *redContrastEnhancement() const { return mRedContrastEnhancement; }
//! Takes ownership
/**
* Sets the contrast enchancement to use for the red channel.
*
* Ownership of the enhancement is transferred.
*
* \see redContrastEnhancement()
* \see setGreenContrastEnhancement()
* \see setBlueContrastEnhancement()
*/
void setRedContrastEnhancement( QgsContrastEnhancement *ce SIP_TRANSFER );
/**
* Returns the contrast enchancement to use for the green channel.
*
* \see setGreenContrastEnhancement()
* \see redContrastEnhancement()
* \see blueContrastEnhancement()
*/
const QgsContrastEnhancement *greenContrastEnhancement() const { return mGreenContrastEnhancement; }
//! Takes ownership
/**
* Sets the contrast enchancement to use for the green channel.
*
* Ownership of the enhancement is transferred.
*
* \see greenContrastEnhancement()
* \see setRedContrastEnhancement()
* \see setBlueContrastEnhancement()
*/
void setGreenContrastEnhancement( QgsContrastEnhancement *ce SIP_TRANSFER );
/**
* Returns the contrast enchancement to use for the blue channel.
*
* \see setBlueContrastEnhancement()
* \see redContrastEnhancement()
* \see greenContrastEnhancement()
*/
const QgsContrastEnhancement *blueContrastEnhancement() const { return mBlueContrastEnhancement; }
//! Takes ownership
/**
* Sets the contrast enchancement to use for the blue channel.
*
* Ownership of the enhancement is transferred.
*
* \see blueContrastEnhancement()
* \see setRedContrastEnhancement()
* \see setGreenContrastEnhancement()
*/
void setBlueContrastEnhancement( QgsContrastEnhancement *ce SIP_TRANSFER );
void writeXml( QDomDocument &doc, QDomElement &parentElem ) const override;

View File

@ -22,7 +22,8 @@ from qgis.core import (
QgsVector3D,
QgsMultiRenderChecker,
QgsMapSettings,
QgsRectangle
QgsRectangle,
QgsContrastEnhancement
)
from qgis.PyQt.QtCore import QDir, QSize
@ -64,10 +65,37 @@ class TestQgsPointCloudRgbRenderer(unittest.TestCase):
renderer.setRedAttribute('r')
self.assertEqual(renderer.redAttribute(), 'r')
redce = QgsContrastEnhancement()
redce.setMinimumValue(100)
redce.setMaximumValue(120)
redce.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchAndClipToMinimumMaximum)
renderer.setRedContrastEnhancement(redce)
greence = QgsContrastEnhancement()
greence.setMinimumValue(130)
greence.setMaximumValue(150)
greence.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
renderer.setGreenContrastEnhancement(greence)
bluece = QgsContrastEnhancement()
bluece.setMinimumValue(170)
bluece.setMaximumValue(190)
bluece.setContrastEnhancementAlgorithm(QgsContrastEnhancement.ClipToMinimumMaximum)
renderer.setBlueContrastEnhancement(bluece)
rr = renderer.clone()
self.assertEqual(rr.blueAttribute(), 'b')
self.assertEqual(rr.greenAttribute(), 'g')
self.assertEqual(rr.redAttribute(), 'r')
self.assertEqual(rr.redContrastEnhancement().minimumValue(), 100)
self.assertEqual(rr.redContrastEnhancement().maximumValue(), 120)
self.assertEqual(rr.redContrastEnhancement().contrastEnhancementAlgorithm(), QgsContrastEnhancement.StretchAndClipToMinimumMaximum)
self.assertEqual(rr.greenContrastEnhancement().minimumValue(), 130)
self.assertEqual(rr.greenContrastEnhancement().maximumValue(), 150)
self.assertEqual(rr.greenContrastEnhancement().contrastEnhancementAlgorithm(), QgsContrastEnhancement.StretchToMinimumMaximum)
self.assertEqual(rr.blueContrastEnhancement().minimumValue(), 170)
self.assertEqual(rr.blueContrastEnhancement().maximumValue(), 190)
self.assertEqual(rr.blueContrastEnhancement().contrastEnhancementAlgorithm(), QgsContrastEnhancement.ClipToMinimumMaximum)
doc = QDomDocument("testdoc")
elem = renderer.save(doc, QgsReadWriteContext())
@ -76,6 +104,15 @@ class TestQgsPointCloudRgbRenderer(unittest.TestCase):
self.assertEqual(r2.blueAttribute(), 'b')
self.assertEqual(r2.greenAttribute(), 'g')
self.assertEqual(r2.redAttribute(), 'r')
self.assertEqual(r2.redContrastEnhancement().minimumValue(), 100)
self.assertEqual(r2.redContrastEnhancement().maximumValue(), 120)
self.assertEqual(r2.redContrastEnhancement().contrastEnhancementAlgorithm(), QgsContrastEnhancement.StretchAndClipToMinimumMaximum)
self.assertEqual(r2.greenContrastEnhancement().minimumValue(), 130)
self.assertEqual(r2.greenContrastEnhancement().maximumValue(), 150)
self.assertEqual(r2.greenContrastEnhancement().contrastEnhancementAlgorithm(), QgsContrastEnhancement.StretchToMinimumMaximum)
self.assertEqual(r2.blueContrastEnhancement().minimumValue(), 170)
self.assertEqual(r2.blueContrastEnhancement().maximumValue(), 190)
self.assertEqual(r2.blueContrastEnhancement().contrastEnhancementAlgorithm(), QgsContrastEnhancement.ClipToMinimumMaximum)
def testUsedAttributes(self):
renderer = QgsPointCloudRgbRenderer()
@ -110,6 +147,46 @@ class TestQgsPointCloudRgbRenderer(unittest.TestCase):
TestQgsPointCloudRgbRenderer.report += renderchecker.report()
self.assertTrue(result)
@unittest.skipIf('ept' not in QgsProviderRegistry.instance().providerList(), 'EPT provider not available')
def testRenderWithContrast(self):
layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept')
self.assertTrue(layer.isValid())
layer.renderer().setPenWidth(2)
redce = QgsContrastEnhancement()
redce.setMinimumValue(100)
redce.setMaximumValue(120)
redce.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
layer.renderer().setRedContrastEnhancement(redce)
greence = QgsContrastEnhancement()
greence.setMinimumValue(130)
greence.setMaximumValue(150)
greence.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
layer.renderer().setGreenContrastEnhancement(greence)
bluece = QgsContrastEnhancement()
bluece.setMinimumValue(170)
bluece.setMaximumValue(190)
bluece.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
layer.renderer().setBlueContrastEnhancement(bluece)
mapsettings = QgsMapSettings()
mapsettings.setOutputSize(QSize(400, 400))
mapsettings.setOutputDpi(96)
mapsettings.setDestinationCrs(layer.crs())
mapsettings.setExtent(QgsRectangle(497753.5, 7050887.5, 497754.6, 7050888.6))
mapsettings.setLayers([layer])
renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(mapsettings)
renderchecker.setControlPathPrefix('pointcloudrenderer')
renderchecker.setControlName('expected_rgb_contrast')
result = renderchecker.runTest('expected_rgb_contrast')
TestQgsPointCloudRgbRenderer.report += renderchecker.report()
self.assertTrue(result)
@unittest.skipIf('ept' not in QgsProviderRegistry.instance().providerList(), 'EPT provider not available')
def testRenderOpacity(self):
layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept')

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB