Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support tolerances for QgsRasterTransparency pixel values #58180

Merged
merged 7 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ Constructor for QgsRasterTransparency.
struct TransparentThreeValuePixel
{

TransparentThreeValuePixel( double red = 0, double green = 0, double blue = 0, double opacity = 0 );
TransparentThreeValuePixel( double red = 0, double green = 0, double blue = 0, double opacity = 0, double fuzzyToleranceRed = 4 * DBL_EPSILON, double fuzzyToleranceGreen = 4 * DBL_EPSILON, double fuzzyToleranceBlue = 4 * DBL_EPSILON );
%Docstring
Constructor for TransparentThreeValuePixel.

:param red: red pixel value
:param green: green pixel value
:param blue: blue pixel value
:param opacity: opacity for pixel, between 0 and 1.0
:param fuzzyToleranceRed: (since QGIS 3.40) allows specifying a tolerance for the red color component, where the pixel's red component can deviate from values specified here by a maximum of this tolerance amount
:param fuzzyToleranceGreen: (since QGIS 3.40) allows specifying a tolerance for the green color component, where the pixel's green component can deviate from values specified here by a maximum of this tolerance amount
:param fuzzyToleranceBlue: (since QGIS 3.40) allows specifying a tolerance for the blue color component, where the pixel's blue component can deviate from values specified here by a maximum of this tolerance amount

.. versionadded:: 3.38
%End
Expand All @@ -48,12 +51,22 @@ Constructor for TransparentThreeValuePixel.

double opacity;

double fuzzyToleranceRed;

double fuzzyToleranceGreen;

double fuzzyToleranceBlue;

bool operator==( const QgsRasterTransparency::TransparentThreeValuePixel &other ) const;
bool operator!=( const QgsRasterTransparency::TransparentThreeValuePixel &other ) const;

SIP_PYOBJECT __repr__();
%MethodCode
const QString str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity );
QString str;
if ( !qgsDoubleNear( sipCpp->fuzzyToleranceRed, 0 ) || !qgsDoubleNear( sipCpp->fuzzyToleranceGreen, 0 ) || !qgsDoubleNear( sipCpp->fuzzyToleranceBlue, 0 ) )
str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4, %5, %6, %7>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity ).arg( sipCpp->fuzzyToleranceRed ).arg( sipCpp->fuzzyToleranceGreen ).arg( sipCpp->fuzzyToleranceBlue );
else
str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity );
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
%End
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Returns the (possibly None) map pixel selector tool.
.. versionadded:: 3.22
%End



public slots:


Expand Down
17 changes: 15 additions & 2 deletions python/core/auto_generated/raster/qgsrastertransparency.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ Constructor for QgsRasterTransparency.
struct TransparentThreeValuePixel
{

TransparentThreeValuePixel( double red = 0, double green = 0, double blue = 0, double opacity = 0 );
TransparentThreeValuePixel( double red = 0, double green = 0, double blue = 0, double opacity = 0, double fuzzyToleranceRed = 4 * DBL_EPSILON, double fuzzyToleranceGreen = 4 * DBL_EPSILON, double fuzzyToleranceBlue = 4 * DBL_EPSILON );
%Docstring
Constructor for TransparentThreeValuePixel.

:param red: red pixel value
:param green: green pixel value
:param blue: blue pixel value
:param opacity: opacity for pixel, between 0 and 1.0
:param fuzzyToleranceRed: (since QGIS 3.40) allows specifying a tolerance for the red color component, where the pixel's red component can deviate from values specified here by a maximum of this tolerance amount
:param fuzzyToleranceGreen: (since QGIS 3.40) allows specifying a tolerance for the green color component, where the pixel's green component can deviate from values specified here by a maximum of this tolerance amount
:param fuzzyToleranceBlue: (since QGIS 3.40) allows specifying a tolerance for the blue color component, where the pixel's blue component can deviate from values specified here by a maximum of this tolerance amount

.. versionadded:: 3.38
%End
Expand All @@ -48,12 +51,22 @@ Constructor for TransparentThreeValuePixel.

double opacity;

double fuzzyToleranceRed;

double fuzzyToleranceGreen;

double fuzzyToleranceBlue;

bool operator==( const QgsRasterTransparency::TransparentThreeValuePixel &other ) const;
bool operator!=( const QgsRasterTransparency::TransparentThreeValuePixel &other ) const;

SIP_PYOBJECT __repr__();
%MethodCode
const QString str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity );
QString str;
if ( !qgsDoubleNear( sipCpp->fuzzyToleranceRed, 0 ) || !qgsDoubleNear( sipCpp->fuzzyToleranceGreen, 0 ) || !qgsDoubleNear( sipCpp->fuzzyToleranceBlue, 0 ) )
str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4, %5, %6, %7>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity ).arg( sipCpp->fuzzyToleranceRed ).arg( sipCpp->fuzzyToleranceGreen ).arg( sipCpp->fuzzyToleranceBlue );
else
str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity );
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
%End
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Returns the (possibly None) map pixel selector tool.
.. versionadded:: 3.22
%End



