QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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"
19
20#include <memory>
21
22#include "qgscolorutils.h"
25#include "qgssldexportcontext.h"
26
27#include <QCoreApplication>
28#include <QDomDocument>
29#include <QDomElement>
30#include <QImage>
31#include <QPainter>
32
33// See #9101 before any change of NODATA_COLOR!
34const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 );
35
41
46
48{
49 if ( mOn ) return 1;
50
51 if ( mInput ) return mInput->bandCount();
52
53 return 0;
54}
55
57{
58 QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
59
61
62 if ( mInput ) return mInput->dataType( bandNo );
63
65}
66
71
73{
74 return false;
75}
76
78{
79 // Renderer can only work with numerical values in at least 1 band
80 if ( !input ) return false;
81
82 if ( !mOn )
83 {
84 // In off mode we can connect to anything
85 mInput = input;
86 return true;
87 }
88
89 for ( int i = 1; i <= input->bandCount(); i++ )
90 {
91 const Qgis::DataType bandType = input->dataType( i );
92 // we always allow unknown data types to connect - otherwise invalid layers cannot setup
93 // their original rendering pipe and this information is lost
94 if ( bandType != Qgis::DataType::UnknownDataType && !QgsRasterBlock::typeIsNumeric( bandType ) )
95 {
96 return false;
97 }
98 }
99 mInput = input;
100 return true;
101}
102
104{
105 return -1;
106}
107
109{
110 return false;
111}
112
114{
115 if ( !mInput )
116 {
117 return true;
118 }
119 return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty() ) || !qgsDoubleNear( mOpacity, 1.0 ) );
120}
121
127
128QList< QPair< QString, QColor > > QgsRasterRenderer::legendSymbologyItems() const
129{
130 return QList< QPair< QString, QColor > >();
131}
132
133QList<QgsLayerTreeModelLegendNode *> QgsRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
134{
135 QList<QgsLayerTreeModelLegendNode *> nodes;
136
137 const QList< QPair< QString, QColor > > rasterItemList = legendSymbologyItems();
138 if ( rasterItemList.isEmpty() )
139 return nodes;
140
141 // Paletted raster may have many colors, for example UInt16 may have 65536 colors
142 // and it is very slow, so we limit max count
143 int count = 0;
144 const int max_count = 1000;
145
146 for ( auto itemIt = rasterItemList.constBegin(); itemIt != rasterItemList.constEnd(); ++itemIt, ++count )
147 {
148 nodes << new QgsRasterSymbolLegendNode( nodeLayer, itemIt->second, itemIt->first );
149
150 if ( count == max_count )
151 {
152 const QString label = tr( "following %n item(s) not displayed", nullptr, rasterItemList.size() - max_count );
153 nodes << new QgsSimpleLegendNode( nodeLayer, label );
154 break;
155 }
156 }
157
158 return nodes;
159}
160
161void QgsRasterRenderer::_writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const
162{
163 if ( rasterRendererElem.isNull() )
164 {
165 return;
166 }
167
168 rasterRendererElem.setAttribute( QStringLiteral( "type" ), mType );
169 rasterRendererElem.setAttribute( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
170 rasterRendererElem.setAttribute( QStringLiteral( "alphaBand" ), mAlphaBand );
171 rasterRendererElem.setAttribute( QStringLiteral( "nodataColor" ), mNodataColor.isValid() ? QgsColorUtils::colorToString( mNodataColor ) : QString() );
172
174 {
175 mRasterTransparency->writeXml( doc, rasterRendererElem );
176 }
177
178 QDomElement minMaxOriginElem = doc.createElement( QStringLiteral( "minMaxOrigin" ) );
179 mMinMaxOrigin.writeXml( doc, minMaxOriginElem );
180 rasterRendererElem.appendChild( minMaxOriginElem );
181}
182
184{
185 if ( !mNodataColor.isValid() )
186 return NODATA_COLOR;
187 else
188 return mNodataColor.rgba();
189}
190
191void QgsRasterRenderer::readXml( const QDomElement &rendererElem )
192{
193 if ( rendererElem.isNull() )
194 {
195 return;
196 }
197
198 mType = rendererElem.attribute( QStringLiteral( "type" ) );
199 mOpacity = rendererElem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1.0" ) ).toDouble();
200 mAlphaBand = rendererElem.attribute( QStringLiteral( "alphaBand" ), QStringLiteral( "-1" ) ).toInt();
201 const QString colorEncoded = rendererElem.attribute( QStringLiteral( "nodataColor" ) );
202 mNodataColor = !colorEncoded.isEmpty() ? QgsColorUtils::colorFromString( colorEncoded ) : QColor();
203
204 const QDomElement rasterTransparencyElem = rendererElem.firstChildElement( QStringLiteral( "rasterTransparency" ) );
205 if ( !rasterTransparencyElem.isNull() )
206 {
207 mRasterTransparency = std::make_unique<QgsRasterTransparency>( );
208
209 mRasterTransparency->readXml( rasterTransparencyElem );
210 }
211
212 const QDomElement minMaxOriginElem = rendererElem.firstChildElement( QStringLiteral( "minMaxOrigin" ) );
213 if ( !minMaxOriginElem.isNull() )
214 {
215 mMinMaxOrigin.readXml( minMaxOriginElem );
216 }
217}
218
219void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer *other, bool copyMinMaxOrigin )
220{
221 if ( !other )
222 return;
223
224 setOpacity( other->opacity() );
225 setAlphaBand( other->alphaBand() );
227 setNodataColor( other->nodataColor() );
228 if ( copyMinMaxOrigin )
229 setMinMaxOrigin( other->minMaxOrigin() );
230}
231
232void QgsRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
233{
234 QgsSldExportContext context;
235 context.setExtraProperties( props );
236 toSld( doc, element, context );
237}
238
239bool QgsRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, QgsSldExportContext & ) const
240{
241 QDomElement rasterSymbolizerElem = doc.createElement( QStringLiteral( "sld:RasterSymbolizer" ) );
242 element.appendChild( rasterSymbolizerElem );
243
244 // add opacity only is different from default
245 if ( !qgsDoubleNear( opacity(), 1.0 ) )
246 {
247 QDomElement opacityElem = doc.createElement( QStringLiteral( "sld:Opacity" ) );
248 opacityElem.appendChild( doc.createTextNode( QString::number( opacity() ) ) );
249 rasterSymbolizerElem.appendChild( opacityElem );
250 }
251 return true;
252}
253
255{
256 return true;
257}
258
260{
264 {
265 return true;
266 }
267
268 return false;
269}
270
271bool QgsRasterRenderer::refresh( const QgsRectangle &extent, const QList<double> &, const QList<double> &, bool forceRefresh )
272{
273 if ( !needsRefresh( extent ) && !forceRefresh )
274 {
275 return false;
276 }
277
279 return true;
280}
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
Definition qgis.h:1512
@ NotSet
User defined.
Definition qgis.h:1545
DataType
Raster data types.
Definition qgis.h:372
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition qgis.h:387
@ UnknownDataType
Unknown or unspecified type.
Definition qgis.h:373
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
Definition qgis.h:1563
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 a data type is numeric.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
QgsRasterInterface * mInput
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
QColor nodataColor() const
Returns the color to use for shading nodata pixels.
QgsRasterRenderer(QgsRasterInterface *input=nullptr, const QString &type=QString())
Constructor for QgsRasterRenderer.
virtual QString type() const
Returns a unique string representation of the renderer type.
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.
std::unique_ptr< QgsRasterTransparency > mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
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.
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 Q_DECL_DEPRECATED 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...
A rectangle specified with double values.
Implementation of legend node interface for displaying arbitrary labels with icons.
Holds SLD export options and other information related to SLD export of a QGIS layer style.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
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:6607
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61