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