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