QGIS API Documentation 3.99.0-Master (d270888f95f)
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#include <QString>
33
34using namespace Qt::StringLiterals;
35
36// See #9101 before any change of NODATA_COLOR!
37const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 );
38
44
49
51{
52 if ( mOn ) return 1;
53
54 if ( mInput ) return mInput->bandCount();
55
56 return 0;
57}
58
60{
61 QgsDebugMsgLevel( u"Entered"_s, 4 );
62
64
65 if ( mInput ) return mInput->dataType( bandNo );
66
68}
69
74
76{
77 return false;
78}
79
81{
82 // Renderer can only work with numerical values in at least 1 band
83 if ( !input ) return false;
84
85 if ( !mOn )
86 {
87 // In off mode we can connect to anything
88 mInput = input;
89 return true;
90 }
91
92 for ( int i = 1; i <= input->bandCount(); i++ )
93 {
94 const Qgis::DataType bandType = input->dataType( i );
95 // we always allow unknown data types to connect - otherwise invalid layers cannot setup
96 // their original rendering pipe and this information is lost
97 if ( bandType != Qgis::DataType::UnknownDataType && !QgsRasterBlock::typeIsNumeric( bandType ) )
98 {
99 return false;
100 }
101 }
102 mInput = input;
103 return true;
104}
105
107{
108 return -1;
109}
110
112{
113 return false;
114}
115
117{
118 if ( !mInput )
119 {
120 return true;
121 }
122 return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty() ) || !qgsDoubleNear( mOpacity, 1.0 ) );
123}
124
130
131QList< QPair< QString, QColor > > QgsRasterRenderer::legendSymbologyItems() const
132{
133 return QList< QPair< QString, QColor > >();
134}
135
136QList<QgsLayerTreeModelLegendNode *> QgsRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
137{
138 QList<QgsLayerTreeModelLegendNode *> nodes;
139
140 const QList< QPair< QString, QColor > > rasterItemList = legendSymbologyItems();
141 if ( rasterItemList.isEmpty() )
142 return nodes;
143
144 // Paletted raster may have many colors, for example UInt16 may have 65536 colors
145 // and it is very slow, so we limit max count
146 int count = 0;
147 const int max_count = 1000;
148
149 for ( auto itemIt = rasterItemList.constBegin(); itemIt != rasterItemList.constEnd(); ++itemIt, ++count )
150 {
151 nodes << new QgsRasterSymbolLegendNode( nodeLayer, itemIt->second, itemIt->first );
152
153 if ( count == max_count )
154 {
155 const QString label = tr( "following %n item(s) not displayed", nullptr, rasterItemList.size() - max_count );
156 nodes << new QgsSimpleLegendNode( nodeLayer, label );
157 break;
158 }
159 }
160
161 return nodes;
162}
163
164void QgsRasterRenderer::_writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const
165{
166 if ( rasterRendererElem.isNull() )
167 {
168 return;
169 }
170
171 rasterRendererElem.setAttribute( u"type"_s, mType );
172 rasterRendererElem.setAttribute( u"opacity"_s, QString::number( mOpacity ) );
173 rasterRendererElem.setAttribute( u"alphaBand"_s, mAlphaBand );
174 rasterRendererElem.setAttribute( u"nodataColor"_s, mNodataColor.isValid() ? QgsColorUtils::colorToString( mNodataColor ) : QString() );
175
177 {
178 mRasterTransparency->writeXml( doc, rasterRendererElem );
179 }
180
181 QDomElement minMaxOriginElem = doc.createElement( u"minMaxOrigin"_s );
182 mMinMaxOrigin.writeXml( doc, minMaxOriginElem );
183 rasterRendererElem.appendChild( minMaxOriginElem );
184}
185
187{
188 if ( !mNodataColor.isValid() )
189 return NODATA_COLOR;
190 else
191 return mNodataColor.rgba();
192}
193
194void QgsRasterRenderer::readXml( const QDomElement &rendererElem )
195{
196 if ( rendererElem.isNull() )
197 {
198 return;
199 }
200
201 mType = rendererElem.attribute( u"type"_s );
202 mOpacity = rendererElem.attribute( u"opacity"_s, u"1.0"_s ).toDouble();
203 mAlphaBand = rendererElem.attribute( u"alphaBand"_s, u"-1"_s ).toInt();
204 const QString colorEncoded = rendererElem.attribute( u"nodataColor"_s );
205 mNodataColor = !colorEncoded.isEmpty() ? QgsColorUtils::colorFromString( colorEncoded ) : QColor();
206
207 const QDomElement rasterTransparencyElem = rendererElem.firstChildElement( u"rasterTransparency"_s );
208 if ( !rasterTransparencyElem.isNull() )
209 {
210 mRasterTransparency = std::make_unique<QgsRasterTransparency>( );
211
212 mRasterTransparency->readXml( rasterTransparencyElem );
213 }
214
215 const QDomElement minMaxOriginElem = rendererElem.firstChildElement( u"minMaxOrigin"_s );
216 if ( !minMaxOriginElem.isNull() )
217 {
218 mMinMaxOrigin.readXml( minMaxOriginElem );
219 }
220}
221
222void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer *other, bool copyMinMaxOrigin )
223{
224 if ( !other )
225 return;
226
227 setOpacity( other->opacity() );
228 setAlphaBand( other->alphaBand() );
230 setNodataColor( other->nodataColor() );
231 if ( copyMinMaxOrigin )
232 setMinMaxOrigin( other->minMaxOrigin() );
233}
234
235void QgsRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
236{
237 QgsSldExportContext context;
238 context.setExtraProperties( props );
239 toSld( doc, element, context );
240}
241
242bool QgsRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, QgsSldExportContext & ) const
243{
244 QDomElement rasterSymbolizerElem = doc.createElement( u"sld:RasterSymbolizer"_s );
245 element.appendChild( rasterSymbolizerElem );
246
247 // add opacity only is different from default
248 if ( !qgsDoubleNear( opacity(), 1.0 ) )
249 {
250 QDomElement opacityElem = doc.createElement( u"sld:Opacity"_s );
251 opacityElem.appendChild( doc.createTextNode( QString::number( opacity() ) ) );
252 rasterSymbolizerElem.appendChild( opacityElem );
253 }
254 return true;
255}
256
258{
259 return true;
260}
261
263{
267 {
268 return true;
269 }
270
271 return false;
272}
273
274bool QgsRasterRenderer::refresh( const QgsRectangle &extent, const QList<double> &, const QList<double> &, bool forceRefresh )
275{
276 if ( !needsRefresh( extent ) && !forceRefresh )
277 {
278 return false;
279 }
280
282 return true;
283}
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
Definition qgis.h:1570
@ NotSet
User defined.
Definition qgis.h:1603
DataType
Raster data types.
Definition qgis.h:379
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition qgis.h:394
@ UnknownDataType
Unknown or unspecified type.
Definition qgis.h:380
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
Definition qgis.h:1621
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:6900
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63