QGIS API Documentation 3.29.0-Master (006c3c0232)
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"
20
21#include "qgssymbollayerutils.h"
23
24#include <QCoreApplication>
25#include <QDomDocument>
26#include <QDomElement>
27#include <QImage>
28#include <QPainter>
29
30// See #9101 before any change of NODATA_COLOR!
31const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 );
32
34 : QgsRasterInterface( input )
35 , mType( type )
36{
37}
38
40{
42}
43
45{
46 if ( mOn ) return 1;
47
48 if ( mInput ) return mInput->bandCount();
49
50 return 0;
51}
52
54{
55 QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
56
58
59 if ( mInput ) return mInput->dataType( bandNo );
60
62}
63
64Qgis::RasterRendererFlags QgsRasterRenderer::flags() const
65{
66 return Qgis::RasterRendererFlags();
67}
68
70{
71 return false;
72}
73
75{
76 // Renderer can only work with numerical values in at least 1 band
77 if ( !input ) return false;
78
79 if ( !mOn )
80 {
81 // In off mode we can connect to anything
82 mInput = input;
83 return true;
84 }
85
86 for ( int i = 1; i <= input->bandCount(); i++ )
87 {
88 const Qgis::DataType bandType = input->dataType( i );
89 // we always allow unknown data types to connect - otherwise invalid layers cannot setup
90 // their original rendering pipe and this information is lost
91 if ( bandType != Qgis::DataType::UnknownDataType && !QgsRasterBlock::typeIsNumeric( bandType ) )
92 {
93 return false;
94 }
95 }
96 mInput = input;
97 return true;
98}
99
101{
102 if ( !mInput )
103 {
104 return true;
105 }
106 return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty() ) || !qgsDoubleNear( mOpacity, 1.0 ) );
107}
108
110{
111 delete mRasterTransparency;
113}
114
115QList< QPair< QString, QColor > > QgsRasterRenderer::legendSymbologyItems() const
116{
117 return QList< QPair< QString, QColor > >();
118}
119
120QList<QgsLayerTreeModelLegendNode *> QgsRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
121{
122 QList<QgsLayerTreeModelLegendNode *> nodes;
123
124 const QList< QPair< QString, QColor > > rasterItemList = legendSymbologyItems();
125 if ( rasterItemList.isEmpty() )
126 return nodes;
127
128 // Paletted raster may have many colors, for example UInt16 may have 65536 colors
129 // and it is very slow, so we limit max count
130 int count = 0;
131 const int max_count = 1000;
132
133 for ( auto itemIt = rasterItemList.constBegin(); itemIt != rasterItemList.constEnd(); ++itemIt, ++count )
134 {
135 nodes << new QgsRasterSymbolLegendNode( nodeLayer, itemIt->second, itemIt->first );
136
137 if ( count == max_count )
138 {
139 const QString label = tr( "following %1 items\nnot displayed" ).arg( rasterItemList.size() - max_count );
140 nodes << new QgsSimpleLegendNode( nodeLayer, label );
141 break;
142 }
143 }
144
145 return nodes;
146}
147
148void QgsRasterRenderer::_writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const
149{
150 if ( rasterRendererElem.isNull() )
151 {
152 return;
153 }
154
155 rasterRendererElem.setAttribute( QStringLiteral( "type" ), mType );
156 rasterRendererElem.setAttribute( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
157 rasterRendererElem.setAttribute( QStringLiteral( "alphaBand" ), mAlphaBand );
158 rasterRendererElem.setAttribute( QStringLiteral( "nodataColor" ), mNodataColor.isValid() ? QgsSymbolLayerUtils::encodeColor( mNodataColor ) : QString() );
159
161 {
162 mRasterTransparency->writeXml( doc, rasterRendererElem );
163 }
164
165 QDomElement minMaxOriginElem = doc.createElement( QStringLiteral( "minMaxOrigin" ) );
166 mMinMaxOrigin.writeXml( doc, minMaxOriginElem );
167 rasterRendererElem.appendChild( minMaxOriginElem );
168}
169
171{
172 if ( !mNodataColor.isValid() )
173 return NODATA_COLOR;
174 else
175 return mNodataColor.rgba();
176}
177
178void QgsRasterRenderer::readXml( const QDomElement &rendererElem )
179{
180 if ( rendererElem.isNull() )
181 {
182 return;
183 }
184
185 mType = rendererElem.attribute( QStringLiteral( "type" ) );
186 mOpacity = rendererElem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1.0" ) ).toDouble();
187 mAlphaBand = rendererElem.attribute( QStringLiteral( "alphaBand" ), QStringLiteral( "-1" ) ).toInt();
188 const QString colorEncoded = rendererElem.attribute( QStringLiteral( "nodataColor" ) );
189 mNodataColor = !colorEncoded.isEmpty() ? QgsSymbolLayerUtils::decodeColor( colorEncoded ) : QColor();
190
191 const QDomElement rasterTransparencyElem = rendererElem.firstChildElement( QStringLiteral( "rasterTransparency" ) );
192 if ( !rasterTransparencyElem.isNull() )
193 {
194 delete mRasterTransparency;
196 mRasterTransparency->readXml( rasterTransparencyElem );
197 }
198
199 const QDomElement minMaxOriginElem = rendererElem.firstChildElement( QStringLiteral( "minMaxOrigin" ) );
200 if ( !minMaxOriginElem.isNull() )
201 {
202 mMinMaxOrigin.readXml( minMaxOriginElem );
203 }
204}
205
206void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer *other, bool copyMinMaxOrigin )
207{
208 if ( !other )
209 return;
210
211 setOpacity( other->opacity() );
212 setAlphaBand( other->alphaBand() );
214 setNodataColor( other->nodataColor() );
215 if ( copyMinMaxOrigin )
216 setMinMaxOrigin( other->minMaxOrigin() );
217}
218
219void QgsRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap & ) const
220{
221 QDomElement rasterSymbolizerElem = doc.createElement( QStringLiteral( "sld:RasterSymbolizer" ) );
222 element.appendChild( rasterSymbolizerElem );
223
224 // add opacity only is different from default
225 if ( !qgsDoubleNear( opacity(), 1.0 ) )
226 {
227 QDomElement opacityElem = doc.createElement( QStringLiteral( "sld:Opacity" ) );
228 opacityElem.appendChild( doc.createTextNode( QString::number( opacity() ) ) );
229 rasterSymbolizerElem.appendChild( opacityElem );
230 }
231}
232
234{
235 return true;
236}
DataType
Raster data types.
Definition: qgis.h:129
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ UnknownDataType
Unknown or unspecified type.
Layer tree node points to a map layer.
static bool typeIsNumeric(Qgis::DataType type)
Returns true if data type is numeric.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
virtual int bandCount() const =0
Gets number of bands.
QgsRasterInterface * mInput
virtual QgsRasterInterface * input() const
Current input.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Serialize object.
void readXml(const QDomElement &elem)
Deserialize object.
Raster renderer pipe that applies colors to a raster.
QColor nodataColor() const
Returns the color to use for shading nodata pixels.
QgsRasterRenderer(QgsRasterInterface *input=nullptr, const QString &type=QString())
Constructor for QgsRasterRenderer.
virtual bool canCreateRasterAttributeTable() const
Returns true if the renderer is suitable for attribute table creation.
double mOpacity
Global alpha value (0-1)
bool setInput(QgsRasterInterface *input) override
Set input.
void setMinMaxOrigin(const QgsRasterMinMaxOrigin &origin)
Sets origin of min/max values.
~QgsRasterRenderer() override
int mAlphaBand
Read alpha value from band.
QRgb renderColorForNodataPixel() const
Returns the color for the renderer to use to represent nodata pixels.
const QgsRasterTransparency * rasterTransparency() const
virtual Qgis::RasterRendererFlags flags() const
Returns flags which dictate renderer behavior.
const QgsRasterMinMaxOrigin & minMaxOrigin() const
Returns const reference to origin of min/max values.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses)
int bandCount() const override
Gets number of bands.
double opacity() const
Returns the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
void setAlphaBand(int band)
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
QgsRasterMinMaxOrigin mMinMaxOrigin
Origin of min/max values.
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
virtual QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer)
Creates a set of legend nodes representing the renderer.
void setRasterTransparency(QgsRasterTransparency *t)
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
bool usesTransparency() const
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
static const QRgb NODATA_COLOR
virtual void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
void setNodataColor(const QColor &color)
Sets the color to use for shading nodata pixels.
virtual QList< QPair< QString, QColor > > legendSymbologyItems() const
Returns symbology items if provided by renderer.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Qgis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.
Implementation of legend node interface for displaying raster legend entries.
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Writes the transparency information to an XML document.
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.
Implementation of legend node interface for displaying arbitrary label with icon.
An interface for classes which can visit style entity (e.g.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2915
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39