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