QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
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 "qgscolorutils.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
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
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 return -1;
103}
104
106{
107 return false;
108}
109
111{
112 if ( !mInput )
113 {
114 return true;
115 }
116 return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty() ) || !qgsDoubleNear( mOpacity, 1.0 ) );
117}
118
124
125QList< QPair< QString, QColor > > QgsRasterRenderer::legendSymbologyItems() const
126{
127 return QList< QPair< QString, QColor > >();
128}
129
130QList<QgsLayerTreeModelLegendNode *> QgsRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
131{
132 QList<QgsLayerTreeModelLegendNode *> nodes;
133
134 const QList< QPair< QString, QColor > > rasterItemList = legendSymbologyItems();
135 if ( rasterItemList.isEmpty() )
136 return nodes;
137
138 // Paletted raster may have many colors, for example UInt16 may have 65536 colors
139 // and it is very slow, so we limit max count
140 int count = 0;
141 const int max_count = 1000;
142
143 for ( auto itemIt = rasterItemList.constBegin(); itemIt != rasterItemList.constEnd(); ++itemIt, ++count )
144 {
145 nodes << new QgsRasterSymbolLegendNode( nodeLayer, itemIt->second, itemIt->first );
146
147 if ( count == max_count )
148 {
149 const QString label = tr( "following %n item(s) not displayed", nullptr, rasterItemList.size() - max_count );
150 nodes << new QgsSimpleLegendNode( nodeLayer, label );
151 break;
152 }
153 }
154
155 return nodes;
156}
157
158void QgsRasterRenderer::_writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const
159{
160 if ( rasterRendererElem.isNull() )
161 {
162 return;
163 }
164
165 rasterRendererElem.setAttribute( QStringLiteral( "type" ), mType );
166 rasterRendererElem.setAttribute( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
167 rasterRendererElem.setAttribute( QStringLiteral( "alphaBand" ), mAlphaBand );
168 rasterRendererElem.setAttribute( QStringLiteral( "nodataColor" ), mNodataColor.isValid() ? QgsColorUtils::colorToString( mNodataColor ) : QString() );
169
171 {
172 mRasterTransparency->writeXml( doc, rasterRendererElem );
173 }
174
175 QDomElement minMaxOriginElem = doc.createElement( QStringLiteral( "minMaxOrigin" ) );
176 mMinMaxOrigin.writeXml( doc, minMaxOriginElem );
177 rasterRendererElem.appendChild( minMaxOriginElem );
178}
179
181{
182 if ( !mNodataColor.isValid() )
183 return NODATA_COLOR;
184 else
185 return mNodataColor.rgba();
186}
187
188void QgsRasterRenderer::readXml( const QDomElement &rendererElem )
189{
190 if ( rendererElem.isNull() )
191 {
192 return;
193 }
194
195 mType = rendererElem.attribute( QStringLiteral( "type" ) );
196 mOpacity = rendererElem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1.0" ) ).toDouble();
197 mAlphaBand = rendererElem.attribute( QStringLiteral( "alphaBand" ), QStringLiteral( "-1" ) ).toInt();
198 const QString colorEncoded = rendererElem.attribute( QStringLiteral( "nodataColor" ) );
199 mNodataColor = !colorEncoded.isEmpty() ? QgsColorUtils::colorFromString( colorEncoded ) : QColor();
200
201 const QDomElement rasterTransparencyElem = rendererElem.firstChildElement( QStringLiteral( "rasterTransparency" ) );
202 if ( !rasterTransparencyElem.isNull() )
203 {
204 delete mRasterTransparency;
206 mRasterTransparency->readXml( rasterTransparencyElem );
207 }
208
209 const QDomElement minMaxOriginElem = rendererElem.firstChildElement( QStringLiteral( "minMaxOrigin" ) );
210 if ( !minMaxOriginElem.isNull() )
211 {
212 mMinMaxOrigin.readXml( minMaxOriginElem );
213 }
214}
215
216void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer *other, bool copyMinMaxOrigin )
217{
218 if ( !other )
219 return;
220
221 setOpacity( other->opacity() );
222 setAlphaBand( other->alphaBand() );
224 setNodataColor( other->nodataColor() );
225 if ( copyMinMaxOrigin )
226 setMinMaxOrigin( other->minMaxOrigin() );
227}
228
229void QgsRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap & ) const
230{
231 QDomElement rasterSymbolizerElem = doc.createElement( QStringLiteral( "sld:RasterSymbolizer" ) );
232 element.appendChild( rasterSymbolizerElem );
233
234 // add opacity only is different from default
235 if ( !qgsDoubleNear( opacity(), 1.0 ) )
236 {
237 QDomElement opacityElem = doc.createElement( QStringLiteral( "sld:Opacity" ) );
238 opacityElem.appendChild( doc.createTextNode( QString::number( opacity() ) ) );
239 rasterSymbolizerElem.appendChild( opacityElem );
240 }
241}
242
244{
245 return true;
246}
247
259
260bool QgsRasterRenderer::refresh( const QgsRectangle &extent, const QList<double> &, const QList<double> &, bool forceRefresh )
261{
262 if ( !needsRefresh( extent ) && !forceRefresh )
263 {
264 return false;
265 }
266
268 return true;
269}
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
Definition qgis.h:1422
@ NotSet
User defined.
DataType
Raster data types.
Definition qgis.h:351
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ UnknownDataType
Unknown or unspecified type.
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
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 QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
Qgis::RasterRangeExtent extent() const
Returns the raster extent.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
Serialize object.
void readXml(const QDomElement &elem)
Deserialize object.
Qgis::RasterRangeLimit limits() const
Returns the raster limits.
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.
virtual int inputBand() const
Returns the input band for the renderer, or -1 if no input band is available.
int mAlphaBand
Read alpha value from band.
QgsRectangle mLastRectangleUsedByRefreshContrastEnhancementIfNeeded
To save computations and possible infinite cycle of notifications.
virtual bool setInputBand(int band)
Attempts to set the input band for the renderer.
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.
virtual bool refresh(const QgsRectangle &extent, const QList< double > &min, const QList< double > &max, bool forceRefresh=false)
Refreshes the renderer according to the min and max values associated with the extent.
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
bool needsRefresh(const QgsRectangle &extent) const
Checks if the renderer needs to be refreshed according to extent.
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.
A rectangle specified with double values.
Implementation of legend node interface for displaying arbitrary label with icon.
An interface for classes which can visit style entity (e.g.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:6066
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39