QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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
19
20#include "qgsapplication.h"
21#include "qgscolorrampimpl.h"
28#include "qgsrastershader.h"
31#include "qgssettings.h"
35
36#include <QIcon>
37#include <QString>
38
39using namespace Qt::StringLiterals;
40
50
52{
53 return QgsApplication::getThemeIcon( QString( "styleicons/%1.svg" ).arg( name ) );
54}
55
57{
58 // insert items in a particular order, which is returned in renderersList()
59 insert( QgsRasterRendererRegistryEntry( u"multibandcolor"_s, QObject::tr( "Multiband color" ), QgsMultiBandColorRenderer::create, nullptr, Qgis::RasterRendererCapability::UsesMultipleBands ) );
60 insert( QgsRasterRendererRegistryEntry( u"paletted"_s, QObject::tr( "Paletted/Unique values" ), QgsPalettedRasterRenderer::create, nullptr ) );
61 insert( QgsRasterRendererRegistryEntry( u"singlebandgray"_s, QObject::tr( "Singleband gray" ), QgsSingleBandGrayRenderer::create, nullptr ) );
62 insert( QgsRasterRendererRegistryEntry( u"singlebandpseudocolor"_s, QObject::tr( "Singleband pseudocolor" ), QgsSingleBandPseudoColorRenderer::create, nullptr ) );
63 insert( QgsRasterRendererRegistryEntry( u"singlebandcolordata"_s, QObject::tr( "Singleband color data" ), QgsSingleBandColorDataRenderer::create, nullptr ) );
64 insert( QgsRasterRendererRegistryEntry( u"singlecolor"_s, QObject::tr( "Single color" ), QgsRasterSingleColorRenderer::create, nullptr ) );
65 insert( QgsRasterRendererRegistryEntry( u"hillshade"_s, QObject::tr( "Hillshade" ), QgsHillshadeRenderer::create, nullptr ) );
66 insert( QgsRasterRendererRegistryEntry( u"contour"_s, QObject::tr( "Contours" ), QgsRasterContourRenderer::create, nullptr ) );
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 const QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constFind( rendererName );
115 if ( it != mEntries.constEnd() )
116 {
117 return it.value().capabilities;
118 }
120}
121
123{
124 if ( !provider || provider->bandCount() < 1 )
125 {
126 return nullptr;
127 }
128
129 std::unique_ptr< QgsRasterRenderer > renderer;
130 switch ( drawingStyle )
131 {
133 {
134 const int grayBand = 1; //reasonable default
135
136 // first preference -- use attribute table to generate classes
137 if ( provider->attributeTable( grayBand ) )
138 {
139 std::unique_ptr<QgsColorRamp> ramp;
140 if ( !provider->attributeTable( grayBand )->hasColor() )
141 {
142 ramp = std::make_unique< QgsRandomColorRamp >();
143 }
145 if ( !classes.empty() )
146 {
147 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
148 }
149 }
150
151 // second preference -- use raster color table to generate classes
152 if ( !renderer )
153 {
155 if ( !classes.empty() )
156 {
157 renderer = std::make_unique< QgsPalettedRasterRenderer >( provider, grayBand, classes );
158 }
159 }
160
161 // last preference -- just fallback to single band gray renderer if we couldn't determine color palette
162 if ( !renderer )
163 {
164 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
165
166 QgsContrastEnhancement *ce = new QgsContrastEnhancement( ( Qgis::DataType ) ( provider->dataType( grayBand ) ) );
167
168 // 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).
169 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
170 }
171 }
172 break;
173
176 {
177 const int grayBand = 1;
178
179 // If the raster band has an attribute table try to use it.
180 QString ratErrorMessage;
181 if ( QgsRasterAttributeTable *rat = provider->attributeTable( grayBand ); rat && rat->isValid( &ratErrorMessage ) )
182 {
183 renderer.reset( rat->createRenderer( provider, grayBand ) );
184 }
185
186 if ( !ratErrorMessage.isEmpty() )
187 {
188 QgsDebugMsgLevel( u"Invalid RAT from band 1, RAT was not used to create the renderer: %1."_s.arg( ratErrorMessage ), 2 );
189 }
190
191 if ( !renderer )
192 {
193 renderer = std::make_unique< QgsSingleBandGrayRenderer >( provider, grayBand );
194
195 QgsContrastEnhancement *ce = new QgsContrastEnhancement( ( Qgis::DataType ) ( provider->dataType( grayBand ) ) );
196
197 // 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).
198 qgis::down_cast< QgsSingleBandGrayRenderer * >( renderer.get() )->setContrastEnhancement( ce );
199 }
200 break;
201 }
202
204 {
205 const int bandNo = 1;
206 double minValue = 0;
207 double maxValue = 0;
208 // TODO: avoid calculating statistics if not necessary (default style loaded)
209 minMaxValuesForBand( bandNo, provider, minValue, maxValue );
210 QgsRasterShader *shader = new QgsRasterShader( minValue, maxValue );
211 renderer = std::make_unique< QgsSingleBandPseudoColorRenderer >( provider, bandNo, shader );
212 break;
213 }
215 {
216 const QgsSettings s;
217
218 int redBand = s.value( u"/Raster/defaultRedBand"_s, 1 ).toInt();
219 if ( redBand < 0 || redBand > provider->bandCount() )
220 {
221 redBand = -1;
222 }
223 int greenBand = s.value( u"/Raster/defaultGreenBand"_s, 2 ).toInt();
224 if ( greenBand < 0 || greenBand > provider->bandCount() )
225 {
226 greenBand = -1;
227 }
228 int blueBand = s.value( u"/Raster/defaultBlueBand"_s, 3 ).toInt();
229 if ( blueBand < 0 || blueBand > provider->bandCount() )
230 {
231 blueBand = -1;
232 }
233
234 renderer = std::make_unique< QgsMultiBandColorRenderer >( provider, redBand, greenBand, blueBand );
235 break;
236 }
238 {
239 renderer = std::make_unique< QgsSingleBandColorDataRenderer >( provider, 1 );
240 break;
241 }
242 default:
243 return nullptr;
244 }
245
246 auto tr = std::make_unique< QgsRasterTransparency >();
247 const int bandCount = renderer->usesBands().size();
248 if ( bandCount == 1 )
249 {
250 tr->setTransparentSingleValuePixelList( {} );
251 }
252 else if ( bandCount == 3 )
253 {
254 tr->setTransparentThreeValuePixelList( {} );
255 }
256 renderer->setRasterTransparency( tr.release() );
257 return renderer.release();
258}
259
260bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider *provider, double &minValue, double &maxValue ) const
261{
262 if ( !provider )
263 {
264 return false;
265 }
266
267 minValue = 0;
268 maxValue = 0;
269
270 const QgsSettings s;
271 if ( s.value( u"/Raster/useStandardDeviation"_s, false ).toBool() )
272 {
273 const QgsRasterBandStats stats = provider->bandStatistics( band, Qgis::RasterBandStatistic::Mean | Qgis::RasterBandStatistic::StdDev );
274
275 const double stdDevFactor = s.value( u"/Raster/defaultStandardDeviation"_s, 2.0 ).toDouble();
276 const double diff = stdDevFactor * stats.stdDev;
277 minValue = stats.mean - diff;
278 maxValue = stats.mean + diff;
279 }
280 else
281 {
282 const QgsRasterBandStats stats = provider->bandStatistics( band, Qgis::RasterBandStatistic::Min | Qgis::RasterBandStatistic::Max );
283 minValue = stats.minimumValue;
284 maxValue = stats.maximumValue;
285 }
286 return true;
287}
RasterDrawingStyle
Raster drawing styles.
Definition qgis.h:4936
@ SingleBandGray
A single band image drawn as a range of gray colors.
Definition qgis.h:4938
@ MultiBandSingleBandGray
A layer containing 2 or more bands, but a single band drawn as a range of gray colors.
Definition qgis.h:4944
@ SingleBandColorData
ARGB values rendered directly.
Definition qgis.h:4947
@ MultiBandColor
A layer containing 2 or more bands, mapped to RGB color space. In the case of a multiband with only t...
Definition qgis.h:4946
@ PalettedColor
A "Palette" image drawn using color table.
Definition qgis.h:4940
@ SingleBandPseudoColor
A single band image drawn using a pseudocolor algorithm.
Definition qgis.h:4939
QFlags< RasterRendererCapability > RasterRendererCapabilities
Raster renderer capabilities.
Definition qgis.h:1612
@ StdDev
Standard deviation.
Definition qgis.h:6304
DataType
Raster data types.
Definition qgis.h:393
@ UsesMultipleBands
The renderer utilizes multiple raster bands for color data (note that alpha bands are not considered ...
Definition qgis.h:1603
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Handles contrast enhancement and clipping.
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.
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 ...
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 nullptr) 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).
Stores settings for use within QGIS.
Definition qgssettings.h:68
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:63
QgsRasterRendererWidget *(* QgsRasterRendererWidgetCreateFunc)(QgsRasterLayer *, const QgsRectangle &extent)
QgsRasterRenderer *(* QgsRasterRendererCreateFunc)(const QDomElement &, QgsRasterInterface *input)
Registry for raster renderer entries.
QgsRasterRendererWidgetCreateFunc widgetCreateFunction
Qgis::RasterRendererCapabilities capabilities
Renderer capabilities.
QgsRasterRendererCreateFunc rendererCreateFunction