public slots:


Expand Down
23 changes: 19 additions & 4 deletions src/core/raster/qgsrastertransparency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ double QgsRasterTransparency::opacityForRgbValues( double redValue, double green
//Search through the transparency list looking for a match
auto it = std::find_if( mTransparentThreeValuePixelList.constBegin(), mTransparentThreeValuePixelList.constEnd(), [redValue, greenValue, blueValue]( const TransparentThreeValuePixel & p )
{
return qgsDoubleNear( p.red, redValue )
&& qgsDoubleNear( p.green, greenValue )
&& qgsDoubleNear( p.blue, blueValue );
return qgsDoubleNear( p.red, redValue, p.fuzzyToleranceRed )
&& qgsDoubleNear( p.green, greenValue, p.fuzzyToleranceGreen )
&& qgsDoubleNear( p.blue, blueValue, p.fuzzyToleranceBlue );
} );

if ( it != mTransparentThreeValuePixelList.constEnd() )
Expand Down Expand Up @@ -153,6 +153,12 @@ void QgsRasterTransparency::writeXml( QDomDocument &doc, QDomElement &parentElem
pixelListElement.setAttribute( QStringLiteral( "green" ), QgsRasterBlock::printValue( it->green ) );
pixelListElement.setAttribute( QStringLiteral( "blue" ), QgsRasterBlock::printValue( it->blue ) );
pixelListElement.setAttribute( QStringLiteral( "percentTransparent" ), QString::number( 100.0 * ( 1 - it->opacity ) ) );
if ( !qgsDoubleNear( it->fuzzyToleranceRed, 0 ) )
pixelListElement.setAttribute( QStringLiteral( "toleranceRed" ), QString::number( it->fuzzyToleranceRed ) );
if ( !qgsDoubleNear( it->fuzzyToleranceGreen, 0 ) )
pixelListElement.setAttribute( QStringLiteral( "toleranceGreen" ), QString::number( it->fuzzyToleranceGreen ) );
if ( !qgsDoubleNear( it->fuzzyToleranceBlue, 0 ) )
pixelListElement.setAttribute( QStringLiteral( "toleranceBlue" ), QString::number( it->fuzzyToleranceBlue ) );
threeValuePixelListElement.appendChild( pixelListElement );
}
rasterTransparencyElem.appendChild( threeValuePixelListElement );
Expand Down Expand Up @@ -205,7 +211,16 @@ void QgsRasterTransparency::readXml( const QDomElement &elem )
const double green = currentEntryElem.attribute( QStringLiteral( "green" ) ).toDouble();
const double blue = currentEntryElem.attribute( QStringLiteral( "blue" ) ).toDouble();
const double opacity = 1.0 - currentEntryElem.attribute( QStringLiteral( "percentTransparent" ) ).toDouble() / 100.0;
mTransparentThreeValuePixelList.append( TransparentThreeValuePixel( red, green, blue, opacity ) );
bool redOk = false;
const double toleranceRed = currentEntryElem.attribute( QStringLiteral( "toleranceRed" ) ).toDouble( &redOk );
bool greenOk = false;
const double toleranceGreen = currentEntryElem.attribute( QStringLiteral( "toleranceGreen" ) ).toDouble( &greenOk );
bool blueOk = false;
const double toleranceBlue = currentEntryElem.attribute( QStringLiteral( "toleranceBlue" ) ).toDouble( &blueOk );
mTransparentThreeValuePixelList.append( TransparentThreeValuePixel( red, green, blue, opacity,
redOk ? toleranceRed : 4 * std::numeric_limits<double>::epsilon(),
greenOk ? toleranceGreen : 4 * std::numeric_limits<double>::epsilon(),
blueOk ? toleranceBlue : 4 * std::numeric_limits<double>::epsilon() ) );
}
}
}
58 changes: 55 additions & 3 deletions src/core/raster/qgsrastertransparency.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ class CORE_EXPORT QgsRasterTransparency
* \param green green pixel value
* \param blue blue pixel value
* \param opacity opacity for pixel, between 0 and 1.0
* \param fuzzyToleranceRed (since QGIS 3.40) allows specifying a tolerance for the red color component, where the pixel's red component can deviate from values specified here by a maximum of this tolerance amount
* \param fuzzyToleranceGreen (since QGIS 3.40) allows specifying a tolerance for the green color component, where the pixel's green component can deviate from values specified here by a maximum of this tolerance amount
* \param fuzzyToleranceBlue (since QGIS 3.40) allows specifying a tolerance for the blue color component, where the pixel's blue component can deviate from values specified here by a maximum of this tolerance amount
* \since QGIS 3.38
*/
TransparentThreeValuePixel( double red = 0, double green = 0, double blue = 0, double opacity = 0 )
TransparentThreeValuePixel( double red = 0, double green = 0, double blue = 0, double opacity = 0, double fuzzyToleranceRed = 4 * std::numeric_limits<double>::epsilon(), double fuzzyToleranceGreen = 4 * std::numeric_limits<double>::epsilon(), double fuzzyToleranceBlue = 4 * std::numeric_limits<double>::epsilon() )
: red( red )
, green( green )
, blue( blue )
, opacity( opacity )
, fuzzyToleranceRed( fuzzyToleranceRed )
, fuzzyToleranceGreen( fuzzyToleranceGreen )
, fuzzyToleranceBlue( fuzzyToleranceBlue )
{}

