QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
27QVector<QgsRasterTransparency::TransparentSingleValuePixel> QgsRasterTransparency::transparentSingleValuePixelList() const
28{
29 return mTransparentSingleValuePixelList;
30}
31
32QVector<QgsRasterTransparency::TransparentThreeValuePixel> QgsRasterTransparency::transparentThreeValuePixelList() const
33{
34 return mTransparentThreeValuePixelList;
35}
36
38{
39 //clear the existing list
40 mTransparentSingleValuePixelList.clear();
41
42 //add the initial value
43 mTransparentSingleValuePixelList.append( TransparentSingleValuePixel( value, value, 0 ) );
44}
45
46void QgsRasterTransparency::initializeTransparentPixelList( double redValue, double greenValue, double blueValue )
47{
48 //clear the existing list
49 mTransparentThreeValuePixelList.clear();
50
51 //add the initial values
52 mTransparentThreeValuePixelList.append( TransparentThreeValuePixel( redValue, greenValue, blueValue, 0 ) );
53}
54
55void QgsRasterTransparency::setTransparentSingleValuePixelList( const QVector<QgsRasterTransparency::TransparentSingleValuePixel> &newList )
56{
57 mTransparentSingleValuePixelList = newList;
58}
59
60void QgsRasterTransparency::setTransparentThreeValuePixelList( const QVector<QgsRasterTransparency::TransparentThreeValuePixel> &newList )
61{
62 mTransparentThreeValuePixelList = newList;
63}
64
65int QgsRasterTransparency::alphaValue( double value, int globalTransparency ) const
66{
67 return static_cast< int >( opacityForValue( value ) * globalTransparency );
68}
69
70double QgsRasterTransparency::opacityForValue( double value ) const
71{
72 //if NaN return 0, transparent
73 if ( std::isnan( value ) )
74 {
75 return 0;
76 }
77
78 //Search through the transparency list looking for a match
79 auto it = std::find_if( mTransparentSingleValuePixelList.constBegin(), mTransparentSingleValuePixelList.constEnd(), [value]( const TransparentSingleValuePixel & p )
80 {
81 return ( value > p.min && value < p.max )
82 || ( p.includeMinimum && qgsDoubleNear( value, p.min ) )
83 || ( p.includeMaximum && qgsDoubleNear( value, p.max ) );
84 } );
85
86 if ( it != mTransparentSingleValuePixelList.constEnd() )
87 {
88 return it->opacity;
89 }
90
91 return 1;
92}
93
94int QgsRasterTransparency::alphaValue( double redValue, double greenValue, double blueValue, int globalTransparency ) const
95{
96 return static_cast< int >( opacityForRgbValues( redValue, greenValue, blueValue ) * globalTransparency );
97}
98
99double QgsRasterTransparency::opacityForRgbValues( double redValue, double greenValue, double blueValue ) const
100{
101 //if NaN return 0, transparent
102 if ( std::isnan( redValue ) || std::isnan( greenValue ) || std::isnan( blueValue ) )
103 {
104 return 0;
105 }
106
107 //Search through the transparency list looking for a match
108 auto it = std::find_if( mTransparentThreeValuePixelList.constBegin(), mTransparentThreeValuePixelList.constEnd(), [redValue, greenValue, blueValue]( const TransparentThreeValuePixel & p )
109 {
110 return qgsDoubleNear( p.red, redValue, p.fuzzyToleranceRed )
111 && qgsDoubleNear( p.green, greenValue, p.fuzzyToleranceGreen )
112 && qgsDoubleNear( p.blue, blueValue, p.fuzzyToleranceBlue );
113 } );
114
115 if ( it != mTransparentThreeValuePixelList.constEnd() )
116 {
117 return it->opacity;
118 }
119
120 return 1;
121}
122
124{
125 return mTransparentSingleValuePixelList.isEmpty() && mTransparentThreeValuePixelList.isEmpty();
126}
127
128void QgsRasterTransparency::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
129{
130 QDomElement rasterTransparencyElem = doc.createElement( QStringLiteral( "rasterTransparency" ) );
131 if ( !mTransparentSingleValuePixelList.isEmpty() )
132 {
133 QDomElement singleValuePixelListElement = doc.createElement( QStringLiteral( "singleValuePixelList" ) );
134 auto it = mTransparentSingleValuePixelList.constBegin();
135 for ( ; it != mTransparentSingleValuePixelList.constEnd(); ++it )
136 {
137 QDomElement pixelListElement = doc.createElement( QStringLiteral( "pixelListEntry" ) );
138 pixelListElement.setAttribute( QStringLiteral( "min" ), QgsRasterBlock::printValue( it->min ) );
139 pixelListElement.setAttribute( QStringLiteral( "max" ), QgsRasterBlock::printValue( it->max ) );
140 pixelListElement.setAttribute( QStringLiteral( "percentTransparent" ), QString::number( 100.0 * ( 1 - it->opacity ) ) );
141 singleValuePixelListElement.appendChild( pixelListElement );
142 }
143 rasterTransparencyElem.appendChild( singleValuePixelListElement );
144
145 }
146 if ( !mTransparentThreeValuePixelList.isEmpty() )
147 {
148 QDomElement threeValuePixelListElement = doc.createElement( QStringLiteral( "threeValuePixelList" ) );
149 auto it = mTransparentThreeValuePixelList.constBegin();
150 for ( ; it != mTransparentThreeValuePixelList.constEnd(); ++it )
151 {
152 QDomElement pixelListElement = doc.createElement( QStringLiteral( "pixelListEntry" ) );
153 pixelListElement.setAttribute( QStringLiteral( "red" ), QgsRasterBlock::printValue( it->red ) );
154 pixelListElement.setAttribute( QStringLiteral( "green" ), QgsRasterBlock::printValue( it->green ) );
155 pixelListElement.setAttribute( QStringLiteral( "blue" ), QgsRasterBlock::printValue( it->blue ) );
156 pixelListElement.setAttribute( QStringLiteral( "percentTransparent" ), QString::number( 100.0 * ( 1 - it->opacity ) ) );
157 if ( !qgsDoubleNear( it->fuzzyToleranceRed, 0 ) )
158 pixelListElement.setAttribute( QStringLiteral( "toleranceRed" ), QString::number( it->fuzzyToleranceRed ) );
159 if ( !qgsDoubleNear( it->fuzzyToleranceGreen, 0 ) )
160 pixelListElement.setAttribute( QStringLiteral( "toleranceGreen" ), QString::number( it->fuzzyToleranceGreen ) );
161 if ( !qgsDoubleNear( it->fuzzyToleranceBlue, 0 ) )
162 pixelListElement.setAttribute( QStringLiteral( "toleranceBlue" ), QString::number( it->fuzzyToleranceBlue ) );
163 threeValuePixelListElement.appendChild( pixelListElement );
164 }
165 rasterTransparencyElem.appendChild( threeValuePixelListElement );
166 }
167 parentElem.appendChild( rasterTransparencyElem );
168}
169
170void QgsRasterTransparency::readXml( const QDomElement &elem )
171{
172 if ( elem.isNull() )
173 {
174 return;
175 }
176
177 mTransparentSingleValuePixelList.clear();
178 mTransparentThreeValuePixelList.clear();
179 QDomElement currentEntryElem;
180
181 const QDomElement singlePixelListElem = elem.firstChildElement( QStringLiteral( "singleValuePixelList" ) );
182 if ( !singlePixelListElem.isNull() )
183 {
184 const QDomNodeList entryList = singlePixelListElem.elementsByTagName( QStringLiteral( "pixelListEntry" ) );
185 for ( int i = 0; i < entryList.size(); ++i )
186 {
187 currentEntryElem = entryList.at( i ).toElement();
188 double min = 0;
189 double max = 0;
190 const double opacity = 1.0 - currentEntryElem.attribute( QStringLiteral( "percentTransparent" ) ).toDouble() / 100.0;
191 // Backward compoatibility < 1.9 : pixelValue (before ranges)
192 if ( currentEntryElem.hasAttribute( QStringLiteral( "pixelValue" ) ) )
193 {
194 min = max = currentEntryElem.attribute( QStringLiteral( "pixelValue" ) ).toDouble();
195 }
196 else
197 {
198 min = currentEntryElem.attribute( QStringLiteral( "min" ) ).toDouble();
199 max = currentEntryElem.attribute( QStringLiteral( "max" ) ).toDouble();
200 }
201 mTransparentSingleValuePixelList.append( TransparentSingleValuePixel( min, max, opacity ) );
202 }
203 }
204 const QDomElement threeValuePixelListElem = elem.firstChildElement( QStringLiteral( "threeValuePixelList" ) );
205 if ( !threeValuePixelListElem.isNull() )
206 {
207 const QDomNodeList entryList = threeValuePixelListElem.elementsByTagName( QStringLiteral( "pixelListEntry" ) );
208 for ( int i = 0; i < entryList.size(); ++i )
209 {
210 currentEntryElem = entryList.at( i ).toElement();
211 const double red = currentEntryElem.attribute( QStringLiteral( "red" ) ).toDouble();
212 const double green = currentEntryElem.attribute( QStringLiteral( "green" ) ).toDouble();
213 const double blue = currentEntryElem.attribute( QStringLiteral( "blue" ) ).toDouble();
214 const double opacity = 1.0 - currentEntryElem.attribute( QStringLiteral( "percentTransparent" ) ).toDouble() / 100.0;
215 bool redOk = false;
216 const double toleranceRed = currentEntryElem.attribute( QStringLiteral( "toleranceRed" ) ).toDouble( &redOk );
217 bool greenOk = false;
218 const double toleranceGreen = currentEntryElem.attribute( QStringLiteral( "toleranceGreen" ) ).toDouble( &greenOk );
219 bool blueOk = false;
220 const double toleranceBlue = currentEntryElem.attribute( QStringLiteral( "toleranceBlue" ) ).toDouble( &blueOk );
221 mTransparentThreeValuePixelList.append( TransparentThreeValuePixel( red, green, blue, opacity,
222 redOk ? toleranceRed : 4 * std::numeric_limits<double>::epsilon(),
223 greenOk ? toleranceGreen : 4 * std::numeric_limits<double>::epsilon(),
224 blueOk ? toleranceBlue : 4 * std::numeric_limits<double>::epsilon() ) );
225 }
226 }
227}
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:6607
Defines the transparency for a range of single-band pixel values.
Defines the transparency for a RGB pixel value.