QGIS API Documentation 3.99.0-Master (e9821da5c6b)
Loading...
Searching...
No Matches
qgsrastertransparency.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrastertransparency.cpp - description
3 -------------------
4begin : Mon Nov 30 2007
5copyright : (C) 2007 by Peter J. Ersts
7
8****************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
20
21#include "qgis.h"
22#include "qgsrasterinterface.h"
23
24#include <QDomDocument>
25#include <QDomElement>
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
30QVector<QgsRasterTransparency::TransparentSingleValuePixel> QgsRasterTransparency::transparentSingleValuePixelList() const
31{
32 return mTransparentSingleValuePixelList;
33}
34
35QVector<QgsRasterTransparency::TransparentThreeValuePixel> QgsRasterTransparency::transparentThreeValuePixelList() const
36{
37 return mTransparentThreeValuePixelList;
38}
39
41{
42 //clear the existing list
43 mTransparentSingleValuePixelList.clear();
44
45 //add the initial value
46 mTransparentSingleValuePixelList.append( TransparentSingleValuePixel( value, value, 0 ) );
47}
48
49void QgsRasterTransparency::initializeTransparentPixelList( double redValue, double greenValue, double blueValue )
50{
51 //clear the existing list
52 mTransparentThreeValuePixelList.clear();
53
54 //add the initial values
55 mTransparentThreeValuePixelList.append( TransparentThreeValuePixel( redValue, greenValue, blueValue, 0 ) );
56}
57
58void QgsRasterTransparency::setTransparentSingleValuePixelList( const QVector<QgsRasterTransparency::TransparentSingleValuePixel> &newList )
59{
60 mTransparentSingleValuePixelList = newList;
61}
62
63void QgsRasterTransparency::setTransparentThreeValuePixelList( const QVector<QgsRasterTransparency::TransparentThreeValuePixel> &newList )
64{
65 mTransparentThreeValuePixelList = newList;
66}
67
68int QgsRasterTransparency::alphaValue( double value, int globalTransparency ) const
69{
70 return static_cast< int >( opacityForValue( value ) * globalTransparency );
71}
72
73double QgsRasterTransparency::opacityForValue( double value ) const
74{
75 //if NaN return 0, transparent
76 if ( std::isnan( value ) )
77 {
78 return 0;
79 }
80
81 //Search through the transparency list looking for a match
82 auto it = std::find_if( mTransparentSingleValuePixelList.constBegin(), mTransparentSingleValuePixelList.constEnd(), [value]( const TransparentSingleValuePixel & p )
83 {
84 return ( value > p.min && value < p.max )
85 || ( p.includeMinimum && qgsDoubleNear( value, p.min ) )
86 || ( p.includeMaximum && qgsDoubleNear( value, p.max ) );
87 } );
88
89 if ( it != mTransparentSingleValuePixelList.constEnd() )
90 {
91 return it->opacity;
92 }
93
94 return 1;
95}
96
97int QgsRasterTransparency::alphaValue( double redValue, double greenValue, double blueValue, int globalTransparency ) const
98{
99 return static_cast< int >( opacityForRgbValues( redValue, greenValue, blueValue ) * globalTransparency );
100}
101
102double QgsRasterTransparency::opacityForRgbValues( double redValue, double greenValue, double blueValue ) const
103{
104 //if NaN return 0, transparent
105 if ( std::isnan( redValue ) || std::isnan( greenValue ) || std::isnan( blueValue ) )
106 {
107 return 0;
108 }
109
110 //Search through the transparency list looking for a match
111 auto it = std::find_if( mTransparentThreeValuePixelList.constBegin(), mTransparentThreeValuePixelList.constEnd(), [redValue, greenValue, blueValue]( const TransparentThreeValuePixel & p )
112 {
113 return qgsDoubleNear( p.red, redValue, p.fuzzyToleranceRed )
114 && qgsDoubleNear( p.green, greenValue, p.fuzzyToleranceGreen )
115 && qgsDoubleNear( p.blue, blueValue, p.fuzzyToleranceBlue );
116 } );
117
118 if ( it != mTransparentThreeValuePixelList.constEnd() )
119 {
120 return it->opacity;
121 }
122
123 return 1;
124}
125
127{
128 return mTransparentSingleValuePixelList.isEmpty() && mTransparentThreeValuePixelList.isEmpty();
129}
130
131void QgsRasterTransparency::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
132{
133 QDomElement rasterTransparencyElem = doc.createElement( u"rasterTransparency"_s );
134 if ( !mTransparentSingleValuePixelList.isEmpty() )
135 {
136 QDomElement singleValuePixelListElement = doc.createElement( u"singleValuePixelList"_s );
137 auto it = mTransparentSingleValuePixelList.constBegin();
138 for ( ; it != mTransparentSingleValuePixelList.constEnd(); ++it )
139 {
140 QDomElement pixelListElement = doc.createElement( u"pixelListEntry"_s );
141 pixelListElement.setAttribute( u"min"_s, QgsRasterBlock::printValue( it->min ) );
142 pixelListElement.setAttribute( u"max"_s, QgsRasterBlock::printValue( it->max ) );
143 pixelListElement.setAttribute( u"percentTransparent"_s, QString::number( 100.0 * ( 1 - it->opacity ) ) );
144 singleValuePixelListElement.appendChild( pixelListElement );
145 }
146 rasterTransparencyElem.appendChild( singleValuePixelListElement );
147
148 }
149 if ( !mTransparentThreeValuePixelList.isEmpty() )
150 {
151 QDomElement threeValuePixelListElement = doc.createElement( u"threeValuePixelList"_s );
152 auto it = mTransparentThreeValuePixelList.constBegin();
153 for ( ; it != mTransparentThreeValuePixelList.constEnd(); ++it )
154 {
155 QDomElement pixelListElement = doc.createElement( u"pixelListEntry"_s );
156 pixelListElement.setAttribute( u"red"_s, QgsRasterBlock::printValue( it->red ) );
157 pixelListElement.setAttribute( u"green"_s, QgsRasterBlock::printValue( it->green ) );
158 pixelListElement.setAttribute( u"blue"_s, QgsRasterBlock::printValue( it->blue ) );
159 pixelListElement.setAttribute( u"percentTransparent"_s, QString::number( 100.0 * ( 1 - it->opacity ) ) );
160 if ( !qgsDoubleNear( it->fuzzyToleranceRed, 0 ) )
161 pixelListElement.setAttribute( u"toleranceRed"_s, QString::number( it->fuzzyToleranceRed ) );
162 if ( !qgsDoubleNear( it->fuzzyToleranceGreen, 0 ) )
163 pixelListElement.setAttribute( u"toleranceGreen"_s, QString::number( it->fuzzyToleranceGreen ) );
164 if ( !qgsDoubleNear( it->fuzzyToleranceBlue, 0 ) )
165 pixelListElement.setAttribute( u"toleranceBlue"_s, QString::number( it->fuzzyToleranceBlue ) );
166 threeValuePixelListElement.appendChild( pixelListElement );
167 }
168 rasterTransparencyElem.appendChild( threeValuePixelListElement );
169 }
170 parentElem.appendChild( rasterTransparencyElem );
171}
172
173void QgsRasterTransparency::readXml( const QDomElement &elem )
174{
175 if ( elem.isNull() )
176 {
177 return;
178 }
179
180 mTransparentSingleValuePixelList.clear();
181 mTransparentThreeValuePixelList.clear();
182 QDomElement currentEntryElem;
183
184 const QDomElement singlePixelListElem = elem.firstChildElement( u"singleValuePixelList"_s );
185 if ( !singlePixelListElem.isNull() )
186 {
187 const QDomNodeList entryList = singlePixelListElem.elementsByTagName( u"pixelListEntry"_s );
188 for ( int i = 0; i < entryList.size(); ++i )
189 {
190 currentEntryElem = entryList.at( i ).toElement();
191 double min = 0;
192 double max = 0;
193 const double opacity = 1.0 - currentEntryElem.attribute( u"percentTransparent"_s ).toDouble() / 100.0;
194 // Backward compoatibility < 1.9 : pixelValue (before ranges)
195 if ( currentEntryElem.hasAttribute( u"pixelValue"_s ) )
196 {
197 min = max = currentEntryElem.attribute( u"pixelValue"_s ).toDouble();
198 }
199 else
200 {
201 min = currentEntryElem.attribute( u"min"_s ).toDouble();
202 max = currentEntryElem.attribute( u"max"_s ).toDouble();
203 }
204 mTransparentSingleValuePixelList.append( TransparentSingleValuePixel( min, max, opacity ) );
205 }
206 }
207 const QDomElement threeValuePixelListElem = elem.firstChildElement( u"threeValuePixelList"_s );
208 if ( !threeValuePixelListElem.isNull() )
209 {
210 const QDomNodeList entryList = threeValuePixelListElem.elementsByTagName( u"pixelListEntry"_s );
211 for ( int i = 0; i < entryList.size(); ++i )
212 {
213 currentEntryElem = entryList.at( i ).toElement();
214 const double red = currentEntryElem.attribute( u"red"_s ).toDouble();
215 const double green = currentEntryElem.attribute( u"green"_s ).toDouble();
216 const double blue = currentEntryElem.attribute( u"blue"_s ).toDouble();
217 const double opacity = 1.0 - currentEntryElem.attribute( u"percentTransparent"_s ).toDouble() / 100.0;
218 bool redOk = false;
219 const double toleranceRed = currentEntryElem.attribute( u"toleranceRed"_s ).toDouble( &redOk );
220 bool greenOk = false;
221 const double toleranceGreen = currentEntryElem.attribute( u"toleranceGreen"_s ).toDouble( &greenOk );
222 bool blueOk = false;
223 const double toleranceBlue = currentEntryElem.attribute( u"toleranceBlue"_s ).toDouble( &blueOk );
224 mTransparentThreeValuePixelList.append( TransparentThreeValuePixel( red, green, blue, opacity,
225 redOk ? toleranceRed : 4 * std::numeric_limits<double>::epsilon(),
226 greenOk ? toleranceGreen : 4 * std::numeric_limits<double>::epsilon(),
227 blueOk ? toleranceBlue : 4 * std::numeric_limits<double>::epsilon() ) );
228 }
229 }
230}
static QString printValue(double value, bool localized=false)
Print double value with all necessary significant digits.
void setTransparentSingleValuePixelList(const QVector< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Sets the transparent single value pixel list, replacing the whole existing list.
QVector< QgsRasterTransparency::TransparentSingleValuePixel > transparentSingleValuePixelList() const
Returns the transparent single value pixel list.
Q_DECL_DEPRECATED int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
void initializeTransparentPixelList(double value)
Resets the transparency list to a single value.
double opacityForRgbValues(double redValue, double greenValue, double blueValue) const
Returns the opacity (as a value from 0 to 1) for a set of RGB pixel values.
void setTransparentThreeValuePixelList(const QVector< QgsRasterTransparency::TransparentThreeValuePixel > &newList)
Sets the transparent three value pixel list, replacing the whole existing list.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Writes the transparency information to an XML document.
QVector< QgsRasterTransparency::TransparentThreeValuePixel > transparentThreeValuePixelList() const
Returns the transparent three value pixel list.
bool isEmpty() const
True if there are no entries in the pixel lists except the nodata value.
double opacityForValue(double value) const
Returns the opacity (as a value from 0 to 1) for a single value pixel.
void readXml(const QDomElement &elem)
Reads the transparency information from an XML document.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6924
Defines the transparency for a range of single-band pixel values.
Defines the transparency for a RGB pixel value.