mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-24 00:05:18 -05:00
Add contrast enhancement options for point cloud RGB renderer
This commit is contained in:
parent
171f435e07
commit
bf8ccad89e
@ -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 );
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
||||
@ -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
|
||||
|
||||
};
|
||||
|
||||
@ -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 );
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 );
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 )
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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')
|
||||
|
||||
BIN
tests/testdata/control_images/pointcloudrenderer/expected_rgb_contrast/expected_rgb_contrast.png
vendored
Normal file
BIN
tests/testdata/control_images/pointcloudrenderer/expected_rgb_contrast/expected_rgb_contrast.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 460 KiB |
Loading…
x
Reference in New Issue
Block a user