QGIS API Documentation 3.99.0-Master (d270888f95f)
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
422 && colorRampItems[idx].value - DOUBLE_DIFF_THRESHOLD < val )
423 {
424 idx++;
425 }
426 mLUT.emplace_back( idx );
427 }
428 }
429 }
430 mLUTInitialized = true;
431 }
432
433 // overflow indicates that value > maximum value + DOUBLE_DIFF_THRESHOLD
434 // that way idx can point to the last valid item
435 bool overflow = false;
436
437 // find index of the first ColorRampItem that is equal or higher to theValue
438 const int lutIndex = ( value - mLUTOffset ) * mLUTFactor;
439 if ( value <= mLUTOffset )
440 {
441 idx = 0;
442 }
443 else if ( static_cast< std::size_t>( lutIndex ) >= mLUT.size() )
444 {
445 idx = colorRampItemListCount - 1;
446 if ( colorRampItems[idx].value + DOUBLE_DIFF_THRESHOLD < value )
447 {
448 overflow = true;
449 }
450 }
451 else if ( lutIndex < 0 )
452 {
453 return false;
454 }
455 else
456 {
457 // get initial value from LUT
458 idx = mLUT[ lutIndex ];
459
460 // check if it's correct and if not increase until correct
461 // the LUT is made in such a way the index is always correct or too low, never too high
462 while ( idx < colorRampItemListCount && colorRampItems[idx].value + DOUBLE_DIFF_THRESHOLD < value )
463 {
464 idx++;
465 }
466 if ( idx >= colorRampItemListCount )
467 {
468 idx = colorRampItemListCount - 1;
469 overflow = true;
470 }
471 }
472
473 const QgsColorRampShader::ColorRampItem &currentColorRampItem = colorRampItems[idx];
474
475 switch ( mColorRampType )
476 {
478 {
479 // Interpolate the color between two class breaks linearly.
480 if ( idx < 1 || overflow || currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD <= value )
481 {
482 if ( mClip && ( overflow
483 || currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD > value ) )
484 {
485 return false;
486 }
487 *returnRedValue = currentColorRampItem.color.red();
488 *returnGreenValue = currentColorRampItem.color.green();
489 *returnBlueValue = currentColorRampItem.color.blue();
490 *returnAlphaValue = currentColorRampItem.color.alpha();
491 return true;
492 }
493
494 const QgsColorRampShader::ColorRampItem &previousColorRampItem = colorRampItems[idx - 1];
495
496 const float currentRampRange = currentColorRampItem.value - previousColorRampItem.value;
497 const float offsetInRange = value - previousColorRampItem.value;
498 const float scale = offsetInRange / currentRampRange;
499
500 const int c1Red = previousColorRampItem.color.red();
501 const int c1Green = previousColorRampItem.color.green();
502 const int c1Blue = previousColorRampItem.color.blue();
503 const int c1Alpha = previousColorRampItem.color.alpha();
504
505 const int c2Red = currentColorRampItem.color.red();
506 const int c2Green = currentColorRampItem.color.green();
507 const int c2Blue = currentColorRampItem.color.blue();
508 const int c2Alpha = currentColorRampItem.color.alpha();
509
510 *returnRedValue = c1Red + static_cast< int >( ( c2Red - c1Red ) * scale );
511 *returnGreenValue = c1Green + static_cast< int >( ( c2Green - c1Green ) * scale );
512 *returnBlueValue = c1Blue + static_cast< int >( ( c2Blue - c1Blue ) * scale );
513 *returnAlphaValue = c1Alpha + static_cast< int >( ( c2Alpha - c1Alpha ) * scale );
514 return true;
515 };
517 {
518 // Assign the color of the higher class for every pixel between two class breaks.
519 // NOTE: The implementation has always been different than the documentation,
520 // which said lower class before, see https://github.com/qgis/QGIS/issues/22009
521 if ( overflow )
522 {
523 return false;
524 }
525 *returnRedValue = currentColorRampItem.color.red();
526 *returnGreenValue = currentColorRampItem.color.green();
527 *returnBlueValue = currentColorRampItem.color.blue();
528 *returnAlphaValue = currentColorRampItem.color.alpha();
529 return true;
530 };
532 {
533 // Assign the color of the exact matching value in the color ramp item list
534 if ( !overflow && currentColorRampItem.value - DOUBLE_DIFF_THRESHOLD <= value )
535 {
536 *returnRedValue = currentColorRampItem.color.red();
537 *returnGreenValue = currentColorRampItem.color.green();
538 *returnBlueValue = currentColorRampItem.color.blue();
539 *returnAlphaValue = currentColorRampItem.color.alpha();
540 return true;
541 }
542 else
543 {
544 return false;
545 }
546 }
547 }
548 return false;
549}
550
551bool QgsColorRampShader::shade( double redValue, double greenValue,
552 double blueValue, double alphaValue,
553 int *returnRedValue, int *returnGreenValue,
554 int *returnBlueValue, int *returnAlphaValue ) const
555{
556 Q_UNUSED( redValue )
557 Q_UNUSED( greenValue )
558 Q_UNUSED( blueValue )
559 Q_UNUSED( alphaValue )
560
561 *returnRedValue = 0;
562 *returnGreenValue = 0;
563 *returnBlueValue = 0;
564 *returnAlphaValue = 0;
565
566 return false;
567}
568
569void QgsColorRampShader::legendSymbologyItems( QList< QPair< QString, QColor > > &symbolItems ) const
570{
571 QVector<QgsColorRampShader::ColorRampItem>::const_iterator colorRampIt = mColorRampItemList.constBegin();
572 for ( ; colorRampIt != mColorRampItemList.constEnd(); ++colorRampIt )
573 {
574 symbolItems.push_back( qMakePair( colorRampIt->label, colorRampIt->color ) );
575 }
576}
577
578QDomElement QgsColorRampShader::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
579{
580 QDomElement colorRampShaderElem = doc.createElement( u"colorrampshader"_s );
581 colorRampShaderElem.setAttribute( u"colorRampType"_s, colorRampTypeAsQString() );
582 colorRampShaderElem.setAttribute( u"classificationMode"_s, static_cast< int >( classificationMode() ) );
583 colorRampShaderElem.setAttribute( u"clip"_s, clip() );
584 colorRampShaderElem.setAttribute( u"minimumValue"_s, mMinimumValue );
585 colorRampShaderElem.setAttribute( u"maximumValue"_s, mMaximumValue );
586 colorRampShaderElem.setAttribute( u"labelPrecision"_s, mLabelPrecision );
587
588 // save source color ramp
589 if ( sourceColorRamp() )
590 {
591 const QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( u"[source]"_s, sourceColorRamp(), doc );
592 colorRampShaderElem.appendChild( colorRampElem );
593 }
594
595 //items
596 const QList<QgsColorRampShader::ColorRampItem> itemList = colorRampItemList();
597 QList<QgsColorRampShader::ColorRampItem>::const_iterator itemIt = itemList.constBegin();
598 for ( ; itemIt != itemList.constEnd(); ++itemIt )
599 {
600 QDomElement itemElem = doc.createElement( u"item"_s );
601 itemElem.setAttribute( u"label"_s, itemIt->label );
602 itemElem.setAttribute( u"value"_s, QgsRasterBlock::printValue( itemIt->value ) );
603 itemElem.setAttribute( u"color"_s, itemIt->color.name() );
604 itemElem.setAttribute( u"alpha"_s, itemIt->color.alpha() );
605 colorRampShaderElem.appendChild( itemElem );
606 }
607
608 if ( mLegendSettings )
609 mLegendSettings->writeXml( doc, colorRampShaderElem, context );
610
611 return colorRampShaderElem;
612}
613
614void QgsColorRampShader::readXml( const QDomElement &colorRampShaderElem, const QgsReadWriteContext &context )
615{
616 // try to load color ramp (optional)
617 QDomElement sourceColorRampElem = colorRampShaderElem.firstChildElement( u"colorramp"_s );
618 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( u"name"_s ) == "[source]"_L1 )
619 {
620 setSourceColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ).release() );
621 }
622
623 setColorRampType( colorRampShaderElem.attribute( u"colorRampType"_s, u"INTERPOLATED"_s ) );
624 setClassificationMode( static_cast< Qgis::ShaderClassificationMethod >( colorRampShaderElem.attribute( u"classificationMode"_s, u"1"_s ).toInt() ) );
625 setClip( colorRampShaderElem.attribute( u"clip"_s, u"0"_s ) == "1"_L1 );
626 setMinimumValue( colorRampShaderElem.attribute( u"minimumValue"_s ).toDouble() );
627 setMaximumValue( colorRampShaderElem.attribute( u"maximumValue"_s ).toDouble() );
628 setLabelPrecision( colorRampShaderElem.attribute( u"labelPrecision"_s, u"6"_s ).toDouble() );
629
630 QList<QgsColorRampShader::ColorRampItem> itemList;
631 QDomElement itemElem;
632 QString itemLabel;
633 double itemValue;
634 QColor itemColor;
635
636 const QDomNodeList itemNodeList = colorRampShaderElem.elementsByTagName( u"item"_s );
637 itemList.reserve( itemNodeList.size() );
638 for ( int i = 0; i < itemNodeList.size(); ++i )
639 {
640 itemElem = itemNodeList.at( i ).toElement();
641 itemValue = itemElem.attribute( u"value"_s ).toDouble();
642 itemLabel = itemElem.attribute( u"label"_s );
643 itemColor.setNamedColor( itemElem.attribute( u"color"_s ) );
644 itemColor.setAlpha( itemElem.attribute( u"alpha"_s, u"255"_s ).toInt() );
645
646 itemList.push_back( QgsColorRampShader::ColorRampItem( itemValue, itemColor, itemLabel ) );
647 }
648 setColorRampItemList( itemList );
649
650 if ( !mLegendSettings )
651 mLegendSettings = std::make_unique< QgsColorRampLegendNodeSettings >();
652
653 mLegendSettings->readXml( colorRampShaderElem, context );
654}
655
657{
658 return mLegendSettings.get();
659}
660
662{
663 if ( settings == mLegendSettings.get() )
664 return;
665 mLegendSettings.reset( settings );
666}
ShaderInterpolationMethod
Color ramp shader interpolation methods.
Definition qgis.h:1483
@ Exact
Assigns the color of the exact matching value in the color ramp item list.
Definition qgis.h:1486
@ Linear
Interpolates the color between two class breaks linearly.
Definition qgis.h:1484
@ Discrete
Assigns the color of the higher class for every pixel between two class breaks.
Definition qgis.h:1485
ShaderClassificationMethod
Color ramp shader classification methods.
Definition qgis.h:1498
@ Continuous
Uses breaks from color palette.
Definition qgis.h:1499
@ Quantile
Uses quantile (i.e. equal pixel) count.
Definition qgis.h:1501
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