QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsrastertransparency.cpp
Go to the documentation of this file.
1 /* **************************************************************************
2  qgsrastertransparency.cpp - description
3  -------------------
4 begin : Mon Nov 30 2007
5 copyright : (C) 2007 by Peter J. Ersts
6 email : [email protected]
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"
20 #include "qgsrastertransparency.h"
21 #include "qgis.h"
22 #include "qgslogger.h"
23 
24 #include <QDomDocument>
25 #include <QDomElement>
26 
27 QList<QgsRasterTransparency::TransparentSingleValuePixel> QgsRasterTransparency::transparentSingleValuePixelList() const
28 {
29  return mTransparentSingleValuePixelList;
30 }
31 
32 QList<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  TransparentSingleValuePixel myTransparentSingleValuePixel;
44  myTransparentSingleValuePixel.min = value;
45  myTransparentSingleValuePixel.max = value;
46  myTransparentSingleValuePixel.percentTransparent = 100.0;
47  mTransparentSingleValuePixelList.append( myTransparentSingleValuePixel );
48 }
49 
50 void QgsRasterTransparency::initializeTransparentPixelList( double redValue, double greenValue, double blueValue )
51 {
52  //clearn the existing list
53  mTransparentThreeValuePixelList.clear();
54 
55  //add the initial values
56  TransparentThreeValuePixel myTransparentThreeValuePixel;
57  myTransparentThreeValuePixel.red = redValue;
58  myTransparentThreeValuePixel.green = greenValue;
59  myTransparentThreeValuePixel.blue = blueValue;
60  myTransparentThreeValuePixel.percentTransparent = 100.0;
61  mTransparentThreeValuePixelList.append( myTransparentThreeValuePixel );
62 }
63 
64 void QgsRasterTransparency::setTransparentSingleValuePixelList( const QList<QgsRasterTransparency::TransparentSingleValuePixel> &newList )
65 {
66  mTransparentSingleValuePixelList = newList;
67 }
68 
69 void QgsRasterTransparency::setTransparentThreeValuePixelList( const QList<QgsRasterTransparency::TransparentThreeValuePixel> &newList )
70 {
71  mTransparentThreeValuePixelList = newList;
72 }
73 
74 int QgsRasterTransparency::alphaValue( double value, int globalTransparency ) const
75 {
76  //if NaN return 0, transparent
77  if ( std::isnan( value ) )
78  {
79  return 0;
80  }
81 
82  //Search through the transparency list looking for a match
83  bool myTransparentPixelFound = false;
84  TransparentSingleValuePixel myTransparentPixel = {0, 0, 100};
85  for ( int myListRunner = 0; myListRunner < mTransparentSingleValuePixelList.count(); myListRunner++ )
86  {
87  myTransparentPixel = mTransparentSingleValuePixelList[myListRunner];
88  if ( ( value >= myTransparentPixel.min && value <= myTransparentPixel.max ) ||
89  qgsDoubleNear( value, myTransparentPixel.min ) ||
90  qgsDoubleNear( value, myTransparentPixel.max ) )
91  {
92  myTransparentPixelFound = true;
93  break;
94  }
95  }
96 
97  //if a match was found use the stored transparency percentage
98  if ( myTransparentPixelFound )
99  {
100  return static_cast< int >( static_cast< float >( globalTransparency ) * ( 1.0 - ( myTransparentPixel.percentTransparent / 100.0 ) ) );
101  }
102 
103  return globalTransparency;
104 }
105 
106 int QgsRasterTransparency::alphaValue( double redValue, double greenValue, double blueValue, int globalTransparency ) const
107 {
108  //if NaN return 0, transparent
109  if ( std::isnan( redValue ) || std::isnan( greenValue ) || std::isnan( blueValue ) )
110  {
111  return 0;
112  }
113 
114  //Search through the transparency list looking for a match
115  bool myTransparentPixelFound = false;
116  TransparentThreeValuePixel myTransparentPixel = {0, 0, 0, 100};
117  for ( int myListRunner = 0; myListRunner < mTransparentThreeValuePixelList.count(); myListRunner++ )
118  {
119  myTransparentPixel = mTransparentThreeValuePixelList[myListRunner];
120  if ( qgsDoubleNear( myTransparentPixel.red, redValue ) )
121  {
122  if ( qgsDoubleNear( myTransparentPixel.green, greenValue ) )
123  {
124  if ( qgsDoubleNear( myTransparentPixel.blue, blueValue ) )
125  {
126  myTransparentPixelFound = true;
127  break;
128  }
129  }
130  }
131  }
132 
133  //if a match was found use the stored transparency percentage
134  if ( myTransparentPixelFound )
135  {
136  return static_cast< int >( static_cast< float >( globalTransparency ) * ( 1.0 - ( myTransparentPixel.percentTransparent / 100.0 ) ) );
137  }
138 
139  return globalTransparency;
140 }
141 
143 {
144  return mTransparentSingleValuePixelList.isEmpty() && mTransparentThreeValuePixelList.isEmpty();
145 }
146 
147 void QgsRasterTransparency::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
148 {
149  QDomElement rasterTransparencyElem = doc.createElement( QStringLiteral( "rasterTransparency" ) );
150  if ( !mTransparentSingleValuePixelList.isEmpty() )
151  {
152  QDomElement singleValuePixelListElement = doc.createElement( QStringLiteral( "singleValuePixelList" ) );
153  QList<QgsRasterTransparency::TransparentSingleValuePixel>::const_iterator it = mTransparentSingleValuePixelList.constBegin();
154  for ( ; it != mTransparentSingleValuePixelList.constEnd(); ++it )
155  {
156  QDomElement pixelListElement = doc.createElement( QStringLiteral( "pixelListEntry" ) );
157  pixelListElement.setAttribute( QStringLiteral( "min" ), QgsRasterBlock::printValue( it->min ) );
158  pixelListElement.setAttribute( QStringLiteral( "max" ), QgsRasterBlock::printValue( it->max ) );
159  pixelListElement.setAttribute( QStringLiteral( "percentTransparent" ), QString::number( it->percentTransparent ) );
160  singleValuePixelListElement.appendChild( pixelListElement );
161  }
162  rasterTransparencyElem.appendChild( singleValuePixelListElement );
163 
164  }
165  if ( !mTransparentThreeValuePixelList.isEmpty() )
166  {
167  QDomElement threeValuePixelListElement = doc.createElement( QStringLiteral( "threeValuePixelList" ) );
168  QList<QgsRasterTransparency::TransparentThreeValuePixel>::const_iterator it = mTransparentThreeValuePixelList.constBegin();
169  for ( ; it != mTransparentThreeValuePixelList.constEnd(); ++it )
170  {
171  QDomElement pixelListElement = doc.createElement( QStringLiteral( "pixelListEntry" ) );
172  pixelListElement.setAttribute( QStringLiteral( "red" ), QgsRasterBlock::printValue( it->red ) );
173  pixelListElement.setAttribute( QStringLiteral( "green" ), QgsRasterBlock::printValue( it->green ) );
174  pixelListElement.setAttribute( QStringLiteral( "blue" ), QgsRasterBlock::printValue( it->blue ) );
175  pixelListElement.setAttribute( QStringLiteral( "percentTransparent" ), QString::number( it->percentTransparent ) );
176  threeValuePixelListElement.appendChild( pixelListElement );
177  }
178  rasterTransparencyElem.appendChild( threeValuePixelListElement );
179  }
180  parentElem.appendChild( rasterTransparencyElem );
181 }
182 
183 void QgsRasterTransparency::readXml( const QDomElement &elem )
184 {
185  if ( elem.isNull() )
186  {
187  return;
188  }
189 
190  mTransparentSingleValuePixelList.clear();
191  mTransparentThreeValuePixelList.clear();
192  QDomElement currentEntryElem;
193 
194  QDomElement singlePixelListElem = elem.firstChildElement( QStringLiteral( "singleValuePixelList" ) );
195  if ( !singlePixelListElem.isNull() )
196  {
197  QDomNodeList entryList = singlePixelListElem.elementsByTagName( QStringLiteral( "pixelListEntry" ) );
199  for ( int i = 0; i < entryList.size(); ++i )
200  {
201  currentEntryElem = entryList.at( i ).toElement();
202  sp.percentTransparent = currentEntryElem.attribute( QStringLiteral( "percentTransparent" ) ).toDouble();
203  // Backward compoatibility < 1.9 : pixelValue (before ranges)
204  if ( currentEntryElem.hasAttribute( QStringLiteral( "pixelValue" ) ) )
205  {
206  sp.min = sp.max = currentEntryElem.attribute( QStringLiteral( "pixelValue" ) ).toDouble();
207  }
208  else
209  {
210  sp.min = currentEntryElem.attribute( QStringLiteral( "min" ) ).toDouble();
211  sp.max = currentEntryElem.attribute( QStringLiteral( "max" ) ).toDouble();
212  }
213  mTransparentSingleValuePixelList.append( sp );
214  }
215  }
216  QDomElement threeValuePixelListElem = elem.firstChildElement( QStringLiteral( "threeValuePixelList" ) );
217  if ( !threeValuePixelListElem.isNull() )
218  {
219  QDomNodeList entryList = threeValuePixelListElem.elementsByTagName( QStringLiteral( "pixelListEntry" ) );
221  for ( int i = 0; i < entryList.size(); ++i )
222  {
223  currentEntryElem = entryList.at( i ).toElement();
224  tp.red = currentEntryElem.attribute( QStringLiteral( "red" ) ).toDouble();
225  tp.green = currentEntryElem.attribute( QStringLiteral( "green" ) ).toDouble();
226  tp.blue = currentEntryElem.attribute( QStringLiteral( "blue" ) ).toDouble();
227  tp.percentTransparent = currentEntryElem.attribute( QStringLiteral( "percentTransparent" ) ).toDouble();
228  mTransparentThreeValuePixelList.append( tp );
229  }
230  }
231 }
static QString printValue(double value)
Print double value with all necessary significant digits.
void setTransparentSingleValuePixelList(const QList< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Sets the transparent single value pixel list, replacing the whole existing list.
QList< QgsRasterTransparency::TransparentThreeValuePixel > transparentThreeValuePixelList() const
Returns the transparent three value pixel list.
void setTransparentThreeValuePixelList(const QList< QgsRasterTransparency::TransparentThreeValuePixel > &newList)
Sets the transparent three value pixel list, replacing the whole existing list.
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.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Writes the transparency information to an XML document.
QList< QgsRasterTransparency::TransparentSingleValuePixel > transparentSingleValuePixelList() const
Returns the transparent single value pixel list.
bool isEmpty() const
True if there are no entries in the pixel lists except the nodata value.
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:598