QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
qgscolorrampshader.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscolorrampshader.cpp - description
3 -------------------
4begin : Fri Dec 28 2007
5copyright : (C) 2007 by Peter J. Ersts
7
8This class is based off of code that was originally written by Marco Hugentobler and
9originally 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 "qgscolorrampshader.h"
26
27#include <cmath>
28
29#include "qgis.h"
30#include "qgscolorrampimpl.h"
32#include "qgslogger.h"
33#include "qgsrasterinterface.h"
34#include "qgsreadwritecontext.h"
35#include "qgssymbollayerutils.h"
36
37#include <QString>
38
39using namespace Qt::StringLiterals;
40
43 , mColorRampType( type )
44 , mClassificationMode( classificationMode )
45 , mLegendSettings( std::make_unique< QgsColorRampLegendNodeSettings >() )
46{
47 QgsDebugMsgLevel( u"called."_s, 4 );
48
49 setSourceColorRamp( colorRamp );
50}
51
53
56 , mColorRampType( other.mColorRampType )
57 , mClassificationMode( other.mClassificationMode )
58 , mLUT( other.mLUT )
59 , mLUTOffset( other.mLUTOffset )
60 , mLUTFactor( other.mLUTFactor )
61 , mLUTInitialized( other.mLUTInitialized )
62 , mClip( other.mClip )
63 , mLegendSettings( other.legendSettings() ? new QgsColorRampLegendNodeSettings( *other.legendSettings() ) : new QgsColorRampLegendNodeSettings() )
64{
65 if ( auto *lSourceColorRamp = other.sourceColorRamp() )
66 mSourceColorRamp.reset( lSourceColorRamp->clone() );
67 mColorRampItemList = other.mColorRampItemList;
68}
69
71{
72 if ( &other == this )
73 return *this;
74
75 QgsRasterShaderFunction::operator=( other );
76 if ( auto *lSourceColorRamp = other.sourceColorRamp() )
77 mSourceColorRamp.reset( lSourceColorRamp->clone() );
78 else
79 mSourceColorRamp.reset();
80
81 mColorRampType = other.mColorRampType;
82 mClassificationMode = other.mClassificationMode;
83 mLUT = other.mLUT;
84 mLUTOffset = other.mLUTOffset;
85 mLUTFactor = other.mLUTFactor;
86 mLUTInitialized = other.mLUTInitialized;
87 mClip = other.mClip;
88 mColorRampItemList = other.mColorRampItemList;
89 mLegendSettings.reset( other.legendSettings() ? new QgsColorRampLegendNodeSettings( *other.legendSettings() ) : new QgsColorRampLegendNodeSettings() );
90 return *this;
91}
92
94{
95 switch ( mColorRampType )
96 {
98 return u"INTERPOLATED"_s;
100 return u"DISCRETE"_s;
102 return u"EXACT"_s;
103 }
104 return u"Unknown"_s;
105}
106
107void QgsColorRampShader::setColorRampItemList( const QList<QgsColorRampShader::ColorRampItem> &list )
108{
109 mColorRampItemList = list.toVector();
110 // Reset the look up table when the color ramp is changed
111 mLUTInitialized = false;
112 mLUT.clear();
113}
114
119
121{
122 return mColorRampItemList.isEmpty();
123}
124
125void QgsColorRampShader::setColorRampType( const QString &type )
126{
127 if ( type == "INTERPOLATED"_L1 )
128 {
130 }
131 else if ( type == "DISCRETE"_L1 )
132 {
134 }
135 else
136 {
138 }
139}
140
145
147{
148 auto ramp = std::make_unique< QgsGradientColorRamp >();
149 const int count = mColorRampItemList.size();
150 if ( count == 0 )
151 {
152 const QColor none( 0, 0, 0, 0 );
153 ramp->setColor1( none );
154 ramp->setColor2( none );
155 }
156 else if ( count == 1 )
157 {
158 ramp->setColor1( mColorRampItemList[0].color );
159 ramp->setColor2( mColorRampItemList[0].color );
160 }
161 else
162 {
164 // minimum and maximum values can fall outside the range of the item list
165 const double min = minimumValue();
166 const double max = maximumValue();
167 for ( int i = 0; i < count; i++ )
168 {
169 const double offset = ( mColorRampItemList[i].value - min ) / ( max - min );
170 if ( i == 0 )
171 {
172 ramp->setColor1( mColorRampItemList[i].color );
173 if ( offset <= 0.0 )
174 continue;
175 }
176 else if ( i == count - 1 )
177 {
178 ramp->setColor2( mColorRampItemList[i].color );
179 if ( offset >= 1.0 )
180 continue;
181 }
182 stops << QgsGradientStop( offset, mColorRampItemList[i].color );
183 }
184 ramp->setStops( stops );
185 }
186
187 return ramp.release();
188}
189
191{
192 mSourceColorRamp.reset( colorramp );
193}
194
195void QgsColorRampShader::classifyColorRamp( const int classes, const int band, const QgsRectangle &extent, QgsRasterInterface *input )
196{
197 if ( minimumValue() > maximumValue() )
198 return;
199
201
202 QList<double> entryValues;
203 QVector<QColor> entryColors;
204
205 double min = minimumValue();
206 double max = maximumValue();
207
208 if ( minimumValue() == maximumValue() )
209 {
210 if ( sourceColorRamp() && sourceColorRamp()->count() > 1 )
211 {
212 entryValues.push_back( min );
213 if ( discrete )
214 entryValues.push_back( std::numeric_limits<double>::infinity() );
215 for ( int i = 0; i < entryValues.size(); ++i )
216 entryColors.push_back( sourceColorRamp()->color( sourceColorRamp()->value( i ) ) );
217 }
218 }
220 {
221 if ( sourceColorRamp() && sourceColorRamp()->count() > 1 )
222 {
223 int numberOfEntries = sourceColorRamp()->count();
224 entryValues.reserve( numberOfEntries );
225 if ( discrete )
226 {
227 double intervalDiff = max - min;
228
229 // remove last class when ColorRamp is gradient and discrete, as they are implemented with an extra stop
230 QgsGradientColorRamp *colorGradientRamp = dynamic_cast<QgsGradientColorRamp *>( sourceColorRamp() );
231 if ( colorGradientRamp && colorGradientRamp->isDiscrete() )
232 {
233 numberOfEntries--;
234 }
235 else
236 {
237 // if color ramp is continuous scale values to get equally distributed classes.
238 // Doesn't work perfectly when stops are non equally distributed.
239 intervalDiff *= ( numberOfEntries - 1 ) / static_cast<double>( numberOfEntries );
240 }
241
242 // skip first value (always 0.0)
243 for ( int i = 1; i < numberOfEntries; ++i )
244 {
245 const double value = sourceColorRamp()->value( i );
246 entryValues.push_back( min + value * intervalDiff );
247 }
248 entryValues.push_back( std::numeric_limits<double>::infinity() );
249 }
250 else
251 {
252 for ( int i = 0; i < numberOfEntries; ++i )
253 {
254 const double value = sourceColorRamp()->value( i );
255 entryValues.push_back( min + value * ( max - min ) );
256 }
257 }
258 // for continuous mode take original color map colors
259 for ( int i = 0; i < numberOfEntries; ++i )
260 {
261 const int idx = i;
262 entryColors.push_back( sourceColorRamp()->color( sourceColorRamp()->value( idx ) ) );
263 }
264 }
265 }
266 else // for other classification modes interpolate colors linearly
267 {
268 if ( classes < 2 )
269 return; // < 2 classes is not useful, shouldn't happen, but if it happens save it from crashing
270
272 {
273 // Quantile
274 if ( band < 0 || !input )
275 return; // quantile classification requires a valid band, minMaxOrigin, and input
276
277 double cut1 = std::numeric_limits<double>::quiet_NaN();
278 double cut2 = std::numeric_limits<double>::quiet_NaN();
279 // Note: the sample size in other parts of QGIS appears to be 25000, it is ten times here.
280 const int sampleSize = 250000 * 10;
281
282 // set min and max from histogram, used later to calculate number of decimals to display
283 input->cumulativeCut( band, 0.0, 1.0, min, max, extent, sampleSize );
284
285 entryValues.reserve( classes );
286 if ( discrete )
287 {
288 const double intervalDiff = 1.0 / ( classes );
289 for ( int i = 1; i < classes; ++i )
290 {
291 input->cumulativeCut( band, 0.0, i * intervalDiff, cut1, cut2, extent, sampleSize );
292 entryValues.push_back( cut2 );
293 }
294 entryValues.push_back( std::numeric_limits<double>::infinity() );
295 }
296 else
297 {
298 const double intervalDiff = 1.0 / ( classes - 1 );
299 for ( int i = 0; i < classes; ++i )
300 {
301 input->cumulativeCut( band, 0.0, i * intervalDiff, cut1, cut2, extent, sampleSize );
302 entryValues.push_back( cut2 );
303 }
304 }
305 }
306 else // EqualInterval
307 {
308 entryValues.reserve( classes );
309 if ( discrete )
310 {
311 // in discrete mode the lowest value is not an entry and the highest
312 // value is inf, there are ( numberOfEntries ) of which the first
313 // and last are not used.
314 const double intervalDiff = ( max - min ) / ( classes );
315
316 for ( int i = 1; i < classes; ++i )
317 {
318 entryValues.push_back( min + i * intervalDiff );
319 }
320 entryValues.push_back( std::numeric_limits<double>::infinity() );
321 }
322 else
323 {
324 //because the highest value is also an entry, there are (numberOfEntries - 1) intervals
325 const double intervalDiff = ( max - min ) / ( classes - 1 );
326
327 for ( int i = 0; i < classes; ++i )
328 {
329 entryValues.push_back( min + i * intervalDiff );
330 }
331 }
332 }
333
334 if ( !sourceColorRamp() || sourceColorRamp()->count() == 1 )
335 {
336 //hard code color range from blue -> red (previous default)
337 int colorDiff = 0;
338 if ( classes != 0 )
339 {
340 colorDiff = ( int ) ( 255 / classes );
341 }
342
343 entryColors.reserve( classes );
344 for ( int i = 0; i < classes; ++i )
345 {
346 QColor currentColor;
347 const int idx = i;
348 currentColor.setRgb( colorDiff * idx, 0, 255 - colorDiff * idx );
349 entryColors.push_back( currentColor );
350 }
351 }
352 else
353 {
354 entryColors.reserve( classes );
355 for ( int i = 0; i < classes; ++i )
356 {
357 const int idx = i;
358 entryColors.push_back( sourceColorRamp()->color( ( ( double ) idx ) / ( classes - 1 ) ) );
359 }
360 }
361 }
362
363 QList<double>::const_iterator value_it = entryValues.constBegin();
364 QVector<QColor>::const_iterator color_it = entryColors.constBegin();
365
366 // calculate a reasonable number of decimals to display
367 const double maxabs = std::log10( std::max( std::fabs( max ), std::fabs( min ) ) );
368 const int nDecimals = std::round( std::max( 3.0 + maxabs - std::log10( max - min ), maxabs <= 15.0 ? maxabs + 0.49 : 0.0 ) );
369
370 QList<QgsColorRampShader::ColorRampItem> colorRampItems;
371 for ( ; value_it != entryValues.constEnd(); ++value_it, ++color_it )
372 {
373 QgsColorRampShader::ColorRampItem newColorRampItem;
374 newColorRampItem.value = *value_it;
375 newColorRampItem.color = *color_it;
376 newColorRampItem.label = QString::number( *value_it, 'g', nDecimals );
377 colorRampItems.append( newColorRampItem );
378 }
379
380 std::sort( colorRampItems.begin(), colorRampItems.end() );
381 setColorRampItemList( colorRampItems );
382}
383
384void QgsColorRampShader::classifyColorRamp( const int band, const QgsRectangle &extent, QgsRasterInterface *input )
385{
386 classifyColorRamp( colorRampItemList().count(), band, extent, input );
387}
388
389bool QgsColorRampShader::shade( double value, int *returnRedValue, int *returnGreenValue, int *returnBlueValue, int *returnAlphaValue ) const
390{
391 const int colorRampItemListCount = mColorRampItemList.count();
392 if ( colorRampItemListCount == 0 )
393 {
394 return false;
395 }
396 if ( std::isnan( value ) || std::isinf( value ) )
397 return false;
398
399 const QgsColorRampShader::ColorRampItem *colorRampItems = mColorRampItemList.constData();
400 int idx;
401 if ( !mLUTInitialized )
402 {
403 // calculate LUT for faster index recovery
404 mLUTFactor = 1.0;
405 const double minimumValue = colorRampItems[0].value;
406 mLUTOffset = minimumValue + DOUBLE_DIFF_THRESHOLD;
407 // Only make lut if at least 3 items, with 2 items the low and high cases handle both
408 if ( colorRampItemListCount >= 3 )
409 {
410 const double rangeValue = colorRampItems[colorRampItemListCount - 2].value - minimumValue;
411 if ( rangeValue > 0 )
412 {
413 const int lutSize = 256; // TODO: test if speed can be increased with a different LUT size
414 mLUTFactor = ( lutSize - 0.0000001 ) / rangeValue; // decrease slightly to make sure last LUT category is correct
415 idx = 0;
416 double val;
417 mLUT.reserve( lutSize );
418 for ( int i = 0; i < lutSize; i++ )
419 {
420 val = ( i / mLUTFactor ) + mLUTOffset;
421 while ( idx < colorRampItemListCount && colorRampItems[idx].value - DOUBLE_DIFF_THRESHOLD < val )
422 {
423 idx++;
424 }
425 mLUT.emplace_back( idx );
426 }
427 }
428 }
429 mLUTInitialized = true;
430 }
431
432 // overflow indicates that value > maximum value + DOUBLE_DIFF_THRESHOLD
433 // that way idx can point to the last valid item
434 bool overflow = false;
435
436 // find index of the first ColorRampItem that is equal or higher to theValue
437 const int lutIndex = ( value - mLUTOffset ) * mLUTFactor;
438 if ( value <= mLUTOffset )
439 {
440 idx = 0;
441 }
442 else if ( static_cast< std::size_t>( lutIndex ) >= mLUT.size() )
443 {
444 idx = colorRampItemListCount - 1;
445 if ( colorRampItems[idx].value + DOUBLE_DIFF_THRESHOLD < value )
446 {
447 overflow = true;
448 }
449 }
450 else if ( lutIndex < 0 )
451 {
452 return false;
453 }
454 else
455 {
456 // get initial value from LUT
457 idx = mLUT[lutIndex];
458
459 // check if it's correct and if not increase until correct
460 // the LUT is made in such a way the index is always correct or too low, never too high
461 while ( idx < colorRampItemListCount && colorRampItems[idx].value + DOUBLE_DIFF_THRESHOLD < value )
462 {
463 idx++;
464 }
465 if ( idx >= colorRampItemListCount )
466 {
467 idx = colorRampItemListCount - 1;
468 overflow = true;
469 }
470 }
471
472 const QgsColorRampShader::ColorRampItem &currentColorRampItem = colorRampItems[idx];
473
474 switch ( mColorRampType )
475 {
477 {
478 // Interpolate the color between two class breaks linearly.
479 if ( idx < 1 || overflow || currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD <= value )
480 {
481 if ( mClip && ( overflow || currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD > value ) )
482 {
483 return false;
484 }
485 *returnRedValue = currentColorRampItem.color.red();
486 *returnGreenValue = currentColorRampItem.color.green();
487 *returnBlueValue = currentColorRampItem.color.blue();
488 *returnAlphaValue = currentColorRampItem.color.alpha();
489 return true;
490 }
491
492 const QgsColorRampShader::ColorRampItem &previousColorRampItem = colorRampItems[idx - 1];
493
494 const float currentRampRange = currentColorRampItem.value - previousColorRampItem.value;
495 const float offsetInRange = value - previousColorRampItem.value;
496 const float scale = offsetInRange / currentRampRange;
497
498 const int c1Red = previousColorRampItem.color.red();
499 const int c1Green = previousColorRampItem.color.green();
500 const int c1Blue = previousColorRampItem.color.blue();
501 const int c1Alpha = previousColorRampItem.color.alpha();
502
503 const int c2Red = currentColorRampItem.color.red();
504 const int c2Green = currentColorRampItem.color.green();
505 const int c2Blue = currentColorRampItem.color.blue();
506 const int c2Alpha = currentColorRampItem.color.alpha();
507
508 *returnRedValue = c1Red + static_cast< int >( ( c2Red - c1Red ) * scale );
509 *returnGreenValue = c1Green + static_cast< int >( ( c2Green - c1Green ) * scale );
510 *returnBlueValue = c1Blue + static_cast< int >( ( c2Blue - c1Blue ) * scale );
511 *returnAlphaValue = c1Alpha + static_cast< int >( ( c2Alpha - c1Alpha ) * scale );
512 return true;
513 };
515 {
516 // Assign the color of the higher class for every pixel between two class breaks.
517 // NOTE: The implementation has always been different than the documentation,
518 // which said lower class before, see https://github.com/qgis/QGIS/issues/22009
519 if ( overflow )
520 {
521 return false;
522 }
523 *returnRedValue = currentColorRampItem.color.red();
524 *returnGreenValue = currentColorRampItem.color.green();
525 *returnBlueValue = currentColorRampItem.color.blue();
526 *returnAlphaValue = currentColorRampItem.color.alpha();
527 return true;
528 };
530 {
531 // Assign the color of the exact matching value in the color ramp item list
532 if ( !overflow && currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD <= value )
533 {
534 *returnRedValue = currentColorRampItem.color.red();
535 *returnGreenValue = currentColorRampItem.color.green();
536 *returnBlueValue = currentColorRampItem.color.blue();
537 *returnAlphaValue = currentColorRampItem.color.alpha();
538 return true;
539 }
540 else
541 {
542 return false;
543 }
544 }
545 }
546 return false;
547}
548
549bool QgsColorRampShader::shade( double redValue, double greenValue, double blueValue, double alphaValue, int *returnRedValue, int *returnGreenValue, int *returnBlueValue, int *returnAlphaValue ) const
550{
551 Q_UNUSED( redValue )
552 Q_UNUSED( greenValue )
553 Q_UNUSED( blueValue )
554 Q_UNUSED( alphaValue )
555
556 *returnRedValue = 0;
557 *returnGreenValue = 0;
558 *returnBlueValue = 0;
559 *returnAlphaValue = 0;
560
561 return false;
562}
563
564void QgsColorRampShader::legendSymbologyItems( QList< QPair< QString, QColor > > &symbolItems ) const
565{
566 QVector<QgsColorRampShader::ColorRampItem>::const_iterator colorRampIt = mColorRampItemList.constBegin();
567 for ( ; colorRampIt != mColorRampItemList.constEnd(); ++colorRampIt )
568 {
569 symbolItems.push_back( qMakePair( colorRampIt->label, colorRampIt->color ) );
570 }
571}
572
573QDomElement QgsColorRampShader::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
574{
575 QDomElement colorRampShaderElem = doc.createElement( u"colorrampshader"_s );
576 colorRampShaderElem.setAttribute( u"colorRampType"_s, colorRampTypeAsQString() );
577 colorRampShaderElem.setAttribute( u"classificationMode"_s, static_cast< int >( classificationMode() ) );
578 colorRampShaderElem.setAttribute( u"clip"_s, clip() );
579 colorRampShaderElem.setAttribute( u"minimumValue"_s, mMinimumValue );
580 colorRampShaderElem.setAttribute( u"maximumValue"_s, mMaximumValue );
581 colorRampShaderElem.setAttribute( u"labelPrecision"_s, mLabelPrecision );
582
583 // save source color ramp
584 if ( sourceColorRamp() )
585 {
586 const QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( u"[source]"_s, sourceColorRamp(), doc );
587 colorRampShaderElem.appendChild( colorRampElem );
588 }
589
590 //items
591 const QList<QgsColorRampShader::ColorRampItem> itemList = colorRampItemList();
592 QList<QgsColorRampShader::ColorRampItem>::const_iterator itemIt = itemList.constBegin();
593 for ( ; itemIt != itemList.constEnd(); ++itemIt )
594 {
595 QDomElement itemElem = doc.createElement( u"item"_s );
596 itemElem.setAttribute( u"label"_s, itemIt->label );
597 itemElem.setAttribute( u"value"_s, QgsRasterBlock::printValue( itemIt->value ) );
598 itemElem.setAttribute( u"color"_s, itemIt->color.name() );
599 itemElem.setAttribute( u"alpha"_s, itemIt->color.alpha() );
600 colorRampShaderElem.appendChild( itemElem );
601 }
602
603 if ( mLegendSettings )
604 mLegendSettings->writeXml( doc, colorRampShaderElem, context );
605
606 return colorRampShaderElem;
607}
608
609void QgsColorRampShader::readXml( const QDomElement &colorRampShaderElem, const QgsReadWriteContext &context )
610{
611 // try to load color ramp (optional)
612 QDomElement sourceColorRampElem = colorRampShaderElem.firstChildElement( u"colorramp"_s );
613 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( u"name"_s ) == "[source]"_L1 )
614 {
615 setSourceColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ).release() );
616 }
617
618 setColorRampType( colorRampShaderElem.attribute( u"colorRampType"_s, u"INTERPOLATED"_s ) );
619 setClassificationMode( static_cast< Qgis::ShaderClassificationMethod >( colorRampShaderElem.attribute( u"classificationMode"_s, u"1"_s ).toInt() ) );
620 setClip( colorRampShaderElem.attribute( u"clip"_s, u"0"_s ) == "1"_L1 );
621 setMinimumValue( colorRampShaderElem.attribute( u"minimumValue"_s ).toDouble() );
622 setMaximumValue( colorRampShaderElem.attribute( u"maximumValue"_s ).toDouble() );
623 setLabelPrecision( colorRampShaderElem.attribute( u"labelPrecision"_s, u"6"_s ).toDouble() );
624
625 QList<QgsColorRampShader::ColorRampItem> itemList;
626 QDomElement itemElem;
627 QString itemLabel;
628 double itemValue;
629 QColor itemColor;
630
631 const QDomNodeList itemNodeList = colorRampShaderElem.elementsByTagName( u"item"_s );
632 itemList.reserve( itemNodeList.size() );
633 for ( int i = 0; i < itemNodeList.size(); ++i )
634 {
635 itemElem = itemNodeList.at( i ).toElement();
636 itemValue = itemElem.attribute( u"value"_s ).toDouble();
637 itemLabel = itemElem.attribute( u"label"_s );
638 itemColor.setNamedColor( itemElem.attribute( u"color"_s ) );
639 itemColor.setAlpha( itemElem.attribute( u"alpha"_s, u"255"_s ).toInt() );
640
641 itemList.push_back( QgsColorRampShader::ColorRampItem( itemValue, itemColor, itemLabel ) );
642 }
643 setColorRampItemList( itemList );
644
645 if ( !mLegendSettings )
646 mLegendSettings = std::make_unique< QgsColorRampLegendNodeSettings >();
647
648 mLegendSettings->readXml( colorRampShaderElem, context );
649}
650
652{
653 return mLegendSettings.get();
654}
655
657{
658 if ( settings == mLegendSettings.get() )
659 return;
660 mLegendSettings.reset( settings );
661}
ShaderInterpolationMethod
Color ramp shader interpolation methods.
Definition qgis.h:1503
@ Exact
Assigns the color of the exact matching value in the color ramp item list.
Definition qgis.h:1506
@ Linear
Interpolates the color between two class breaks linearly.
Definition qgis.h:1504
@ Discrete
Assigns the color of the higher class for every pixel between two class breaks.
Definition qgis.h:1505
ShaderClassificationMethod
Color ramp shader classification methods.
Definition qgis.h:1518
@ Continuous
Uses breaks from color palette.
Definition qgis.h:1519
@ Quantile
Uses quantile (i.e. equal pixel) count.
Definition qgis.h:1521
Settings for a color ramp legend node.
~QgsColorRampShader() override
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Returns legend symbology items if provided by renderer.
Qgis::ShaderClassificationMethod classificationMode() const
Returns the classification mode.
Qgis::ShaderInterpolationMethod colorRampType() const
Returns the color ramp interpolation method.
const QgsColorRampLegendNodeSettings * legendSettings() const
Returns the color ramp shader legend settings.
bool isEmpty() const
Whether the color ramp contains any items.
void setSourceColorRamp(QgsColorRamp *colorramp)
Set the source color ramp.
void setClassificationMode(Qgis::ShaderClassificationMethod classificationMode)
Sets the classification mode.
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Returns the custom color map.
QgsColorRampShader & operator=(const QgsColorRampShader &other)
void setClip(bool clip)
Sets whether the shader should not render values out of range.
bool clip() const
Returns whether the shader will clip values which are out of range.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context=QgsReadWriteContext()) const
Writes configuration to a new DOM element.
bool shade(double value, int *returnRedValue, int *returnGreenValue, int *returnBlueValue, int *returnAlphaValue) const override
Generates an new RGBA value based on one input value.
QgsColorRamp * sourceColorRamp() const
Returns the source color ramp.
QgsColorRamp * createColorRamp() const
Creates a gradient color ramp from shader settings.
void classifyColorRamp(int classes=0, int band=-1, const QgsRectangle &extent=QgsRectangle(), QgsRasterInterface *input=nullptr)
Classify color ramp shader.
void setColorRampType(Qgis::ShaderInterpolationMethod colorRampType)
Sets the color ramp interpolation method.
void setColorRampItemList(const QList< QgsColorRampShader::ColorRampItem > &list)
Sets a custom color map.
QString colorRampTypeAsQString() const
Returns the color ramp type as a string.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context=QgsReadWriteContext())
Reads configuration from the given DOM element.
QgsColorRampShader(double minimumValue=0.0, double maximumValue=255.0, QgsColorRamp *colorRamp=nullptr, Qgis::ShaderInterpolationMethod type=Qgis::ShaderInterpolationMethod::Linear, Qgis::ShaderClassificationMethod classificationMode=Qgis::ShaderClassificationMethod::Continuous)
Creates a new color ramp shader.
std::unique_ptr< QgsColorRamp > mSourceColorRamp
Source color ramp.
void setLegendSettings(QgsColorRampLegendNodeSettings *settings)
Sets the color ramp shader legend settings.
Abstract base class for color ramps.
virtual int count() const =0
Returns number of defined colors, or -1 if undefined.
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
Represents a color stop within a QgsGradientColorRamp color ramp.
static QString printValue(double value, bool localized=false)
Print double value with all necessary significant digits.
Base class for processing filters like renderers, reprojector, resampler etc.
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.
double mMinimumValue
User defineable minimum value for the shading function.
QgsRasterShaderFunction(double minimumValue=0.0, double maximumValue=255.0)
double maximumValue() const
Returns the minimum value for the raster shader.
double mMaximumValue
User defineable maximum value for the shading function.
void setLabelPrecision(int labelPrecision)
Sets label precision to labelPrecision.
virtual void setMaximumValue(double value)
Sets the maximum value for the raster shader.
virtual void setMinimumValue(double value)
Sets the minimum value for the raster shader.
int mLabelPrecision
Label precision.
double minimumValue() const
Returns the maximum value for the raster shader.
A container for the context for various read/write operations on objects.
A rectangle specified with double values.
static std::unique_ptr< QgsColorRamp > loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QDomElement saveColorRamp(const QString &name, const QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
QList< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
#define DOUBLE_DIFF_THRESHOLD
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63