QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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 return ( value > p.min && value < p.max ) || ( p.includeMinimum && qgsDoubleNear( value, p.min ) ) || ( 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 return qgsDoubleNear( p.red, redValue, p.fuzzyToleranceRed ) && qgsDoubleNear( p.green, greenValue, p.fuzzyToleranceGreen ) && qgsDoubleNear( p.blue, blueValue, p.fuzzyToleranceBlue );
110 } );
111
112 if ( it != mTransparentThreeValuePixelList.constEnd() )
113 {
114 return it->opacity;
115 }
116
117 return 1;
118}
119
121{
122 return mTransparentSingleValuePixelList.isEmpty() && mTransparentThreeValuePixelList.isEmpty();
123}
124
125void QgsRasterTransparency::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
126{
127 QDomElement rasterTransparencyElem = doc.createElement( u"rasterTransparency"_s );
128 if ( !mTransparentSingleValuePixelList.isEmpty() )
129 {
130 QDomElement singleValuePixelListElement = doc.createElement( u"singleValuePixelList"_s );
131 auto it = mTransparentSingleValuePixelList.constBegin();
132 for ( ; it != mTransparentSingleValuePixelList.constEnd(); ++it )
133 {
134 QDomElement pixelListElement = doc.createElement( u"pixelListEntry"_s );
135 pixelListElement.setAttribute( u"min"_s, QgsRasterBlock::printValue( it->min ) );
136 pixelListElement.setAttribute( u"max"_s, QgsRasterBlock::printValue( it->max ) );
137 pixelListElement.setAttribute( u"percentTransparent"_s, QString::number( 100.0 * ( 1 - it->opacity ) ) );
138 singleValuePixelListElement.appendChild( pixelListElement );
139 }
140 rasterTransparencyElem.appendChild( singleValuePixelListElement );
141 }
142 if ( !mTransparentThreeValuePixelList.isEmpty() )
143 {
144 QDomElement threeValuePixelListElement = doc.createElement( u"threeValuePixelList"_s );
145 auto it = mTransparentThreeValuePixelList.constBegin();
146 for ( ; it != mTransparentThreeValuePixelList.constEnd(); ++it )
147 {
148 QDomElement pixelListElement = doc.createElement( u"pixelListEntry"_s );
149 pixelListElement.setAttribute( u"red"_s, QgsRasterBlock::printValue( it->red ) );
150 pixelListElement.setAttribute( u"green"_s, QgsRasterBlock::printValue( it->green ) );
151 pixelListElement.setAttribute( u"blue"_s, QgsRasterBlock::printValue( it->blue ) );
152 pixelListElement.setAttribute( u"percentTransparent"_s, QString::number( 100.0 * ( 1 - it->opacity ) ) );
153 if ( !qgsDoubleNear( it->fuzzyToleranceRed, 0 ) )
154 pixelListElement.setAttribute( u"toleranceRed"_s, QString::number( it->fuzzyToleranceRed ) );
155 if ( !qgsDoubleNear( it->fuzzyToleranceGreen, 0 ) )
156 pixelListElement.setAttribute( u"toleranceGreen"_s, QString::number( it->fuzzyToleranceGreen ) );
157 if ( !qgsDoubleNear( it->fuzzyToleranceBlue, 0 ) )
158 pixelListElement.setAttribute( u"toleranceBlue"_s, QString::number( it->fuzzyToleranceBlue ) );
159 threeValuePixelListElement.appendChild( pixelListElement );
160 }
161 rasterTransparencyElem.appendChild( threeValuePixelListElement );
162 }
163 parentElem.appendChild( rasterTransparencyElem );
164}
165
166void QgsRasterTransparency::readXml( const QDomElement &elem )
167{
168 if ( elem.isNull() )
169 {
170 return;
171 }
172
173 mTransparentSingleValuePixelList.clear();
174 mTransparentThreeValuePixelList.clear();
175 QDomElement currentEntryElem;
176
177 const QDomElement singlePixelListElem = elem.firstChildElement( u"singleValuePixelList"_s );
178 if ( !singlePixelListElem.isNull() )
179 {
180 const QDomNodeList entryList = singlePixelListElem.elementsByTagName( u"pixelListEntry"_s );
181 for ( int i = 0; i < entryList.size(); ++i )
182 {
183 currentEntryElem = entryList.at( i ).toElement();
184 double min = 0;
185 double max = 0;
186 const double opacity = 1.0 - currentEntryElem.attribute( u"percentTransparent"_s ).toDouble() / 100.0;
187 // Backward compoatibility < 1.9 : pixelValue (before ranges)
188 if ( currentEntryElem.hasAttribute( u"pixelValue"_s ) )
189 {
190 min = max = currentEntryElem.attribute( u"pixelValue"_s ).toDouble();
191 }
192 else
193 {
194 min = currentEntryElem.attribute( u"min"_s ).toDouble();
195 max = currentEntryElem.attribute( u"max"_s ).toDouble();
196 }
197 mTransparentSingleValuePixelList.append( TransparentSingleValuePixel( min, max, opacity ) );
198 }
199 }
200 const QDomElement threeValuePixelListElem = elem.firstChildElement( u"threeValuePixelList"_s );
201 if ( !threeValuePixelListElem.isNull() )
202 {
203 const QDomNodeList entryList = threeValuePixelListElem.elementsByTagName( u"pixelListEntry"_s );
204 for ( int i = 0; i < entryList.size(); ++i )
205 {
206 currentEntryElem = entryList.at( i ).toElement();
207 const double red = currentEntryElem.attribute( u"red"_s ).toDouble();
208 const double green = currentEntryElem.attribute( u"green"_s ).toDouble();
209 const double blue = currentEntryElem.attribute( u"blue"_s ).toDouble();
210 const double opacity = 1.0 - currentEntryElem.attribute( u"percentTransparent"_s ).toDouble() / 100.0;
211 bool redOk = false;
212 const double toleranceRed = currentEntryElem.attribute( u"toleranceRed"_s ).toDouble( &redOk );
213 bool greenOk = false;
214 const double toleranceGreen = currentEntryElem.attribute( u"toleranceGreen"_s ).toDouble( &greenOk );
215 bool blueOk = false;
216 const double toleranceBlue = currentEntryElem.attribute( u"toleranceBlue"_s ).toDouble( &blueOk );
217 mTransparentThreeValuePixelList.append( TransparentThreeValuePixel(
218 red,
219 green,
220 blue,
221 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 }
228}
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:6975
Defines the transparency for a range of single-band pixel values.
Defines the transparency for a RGB pixel value.