QGIS API Documentation  2.99.0-Master (19b062c)
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 : 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"
20 #include "qgsrastertransparency.h"
21 #include "qgis.h"
22 #include "qgslogger.h"
23 
24 #include <QDomDocument>
25 #include <QDomElement>
26 
30 QList<QgsRasterTransparency::TransparentSingleValuePixel> QgsRasterTransparency::transparentSingleValuePixelList() const
31 {
32  return mTransparentSingleValuePixelList;
33 }
34 
38 QList<QgsRasterTransparency::TransparentThreeValuePixel> QgsRasterTransparency::transparentThreeValuePixelList() const
39 {
40  return mTransparentThreeValuePixelList;
41 }
42 
47 {
48  //clear the existing list
49  mTransparentSingleValuePixelList.clear();
50 
51  //add the initial value
52  TransparentSingleValuePixel myTransparentSingleValuePixel;
53  myTransparentSingleValuePixel.min = value;
54  myTransparentSingleValuePixel.max = value;
55  myTransparentSingleValuePixel.percentTransparent = 100.0;
56  mTransparentSingleValuePixelList.append( myTransparentSingleValuePixel );
57 }
58 
62 void QgsRasterTransparency::initializeTransparentPixelList( double redValue, double greenValue, double blueValue )
63 {
64  //clearn the existing list
65  mTransparentThreeValuePixelList.clear();
66 
67  //add the initial values
68  TransparentThreeValuePixel myTransparentThreeValuePixel;
69  myTransparentThreeValuePixel.red = redValue;
70  myTransparentThreeValuePixel.green = greenValue;
71  myTransparentThreeValuePixel.blue = blueValue;
72  myTransparentThreeValuePixel.percentTransparent = 100.0;
73  mTransparentThreeValuePixelList.append( myTransparentThreeValuePixel );
74 }
75 
76 
80 void QgsRasterTransparency::setTransparentSingleValuePixelList( const QList<QgsRasterTransparency::TransparentSingleValuePixel> &newList )
81 {
82  mTransparentSingleValuePixelList = newList;
83 }
84 
88 void QgsRasterTransparency::setTransparentThreeValuePixelList( const QList<QgsRasterTransparency::TransparentThreeValuePixel> &newList )
89 {
90  mTransparentThreeValuePixelList = newList;
91 }
92 
99 int QgsRasterTransparency::alphaValue( double value, int globalTransparency ) const
100 {
101  //if NaN return 0, transparent
102  if ( std::isnan( value ) )
103  {
104  return 0;
105  }
106 
107  //Search through the transparency list looking for a match
108  bool myTransparentPixelFound = false;
109  TransparentSingleValuePixel myTransparentPixel = {0, 0, 100};
110  for ( int myListRunner = 0; myListRunner < mTransparentSingleValuePixelList.count(); myListRunner++ )
111  {
112  myTransparentPixel = mTransparentSingleValuePixelList[myListRunner];
113  if ( ( value >= myTransparentPixel.min && value <= myTransparentPixel.max ) ||
114  qgsDoubleNear( value, myTransparentPixel.min ) ||
115  qgsDoubleNear( value, myTransparentPixel.max ) )
116  {
117  myTransparentPixelFound = true;
118  break;
119  }
120  }
121 
122  //if a match was found use the stored transparency percentage
123  if ( myTransparentPixelFound )
124  {
125  return static_cast< int >( static_cast< float >( globalTransparency ) * ( 1.0 - ( myTransparentPixel.percentTransparent / 100.0 ) ) );
126  }
127 
128  return globalTransparency;
129 }
130 
139 int QgsRasterTransparency::alphaValue( double redValue, double greenValue, double blueValue, int globalTransparency ) const
140 {
141  //if NaN return 0, transparent
142  if ( std::isnan( redValue ) || std::isnan( greenValue ) || std::isnan( blueValue ) )
143  {
144  return 0;
145  }
146 
147  //Search through the transparency list looking for a match
148  bool myTransparentPixelFound = false;
149  TransparentThreeValuePixel myTransparentPixel = {0, 0, 0, 100};
150  for ( int myListRunner = 0; myListRunner < mTransparentThreeValuePixelList.count(); myListRunner++ )
151  {
152  myTransparentPixel = mTransparentThreeValuePixelList[myListRunner];
153  if ( qgsDoubleNear( myTransparentPixel.red, redValue ) )
154  {
155  if ( qgsDoubleNear( myTransparentPixel.green, greenValue ) )
156  {
157  if ( qgsDoubleNear( myTransparentPixel.blue, blueValue ) )
158  {
159  myTransparentPixelFound = true;
160  break;
161  }
162  }
163  }
164  }
165 
166  //if a match was found use the stored transparency percentage
167  if ( myTransparentPixelFound )
168  {
169  return static_cast< int >( static_cast< float >( globalTransparency ) * ( 1.0 - ( myTransparentPixel.percentTransparent / 100.0 ) ) );
170  }
171 
172  return globalTransparency;
173 }
174 
176 {
177  return mTransparentSingleValuePixelList.isEmpty() && mTransparentThreeValuePixelList.isEmpty();
178 }
179 
180 void QgsRasterTransparency::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
181 {
182  QDomElement rasterTransparencyElem = doc.createElement( QStringLiteral( "rasterTransparency" ) );
183  if ( !mTransparentSingleValuePixelList.isEmpty() )
184  {
185  QDomElement singleValuePixelListElement = doc.createElement( QStringLiteral( "singleValuePixelList" ) );
186  QList<QgsRasterTransparency::TransparentSingleValuePixel>::const_iterator it = mTransparentSingleValuePixelList.constBegin();
187  for ( ; it != mTransparentSingleValuePixelList.constEnd(); ++it )
188  {
189  QDomElement pixelListElement = doc.createElement( QStringLiteral( "pixelListEntry" ) );
190  pixelListElement.setAttribute( QStringLiteral( "min" ), QgsRasterBlock::printValue( it->min ) );
191  pixelListElement.setAttribute( QStringLiteral( "max" ), QgsRasterBlock::printValue( it->max ) );
192  pixelListElement.setAttribute( QStringLiteral( "percentTransparent" ), QString::number( it->percentTransparent ) );
193  singleValuePixelListElement.appendChild( pixelListElement );
194  }
195  rasterTransparencyElem.appendChild( singleValuePixelListElement );
196 
197  }
198  if ( !mTransparentThreeValuePixelList.isEmpty() )
199  {
200  QDomElement threeValuePixelListElement = doc.createElement( QStringLiteral( "threeValuePixelList" ) );
201  QList<QgsRasterTransparency::TransparentThreeValuePixel>::const_iterator it = mTransparentThreeValuePixelList.constBegin();
202  for ( ; it != mTransparentThreeValuePixelList.constEnd(); ++it )
203  {
204  QDomElement pixelListElement = doc.createElement( QStringLiteral( "pixelListEntry" ) );
205  pixelListElement.setAttribute( QStringLiteral( "red" ), QgsRasterBlock::printValue( it->red ) );
206  pixelListElement.setAttribute( QStringLiteral( "green" ), QgsRasterBlock::printValue( it->green ) );
207  pixelListElement.setAttribute( QStringLiteral( "blue" ), QgsRasterBlock::printValue( it->blue ) );
208  pixelListElement.setAttribute( QStringLiteral( "percentTransparent" ), QString::number( it->percentTransparent ) );
209  threeValuePixelListElement.appendChild( pixelListElement );
210  }
211  rasterTransparencyElem.appendChild( threeValuePixelListElement );
212  }
213  parentElem.appendChild( rasterTransparencyElem );
214 }
215 
216 void QgsRasterTransparency::readXml( const QDomElement &elem )
217 {
218  if ( elem.isNull() )
219  {
220  return;
221  }
222 
223  mTransparentSingleValuePixelList.clear();
224  mTransparentThreeValuePixelList.clear();
225  QDomElement currentEntryElem;
226 
227  QDomElement singlePixelListElem = elem.firstChildElement( QStringLiteral( "singleValuePixelList" ) );
228  if ( !singlePixelListElem.isNull() )
229  {
230  QDomNodeList entryList = singlePixelListElem.elementsByTagName( QStringLiteral( "pixelListEntry" ) );
232  for ( int i = 0; i < entryList.size(); ++i )
233  {
234  currentEntryElem = entryList.at( i ).toElement();
235  sp.percentTransparent = currentEntryElem.attribute( QStringLiteral( "percentTransparent" ) ).toDouble();
236  // Backward compoatibility < 1.9 : pixelValue (before ranges)
237  if ( currentEntryElem.hasAttribute( QStringLiteral( "pixelValue" ) ) )
238  {
239  sp.min = sp.max = currentEntryElem.attribute( QStringLiteral( "pixelValue" ) ).toDouble();
240  }
241  else
242  {
243  sp.min = currentEntryElem.attribute( QStringLiteral( "min" ) ).toDouble();
244  sp.max = currentEntryElem.attribute( QStringLiteral( "max" ) ).toDouble();
245  }
246  mTransparentSingleValuePixelList.append( sp );
247  }
248  }
249  QDomElement threeValuePixelListElem = elem.firstChildElement( QStringLiteral( "threeValuePixelList" ) );
250  if ( !threeValuePixelListElem.isNull() )
251  {
252  QDomNodeList entryList = threeValuePixelListElem.elementsByTagName( QStringLiteral( "pixelListEntry" ) );
254  for ( int i = 0; i < entryList.size(); ++i )
255  {
256  currentEntryElem = entryList.at( i ).toElement();
257  tp.red = currentEntryElem.attribute( QStringLiteral( "red" ) ).toDouble();
258  tp.green = currentEntryElem.attribute( QStringLiteral( "green" ) ).toDouble();
259  tp.blue = currentEntryElem.attribute( QStringLiteral( "blue" ) ).toDouble();
260  tp.percentTransparent = currentEntryElem.attribute( QStringLiteral( "percentTransparent" ) ).toDouble();
261  mTransparentThreeValuePixelList.append( tp );
262  }
263  }
264 }
int alphaValue(double, int globalTransparency=255) const
Returns the transparency value for a single value Pixel.
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)
Mutator for transparentThreeValuePixelList.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:227
void readXml(const QDomElement &elem)
Reads the transparency information from an XML document.
QList< QgsRasterTransparency::TransparentSingleValuePixel > transparentSingleValuePixelList() const
Accessor for transparentSingleValuePixelList.
void setTransparentSingleValuePixelList(const QList< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Mutator for transparentSingleValuePixelList.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Writes the transparency information to an XML document.
QList< QgsRasterTransparency::TransparentThreeValuePixel > transparentThreeValuePixelList() const
Accessor for transparentThreeValuePixelList.
void initializeTransparentPixelList(double)
Reset to the transparency list to a single value.