QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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 }
bool isEmpty() const
True if there are no entries in the pixel lists except the nodata value.
static QString printValue(double value)
Print double value with all necessary significant digits.
void setTransparentThreeValuePixelList(const QList< QgsRasterTransparency::TransparentThreeValuePixel > &newList)
Sets the transparent three value pixel list, replacing the whole existing list.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:280
void initializeTransparentPixelList(double value)
Resets the transparency list to a single value.
void readXml(const QDomElement &elem)
Reads the transparency information from an XML document.
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
QList< QgsRasterTransparency::TransparentSingleValuePixel > transparentSingleValuePixelList() const
Returns the transparent single value pixel list.
void setTransparentSingleValuePixelList(const QList< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Sets the transparent single value pixel list, replacing the whole existing list.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Writes the transparency information to an XML document.
QList< QgsRasterTransparency::TransparentThreeValuePixel > transparentThreeValuePixelList() const
Returns the transparent three value pixel list.