QGIS API Documentation  2.99.0-Master (c42dad3)
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 #include "qgsrasterdataprovider.h"
20 #include "qgsrastershader.h"
21 #include "qgsrastertransparency.h"
27 #include "qgshillshaderenderer.h"
28 #include "qgsapplication.h"
29 
30 #include <QSettings>
31 #include <QIcon>
32 
33 QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry( const QString& theName, const QString& theVisibleName,
34  QgsRasterRendererCreateFunc rendererFunction,
35  QgsRasterRendererWidgetCreateFunc widgetFunction )
36  : name( theName )
37  , visibleName( theVisibleName )
38  , rendererCreateFunction( rendererFunction )
39  , widgetCreateFunction( widgetFunction )
40 {
41 }
42 
44 {
45 }
46 
48 {
49  return QgsApplication::getThemeIcon( QString( "styleicons/%1.svg" ).arg( name ) );
50 }
51 
53 {
54  static QgsRasterRendererRegistry mInstance;
55  return &mInstance;
56 }
57 
59 {
60  // insert items in a particular order, which is returned in renderersList()
61  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "multibandcolor" ), QObject::tr( "Multiband color" ),
63  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "paletted" ), QObject::tr( "Paletted" ), QgsPalettedRasterRenderer::create, nullptr ) );
64  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandgray" ), QObject::tr( "Singleband gray" ),
66  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandpseudocolor" ), QObject::tr( "Singleband pseudocolor" ),
68  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandcolordata" ), QObject::tr( "Singleband color data" ),
70  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "hillshade" ), QObject::tr( "Hillshade" ),
71  QgsHillshadeRenderer::create, nullptr ) );
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 
89 bool QgsRasterRendererRegistry::rendererData( const QString& rendererName, QgsRasterRendererRegistryEntry& data ) const
90 {
91  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 
105 QList< 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  if ( !provider || provider->bandCount() < 1 )
120  {
121  return nullptr;
122  }
123 
124 
125  QgsRasterRenderer* renderer = nullptr;
126  switch ( theDrawingStyle )
127  {
129  {
130  int grayBand = 1; //reasonable default
131  QList<QgsColorRampShader::ColorRampItem> colorEntries = provider->colorTable( grayBand );
132 
133  //go through list and take maximum value (it could be that entries don't start at 0 or indices are not contiguous)
134  int colorArraySize = 0;
135  QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = colorEntries.constBegin();
136  for ( ; colorIt != colorEntries.constEnd(); ++colorIt )
137  {
138  if ( colorIt->value > colorArraySize )
139  {
140  colorArraySize = ( int )( colorIt->value );
141  }
142  }
143 
144  colorArraySize += 1; //usually starts at 0
145  QColor* colorArray = new QColor[ colorArraySize ];
146  colorIt = colorEntries.constBegin();
147  QVector<QString> labels;
148  for ( ; colorIt != colorEntries.constEnd(); ++colorIt )
149  {
150  int idx = ( int )( colorIt->value );
151  colorArray[idx] = colorIt->color;
152  if ( !colorIt->label.isEmpty() )
153  {
154  if ( labels.size() <= idx ) labels.resize( idx + 1 );
155  labels[idx] = colorIt->label;
156  }
157  }
158 
159  renderer = new QgsPalettedRasterRenderer( provider,
160  grayBand,
161  colorArray,
162  colorArraySize,
163  labels );
164  }
165  break;
168  {
169  int grayBand = 1;
170  renderer = new QgsSingleBandGrayRenderer( provider, grayBand );
171 
173  provider->dataType( grayBand ) ) );
174 
175 // 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).
176  (( QgsSingleBandGrayRenderer* )renderer )->setContrastEnhancement( ce );
177  break;
178  }
180  {
181  int bandNo = 1;
182  double minValue = 0;
183  double maxValue = 0;
184  // TODO: avoid calculating statistics if not necessary (default style loaded)
185  minMaxValuesForBand( bandNo, provider, minValue, maxValue );
186  QgsRasterShader* shader = new QgsRasterShader( minValue, maxValue );
187  renderer = new QgsSingleBandPseudoColorRenderer( provider, bandNo, shader );
188  break;
189  }
191  {
192  QSettings s;
193 
194  int redBand = s.value( QStringLiteral( "/Raster/defaultRedBand" ), 1 ).toInt();
195  if ( redBand < 0 || redBand > provider->bandCount() )
196  {
197  redBand = -1;
198  }
199  int greenBand = s.value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt();
200  if ( greenBand < 0 || greenBand > provider->bandCount() )
201  {
202  greenBand = -1;
203  }
204  int blueBand = s.value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt();
205  if ( blueBand < 0 || blueBand > provider->bandCount() )
206  {
207  blueBand = -1;
208  }
209 
210  renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
211  break;
212  }
214  {
215  renderer = new QgsSingleBandColorDataRenderer( provider, 1 );
216  break;
217  }
218  default:
219  return nullptr;
220  }
221 
222  QgsRasterTransparency* tr = new QgsRasterTransparency(); //renderer takes ownership
223  int bandCount = renderer->usesBands().size();
224  if ( bandCount == 1 )
225  {
226  QList<QgsRasterTransparency::TransparentSingleValuePixel> transparentSingleList;
227  tr->setTransparentSingleValuePixelList( transparentSingleList );
228  }
229  else if ( bandCount == 3 )
230  {
231  QList<QgsRasterTransparency::TransparentThreeValuePixel> transparentThreeValueList;
232  tr->setTransparentThreeValuePixelList( transparentThreeValueList );
233  }
234  renderer->setRasterTransparency( tr );
235  return renderer;
236 }
237 
238 bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider* provider, double& minValue, double& maxValue ) const
239 {
240  if ( !provider )
241  {
242  return false;
243  }
244 
245  minValue = 0;
246  maxValue = 0;
247 
248  QSettings s;
249  if ( s.value( QStringLiteral( "/Raster/useStandardDeviation" ), false ).toBool() )
250  {
252 
253  double stdDevFactor = s.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble();
254  double diff = stdDevFactor * stats.stdDev;
255  minValue = stats.mean - diff;
256  maxValue = stats.mean + diff;
257  }
258  else
259  {
261  minValue = stats.minimumValue;
262  maxValue = stats.maximumValue;
263  }
264  return true;
265 }
virtual int bandCount() const =0
Get number of bands.
Interface for all raster shaders.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Renderer for paletted raster images.
DrawingStyle
This enumerator describes the different kinds of drawing we can do.
Definition: qgsraster.h:112
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
virtual QList< QgsColorRampShader::ColorRampItem > colorTable(int bandNo) const
virtual QList< int > usesBands() const
Returns a list of band numbers used by the renderer.
QgsRasterRendererWidgetCreateFunc widgetCreateFunction
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
QgsRasterRenderer *(* QgsRasterRendererCreateFunc)(const QDomElement &, QgsRasterInterface *input)
DataType
Raster data types.
Definition: qgis.h:60
double maximumValue
The maximum cell value in the raster band.
void setTransparentThreeValuePixelList(const QList< TransparentThreeValuePixel > &theNewList)
Mutator for transparentThreeValuePixelList.
Registry for raster renderers.
Raster renderer pipe for single band color.
bool rendererData(const QString &rendererName, QgsRasterRendererRegistryEntry &data) const
virtual QgsRasterBandStats bandStatistics(int theBandNo, int theStats=QgsRasterBandStats::All, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Get band statistics.
double stdDev
The standard deviation of the cell values.
The RasterBandStats struct is a container for statistics about a single raster band.
static QgsRasterRendererRegistry * instance()
double mean
The mean cell value for the band. NO_DATA values are excluded.
virtual Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
void insert(const QgsRasterRendererRegistryEntry &entry)
Raster renderer pipe for single band pseudocolor.
Raster renderer pipe for single band gray.
QgsRasterRenderer * defaultRendererForDrawingStyle(QgsRaster::DrawingStyle theDrawingStyle, QgsRasterDataProvider *provider) const
Creates a default renderer for a raster drawing style (considering user options such as default contr...
QgsRasterRendererWidget *(* QgsRasterRendererWidgetCreateFunc)(QgsRasterLayer *, const QgsRectangle &extent)
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Registry for raster renderer entries.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
void setTransparentSingleValuePixelList(const QList< TransparentSingleValuePixel > &theNewList)
Mutator for transparentSingleValuePixelList.
double minimumValue
The minimum cell value in the raster band.
Renderer for multiband images with the color components.
Manipulates raster pixel values so that they enhanceContrast or clip into a specified numerical range...
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
QList< QgsRasterRendererRegistryEntry > entries() const
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Factory method to create a new renderer.
void setRasterTransparency(QgsRasterTransparency *t)
void insertWidgetFunction(const QString &rendererName, QgsRasterRendererWidgetCreateFunc func)
Raster renderer pipe that applies colors to a raster.
QgsRasterRendererCreateFunc rendererCreateFunction
Base class for raster data providers.