QGIS API Documentation  3.13.0-Master (b73bd58cfb)
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 "qgssymbollayerutils.h"
22 
23 #include <QCoreApplication>
24 #include <QDomDocument>
25 #include <QDomElement>
26 #include <QImage>
27 #include <QPainter>
28 
29 // See #9101 before any change of NODATA_COLOR!
30 const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 );
31 
33  : QgsRasterInterface( input )
34  , mType( type )
35 {
36 }
37 
39 {
40  delete mRasterTransparency;
41 }
42 
44 {
45  if ( mOn ) return 1;
46 
47  if ( mInput ) return mInput->bandCount();
48 
49  return 0;
50 }
51 
53 {
54  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
55 
56  if ( mOn ) return Qgis::ARGB32_Premultiplied;
57 
58  if ( mInput ) return mInput->dataType( bandNo );
59 
60  return Qgis::UnknownDataType;
61 }
62 
64 {
65  // Renderer can only work with numerical values in at least 1 band
66  if ( !input ) return false;
67 
68  if ( !mOn )
69  {
70  // In off mode we can connect to anything
71  mInput = input;
72  return true;
73  }
74 
75  for ( int i = 1; i <= input->bandCount(); i++ )
76  {
77  const Qgis::DataType bandType = input->dataType( i );
78  // we always allow unknown data types to connect - otherwise invalid layers cannot setup
79  // their original rendering pipe and this information is lost
80  if ( bandType != Qgis::UnknownDataType && !QgsRasterBlock::typeIsNumeric( bandType ) )
81  {
82  return false;
83  }
84  }
85  mInput = input;
86  return true;
87 }
88 
90 {
91  if ( !mInput )
92  {
93  return true;
94  }
95  return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty() ) || !qgsDoubleNear( mOpacity, 1.0 ) );
96 }
97 
99 {
100  delete mRasterTransparency;
102 }
103 
104 void QgsRasterRenderer::_writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const
105 {
106  if ( rasterRendererElem.isNull() )
107  {
108  return;
109  }
110 
111  rasterRendererElem.setAttribute( QStringLiteral( "type" ), mType );
112  rasterRendererElem.setAttribute( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
113  rasterRendererElem.setAttribute( QStringLiteral( "alphaBand" ), mAlphaBand );
114  rasterRendererElem.setAttribute( QStringLiteral( "nodataColor" ), mNodataColor.isValid() ? QgsSymbolLayerUtils::encodeColor( mNodataColor ) : QString() );
115 
116  if ( mRasterTransparency )
117  {
118  mRasterTransparency->writeXml( doc, rasterRendererElem );
119  }
120 
121  QDomElement minMaxOriginElem = doc.createElement( QStringLiteral( "minMaxOrigin" ) );
122  mMinMaxOrigin.writeXml( doc, minMaxOriginElem );
123  rasterRendererElem.appendChild( minMaxOriginElem );
124 }
125 
127 {
128  if ( !mNodataColor.isValid() )
129  return NODATA_COLOR;
130  else
131  return mNodataColor.rgba();
132 }
133 
134 void QgsRasterRenderer::readXml( const QDomElement &rendererElem )
135 {
136  if ( rendererElem.isNull() )
137  {
138  return;
139  }
140 
141  mType = rendererElem.attribute( QStringLiteral( "type" ) );
142  mOpacity = rendererElem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1.0" ) ).toDouble();
143  mAlphaBand = rendererElem.attribute( QStringLiteral( "alphaBand" ), QStringLiteral( "-1" ) ).toInt();
144  const QString colorEncoded = rendererElem.attribute( QStringLiteral( "nodataColor" ) );
145  mNodataColor = !colorEncoded.isEmpty() ? QgsSymbolLayerUtils::decodeColor( colorEncoded ) : QColor();
146 
147  QDomElement rasterTransparencyElem = rendererElem.firstChildElement( QStringLiteral( "rasterTransparency" ) );
148  if ( !rasterTransparencyElem.isNull() )
149  {
150  delete mRasterTransparency;
152  mRasterTransparency->readXml( rasterTransparencyElem );
153  }
154 
155  QDomElement minMaxOriginElem = rendererElem.firstChildElement( QStringLiteral( "minMaxOrigin" ) );
156  if ( !minMaxOriginElem.isNull() )
157  {
158  mMinMaxOrigin.readXml( minMaxOriginElem );
159  }
160 }
161 
162 void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer *other, bool copyMinMaxOrigin )
163 {
164  if ( !other )
165  return;
166 
167  setOpacity( other->opacity() );
168  setAlphaBand( other->alphaBand() );
169  setRasterTransparency( other->rasterTransparency() ? new QgsRasterTransparency( *other->rasterTransparency() ) : nullptr );
170  setNodataColor( other->nodataColor() );
171  if ( copyMinMaxOrigin )
172  setMinMaxOrigin( other->minMaxOrigin() );
173 }
174 
175 void QgsRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap & ) const
176 {
177  QDomElement rasterSymbolizerElem = doc.createElement( QStringLiteral( "sld:RasterSymbolizer" ) );
178  element.appendChild( rasterSymbolizerElem );
179 
180  // add opacity only is different from default
181  if ( !qgsDoubleNear( opacity(), 1.0 ) )
182  {
183  QDomElement opacityElem = doc.createElement( QStringLiteral( "sld:Opacity" ) );
184  opacityElem.appendChild( doc.createTextNode( QString::number( opacity() ) ) );
185  rasterSymbolizerElem.appendChild( opacityElem );
186  }
187 }
188 
190 {
191  return true;
192 }
virtual int bandCount() const =0
Gets number of bands.
bool isEmpty() const
True if there are no entries in the pixel lists except the nodata value.
virtual void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
QColor nodataColor() const
Returns the color to use for shading nodata pixels.
double opacity() const
Returns the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
static bool typeIsNumeric(Qgis::DataType type)
Returns true if data type is numeric.
virtual QgsRasterInterface * input() const
Current input.
QgsRasterRenderer(QgsRasterInterface *input=nullptr, const QString &type=QString())
Constructor for QgsRasterRenderer.
DataType
Raster data types.
Definition: qgis.h:101
QgsRasterMinMaxOrigin mMinMaxOrigin
Origin of min/max values.
const QgsRasterMinMaxOrigin & minMaxOrigin() const
Returns const reference to origin of min/max values.
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
An interface for classes which can visit style entity (e.g.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:694
const QgsRasterTransparency * rasterTransparency() const
static QString encodeColor(const QColor &color)
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:116
static const QRgb NODATA_COLOR
bool setInput(QgsRasterInterface *input) override
Set input.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses) ...
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
void readXml(const QDomElement &elem)
Deserialize object.
bool usesTransparency() const
Unknown or unspecified type.
Definition: qgis.h:103
void readXml(const QDomElement &elem)
Reads the transparency information from an XML document.
int mAlphaBand
Read alpha value from band.
void setAlphaBand(int band)
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
int bandCount() const override
Gets number of bands.
Qgis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.
Base class for processing filters like renderers, reprojector, resampler etc.
void setMinMaxOrigin(const QgsRasterMinMaxOrigin &origin)
Sets origin of min/max values.
void setNodataColor(const QColor &color)
Sets the color to use for shading nodata pixels.
~QgsRasterRenderer() override
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Writes the transparency information to an XML document.
QRgb renderColorForNodataPixel() const
Returns the color for the renderer to use to represent nodata pixels.
double mOpacity
Global alpha value (0-1)
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1...
QgsRasterInterface * mInput
void setRasterTransparency(QgsRasterTransparency *t)
Raster renderer pipe that applies colors to a raster.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Serialize object.
static QColor decodeColor(const QString &str)