/**
Expand All @@ -84,12 +90,54 @@ class CORE_EXPORT QgsRasterTransparency
*/
double opacity = 0;

/**
* Fuzzy tolerance for red values.
*
* If non zero, the pixel's red component can deviate from values specified in this object by a maximum of this tolerance amount.
*
* \since QGIS 3.40
*/
#ifndef SIP_RUN
double fuzzyToleranceRed = 4 * std::numeric_limits<double>::epsilon();
#else
double fuzzyToleranceRed;
#endif

/**
* Fuzzy tolerance for green values.
*
* If non zero, the pixel's green component can deviate from values specified in this object by a maximum of this tolerance amount.
*
* \since QGIS 3.40
*/
#ifndef SIP_RUN
double fuzzyToleranceGreen = 4 * std::numeric_limits<double>::epsilon();
#else
double fuzzyToleranceGreen;
#endif

/**
* Fuzzy tolerance for blue values.
*
* If non zero, the pixel's blue component can deviate from values specified in this object by a maximum of this tolerance amount.
*
* \since QGIS 3.40
*/
#ifndef SIP_RUN
double fuzzyToleranceBlue = 4 * std::numeric_limits<double>::epsilon();
#else
double fuzzyToleranceBlue;
#endif

bool operator==( const QgsRasterTransparency::TransparentThreeValuePixel &other ) const
{
return qgsDoubleNear( red, other.red )
&& qgsDoubleNear( green, other.green )
&& qgsDoubleNear( blue, other.blue )
&& qgsDoubleNear( opacity, other.opacity );
&& qgsDoubleNear( opacity, other.opacity )
&& qgsDoubleNear( fuzzyToleranceRed, other.fuzzyToleranceRed )
&& qgsDoubleNear( fuzzyToleranceGreen, other.fuzzyToleranceGreen )
&& qgsDoubleNear( fuzzyToleranceBlue, other.fuzzyToleranceBlue );
}
bool operator!=( const QgsRasterTransparency::TransparentThreeValuePixel &other ) const
{
Expand All @@ -99,7 +147,11 @@ class CORE_EXPORT QgsRasterTransparency
#ifdef SIP_RUN
SIP_PYOBJECT __repr__();
% MethodCode
const QString str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity );
QString str;
if ( !qgsDoubleNear( sipCpp->fuzzyToleranceRed, 0 ) || !qgsDoubleNear( sipCpp->fuzzyToleranceGreen, 0 ) || !qgsDoubleNear( sipCpp->fuzzyToleranceBlue, 0 ) )
str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4, %5, %6, %7>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity ).arg( sipCpp->fuzzyToleranceRed ).arg( sipCpp->fuzzyToleranceGreen ).arg( sipCpp->fuzzyToleranceBlue );
else
str = QStringLiteral( "<QgsRasterTransparency.TransparentThreeValuePixel: %1, %2, %3, %4>" ).arg( sipCpp->red ).arg( sipCpp->green ).arg( sipCpp->blue ).arg( sipCpp->opacity );
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
% End
#endif
Expand Down
Loading
Loading