QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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 , rendererCreateFunction( rendererFunction )
42 , widgetCreateFunction( widgetFunction )
43{
44}
45
47{
48 return QgsApplication::getThemeIcon( QString( "styleicons/%1.svg" ).arg( name ) );
49}
50
52{
53 // insert items in a particular order, which is returned in renderersList()
54 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "multibandcolor" ), QObject::tr( "Multiband color" ),
56 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "paletted" ), QObject::tr( "Paletted/Unique values" ), QgsPalettedRasterRenderer::create, nullptr ) );
57 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandgray" ), QObject::tr( "Singleband gray" ),
59 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandpseudocolor" ), QObject::tr( "Singleband pseudocolor" ),
61 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandcolordata" ), QObject::tr( "Singleband color data" ),
63 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "hillshade" ), QObject::tr( "Hillshade" ),
65 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "contour" ), QObject::tr( "Contours" ),
67}
68
70{
71 mEntries.insert( entry.name, entry );
72 mSortedEntries.append( entry.name );
73}
74
76{
77 if ( !mEntries.contains( rendererName ) )
78 {
79 return;
80 }
81 mEntries[rendererName].widgetCreateFunction = func;
82}
83
84bool QgsRasterRendererRegistry::rendererData( const QString &rendererName, QgsRasterRendererRegistryEntry &data ) const
85{
86 const QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.find( rendererName );
87 if ( it == mEntries.constEnd() )
88 {
89 return false;
90 }
91 data = it.value();
92 return true;
93}
94
96{
97 return mSortedEntries;
98}
99
100QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() const
101{
102 QList< QgsRasterRendererRegistryEntry > result;
103
104 QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constBegin();
105 for ( ; it != mEntries.constEnd(); ++it )
106 {
107 result.push_back( it.value() );
108 }
109 return result;
110}
111
113{
114 if ( !provider || provider->bandCount() < 1 )
115 {
116 return nullptr;
117 }
118
119 std::unique_ptr< QgsRasterRenderer > renderer;
120 switch ( drawingStyle )
121 {
123 {
124 const int grayBand = 1; //reasonable default
125
126 // first preference -- use attribute table to generate classes
127 if ( provider->attributeTable( grayBand ) )
128 {
129 std::unique_ptr<QgsColorRamp> ramp;
130 if ( ! provider->attributeTable( grayBand )->hasColor() )
131 {
132 ramp = std::make_unique< QgsRandomColorRamp >();
133 }
135 if ( !classes.empty() )
136 {
137 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
138 }
139 }
140
141 // second preference -- use raster color table to generate classes
142 if ( !renderer )
143 {
145 if ( !classes.empty() )
146 {
147 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
148 }
149 }
150
151 // last preference -- just fallback to single band gray renderer if we couldn't determine color palette
152 if ( ! renderer )
153 {
154 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
155
157 provider->dataType( grayBand ) ) );
158
159 // 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).
160 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
161 }
162 }
163 break;
164
167 {
168 const int grayBand = 1;
169
170 // If the raster band has an attribute table try to use it.
171 QString ratErrorMessage;
172 if ( QgsRasterAttributeTable *rat = provider->attributeTable( grayBand ); rat && rat->isValid( &ratErrorMessage ) )
173 {
174 renderer.reset( rat->createRenderer( provider, grayBand ) );
175 }
176
177 if ( ! ratErrorMessage.isEmpty() )
178 {
179 QgsDebugMsgLevel( QStringLiteral( "Invalid RAT from band 1, RAT was not used to create the renderer: %1." ).arg( ratErrorMessage ), 2 );
180 }
181
182 if ( ! renderer )
183 {
184 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
185
187 provider->dataType( grayBand ) ) );
188
189 // 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).
190 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
191 }
192 break;
193 }
194
196 {
197 const int bandNo = 1;
198 double minValue = 0;
199 double maxValue = 0;
200 // TODO: avoid calculating statistics if not necessary (default style loaded)
201 minMaxValuesForBand( bandNo, provider, minValue, maxValue );
202 QgsRasterShader *shader = new QgsRasterShader( minValue, maxValue );
203 renderer = std::make_unique< QgsSingleBandPseudoColorRenderer >( provider, bandNo, shader );
204 break;
205 }
207 {
208 const QgsSettings s;
209
210 int redBand = s.value( QStringLiteral( "/Raster/defaultRedBand" ), 1 ).toInt();
211 if ( redBand < 0 || redBand > provider->bandCount() )
212 {
213 redBand = -1;
214 }
215 int greenBand = s.value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt();
216 if ( greenBand < 0 || greenBand > provider->bandCount() )
217 {
218 greenBand = -1;
219 }
220 int blueBand = s.value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt();
221 if ( blueBand < 0 || blueBand > provider->bandCount() )
222 {
223 blueBand = -1;
224 }
225
226 renderer = std::make_unique< QgsMultiBandColorRenderer >( provider, redBand, greenBand, blueBand );
227 break;
228 }
229 case Qgis::RasterDrawingStyle::SingleBandColorData:
230 {
231 renderer = std::make_unique< QgsSingleBandColorDataRenderer >( provider, 1 );
232 break;
233 }
234 default:
235 return nullptr;
236 }
237
238 std::unique_ptr< QgsRasterTransparency > tr = std::make_unique< QgsRasterTransparency >();
239 const int bandCount = renderer->usesBands().size();
240 if ( bandCount == 1 )
241 {
242 const QList<QgsRasterTransparency::TransparentSingleValuePixel> transparentSingleList;
243 tr->setTransparentSingleValuePixelList( transparentSingleList );
244 }
245 else if ( bandCount == 3 )
246 {
247 const QList<QgsRasterTransparency::TransparentThreeValuePixel> transparentThreeValueList;
248 tr->setTransparentThreeValuePixelList( transparentThreeValueList );
249 }
250 renderer->setRasterTransparency( tr.release() );
251 return renderer.release();
252}
253
254bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider *provider, double &minValue, double &maxValue ) const
255{
256 if ( !provider )
257 {
258 return false;
259 }
260
261 minValue = 0;
262 maxValue = 0;
263
264 const QgsSettings s;
265 if ( s.value( QStringLiteral( "/Raster/useStandardDeviation" ), false ).toBool() )
266 {
268
269 const double stdDevFactor = s.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble();
270 const double diff = stdDevFactor * stats.stdDev;
271 minValue = stats.mean - diff;
272 maxValue = stats.mean + diff;
273 }
274 else
275 {
277 minValue = stats.minimumValue;
278 maxValue = stats.maximumValue;
279 }
280 return true;
281}
RasterDrawingStyle
Raster drawing styles.
Definition: qgis.h:2895
@ 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.
@ 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.
DataType
Raster data types.
Definition: qgis.h:242
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
virtual int bandCount() const =0
Gets number of bands.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
void insertWidgetFunction(const QString &rendererName, QgsRasterRendererWidgetCreateFunc func)
QList< QgsRasterRendererRegistryEntry > entries() const
void insert(const QgsRasterRendererRegistryEntry &entry)
bool rendererData(const QString &rendererName, QgsRasterRendererRegistryEntry &data) const
QgsRasterRenderer * defaultRendererForDrawingStyle(Qgis::RasterDrawingStyle drawingStyle, QgsRasterDataProvider *provider) const
Creates a default renderer for a raster drawing style (considering user options such as default contr...
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:63
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.