23 #define DOUBLE_DIFF_THRESHOLD 0.0 // 0.0000001 35 , mColorRampType( type )
36 , mClassificationMode( classificationMode )
45 , mColorRampType( other.mColorRampType )
46 , mClassificationMode( other.mClassificationMode )
48 , mLUTOffset( other.mLUTOffset )
49 , mLUTFactor( other.mLUTFactor )
50 , mLUTInitialized( other.mLUTInitialized )
51 , mClip( other.mClip )
59 mColorRampType = other.mColorRampType;
60 mClassificationMode = other.mClassificationMode;
62 mLUTOffset = other.mLUTOffset;
63 mLUTFactor = other.mLUTFactor;
64 mLUTInitialized = other.mLUTInitialized;
71 switch ( mColorRampType )
74 return QStringLiteral(
"INTERPOLATED" );
76 return QStringLiteral(
"DISCRETE" );
78 return QStringLiteral(
"EXACT" );
80 return QStringLiteral(
"Unknown" );
85 mColorRampItemList = list.toVector();
87 mLUTInitialized =
false;
98 if ( type == QLatin1String(
"INTERPOLATED" ) )
102 else if ( type == QLatin1String(
"DISCRETE" ) )
108 mColorRampType =
Exact;
131 QList<double> entryValues;
132 QVector<QColor> entryColors;
142 entryValues.reserve( numberOfEntries );
145 double intervalDiff = max - min;
149 if ( colorGradientRamp && colorGradientRamp->
isDiscrete() )
157 intervalDiff *= ( numberOfEntries - 1 ) / (
double )numberOfEntries;
161 for (
int i = 1; i < numberOfEntries; ++i )
164 entryValues.push_back( min + value * intervalDiff );
166 entryValues.push_back( std::numeric_limits<double>::infinity() );
170 for (
int i = 0; i < numberOfEntries; ++i )
173 entryValues.push_back( min + value * ( max - min ) );
177 for (
int i = 0; i < numberOfEntries; ++i )
192 if ( band < 0 || !input )
195 double cut1 = std::numeric_limits<double>::quiet_NaN();
196 double cut2 = std::numeric_limits<double>::quiet_NaN();
197 int sampleSize = 250000;
200 input->
cumulativeCut( band, 0.0, 1.0, min, max, extent, sampleSize );
202 entryValues.reserve( classes );
205 double intervalDiff = 1.0 / ( classes );
206 for (
int i = 1; i < classes; ++i )
208 input->
cumulativeCut( band, 0.0, i * intervalDiff, cut1, cut2, extent, sampleSize );
209 entryValues.push_back( cut2 );
211 entryValues.push_back( std::numeric_limits<double>::infinity() );
215 double intervalDiff = 1.0 / ( classes - 1 );
216 for (
int i = 0; i < classes; ++i )
218 input->
cumulativeCut( band, 0.0, i * intervalDiff, cut1, cut2, extent, sampleSize );
219 entryValues.push_back( cut2 );
225 entryValues.reserve( classes );
231 double intervalDiff = ( max - min ) / ( classes );
233 for (
int i = 1; i < classes; ++i )
235 entryValues.push_back( min + i * intervalDiff );
237 entryValues.push_back( std::numeric_limits<double>::infinity() );
242 double intervalDiff = ( max - min ) / ( classes - 1 );
244 for (
int i = 0; i < classes; ++i )
246 entryValues.push_back( min + i * intervalDiff );
257 colorDiff = ( int )( 255 / classes );
260 entryColors.reserve( classes );
261 for (
int i = 0; i < classes; ++i )
265 currentColor.setRgb( colorDiff * idx, 0, 255 - colorDiff * idx );
266 entryColors.push_back( currentColor );
271 entryColors.reserve( classes );
272 for (
int i = 0; i < classes; ++i )
275 entryColors.push_back(
sourceColorRamp()->color( ( (
double ) idx ) / ( classes - 1 ) ) );
280 QList<double>::const_iterator value_it = entryValues.constBegin();
281 QVector<QColor>::const_iterator color_it = entryColors.constBegin();
284 double maxabs = std::log10( std::max( std::fabs( max ), std::fabs( min ) ) );
285 int nDecimals = std::round( std::max( 3.0 + maxabs - std::log10( max - min ), maxabs <= 15.0 ? maxabs + 0.49 : 0.0 ) );
287 QList<QgsColorRampShader::ColorRampItem> colorRampItems;
288 for ( ; value_it != entryValues.constEnd(); ++value_it, ++color_it )
291 newColorRampItem.
value = *value_it;
292 newColorRampItem.
color = *color_it;
293 newColorRampItem.
label = QString::number( *value_it,
'g', nDecimals );
294 colorRampItems.append( newColorRampItem );
297 std::sort( colorRampItems.begin(), colorRampItems.end() );
308 if ( mColorRampItemList.isEmpty() )
312 if ( std::isnan( value ) || std::isinf( value ) )
315 int colorRampItemListCount = mColorRampItemList.count();
317 if ( !mLUTInitialized )
324 if ( colorRampItemListCount >= 3 )
326 double rangeValue = mColorRampItemList.at( colorRampItemListCount - 2 ).value -
minimumValue;
327 if ( rangeValue > 0 )
330 mLUTFactor = ( lutSize - 0.0000001 ) / rangeValue;
333 mLUT.reserve( lutSize );
334 for (
int i = 0; i < lutSize; i++ )
336 val = ( i / mLUTFactor ) + mLUTOffset;
337 while ( idx < colorRampItemListCount
338 && mColorRampItemList.at( idx ).value - DOUBLE_DIFF_THRESHOLD < val )
342 mLUT.push_back( idx );
346 mLUTInitialized =
true;
351 bool overflow =
false;
354 int lutIndex = ( value - mLUTOffset ) * mLUTFactor;
355 if ( value < mLUTOffset )
359 else if ( lutIndex >= mLUT.count() )
361 idx = colorRampItemListCount - 1;
370 idx = mLUT.at( lutIndex );
374 while ( idx < colorRampItemListCount && mColorRampItemList.at( idx ).value +
DOUBLE_DIFF_THRESHOLD < value )
378 if ( idx >= colorRampItemListCount )
380 idx = colorRampItemListCount - 1;
392 if ( mClip && ( overflow
397 *returnRedValue = currentColorRampItem.
color.red();
398 *returnGreenValue = currentColorRampItem.
color.green();
399 *returnBlueValue = currentColorRampItem.
color.blue();
400 *returnAlphaValue = currentColorRampItem.
color.alpha();
406 double currentRampRange = currentColorRampItem.
value - previousColorRampItem.
value;
407 double offsetInRange = value - previousColorRampItem.
value;
408 double scale = offsetInRange / currentRampRange;
410 *returnRedValue =
static_cast< int >(
static_cast< double >( previousColorRampItem.
color.red() ) + ( static_cast< double >( currentColorRampItem.
color.red() - previousColorRampItem.
color.red() ) * scale ) );
411 *returnGreenValue =
static_cast< int >(
static_cast< double >( previousColorRampItem.
color.green() ) + ( static_cast< double >( currentColorRampItem.
color.green() - previousColorRampItem.
color.green() ) * scale ) );
412 *returnBlueValue =
static_cast< int >(
static_cast< double >( previousColorRampItem.
color.blue() ) + ( static_cast< double >( currentColorRampItem.
color.blue() - previousColorRampItem.
color.blue() ) * scale ) );
413 *returnAlphaValue =
static_cast< int >(
static_cast< double >( previousColorRampItem.
color.alpha() ) + ( static_cast< double >( currentColorRampItem.
color.alpha() - previousColorRampItem.
color.alpha() ) * scale ) );
425 *returnRedValue = currentColorRampItem.
color.red();
426 *returnGreenValue = currentColorRampItem.
color.green();
427 *returnBlueValue = currentColorRampItem.
color.blue();
428 *returnAlphaValue = currentColorRampItem.
color.alpha();
436 *returnRedValue = currentColorRampItem.
color.red();
437 *returnGreenValue = currentColorRampItem.
color.green();
438 *returnBlueValue = currentColorRampItem.
color.blue();
439 *returnAlphaValue = currentColorRampItem.
color.alpha();
450 double blueValue,
double alphaValue,
451 int *returnRedValue,
int *returnGreenValue,
452 int *returnBlueValue,
int *returnAlphaValue )
454 Q_UNUSED( redValue );
455 Q_UNUSED( greenValue );
456 Q_UNUSED( blueValue );
457 Q_UNUSED( alphaValue );
460 *returnGreenValue = 0;
461 *returnBlueValue = 0;
462 *returnAlphaValue = 0;
469 QVector<QgsColorRampShader::ColorRampItem>::const_iterator colorRampIt = mColorRampItemList.constBegin();
470 for ( ; colorRampIt != mColorRampItemList.constEnd(); ++colorRampIt )
472 symbolItems.push_back( qMakePair( colorRampIt->label, colorRampIt->color ) );
A rectangle specified with double values.
void setColorRampItemList(const QList< QgsColorRampShader::ColorRampItem > &list)
Set custom colormap.
Uses quantile (i.e. equal pixel) count.
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
Abstract base class for color ramps.
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Get the custom colormap.
QgsColorRampShader & operator=(const QgsColorRampShader &other)
Assignment operator.
double maximumValue() const
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.
Type
Supported methods for color interpolation.
void setColorRampType(QgsColorRampShader::Type colorRampType)
Set the color ramp type.
#define QgsDebugMsgLevel(str, level)
The raster shade function applies a shader to a pixel at render time - typically used to render grays...
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Get symbology items if provided by renderer.
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
virtual int count() const =0
Returns number of defined colors, or -1 if undefined.
void setSourceColorRamp(QgsColorRamp *colorramp)
Set the source color ramp.
double minimumValue() const
Base class for processing filters like renderers, reprojector, resampler etc.
QString colorRampTypeAsQString()
Get the color ramp type as a string.
bool shade(double value, int *returnRedValue, int *returnGreenValue, int *returnBlueValue, int *returnAlphaValue) override
Generates and new RGB value based on one input value.
Type colorRampType() const
Get the color ramp type.
Assigns the color of the exact matching value in the color ramp item list.
void classifyColorRamp(const int classes=0, const int band=-1, const QgsRectangle &extent=QgsRectangle(), QgsRasterInterface *input=nullptr)
Classify color ramp shader.
Uses breaks from color palette.
std::unique_ptr< QgsColorRamp > mSourceColorRamp
Source color ramp.
#define DOUBLE_DIFF_THRESHOLD
Interpolates the color between two class breaks linearly.
ClassificationMode
Classification modes used to create the color ramp shader.
Assigns the color of the higher class for every pixel between two class breaks.
ClassificationMode classificationMode() const
Returns the classification mode.
QgsColorRamp * sourceColorRamp() const
Get the source color ramp.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
QgsColorRampShader(double minimumValue=0.0, double maximumValue=255.0, QgsColorRamp *colorRamp=nullptr, Type type=Interpolated, ClassificationMode classificationMode=Continuous)
Creates a new color ramp shader.