QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsrasterrendererregistry.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrasterrendererregistry.cpp
3 -----------------------------
4 begin : January 2012
5 copyright : (C) 2012 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
20#include "qgsrastershader.h"
24#include "qgscolorrampimpl.h"
30#include "qgsapplication.h"
31#include "qgssettings.h"
33
34#include <QIcon>
35
36QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry( const QString &name, const QString &visibleName,
37 QgsRasterRendererCreateFunc rendererFunction,
39 : name( name )
40 , visibleName( visibleName )
41 , capabilities( capabilities )
42 , rendererCreateFunction( rendererFunction )
43 , widgetCreateFunction( widgetFunction )
44{
45}
46
48{
49 return QgsApplication::getThemeIcon( QString( "styleicons/%1.svg" ).arg( name ) );
50}
51
53{
54 // insert items in a particular order, which is returned in renderersList()
55 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "multibandcolor" ), QObject::tr( "Multiband color" ),
58 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "paletted" ), QObject::tr( "Paletted/Unique values" ), QgsPalettedRasterRenderer::create, nullptr ) );
59 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandgray" ), QObject::tr( "Singleband gray" ),
61 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandpseudocolor" ), QObject::tr( "Singleband pseudocolor" ),
63 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandcolordata" ), QObject::tr( "Singleband color data" ),
65 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "hillshade" ), QObject::tr( "Hillshade" ),
67 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "contour" ), QObject::tr( "Contours" ),
69}
70
72{
73 mEntries.insert( entry.name, entry );
74 mSortedEntries.append( entry.name );
75}
76
78{
79 if ( !mEntries.contains( rendererName ) )
80 {
81 return;
82 }
83 mEntries[rendererName].widgetCreateFunction = func;
84}
85
86bool QgsRasterRendererRegistry::rendererData( const QString &rendererName, QgsRasterRendererRegistryEntry &data ) const
87{
88 const QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.find( rendererName );
89 if ( it == mEntries.constEnd() )
90 {
91 return false;
92 }
93 data = it.value();
94 return true;
95}
96
98{
99 return mSortedEntries;
100}
101
102QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() const
103{
104 QList< QgsRasterRendererRegistryEntry > result;
105
106 QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constBegin();
107 for ( ; it != mEntries.constEnd(); ++it )
108 {
109 result.push_back( it.value() );
110 }
111 return result;
112}
113
115{
116 const QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constFind( rendererName );
117 if ( it != mEntries.constEnd() )
118 {
119 return it.value().capabilities;
120 }
122}
123
125{
126 if ( !provider || provider->bandCount() < 1 )
127 {
128 return nullptr;
129 }
130
131 std::unique_ptr< QgsRasterRenderer > renderer;
132 switch ( drawingStyle )
133 {
135 {
136 const int grayBand = 1; //reasonable default
137
138 // first preference -- use attribute table to generate classes
139 if ( provider->attributeTable( grayBand ) )
140 {
141 std::unique_ptr<QgsColorRamp> ramp;
142 if ( ! provider->attributeTable( grayBand )->hasColor() )
143 {
144 ramp = std::make_unique< QgsRandomColorRamp >();
145 }
147 if ( !classes.empty() )
148 {
149 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
150 }
151 }
152
153 // second preference -- use raster color table to generate classes
154 if ( !renderer )
155 {
157 if ( !classes.empty() )
158 {
159 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
160 }
161 }
162
163 // last preference -- just fallback to single band gray renderer if we couldn't determine color palette
164 if ( ! renderer )
165 {
166 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
167
169 provider->dataType( grayBand ) ) );
170
171 // Default contrast enhancement is set from QgsRasterLayer, it has already setContrastEnhancementAlgorithm(). Default enhancement must only be set if default style was not loaded (to avoid stats calculation).
172 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
173 }
174 }
175 break;
176
179 {
180 const int grayBand = 1;
181
182 // If the raster band has an attribute table try to use it.
183 QString ratErrorMessage;
184 if ( QgsRasterAttributeTable *rat = provider->attributeTable( grayBand ); rat && rat->isValid( &ratErrorMessage ) )
185 {
186 renderer.reset( rat->createRenderer( provider, grayBand ) );
187 }
188
189 if ( ! ratErrorMessage.isEmpty() )
190 {
191 QgsDebugMsgLevel( QStringLiteral( "Invalid RAT from band 1, RAT was not used to create the renderer: %1." ).arg( ratErrorMessage ), 2 );
192 }
193
194 if ( ! renderer )
195 {
196 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
197
199 provider->dataType( grayBand ) ) );
200
201 // Default contrast enhancement is set from QgsRasterLayer, it has already setContrastEnhancementAlgorithm(). Default enhancement must only be set if default style was not loaded (to avoid stats calculation).
202 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
203 }
204 break;
205 }
206
208 {
209 const int bandNo = 1;
210 double minValue = 0;
211 double maxValue = 0;
212 // TODO: avoid calculating statistics if not necessary (default style loaded)
213 minMaxValuesForBand( bandNo, provider, minValue, maxValue );
214 QgsRasterShader *shader = new QgsRasterShader( minValue, maxValue );
215 renderer = std::make_unique< QgsSingleBandPseudoColorRenderer >( provider, bandNo, shader );
216 break;
217 }
219 {
220 const QgsSettings s;
221
222 int redBand = s.value( QStringLiteral( "/Raster/defaultRedBand" ), 1 ).toInt();
223 if ( redBand < 0 || redBand > provider->bandCount() )
224 {
225 redBand = -1;
226 }
227 int greenBand = s.value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt();
228 if ( greenBand < 0 || greenBand > provider->bandCount() )
229 {
230 greenBand = -1;
231 }
232 int blueBand = s.value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt();
233 if ( blueBand < 0 || blueBand > provider->bandCount() )
234 {
235 blueBand = -1;
236 }
237
238 renderer = std::make_unique< QgsMultiBandColorRenderer >( provider, redBand, greenBand, blueBand );
239 break;
240 }
242 {
243 renderer = std::make_unique< QgsSingleBandColorDataRenderer >( provider, 1 );
244 break;
245 }
246 default:
247 return nullptr;
248 }
249
250 std::unique_ptr< QgsRasterTransparency > tr = std::make_unique< QgsRasterTransparency >();
251 const int bandCount = renderer->usesBands().size();
252 if ( bandCount == 1 )
253 {
254 tr->setTransparentSingleValuePixelList( {} );
255 }
256 else if ( bandCount == 3 )
257 {
258 tr->setTransparentThreeValuePixelList( {} );
259 }
260 renderer->setRasterTransparency( tr.release() );
261 return renderer.release();
262}
263
264bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider *provider, double &minValue, double &maxValue ) const
265{
266 if ( !provider )
267 {
268 return false;
269 }
270
271 minValue = 0;
272 maxValue = 0;
273
274 const QgsSettings s;
275 if ( s.value( QStringLiteral( "/Raster/useStandardDeviation" ), false ).toBool() )
276 {
278
279 const double stdDevFactor = s.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble();
280 const double diff = stdDevFactor * stats.stdDev;
281 minValue = stats.mean - diff;
282 maxValue = stats.mean + diff;
283 }
284 else
285 {
287 minValue = stats.minimumValue;
288 maxValue = stats.maximumValue;
289 }
290 return true;
291}
RasterDrawingStyle
Raster drawing styles.
Definition: qgis.h:3958
@ SingleBandGray
A single band image drawn as a range of gray colors.
@ MultiBandSingleBandGray
A layer containing 2 or more bands, but a single band drawn as a range of gray colors.
@ SingleBandColorData
ARGB values rendered directly.
@ MultiBandColor
A layer containing 2 or more bands, mapped to RGB color space. In the case of a multiband with only t...
@ PalettedColor
A "Palette" image drawn using color table.
@ SingleBandPseudoColor
A single band image drawn using a pseudocolor algorithm.
QFlags< RasterRendererCapability > RasterRendererCapabilities
Raster renderer capabilities.
Definition: qgis.h:1182
@ StdDev
Standard deviation.
DataType
Raster data types.
Definition: qgis.h:269
@ UsesMultipleBands
The renderer utilizes multiple raster bands for color data (note that alpha bands are not considered ...
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a specified ...
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Factory method to create a new renderer.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
static QgsPalettedRasterRenderer::MultiValueClassData rasterAttributeTableToClassData(const QgsRasterAttributeTable *attributeTable, int classificationColumn=-1, QgsColorRamp *ramp=nullptr)
Reads and returns classes from the Raster Attribute Table attributeTable, optionally classifying the ...
QList< QgsPalettedRasterRenderer::Class > ClassData
Map of value to class properties.
QList< QgsPalettedRasterRenderer::MultiValueClass > MultiValueClassData
Map of multi value to class properties.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
static QgsPalettedRasterRenderer::ClassData colorTableToClassData(const QList< QgsColorRampShader::ColorRampItem > &table)
Converts a raster color table to paletted renderer class data.
The QgsRasterAttributeTable class represents a Raster Attribute Table (RAT).
bool hasColor() const
Returns true if the Raster Attribute Table has color RGBA information.
bool isValid(QString *errorMessage=nullptr) const
Returns true if the Raster Attribute Table is valid, optionally reporting validity checks results in ...
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Creates an instance of the renderer based on definition from XML (used by renderer registry)
Base class for raster data providers.
QgsRasterAttributeTable * attributeTable(int bandNumber) const
Returns the (possibly NULL) attribute table for the specified bandNumber.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
virtual QList< QgsColorRampShader::ColorRampItem > colorTable(int bandNo) const
Q_DECL_DEPRECATED QgsRasterBandStats bandStatistics(int bandNo, int stats, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual int bandCount() const =0
Gets number of bands.
void insertWidgetFunction(const QString &rendererName, QgsRasterRendererWidgetCreateFunc func)
Sets the widget creation function for a renderer.
QgsRasterRendererRegistry()
Constructor for QgsRasterRendererRegistry.
QList< QgsRasterRendererRegistryEntry > entries() const
Returns the list of registered renderers.
void insert(const QgsRasterRendererRegistryEntry &entry)
Inserts a new entry into the registry.
bool rendererData(const QString &rendererName, QgsRasterRendererRegistryEntry &data) const
Retrieves renderer data from the registry.
QgsRasterRenderer * defaultRendererForDrawingStyle(Qgis::RasterDrawingStyle drawingStyle, QgsRasterDataProvider *provider) const
Creates a default renderer for a raster drawing style (considering user options such as default contr...
Qgis::RasterRendererCapabilities rendererCapabilities(const QString &rendererName) const
Returns the capabilities for the renderer with the specified name.
QStringList renderersList() const
Returns a list of the names of registered renderers.
Raster renderer pipe that applies colors to a raster.
Interface for all raster shaders.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsRasterRendererWidget *(* QgsRasterRendererWidgetCreateFunc)(QgsRasterLayer *, const QgsRectangle &extent)
QgsRasterRenderer *(* QgsRasterRendererCreateFunc)(const QDomElement &, QgsRasterInterface *input)
Registry for raster renderer entries.
QgsRasterRendererRegistryEntry()=default
Constructor for QgsRasterRendererRegistryEntry.