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