QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgscolorrampshader.cpp
Go to the documentation of this file.
1 /* **************************************************************************
2  qgscolorrampshader.cpp - description
3  -------------------
4 begin : Fri Dec 28 2007
5 copyright : (C) 2007 by Peter J. Ersts
6 email : [email protected]
7 
8 This class is based off of code that was originally written by Marco Hugentobler and
9 originally part of the larger QgsRasterLayer class
10 ****************************************************************************/
11 
12 /* **************************************************************************
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  ***************************************************************************/
20 
21 // Threshold for treating values as exact match.
22 // Set to 0.0 to support displaying small values (https://github.com/qgis/QGIS/issues/20706)
23 #define DOUBLE_DIFF_THRESHOLD 0.0 // 0.0000001
24 
25 #include "qgslogger.h"
26 #include "qgis.h"
27 #include "qgscolorramp.h"
28 #include "qgscolorrampshader.h"
29 #include "qgsrasterinterface.h"
30 #include "qgsrasterminmaxorigin.h"
31 #include "qgssymbollayerutils.h"
32 
33 #include <cmath>
34 QgsColorRampShader::QgsColorRampShader( double minimumValue, double maximumValue, QgsColorRamp *colorRamp, Type type, ClassificationMode classificationMode )
35  : QgsRasterShaderFunction( minimumValue, maximumValue )
36  , mColorRampType( type )
37  , mClassificationMode( classificationMode )
38 {
39  QgsDebugMsgLevel( QStringLiteral( "called." ), 4 );
40 
41  setSourceColorRamp( colorRamp );
42 }
43 
45  : QgsRasterShaderFunction( other )
46  , mColorRampType( other.mColorRampType )
47  , mClassificationMode( other.mClassificationMode )
48  , mLUT( other.mLUT )
49  , mLUTOffset( other.mLUTOffset )
50  , mLUTFactor( other.mLUTFactor )
51  , mLUTInitialized( other.mLUTInitialized )
52  , mClip( other.mClip )
53 {
54  if ( auto *lSourceColorRamp = other.sourceColorRamp() )
55  mSourceColorRamp.reset( lSourceColorRamp->clone() );
56  mColorRampItemList = other.mColorRampItemList;
57 }
58 
60 {
61  QgsRasterShaderFunction::operator=( other );
62  if ( auto *lSourceColorRamp = other.sourceColorRamp() )
63  mSourceColorRamp.reset( lSourceColorRamp->clone() );
64  else
65  mSourceColorRamp.reset();
66 
67  mColorRampType = other.mColorRampType;
68  mClassificationMode = other.mClassificationMode;
69  mLUT = other.mLUT;
70  mLUTOffset = other.mLUTOffset;
71  mLUTFactor = other.mLUTFactor;
72  mLUTInitialized = other.mLUTInitialized;
73  mClip = other.mClip;
74  mColorRampItemList = other.mColorRampItemList;
75  return *this;
76 }
77 
79 {
80  switch ( mColorRampType )
81  {
82  case Interpolated:
83  return QStringLiteral( "INTERPOLATED" );
84  case Discrete:
85  return QStringLiteral( "DISCRETE" );
86  case Exact:
87  return QStringLiteral( "EXACT" );
88  }
89  return QStringLiteral( "Unknown" );
90 }
91 
92 void QgsColorRampShader::setColorRampItemList( const QList<QgsColorRampShader::ColorRampItem> &list )
93 {
94  mColorRampItemList = list.toVector();
95  // Reset the look up table when the color ramp is changed
96  mLUTInitialized = false;
97  mLUT.clear();
98 }
99 
101 {
102  mColorRampType = colorRampType;
103 }
104 
106 {
107  return mColorRampItemList.isEmpty();
108 }
109 
110 void QgsColorRampShader::setColorRampType( const QString &type )
111 {
112  if ( type == QLatin1String( "INTERPOLATED" ) )
113  {
114  mColorRampType = Interpolated;
115  }
116  else if ( type == QLatin1String( "DISCRETE" ) )
117  {
118  mColorRampType = Discrete;
119  }
120  else
121  {
122  mColorRampType = Exact;
123  }
124 }
125 
127 {
128  return mSourceColorRamp.get();
129 }
130 
132 {
133  mSourceColorRamp.reset( colorramp );
134 }
135 
136 void QgsColorRampShader::classifyColorRamp( const int classes, const int band, const QgsRectangle &extent, QgsRasterInterface *input )
137 {
138  if ( minimumValue() >= maximumValue() )
139  {
140  return;
141  }
142 
143  bool discrete = colorRampType() == Discrete;
144 
145  QList<double> entryValues;
146  QVector<QColor> entryColors;
147 
148  double min = minimumValue();
149  double max = maximumValue();
150 
151  if ( classificationMode() == Continuous )
152  {
153  if ( sourceColorRamp() && sourceColorRamp()->count() > 1 )
154  {
155  int numberOfEntries = sourceColorRamp()->count();
156  entryValues.reserve( numberOfEntries );
157  if ( discrete )
158  {
159  double intervalDiff = max - min;
160 
161  // remove last class when ColorRamp is gradient and discrete, as they are implemented with an extra stop
162  QgsGradientColorRamp *colorGradientRamp = dynamic_cast<QgsGradientColorRamp *>( sourceColorRamp() );
163  if ( colorGradientRamp && colorGradientRamp->isDiscrete() )
164  {
165  numberOfEntries--;
166  }
167  else
168  {
169  // if color ramp is continuous scale values to get equally distributed classes.
170  // Doesn't work perfectly when stops are non equally distributed.
171  intervalDiff *= ( numberOfEntries - 1 ) / static_cast<double>( numberOfEntries );
172  }
173 
174  // skip first value (always 0.0)
175  for ( int i = 1; i < numberOfEntries; ++i )
176  {
177  double value = sourceColorRamp()->value( i );
178  entryValues.push_back( min + value * intervalDiff );
179  }
180  entryValues.push_back( std::numeric_limits<double>::infinity() );
181  }
182  else
183  {
184  for ( int i = 0; i < numberOfEntries; ++i )
185  {
186  double value = sourceColorRamp()->value( i );
187  entryValues.push_back( min + value * ( max - min ) );
188  }
189  }
190  // for continuous mode take original color map colors
191  for ( int i = 0; i < numberOfEntries; ++i )
192  {
193  int idx = i;
194  entryColors.push_back( sourceColorRamp()->color( sourceColorRamp()->value( idx ) ) );
195  }
196  }
197  }
198  else // for other classification modes interpolate colors linearly
199  {
200  if ( classes < 2 )
201  return; // < 2 classes is not useful, shouldn't happen, but if it happens save it from crashing
202 
203  if ( classificationMode() == Quantile )
204  {
205  // Quantile
206  if ( band < 0 || !input )
207  return; // quantile classification requires a valid band, minMaxOrigin, and input
208 
209  double cut1 = std::numeric_limits<double>::quiet_NaN();
210  double cut2 = std::numeric_limits<double>::quiet_NaN();
211  // Note: the sample size in other parts of QGIS appears to be 25000, it is ten times here.
212  const int sampleSize = 250000 * 10;
213 
214  // set min and max from histogram, used later to calculate number of decimals to display
215  input->cumulativeCut( band, 0.0, 1.0, min, max, extent, sampleSize );
216 
217  entryValues.reserve( classes );
218  if ( discrete )
219  {
220  double intervalDiff = 1.0 / ( classes );
221  for ( int i = 1; i < classes; ++i )
222  {
223  input->cumulativeCut( band, 0.0, i * intervalDiff, cut1, cut2, extent, sampleSize );
224  entryValues.push_back( cut2 );
225  }
226  entryValues.push_back( std::numeric_limits<double>::infinity() );
227  }
228  else
229  {
230  double intervalDiff = 1.0 / ( classes - 1 );
231  for ( int i = 0; i < classes; ++i )
232  {
233  input->cumulativeCut( band, 0.0, i * intervalDiff, cut1, cut2, extent, sampleSize );
234  entryValues.push_back( cut2 );
235  }
236  }
237  }
238  else // EqualInterval
239  {
240  entryValues.reserve( classes );
241  if ( discrete )
242  {
243  // in discrete mode the lowest value is not an entry and the highest
244  // value is inf, there are ( numberOfEntries ) of which the first
245  // and last are not used.
246  double intervalDiff = ( max - min ) / ( classes );
247 
248  for ( int i = 1; i < classes; ++i )
249  {
250  entryValues.push_back( min + i * intervalDiff );
251  }
252  entryValues.push_back( std::numeric_limits<double>::infinity() );
253  }
254  else
255  {
256  //because the highest value is also an entry, there are (numberOfEntries - 1) intervals
257  double intervalDiff = ( max - min ) / ( classes - 1 );
258 
259  for ( int i = 0; i < classes; ++i )
260  {
261  entryValues.push_back( min + i * intervalDiff );
262  }
263  }
264  }
265 
266  if ( !sourceColorRamp() || sourceColorRamp()->count() == 1 )
267  {
268  //hard code color range from blue -> red (previous default)
269  int colorDiff = 0;
270  if ( classes != 0 )
271  {
272  colorDiff = ( int )( 255 / classes );
273  }
274 
275  entryColors.reserve( classes );
276  for ( int i = 0; i < classes; ++i )
277  {
278  QColor currentColor;
279  int idx = i;
280  currentColor.setRgb( colorDiff * idx, 0, 255 - colorDiff * idx );
281  entryColors.push_back( currentColor );
282  }
283  }
284  else
285  {
286  entryColors.reserve( classes );
287  for ( int i = 0; i < classes; ++i )
288  {
289  int idx = i;
290  entryColors.push_back( sourceColorRamp()->color( ( ( double ) idx ) / ( classes - 1 ) ) );
291  }
292  }
293  }
294 
295  QList<double>::const_iterator value_it = entryValues.constBegin();
296  QVector<QColor>::const_iterator color_it = entryColors.constBegin();
297 
298  // calculate a reasonable number of decimals to display
299  double maxabs = std::log10( std::max( std::fabs( max ), std::fabs( min ) ) );
300  int nDecimals = std::round( std::max( 3.0 + maxabs - std::log10( max - min ), maxabs <= 15.0 ? maxabs + 0.49 : 0.0 ) );
301 
302  QList<QgsColorRampShader::ColorRampItem> colorRampItems;
303  for ( ; value_it != entryValues.constEnd(); ++value_it, ++color_it )
304  {
305  QgsColorRampShader::ColorRampItem newColorRampItem;
306  newColorRampItem.value = *value_it;
307  newColorRampItem.color = *color_it;
308  newColorRampItem.label = QString::number( *value_it, 'g', nDecimals );
309  colorRampItems.append( newColorRampItem );
310  }
311 
312  std::sort( colorRampItems.begin(), colorRampItems.end() );
313  setColorRampItemList( colorRampItems );
314 }
315 
316 void QgsColorRampShader::classifyColorRamp( const int band, const QgsRectangle &extent, QgsRasterInterface *input )
317 {
318  classifyColorRamp( colorRampItemList().count(), band, extent, input );
319 }
320 
321 bool QgsColorRampShader::shade( double value, int *returnRedValue, int *returnGreenValue, int *returnBlueValue, int *returnAlphaValue ) const
322 {
323  if ( mColorRampItemList.isEmpty() )
324  {
325  return false;
326  }
327  if ( std::isnan( value ) || std::isinf( value ) )
328  return false;
329 
330  int colorRampItemListCount = mColorRampItemList.count();
331  const QgsColorRampShader::ColorRampItem *colorRampItems = mColorRampItemList.constData();
332  int idx;
333  if ( !mLUTInitialized )
334  {
335  // calculate LUT for faster index recovery
336  mLUTFactor = 1.0;
337  double minimumValue = colorRampItems[0].value;
338  mLUTOffset = minimumValue + DOUBLE_DIFF_THRESHOLD;
339  // Only make lut if at least 3 items, with 2 items the low and high cases handle both
340  if ( colorRampItemListCount >= 3 )
341  {
342  double rangeValue = colorRampItems[colorRampItemListCount - 2].value - minimumValue;
343  if ( rangeValue > 0 )
344  {
345  int lutSize = 256; // TODO: test if speed can be increased with a different LUT size
346  mLUTFactor = ( lutSize - 0.0000001 ) / rangeValue; // decrease slightly to make sure last LUT category is correct
347  idx = 0;
348  double val;
349  mLUT.reserve( lutSize );
350  for ( int i = 0; i < lutSize; i++ )
351  {
352  val = ( i / mLUTFactor ) + mLUTOffset;
353  while ( idx < colorRampItemListCount
354  && colorRampItems[idx].value - DOUBLE_DIFF_THRESHOLD < val )
355  {
356  idx++;
357  }
358  mLUT.push_back( idx );
359  }
360  }
361  }
362  mLUTInitialized = true;
363  }
364 
365  // overflow indicates that value > maximum value + DOUBLE_DIFF_THRESHOLD
366  // that way idx can point to the last valid item
367  bool overflow = false;
368 
369  // find index of the first ColorRampItem that is equal or higher to theValue
370  int lutIndex = ( value - mLUTOffset ) * mLUTFactor;
371  if ( value < mLUTOffset )
372  {
373  idx = 0;
374  }
375  else if ( lutIndex >= mLUT.count() )
376  {
377  idx = colorRampItemListCount - 1;
378  if ( colorRampItems[idx].value + DOUBLE_DIFF_THRESHOLD < value )
379  {
380  overflow = true;
381  }
382  }
383  else if ( lutIndex < 0 )
384  {
385  return false;
386  }
387  else
388  {
389  // get initial value from LUT
390  idx = mLUT.at( lutIndex );
391 
392  // check if it's correct and if not increase until correct
393  // the LUT is made in such a way the index is always correct or too low, never too high
394  while ( idx < colorRampItemListCount && colorRampItems[idx].value + DOUBLE_DIFF_THRESHOLD < value )
395  {
396  idx++;
397  }
398  if ( idx >= colorRampItemListCount )
399  {
400  idx = colorRampItemListCount - 1;
401  overflow = true;
402  }
403  }
404 
405  const QgsColorRampShader::ColorRampItem &currentColorRampItem = colorRampItems[idx];
406 
407  switch ( colorRampType() )
408  {
409  case Interpolated:
410  {
411  // Interpolate the color between two class breaks linearly.
412  if ( idx < 1 || overflow || currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD <= value )
413  {
414  if ( mClip && ( overflow
415  || currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD > value ) )
416  {
417  return false;
418  }
419  *returnRedValue = currentColorRampItem.color.red();
420  *returnGreenValue = currentColorRampItem.color.green();
421  *returnBlueValue = currentColorRampItem.color.blue();
422  *returnAlphaValue = currentColorRampItem.color.alpha();
423  return true;
424  }
425 
426  const QgsColorRampShader::ColorRampItem &previousColorRampItem = colorRampItems[idx - 1];
427 
428  float currentRampRange = currentColorRampItem.value - previousColorRampItem.value;
429  float offsetInRange = value - previousColorRampItem.value;
430  float scale = offsetInRange / currentRampRange;
431  const QRgb c1 = previousColorRampItem.color.rgba();
432  const QRgb c2 = currentColorRampItem.color.rgba();
433 
434  *returnRedValue = qRed( c1 ) + static_cast< int >( ( qRed( c2 ) - qRed( c1 ) ) * scale );
435  *returnGreenValue = qGreen( c1 ) + static_cast< int >( ( qGreen( c2 ) - qGreen( c1 ) ) * scale );
436  *returnBlueValue = qBlue( c1 ) + static_cast< int >( ( qBlue( c2 ) - qBlue( c1 ) ) * scale );
437  *returnAlphaValue = qAlpha( c1 ) + static_cast< int >( ( qAlpha( c2 ) - qAlpha( c1 ) ) * scale );
438  return true;
439  };
440  case Discrete:
441  {
442  // Assign the color of the higher class for every pixel between two class breaks.
443  // NOTE: The implementation has always been different than the documentation,
444  // which said lower class before, see https://github.com/qgis/QGIS/issues/22009
445  if ( overflow )
446  {
447  return false;
448  }
449  *returnRedValue = currentColorRampItem.color.red();
450  *returnGreenValue = currentColorRampItem.color.green();
451  *returnBlueValue = currentColorRampItem.color.blue();
452  *returnAlphaValue = currentColorRampItem.color.alpha();
453  return true;
454  };
455  case Exact:
456  {
457  // Assign the color of the exact matching value in the color ramp item list
458  if ( !overflow && currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD <= value )
459  {
460  *returnRedValue = currentColorRampItem.color.red();
461  *returnGreenValue = currentColorRampItem.color.green();
462  *returnBlueValue = currentColorRampItem.color.blue();
463  *returnAlphaValue = currentColorRampItem.color.alpha();
464  return true;
465  }
466  else
467  {
468  return false;
469  }
470  }
471  }
472  return false;
473 }
474 
475 bool QgsColorRampShader::shade( double redValue, double greenValue,
476  double blueValue, double alphaValue,
477  int *returnRedValue, int *returnGreenValue,
478  int *returnBlueValue, int *returnAlphaValue ) const
479 {
480  Q_UNUSED( redValue )
481  Q_UNUSED( greenValue )
482  Q_UNUSED( blueValue )
483  Q_UNUSED( alphaValue )
484 
485  *returnRedValue = 0;
486  *returnGreenValue = 0;
487  *returnBlueValue = 0;
488  *returnAlphaValue = 0;
489 
490  return false;
491 }
492 
493 void QgsColorRampShader::legendSymbologyItems( QList< QPair< QString, QColor > > &symbolItems ) const
494 {
495  QVector<QgsColorRampShader::ColorRampItem>::const_iterator colorRampIt = mColorRampItemList.constBegin();
496  for ( ; colorRampIt != mColorRampItemList.constEnd(); ++colorRampIt )
497  {
498  symbolItems.push_back( qMakePair( colorRampIt->label, colorRampIt->color ) );
499  }
500 }
501 
502 QDomElement QgsColorRampShader::writeXml( QDomDocument &doc ) const
503 {
504  QDomElement colorRampShaderElem = doc.createElement( QStringLiteral( "colorrampshader" ) );
505  colorRampShaderElem.setAttribute( QStringLiteral( "colorRampType" ), colorRampTypeAsQString() );
506  colorRampShaderElem.setAttribute( QStringLiteral( "classificationMode" ), classificationMode() );
507  colorRampShaderElem.setAttribute( QStringLiteral( "clip" ), clip() );
508  colorRampShaderElem.setAttribute( QStringLiteral( "minimumValue" ), mMinimumValue );
509  colorRampShaderElem.setAttribute( QStringLiteral( "maximumValue" ), mMaximumValue );
510 
511  // save source color ramp
512  if ( sourceColorRamp() )
513  {
514  QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( QStringLiteral( "[source]" ), sourceColorRamp(), doc );
515  colorRampShaderElem.appendChild( colorRampElem );
516  }
517 
518  //items
519  QList<QgsColorRampShader::ColorRampItem> itemList = colorRampItemList();
520  QList<QgsColorRampShader::ColorRampItem>::const_iterator itemIt = itemList.constBegin();
521  for ( ; itemIt != itemList.constEnd(); ++itemIt )
522  {
523  QDomElement itemElem = doc.createElement( QStringLiteral( "item" ) );
524  itemElem.setAttribute( QStringLiteral( "label" ), itemIt->label );
525  itemElem.setAttribute( QStringLiteral( "value" ), QgsRasterBlock::printValue( itemIt->value ) );
526  itemElem.setAttribute( QStringLiteral( "color" ), itemIt->color.name() );
527  itemElem.setAttribute( QStringLiteral( "alpha" ), itemIt->color.alpha() );
528  colorRampShaderElem.appendChild( itemElem );
529  }
530  return colorRampShaderElem;
531 }
532 
533 void QgsColorRampShader::readXml( const QDomElement &colorRampShaderElem )
534 {
535  // try to load color ramp (optional)
536  QDomElement sourceColorRampElem = colorRampShaderElem.firstChildElement( QStringLiteral( "colorramp" ) );
537  if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral( "name" ) ) == QLatin1String( "[source]" ) )
538  {
539  setSourceColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ) );
540  }
541 
542  setColorRampType( colorRampShaderElem.attribute( QStringLiteral( "colorRampType" ), QStringLiteral( "INTERPOLATED" ) ) );
543  setClassificationMode( static_cast< QgsColorRampShader::ClassificationMode >( colorRampShaderElem.attribute( QStringLiteral( "classificationMode" ), QStringLiteral( "1" ) ).toInt() ) );
544  setClip( colorRampShaderElem.attribute( QStringLiteral( "clip" ), QStringLiteral( "0" ) ) == QLatin1String( "1" ) );
545  setMinimumValue( colorRampShaderElem.attribute( QStringLiteral( "minimumValue" ) ).toDouble() );
546  setMaximumValue( colorRampShaderElem.attribute( QStringLiteral( "maximumValue" ) ).toDouble() );
547 
548  QList<QgsColorRampShader::ColorRampItem> itemList;
549  QDomElement itemElem;
550  QString itemLabel;
551  double itemValue;
552  QColor itemColor;
553 
554  QDomNodeList itemNodeList = colorRampShaderElem.elementsByTagName( QStringLiteral( "item" ) );
555  itemList.reserve( itemNodeList.size() );
556  for ( int i = 0; i < itemNodeList.size(); ++i )
557  {
558  itemElem = itemNodeList.at( i ).toElement();
559  itemValue = itemElem.attribute( QStringLiteral( "value" ) ).toDouble();
560  itemLabel = itemElem.attribute( QStringLiteral( "label" ) );
561  itemColor.setNamedColor( itemElem.attribute( QStringLiteral( "color" ) ) );
562  itemColor.setAlpha( itemElem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "255" ) ).toInt() );
563 
564  itemList.push_back( QgsColorRampShader::ColorRampItem( itemValue, itemColor, itemLabel ) );
565  }
566  setColorRampItemList( itemList );
567 }
qgsrasterminmaxorigin.h
QgsColorRamp
Abstract base class for color ramps.
Definition: qgscolorramp.h:32
QgsRasterBlock::printValue
static QString printValue(double value)
Print double value with all necessary significant digits.
Definition: qgsrasterblock.cpp:626
QgsColorRampShader::setSourceColorRamp
void setSourceColorRamp(QgsColorRamp *colorramp)
Set the source color ramp.
Definition: qgscolorrampshader.cpp:131
QgsGradientColorRamp
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Definition: qgscolorramp.h:151
QgsColorRampShader::setClassificationMode
void setClassificationMode(ClassificationMode classificationMode)
Sets classification mode.
Definition: qgscolorrampshader.h:184
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsColorRampShader::writeXml
QDomElement writeXml(QDomDocument &doc) const
Writes configuration to a new DOM element.
Definition: qgscolorrampshader.cpp:502
QgsRasterInterface::cumulativeCut
virtual void cumulativeCut(int bandNo, double lowerCount, double upperCount, double &lowerValue, double &upperValue, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0)
Find values for cumulative pixel count cut.
Definition: qgsrasterinterface.cpp:523
QgsColorRampShader::isEmpty
bool isEmpty() const
Whether the color ramp contains any items.
Definition: qgscolorrampshader.cpp:105
qgssymbollayerutils.h
QgsColorRampShader::classifyColorRamp
void classifyColorRamp(int classes=0, int band=-1, const QgsRectangle &extent=QgsRectangle(), QgsRasterInterface *input=nullptr)
Classify color ramp shader.
Definition: qgscolorrampshader.cpp:136
QgsRasterShaderFunction::maximumValue
double maximumValue() const
Returns the minimum value for the raster shader.
Definition: qgsrastershaderfunction.h:119
qgis.h
qgscolorrampshader.h
QgsRasterShaderFunction::mMinimumValue
double mMinimumValue
User defineable minimum value for the shading function.
Definition: qgsrastershaderfunction.h:131
QgsColorRampShader
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
Definition: qgscolorrampshader.h:40
QgsColorRampShader::Type
Type
Supported methods for color interpolation.
Definition: qgscolorrampshader.h:46
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsColorRampShader::colorRampTypeAsQString
QString colorRampTypeAsQString() const
Returns the color ramp type as a string.
Definition: qgscolorrampshader.cpp:78
QgsColorRampShader::Quantile
@ Quantile
Uses quantile (i.e. equal pixel) count.
Definition: qgscolorrampshader.h:57
QgsColorRampShader::Discrete
@ Discrete
Assigns the color of the higher class for every pixel between two class breaks.
Definition: qgscolorrampshader.h:48
QgsColorRampShader::ColorRampItem::color
QColor color
Definition: qgscolorrampshader.h:98
qgsrasterinterface.h
QgsColorRampShader::setColorRampType
void setColorRampType(QgsColorRampShader::Type colorRampType)
Sets the color ramp type.
Definition: qgscolorrampshader.cpp:100
QgsColorRampShader::Continuous
@ Continuous
Uses breaks from color palette.
Definition: qgscolorrampshader.h:55
QgsColorRampShader::sourceColorRamp
QgsColorRamp * sourceColorRamp() const
Returns the source color ramp.
Definition: qgscolorrampshader.cpp:126
QgsColorRampShader::setClip
void setClip(bool clip)
Sets whether the shader should not render values out of range.
Definition: qgscolorrampshader.h:194
QgsColorRampShader::ColorRampItem
Definition: qgscolorrampshader.h:86
QgsColorRampShader::legendSymbologyItems
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Returns legend symbology items if provided by renderer.
Definition: qgscolorrampshader.cpp:493
QgsColorRampShader::Exact
@ Exact
Assigns the color of the exact matching value in the color ramp item list.
Definition: qgscolorrampshader.h:49
qgscolorramp.h
QgsColorRampShader::QgsColorRampShader
QgsColorRampShader(double minimumValue=0.0, double maximumValue=255.0, QgsColorRamp *colorRamp=nullptr, Type type=Interpolated, ClassificationMode classificationMode=Continuous)
Creates a new color ramp shader.
Definition: qgscolorrampshader.cpp:34
QgsSymbolLayerUtils::saveColorRamp
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
Definition: qgssymbollayerutils.cpp:3112
QgsRasterShaderFunction::setMaximumValue
virtual void setMaximumValue(double value)
Sets the maximum value for the raster shader.
Definition: qgsrastershaderfunction.cpp:30
QgsRasterShaderFunction::mMaximumValue
double mMaximumValue
User defineable maximum value for the shading function.
Definition: qgsrastershaderfunction.h:128
DOUBLE_DIFF_THRESHOLD
#define DOUBLE_DIFF_THRESHOLD
Definition: qgscolorrampshader.cpp:23
QgsColorRampShader::setColorRampItemList
void setColorRampItemList(const QList< QgsColorRampShader::ColorRampItem > &list)
Sets a custom colormap.
Definition: qgscolorrampshader.cpp:92
QgsColorRampShader::readXml
void readXml(const QDomElement &elem)
Reads configuration from the given DOM element.
Definition: qgscolorrampshader.cpp:533
QgsRasterShaderFunction::minimumValue
double minimumValue() const
Returns the maximum value for the raster shader.
Definition: qgsrastershaderfunction.h:112
QgsSymbolLayerUtils::loadColorRamp
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
Definition: qgssymbollayerutils.cpp:3087
QgsColorRampShader::colorRampItemList
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Returns the custom colormap.
Definition: qgscolorrampshader.h:105
QgsColorRampShader::colorRampType
Type colorRampType() const
Returns the color ramp type.
Definition: qgscolorrampshader.h:108
QgsColorRampShader::operator=
QgsColorRampShader & operator=(const QgsColorRampShader &other)
Assignment operator.
Definition: qgscolorrampshader.cpp:59
QgsColorRampShader::ClassificationMode
ClassificationMode
Classification modes used to create the color ramp shader.
Definition: qgscolorrampshader.h:54
QgsRasterInterface
Base class for processing filters like renderers, reprojector, resampler etc.
Definition: qgsrasterinterface.h:117
QgsColorRampShader::shade
bool shade(double value, int *returnRedValue, int *returnGreenValue, int *returnBlueValue, int *returnAlphaValue) const override
Generates and new RGB value based on one input value.
Definition: qgscolorrampshader.cpp:321
QgsColorRampShader::clip
bool clip() const
Returns whether the shader will clip values which are out of range.
Definition: qgscolorrampshader.h:200
QgsColorRamp::count
virtual int count() const =0
Returns number of defined colors, or -1 if undefined.
QgsColorRamp::color
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
QgsRasterShaderFunction
The raster shade function applies a shader to a pixel at render time - typically used to render grays...
Definition: qgsrastershaderfunction.h:35
QgsColorRampShader::mSourceColorRamp
std::unique_ptr< QgsColorRamp > mSourceColorRamp
Source color ramp.
Definition: qgscolorrampshader.h:205
QgsColorRampShader::classificationMode
ClassificationMode classificationMode() const
Returns the classification mode.
Definition: qgscolorrampshader.h:187
QgsColorRampShader::ColorRampItem::label
QString label
Definition: qgscolorrampshader.h:96
qgslogger.h
QgsColorRampShader::Interpolated
@ Interpolated
Interpolates the color between two class breaks linearly.
Definition: qgscolorrampshader.h:47
QgsGradientColorRamp::isDiscrete
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
Definition: qgscolorramp.h:221
QgsColorRampShader::ColorRampItem::value
double value
Definition: qgscolorrampshader.h:97
QgsColorRamp::value
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
QgsRasterShaderFunction::setMinimumValue
virtual void setMinimumValue(double value)
Sets the minimum value for the raster shader.
Definition: qgsrastershaderfunction.cpp:38