QGIS API Documentation  2.17.0-Master (0497e4a)
qgsrasterrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterrenderer.cpp
3  ---------------------
4  begin : December 2011
5  copyright : (C) 2011 by Marco Hugentobler
6  email : marco at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsrasterrenderer.h"
19 #include "qgsrastertransparency.h"
20 
21 #include <QCoreApplication>
22 #include <QDomDocument>
23 #include <QDomElement>
24 #include <QImage>
25 #include <QPainter>
26 
27 // See #9101 before any change of NODATA_COLOR!
28 const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 );
29 
31  : QgsRasterInterface( input )
32  , mType( type ), mOpacity( 1.0 ), mRasterTransparency( nullptr )
33  , mAlphaBand( -1 ) //, mInvertColor( false )
34 {
35 }
36 
38 {
39  delete mRasterTransparency;
40 }
41 
43 {
44  if ( mOn ) return 1;
45 
46  if ( mInput ) return mInput->bandCount();
47 
48  return 0;
49 }
50 
52 {
53  QgsDebugMsgLevel( "Entered", 4 );
54 
55  if ( mOn ) return QGis::ARGB32_Premultiplied;
56 
57  if ( mInput ) return mInput->dataType( bandNo );
58 
59  return QGis::UnknownDataType;
60 }
61 
63 {
64  // Renderer can only work with numerical values in at least 1 band
65  if ( !input ) return false;
66 
67  if ( !mOn )
68  {
69  // In off mode we can connect to anything
70  mInput = input;
71  return true;
72  }
73 
74  for ( int i = 1; i <= input->bandCount(); i++ )
75  {
76  if ( !QgsRasterBlock::typeIsNumeric( input->dataType( i ) ) )
77  {
78  return false;
79  }
80  }
81  mInput = input;
82  return true;
83 }
84 
86 {
87  if ( !mInput )
88  {
89  return true;
90  }
91  return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty() ) || !qgsDoubleNear( mOpacity, 1.0 ) );
92 }
93 
95 {
96  delete mRasterTransparency;
98 }
99 
100 void QgsRasterRenderer::_writeXML( QDomDocument& doc, QDomElement& rasterRendererElem ) const
101 {
102  if ( rasterRendererElem.isNull() )
103  {
104  return;
105  }
106 
107  rasterRendererElem.setAttribute( "type", mType );
108  rasterRendererElem.setAttribute( "opacity", QString::number( mOpacity ) );
109  rasterRendererElem.setAttribute( "alphaBand", mAlphaBand );
110 
111  if ( mRasterTransparency )
112  {
113  mRasterTransparency->writeXML( doc, rasterRendererElem );
114  }
115 }
116 
117 void QgsRasterRenderer::readXML( const QDomElement& rendererElem )
118 {
119  if ( rendererElem.isNull() )
120  {
121  return;
122  }
123 
124  mType = rendererElem.attribute( "type" );
125  mOpacity = rendererElem.attribute( "opacity", "1.0" ).toDouble();
126  mAlphaBand = rendererElem.attribute( "alphaBand", "-1" ).toInt();
127 
128  QDomElement rasterTransparencyElem = rendererElem.firstChildElement( "rasterTransparency" );
129  if ( !rasterTransparencyElem.isNull() )
130  {
131  delete mRasterTransparency;
133  mRasterTransparency->readXML( rasterTransparencyElem );
134  }
135 }
136 
138 {
139  if ( !other )
140  return;
141 
142  setOpacity( other->opacity() );
143  setAlphaBand( other->alphaBand() );
144  setRasterTransparency( other->rasterTransparency() ? new QgsRasterTransparency( *other->rasterTransparency() ) : nullptr );
145 }
146 
148 {
149  if ( theOrigin == MinMaxUnknown )
150  {
151  return "Unknown";
152  }
153  else if ( theOrigin == MinMaxUser )
154  {
155  return "User";
156  }
157 
158  QString name;
159  if ( theOrigin & MinMaxMinMax )
160  {
161  name += "MinMax";
162  }
163  else if ( theOrigin & MinMaxCumulativeCut )
164  {
165  name += "CumulativeCut";
166  }
167  else if ( theOrigin & MinMaxStdDev )
168  {
169  name += "StdDev";
170  }
171 
172  if ( theOrigin & MinMaxFullExtent )
173  {
174  name += "FullExtent";
175  }
176  else if ( theOrigin & MinMaxSubExtent )
177  {
178  name += "SubExtent";
179  }
180 
181  if ( theOrigin & MinMaxEstimated )
182  {
183  name += "Estimated";
184  }
185  else if ( theOrigin & MinMaxExact )
186  {
187  name += "Exact";
188  }
189  return name;
190 }
191 
193 {
194  if ( theOrigin == MinMaxUnknown )
195  {
196  return tr( "Unknown" );
197  }
198  else if ( theOrigin == MinMaxUser )
199  {
200  return tr( "User defined" );
201  }
202 
203  QString label;
204  QString est_exact;
205  QString values;
206  QString extent;
207 
208  if ( theOrigin & MinMaxEstimated )
209  {
210  est_exact = tr( "Estimated" );
211  }
212  else if ( theOrigin & MinMaxExact )
213  {
214  est_exact = tr( "Exact" );
215  }
216 
217  if ( theOrigin & MinMaxMinMax )
218  {
219  values = tr( "min / max" );
220  }
221  else if ( theOrigin & MinMaxCumulativeCut )
222  {
223  values = tr( "cumulative cut" );
224  }
225  else if ( theOrigin & MinMaxStdDev )
226  {
227  values = tr( "standard deviation" );
228  }
229 
230  if ( theOrigin & MinMaxFullExtent )
231  {
232  extent = tr( "full extent" );
233  }
234  else if ( theOrigin & MinMaxSubExtent )
235  {
236  extent = tr( "sub extent" );
237  }
238 
239  label = QCoreApplication::translate( "QgsRasterRenderer", "%1 %2 of %3.",
240  "min/max origin label in raster properties, where %1 - estimated/exact, %2 - values (min/max, stddev, etc.), %3 - extent" )
241  .arg( est_exact,
242  values,
243  extent );
244  return label;
245 }
246 
248 {
249  if ( theName.contains( "Unknown" ) )
250  {
251  return MinMaxUnknown;
252  }
253  else if ( theName.contains( "User" ) )
254  {
255  return MinMaxUser;
256  }
257 
258  int origin = 0;
259 
260  if ( theName.contains( "MinMax" ) )
261  {
262  origin |= MinMaxMinMax;
263  }
264  else if ( theName.contains( "CumulativeCut" ) )
265  {
266  origin |= MinMaxCumulativeCut;
267  }
268  else if ( theName.contains( "StdDev" ) )
269  {
270  origin |= MinMaxStdDev;
271  }
272 
273  if ( theName.contains( "FullExtent" ) )
274  {
275  origin |= MinMaxFullExtent;
276  }
277  else if ( theName.contains( "SubExtent" ) )
278  {
279  origin |= MinMaxSubExtent;
280  }
281 
282  if ( theName.contains( "Estimated" ) )
283  {
284  origin |= MinMaxEstimated;
285  }
286  else if ( theName.contains( "Exact" ) )
287  {
288  origin |= MinMaxExact;
289  }
290  return origin;
291 }
virtual int bandCount() const =0
Get number of bands.
bool isEmpty() const
True if there are no entries in the pixel lists except the nodata value.
Unknown or unspecified type.
Definition: qgis.h:135
QString attribute(const QString &name, const QString &defValue) const
double opacity() const
static bool typeIsNumeric(QGis::DataType type)
Returns true if data type is numeric.
virtual QgsRasterInterface * input() const
Current input.
void copyCommonProperties(const QgsRasterRenderer *other)
Copies common properties like opacity / transparency data from other renderer.
static int minMaxOriginFromName(const QString &theName)
double toDouble(bool *ok) const
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:353
const QgsRasterTransparency * rasterTransparency() const
void readXML(const QDomElement &rendererElem) override
Sets base class members from xml.
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value.
static const QRgb NODATA_COLOR
virtual bool setInput(QgsRasterInterface *input) override
Set input.
QString number(int n, int base)
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:150
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
void setAttribute(const QString &name, const QString &value)
int toInt(bool *ok, int base) const
static QString minMaxOriginLabel(int theOrigin)
bool usesTransparency() const
void _writeXML(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXML method of subclasses) ...
int mAlphaBand
Read alpha value from band.
virtual QGis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
void setAlphaBand(int band)
virtual int bandCount() const override
Get number of bands.
Base class for processing filters like renderers, reprojector, resampler etc.
bool contains(QChar ch, Qt::CaseSensitivity cs) const
bool isNull() const
virtual QgsRectangle extent()
Get the extent of the interface.
QDomElement firstChildElement(const QString &tagName) const
QString translate(const char *context, const char *sourceText, const char *disambiguation, Encoding encoding)
static QString minMaxOriginName(int theOrigin)
DataType
Raster data types.
Definition: qgis.h:133
void readXML(const QDomElement &elem)
QgsRasterRenderer(QgsRasterInterface *input=nullptr, const QString &type="")
double mOpacity
Global alpha value (0-1)
void writeXML(QDomDocument &doc, QDomElement &parentElem) const
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
void setOpacity(double opacity)
QgsRasterInterface * mInput
void setRasterTransparency(QgsRasterTransparency *t)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
Raster renderer pipe that applies colors to a raster.
virtual QGis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.