QGIS API Documentation 3.39.0-Master (73c886ac97c)
Loading...
Searching...
No Matches
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"
31#include "qgsapplication.h"
32#include "qgssettings.h"
34
35#include <QIcon>
36
37QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry( const QString &name, const QString &visibleName,
38 QgsRasterRendererCreateFunc rendererFunction,
40 : name( name )
41 , visibleName( visibleName )
42 , capabilities( capabilities )
43 , rendererCreateFunction( rendererFunction )
44 , widgetCreateFunction( widgetFunction )
45{
46}
47
49{
50 return QgsApplication::getThemeIcon( QString( "styleicons/%1.svg" ).arg( name ) );
51}
52
54{
55 // insert items in a particular order, which is returned in renderersList()
56 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "multibandcolor" ), QObject::tr( "Multiband color" ),
59 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "paletted" ), QObject::tr( "Paletted/Unique values" ), QgsPalettedRasterRenderer::create, nullptr ) );
60 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandgray" ), QObject::tr( "Singleband gray" ),
62 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandpseudocolor" ), QObject::tr( "Singleband pseudocolor" ),
64 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandcolordata" ), QObject::tr( "Singleband color data" ),
66 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlecolor" ), QObject::tr( "Single color" ),
68 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "hillshade" ), QObject::tr( "Hillshade" ),
70 insert( QgsRasterRendererRegistryEntry( QStringLiteral( "contour" ), QObject::tr( "Contours" ),
72}
73
75{
76 mEntries.insert( entry.name, entry );
77 mSortedEntries.append( entry.name );
78}
79
81{
82 if ( !mEntries.contains( rendererName ) )
83 {
84 return;
85 }
86 mEntries[rendererName].widgetCreateFunction = func;
87}
88
89bool QgsRasterRendererRegistry::rendererData( const QString &rendererName, QgsRasterRendererRegistryEntry &data ) const
90{
91 const QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.find( rendererName );
92 if ( it == mEntries.constEnd() )
93 {
94 return false;
95 }
96 data = it.value();
97 return true;
98}
99
101{
102 return mSortedEntries;
103}
104
105QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() const
106{
107 QList< QgsRasterRendererRegistryEntry > result;
108
109 QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constBegin();
110 for ( ; it != mEntries.constEnd(); ++it )
111 {
112 result.push_back( it.value() );
113 }
114 return result;
115}
116
118{
119 const QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constFind( rendererName );
120 if ( it != mEntries.constEnd() )
121 {
122 return it.value().capabilities;
123 }
125}
126
128{
129 if ( !provider || provider->bandCount() < 1 )
130 {
131 return nullptr;
132 }
133
134 std::unique_ptr< QgsRasterRenderer > renderer;
135 switch ( drawingStyle )
136 {
138 {
139 const int grayBand = 1; //reasonable default
140
141 // first preference -- use attribute table to generate classes
142 if ( provider->attributeTable( grayBand ) )
143 {
144 std::unique_ptr<QgsColorRamp> ramp;
145 if ( ! provider->attributeTable( grayBand )->hasColor() )
146 {
147 ramp = std::make_unique< QgsRandomColorRamp >();
148 }
150 if ( !classes.empty() )
151 {
152 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
153 }
154 }
155
156 // second preference -- use raster color table to generate classes
157 if ( !renderer )
158 {
160 if ( !classes.empty() )
161 {
162 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
163 }
164 }
165
166 // last preference -- just fallback to single band gray renderer if we couldn't determine color palette
167 if ( ! renderer )
168 {
169 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
170
172 provider->dataType( grayBand ) ) );
173
174 // 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).
175 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
176 }
177 }
178 break;
179
182 {
183 const int grayBand = 1;
184
185 // If the raster band has an attribute table try to use it.
186 QString ratErrorMessage;
187 if ( QgsRasterAttributeTable *rat = provider->attributeTable( grayBand ); rat && rat->isValid( &ratErrorMessage ) )
188 {
189 renderer.reset( rat->createRenderer( provider, grayBand ) );
190 }
191
192 if ( ! ratErrorMessage.isEmpty() )
193 {
194 QgsDebugMsgLevel( QStringLiteral( "Invalid RAT from band 1, RAT was not used to create the renderer: %1." ).arg( ratErrorMessage ), 2 );
195 }
196
197 if ( ! renderer )
198 {
199 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
200
202 provider->dataType( grayBand ) ) );
203
204 // 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).
205 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
206 }
207 break;
208 }
209
211 {
212 const int bandNo = 1;
213 double minValue = 0;
214 double maxValue = 0;
215 // TODO: avoid calculating statistics if not necessary (default style loaded)
216 minMaxValuesForBand( bandNo, provider, minValue, maxValue );
217 QgsRasterShader *shader = new QgsRasterShader( minValue, maxValue );
218 renderer = std::make_unique< QgsSingleBandPseudoColorRenderer >( provider, bandNo, shader );
219 break;
220 }
222 {
223 const QgsSettings s;
224
225 int redBand = s.value( QStringLiteral( "/Raster/defaultRedBand" ), 1 ).toInt();
226 if ( redBand < 0 || redBand > provider->bandCount() )
227 {
228 redBand = -1;
229 }
230 int greenBand = s.value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt();
231 if ( greenBand < 0 || greenBand > provider->bandCount() )
232 {
233 greenBand = -1;
234 }
235 int blueBand = s.value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt();
236 if ( blueBand < 0 || blueBand > provider->bandCount() )
237 {
238 blueBand = -1;
239 }
240
241 renderer = std::make_unique< QgsMultiBandColorRenderer >( provider, redBand, greenBand, blueBand );
242 break;
243 }
245 {
246 renderer = std::make_unique< QgsSingleBandColorDataRenderer >( provider, 1 );
247 break;
248 }
249 default:
250 return nullptr;
251 }
252
253 std::unique_ptr< QgsRasterTransparency > tr = std::make_unique< QgsRasterTransparency >();
254 const int bandCount = renderer->usesBands().size();
255 if ( bandCount == 1 )
256 {
257 tr->setTransparentSingleValuePixelList( {} );
258 }
259 else if ( bandCount == 3 )
260 {
261 tr->setTransparentThreeValuePixelList( {} );
262 }
263 renderer->setRasterTransparency( tr.release() );
264 return renderer.release();
265}
266
267bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider *provider, double &minValue, double &maxValue ) const
268{
269 if ( !provider )
270 {
271 return false;
272 }
273
274 minValue = 0;
275 maxValue = 0;
276
277 const QgsSettings s;
278 if ( s.value( QStringLiteral( "/Raster/useStandardDeviation" ), false ).toBool() )
279 {
281
282 const double stdDevFactor = s.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble();
283 const double diff = stdDevFactor * stats.stdDev;
284 minValue = stats.mean - diff;
285 maxValue = stats.mean + diff;
286 }
287 else
288 {
290 minValue = stats.minimumValue;
291 maxValue = stats.maximumValue;
292 }
293 return true;
294}
RasterDrawingStyle
Raster drawing styles.
Definition qgis.h:4128
@ 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:1247
@ StdDev
Standard deviation.
DataType
Raster data types.
Definition qgis.h:288
@ 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.
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.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Creates an instance of the renderer based on definition from XML (used by the renderer registry)
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.