QGIS API Documentation  2.99.0-Master (0a63d1f)
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  // insert items in a particular order, which is returned in renderersList()
55  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "multibandcolor" ), QObject::tr( "Multiband color" ),
57  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "paletted" ), QObject::tr( "Paletted" ), QgsPalettedRasterRenderer::create, nullptr ) );
58  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandgray" ), QObject::tr( "Singleband gray" ),
60  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandpseudocolor" ), QObject::tr( "Singleband pseudocolor" ),
62  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandcolordata" ), QObject::tr( "Singleband color data" ),
64  insert( QgsRasterRendererRegistryEntry( QStringLiteral( "hillshade" ), QObject::tr( "Hillshade" ),
65  QgsHillshadeRenderer::create, nullptr ) );
66 }
67 
69 {
70  mEntries.insert( entry.name, entry );
71  mSortedEntries.append( entry.name );
72 }
73 
75 {
76  if ( !mEntries.contains( rendererName ) )
77  {
78  return;
79  }
80  mEntries[rendererName].widgetCreateFunction = func;
81 }
82 
83 bool QgsRasterRendererRegistry::rendererData( const QString& rendererName, QgsRasterRendererRegistryEntry& data ) const
84 {
85  QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.find( rendererName );
86  if ( it == mEntries.constEnd() )
87  {
88  return false;
89  }
90  data = it.value();
91  return true;
92 }
93 
95 {
96  return mSortedEntries;
97 }
98 
99 QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() const
100 {
101  QList< QgsRasterRendererRegistryEntry > result;
102 
103  QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constBegin();
104  for ( ; it != mEntries.constEnd(); ++it )
105  {
106  result.push_back( it.value() );
107  }
108  return result;
109 }
110 
112 {
113  if ( !provider || provider->bandCount() < 1 )
114  {
115  return nullptr;
116  }
117 
118 
119  QgsRasterRenderer* renderer = nullptr;
120  switch ( theDrawingStyle )
121  {
123  {
124  int grayBand = 1; //reasonable default
125  QList<QgsColorRampShader::ColorRampItem> colorEntries = provider->colorTable( grayBand );
126 
127  //go through list and take maximum value (it could be that entries don't start at 0 or indices are not contiguous)
128  int colorArraySize = 0;
129  QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = colorEntries.constBegin();
130  for ( ; colorIt != colorEntries.constEnd(); ++colorIt )
131  {
132  if ( colorIt->value > colorArraySize )
133  {
134  colorArraySize = ( int )( colorIt->value );
135  }
136  }
137 
138  colorArraySize += 1; //usually starts at 0
139  QColor* colorArray = new QColor[ colorArraySize ];
140  colorIt = colorEntries.constBegin();
141  QVector<QString> labels;
142  for ( ; colorIt != colorEntries.constEnd(); ++colorIt )
143  {
144  int idx = ( int )( colorIt->value );
145  colorArray[idx] = colorIt->color;
146  if ( !colorIt->label.isEmpty() )
147  {
148  if ( labels.size() <= idx ) labels.resize( idx + 1 );
149  labels[idx] = colorIt->label;
150  }
151  }
152 
153  renderer = new QgsPalettedRasterRenderer( provider,
154  grayBand,
155  colorArray,
156  colorArraySize,
157  labels );
158  }
159  break;
162  {
163  int grayBand = 1;
164  renderer = new QgsSingleBandGrayRenderer( provider, grayBand );
165 
167  provider->dataType( grayBand ) ) );
168 
169 // 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).
170  (( QgsSingleBandGrayRenderer* )renderer )->setContrastEnhancement( ce );
171  break;
172  }
174  {
175  int bandNo = 1;
176  double minValue = 0;
177  double maxValue = 0;
178  // TODO: avoid calculating statistics if not necessary (default style loaded)
179  minMaxValuesForBand( bandNo, provider, minValue, maxValue );
180  QgsRasterShader* shader = new QgsRasterShader( minValue, maxValue );
181  renderer = new QgsSingleBandPseudoColorRenderer( provider, bandNo, shader );
182  break;
183  }
185  {
186  QSettings s;
187 
188  int redBand = s.value( QStringLiteral( "/Raster/defaultRedBand" ), 1 ).toInt();
189  if ( redBand < 0 || redBand > provider->bandCount() )
190  {
191  redBand = -1;
192  }
193  int greenBand = s.value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt();
194  if ( greenBand < 0 || greenBand > provider->bandCount() )
195  {
196  greenBand = -1;
197  }
198  int blueBand = s.value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt();
199  if ( blueBand < 0 || blueBand > provider->bandCount() )
200  {
201  blueBand = -1;
202  }
203 
204  renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
205  break;
206  }
208  {
209  renderer = new QgsSingleBandColorDataRenderer( provider, 1 );
210  break;
211  }
212  default:
213  return nullptr;
214  }
215 
216  QgsRasterTransparency* tr = new QgsRasterTransparency(); //renderer takes ownership
217  int bandCount = renderer->usesBands().size();
218  if ( bandCount == 1 )
219  {
220  QList<QgsRasterTransparency::TransparentSingleValuePixel> transparentSingleList;
221  tr->setTransparentSingleValuePixelList( transparentSingleList );
222  }
223  else if ( bandCount == 3 )
224  {
225  QList<QgsRasterTransparency::TransparentThreeValuePixel> transparentThreeValueList;
226  tr->setTransparentThreeValuePixelList( transparentThreeValueList );
227  }
228  renderer->setRasterTransparency( tr );
229  return renderer;
230 }
231 
232 bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider* provider, double& minValue, double& maxValue ) const
233 {
234  if ( !provider )
235  {
236  return false;
237  }
238 
239  minValue = 0;
240  maxValue = 0;
241 
242  QSettings s;
243  if ( s.value( QStringLiteral( "/Raster/useStandardDeviation" ), false ).toBool() )
244  {
246 
247  double stdDevFactor = s.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble();
248  double diff = stdDevFactor * stats.stdDev;
249  minValue = stats.mean - diff;
250  maxValue = stats.mean + diff;
251  }
252  else
253  {
255  minValue = stats.minimumValue;
256  maxValue = stats.maximumValue;
257  }
258  return true;
259 }
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:104
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:61
double maximumValue
The maximum cell value in the raster band.
void setTransparentThreeValuePixelList(const QList< TransparentThreeValuePixel > &theNewList)
Mutator for transparentThreeValuePixelList.
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.
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.