QGIS API Documentation 3.28.14-Firenze (exported)
Loading...
Searching...
No Matches
qgspalettedrasterrenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspalettedrasterrenderer.cpp
3 -----------------------------
4 begin : December 2011
5 copyright : (C) 2011 by Marco Hugentobler
6 email : marco at sourcepole dot ch
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
20#include "qgsrasterviewport.h"
21#include "qgssymbollayerutils.h"
23#include "qgsmessagelog.h"
24#include "qgsrasteriterator.h"
26#include "qgscolorrampimpl.h"
27
28#include <QColor>
29#include <QDomDocument>
30#include <QDomElement>
31#include <QImage>
32#include <QVector>
33#include <memory>
34#include <set>
35#include <QRegularExpression>
36#include <QTextStream>
37
38const int QgsPalettedRasterRenderer::MAX_FLOAT_CLASSES = 65536;
39
41 : QgsRasterRenderer( input, QStringLiteral( "paletted" ) )
42 , mBand( bandNumber )
43 , mClassData( classes )
44{
45 updateArrays();
46}
47
49{
50 QgsPalettedRasterRenderer *renderer = new QgsPalettedRasterRenderer( nullptr, mBand, mClassData );
51 if ( mSourceColorRamp )
52 renderer->setSourceColorRamp( mSourceColorRamp->clone() );
53
54 renderer->copyCommonProperties( this );
55 return renderer;
56}
57
62
64{
65 if ( elem.isNull() )
66 {
67 return nullptr;
68 }
69
70 const int bandNumber = elem.attribute( QStringLiteral( "band" ), QStringLiteral( "-1" ) ).toInt();
71 ClassData classData;
72
73 const QDomElement paletteElem = elem.firstChildElement( QStringLiteral( "colorPalette" ) );
74 if ( !paletteElem.isNull() )
75 {
76 const QDomNodeList paletteEntries = paletteElem.elementsByTagName( QStringLiteral( "paletteEntry" ) );
77
78 QDomElement entryElem;
79 double value;
80
81 for ( int i = 0; i < paletteEntries.size(); ++i )
82 {
83 QColor color;
84 QString label;
85 entryElem = paletteEntries.at( i ).toElement();
86 value = entryElem.attribute( QStringLiteral( "value" ), QStringLiteral( "0" ) ).toDouble();
87 color = QColor( entryElem.attribute( QStringLiteral( "color" ), QStringLiteral( "#000000" ) ) );
88 color.setAlpha( entryElem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "255" ) ).toInt() );
89 label = entryElem.attribute( QStringLiteral( "label" ) );
90 QgsDebugMsgLevel( QStringLiteral( "Value: %1, label: %2, color: %3" ).arg( value ).arg( label, entryElem.attribute( QStringLiteral( "color" ) ) ), 4 );
91 classData << Class( value, color, label );
92 }
93 }
94
95 QgsPalettedRasterRenderer *r = new QgsPalettedRasterRenderer( input, bandNumber, classData );
96 r->readXml( elem );
97
98 // try to load color ramp (optional)
99 QDomElement sourceColorRampElem = elem.firstChildElement( QStringLiteral( "colorramp" ) );
100 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral( "name" ) ) == QLatin1String( "[source]" ) )
101 {
102 r->setSourceColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ) );
103 }
104
105 return r;
106}
107
112
113QString QgsPalettedRasterRenderer::label( double idx ) const
114{
115 const auto constMClassData = mClassData;
116 for ( const Class &c : constMClassData )
117 {
118 if ( c.value == idx )
119 return c.label;
120 }
121
122 return QString();
123}
124
125void QgsPalettedRasterRenderer::setLabel( double idx, const QString &label )
126{
127 ClassData::iterator cIt = mClassData.begin();
128 for ( ; cIt != mClassData.end(); ++cIt )
129 {
130 if ( cIt->value == idx )
131 {
132 cIt->label = label;
133 return;
134 }
135 }
136}
137
138QgsRasterBlock *QgsPalettedRasterRenderer::block( int, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback )
139{
140 std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() );
141 if ( !mInput || mClassData.isEmpty() )
142 {
143 return outputBlock.release();
144 }
145
146 const std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( mBand, extent, width, height, feedback ) );
147
148 if ( !inputBlock || inputBlock->isEmpty() )
149 {
150 QgsDebugMsg( QStringLiteral( "No raster data!" ) );
151 return outputBlock.release();
152 }
153
154 double currentOpacity = mOpacity;
155
156 //rendering is faster without considering user-defined transparency
157 const bool hasTransparency = usesTransparency();
158
159 std::shared_ptr< QgsRasterBlock > alphaBlock;
160
161 if ( mAlphaBand > 0 && mAlphaBand != mBand )
162 {
163 alphaBlock.reset( mInput->block( mAlphaBand, extent, width, height, feedback ) );
164 if ( !alphaBlock || alphaBlock->isEmpty() )
165 {
166 return outputBlock.release();
167 }
168 }
169 else if ( mAlphaBand == mBand )
170 {
171 alphaBlock = inputBlock;
172 }
173
174 if ( !outputBlock->reset( Qgis::DataType::ARGB32_Premultiplied, width, height ) )
175 {
176 return outputBlock.release();
177 }
178
179 const QRgb myDefaultColor = renderColorForNodataPixel();
180
181 //use direct data access instead of QgsRasterBlock::setValue
182 //because of performance
183 Q_ASSERT( outputBlock ); // to make cppcheck happy
184 unsigned int *outputData = ( unsigned int * )( outputBlock->bits() );
185
186 const qgssize rasterSize = ( qgssize )width * height;
187 bool isNoData = false;
188 for ( qgssize i = 0; i < rasterSize; ++i )
189 {
190 const double value = inputBlock->valueAndNoData( i, isNoData );
191 if ( isNoData )
192 {
193 outputData[i] = myDefaultColor;
194 continue;
195 }
196 if ( !mColors.contains( value ) )
197 {
198 outputData[i] = myDefaultColor;
199 continue;
200 }
201
202 if ( !hasTransparency )
203 {
204 outputData[i] = mColors.value( value );
205 }
206 else
207 {
208 currentOpacity = mOpacity;
210 {
211 currentOpacity = mRasterTransparency->alphaValue( value, mOpacity * 255 ) / 255.0;
212 }
213 if ( mAlphaBand > 0 )
214 {
215 const double alpha = alphaBlock->value( i );
216 if ( alpha == 0 )
217 {
218 outputBlock->setColor( i, myDefaultColor );
219 continue;
220 }
221 else
222 {
223 currentOpacity *= alpha / 255.0;
224 }
225 }
226
227 const QRgb c = mColors.value( value );
228 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
229 }
230 }
231
232 return outputBlock.release();
233}
234
235void QgsPalettedRasterRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
236{
237 if ( parentElem.isNull() )
238 {
239 return;
240 }
241
242 QDomElement rasterRendererElem = doc.createElement( QStringLiteral( "rasterrenderer" ) );
243 _writeXml( doc, rasterRendererElem );
244
245 rasterRendererElem.setAttribute( QStringLiteral( "band" ), mBand );
246 QDomElement colorPaletteElem = doc.createElement( QStringLiteral( "colorPalette" ) );
247 ClassData::const_iterator it = mClassData.constBegin();
248 for ( ; it != mClassData.constEnd(); ++it )
249 {
250 const QColor color = it->color;
251 QDomElement colorElem = doc.createElement( QStringLiteral( "paletteEntry" ) );
252 colorElem.setAttribute( QStringLiteral( "value" ), it->value );
253 colorElem.setAttribute( QStringLiteral( "color" ), color.name() );
254 colorElem.setAttribute( QStringLiteral( "alpha" ), color.alpha() );
255 if ( !it->label.isEmpty() )
256 {
257 colorElem.setAttribute( QStringLiteral( "label" ), it->label );
258 }
259 colorPaletteElem.appendChild( colorElem );
260 }
261 rasterRendererElem.appendChild( colorPaletteElem );
262
263 // save source color ramp
264 if ( mSourceColorRamp )
265 {
266 const QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( QStringLiteral( "[source]" ), mSourceColorRamp.get(), doc );
267 rasterRendererElem.appendChild( colorRampElem );
268 }
269
270 parentElem.appendChild( rasterRendererElem );
271}
272
273void QgsPalettedRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
274{
275 // create base structure
276 QgsRasterRenderer::toSld( doc, element, props );
277
278 // look for RasterSymbolizer tag
279 const QDomNodeList elements = element.elementsByTagName( QStringLiteral( "sld:RasterSymbolizer" ) );
280 if ( elements.size() == 0 )
281 return;
282
283 // there SHOULD be only one
284 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
285
286 // add Channel Selection tags
287 QDomElement channelSelectionElem = doc.createElement( QStringLiteral( "sld:ChannelSelection" ) );
288 rasterSymbolizerElem.appendChild( channelSelectionElem );
289
290 // for the mapped band
291 QDomElement channelElem = doc.createElement( QStringLiteral( "sld:GrayChannel" ) );
292 channelSelectionElem.appendChild( channelElem );
293
294 // set band
295 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( "sld:SourceChannelName" ) );
296 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( band() ) ) );
297 channelElem.appendChild( sourceChannelNameElem );
298
299 // add ColorMap tag
300 QDomElement colorMapElem = doc.createElement( QStringLiteral( "sld:ColorMap" ) );
301 colorMapElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "values" ) );
302 if ( this->classes().size() >= 255 )
303 colorMapElem.setAttribute( QStringLiteral( "extended" ), QStringLiteral( "true" ) );
304 rasterSymbolizerElem.appendChild( colorMapElem );
305
306 // for each color set a ColorMapEntry tag nested into "sld:ColorMap" tag
307 // e.g. <ColorMapEntry color="#EEBE2F" quantity="-300" label="label" opacity="0"/>
308 const QList<QgsPalettedRasterRenderer::Class> classes = this->classes();
309 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt = classes.constBegin();
310 for ( ; classDataIt != classes.constEnd(); ++classDataIt )
311 {
312 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral( "sld:ColorMapEntry" ) );
313 colorMapElem.appendChild( colorMapEntryElem );
314
315 // set colorMapEntryElem attributes
316 colorMapEntryElem.setAttribute( QStringLiteral( "color" ), classDataIt->color.name() );
317 colorMapEntryElem.setAttribute( QStringLiteral( "quantity" ), QString::number( classDataIt->value ) );
318 colorMapEntryElem.setAttribute( QStringLiteral( "label" ), classDataIt->label );
319 if ( classDataIt->color.alphaF() != 1.0 )
320 {
321 colorMapEntryElem.setAttribute( QStringLiteral( "opacity" ), QString::number( classDataIt->color.alphaF() ) );
322 }
323 }
324}
325
327{
328 if ( mSourceColorRamp )
329 {
330 QgsStyleColorRampEntity entity( mSourceColorRamp.get() );
331 if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity ) ) )
332 return false;
333 }
334
335 return true;
336}
337
338QList< QPair< QString, QColor > > QgsPalettedRasterRenderer::legendSymbologyItems() const
339{
340 QList< QPair< QString, QColor > > symbolItems;
341 for ( const QgsPalettedRasterRenderer::Class &classData : mClassData )
342 {
343 const QString lab = classData.label.isEmpty() ? QString::number( classData.value ) : classData.label;
344 symbolItems << qMakePair( lab, classData.color );
345 }
346 return symbolItems;
347}
348
349
350QList<QgsLayerTreeModelLegendNode *> QgsPalettedRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
351{
352 QList<QgsLayerTreeModelLegendNode *> res;
353
354 const QString name = displayBandName( mBand );
355 if ( !name.isEmpty() )
356 {
357 res << new QgsSimpleLegendNode( nodeLayer, name );
358 }
359
360 const QList< QPair< QString, QColor > > items = legendSymbologyItems();
361 res.reserve( res.size() + items.size() );
362 for ( const QPair< QString, QColor > &item : items )
363 {
364 res << new QgsRasterSymbolLegendNode( nodeLayer, item.second, item.first );
365 }
366
367 return res;
368}
369
370
372{
373 QList<int> bandList;
374 if ( mBand != -1 )
375 {
376 bandList << mBand;
377 }
378 return bandList;
379}
380
382{
383 mSourceColorRamp.reset( ramp );
384}
385
387{
388 return mSourceColorRamp.get();
389}
390
392{
393 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
395 for ( ; colorIt != table.constEnd(); ++colorIt )
396 {
397 classes << QgsPalettedRasterRenderer::Class( colorIt->value, colorIt->color, colorIt->label );
398 }
399 return classes;
400}
401
403{
405
406 const QRegularExpression linePartRx( QStringLiteral( "[\\s,:]+" ) );
407
408#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
409 const QStringList parts = string.split( '\n', QString::SkipEmptyParts );
410#else
411 const QStringList parts = string.split( '\n', Qt::SkipEmptyParts );
412#endif
413 for ( const QString &part : parts )
414 {
415#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
416 const QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
417#else
418 const QStringList lineParts = part.split( linePartRx, Qt::SkipEmptyParts );
419#endif
420 bool ok = false;
421 switch ( lineParts.count() )
422 {
423 case 1:
424 {
425 const int value = lineParts.at( 0 ).toInt( &ok );
426 if ( !ok )
427 continue;
428
429 classes << Class( value );
430 break;
431 }
432
433 case 2:
434 {
435 const int value = lineParts.at( 0 ).toInt( &ok );
436 if ( !ok )
437 continue;
438
439 const QColor c( lineParts.at( 1 ) );
440
441 classes << Class( value, c );
442 break;
443 }
444
445 default:
446 {
447 if ( lineParts.count() < 4 )
448 continue;
449
450 const int value = lineParts.at( 0 ).toInt( &ok );
451 if ( !ok )
452 continue;
453
454 bool rOk = false;
455 const double r = lineParts.at( 1 ).toDouble( &rOk );
456 bool gOk = false;
457 const double g = lineParts.at( 2 ).toDouble( &gOk );
458 bool bOk = false;
459 const double b = lineParts.at( 3 ).toDouble( &bOk );
460
461 QColor c;
462 if ( rOk && gOk && bOk )
463 {
464 c = QColor( r, g, b );
465 }
466
467 if ( lineParts.count() >= 5 )
468 {
469 const double alpha = lineParts.at( 4 ).toDouble( &ok );
470 if ( ok )
471 c.setAlpha( alpha );
472 }
473
474 QString label;
475 if ( lineParts.count() > 5 )
476 {
477 label = lineParts.mid( 5 ).join( ' ' );
478 }
479
480 classes << Class( value, c, label );
481 break;
482 }
483 }
484
485 }
486 return classes;
487}
488
490{
491 QFile inputFile( path );
492 QString input;
493 if ( inputFile.open( QIODevice::ReadOnly ) )
494 {
495 QTextStream in( &inputFile );
496 input = in.readAll();
497 inputFile.close();
498 }
499 return classDataFromString( input );
500}
501
503{
504 QStringList out;
505 // must be sorted
507 std::sort( cd.begin(), cd.end(), []( const Class & a, const Class & b ) -> bool
508 {
509 return a.value < b.value;
510 } );
511
512 const auto constCd = cd;
513 for ( const Class &c : constCd )
514 {
515 out << QStringLiteral( "%1 %2 %3 %4 %5 %6" ).arg( c.value ).arg( c.color.red() )
516 .arg( c.color.green() ).arg( c.color.blue() ).arg( c.color.alpha() ).arg( c.label );
517 }
518 return out.join( '\n' );
519}
520
522{
523 if ( !raster )
524 return ClassData();
525
526 ClassData data;
527
528 if ( bandNumber > 0 && bandNumber <= raster->bandCount() )
529 {
530 qlonglong numClasses = 0;
531
532 if ( feedback )
533 feedback->setProgress( 0 );
534
535 // Collect unique values for float rasters
536 if ( raster->dataType( bandNumber ) == Qgis::DataType::Float32 || raster->dataType( bandNumber ) == Qgis::DataType::Float64 )
537 {
538
539 if ( feedback && feedback->isCanceled() )
540 {
541 return data;
542 }
543
544 std::set<double> values;
545
548
549 QgsRasterIterator iter( raster );
550 iter.startRasterRead( bandNumber, raster->xSize(), raster->ySize(), raster->extent(), feedback );
551
552 const int nbBlocksWidth = static_cast< int >( std::ceil( 1.0 * raster->xSize() / maxWidth ) );
553 const int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * raster->ySize() / maxHeight ) );
554 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
555
556 int iterLeft = 0;
557 int iterTop = 0;
558 int iterCols = 0;
559 int iterRows = 0;
560 std::unique_ptr< QgsRasterBlock > rasterBlock;
561 QgsRectangle blockExtent;
562 bool isNoData = false;
563 while ( iter.readNextRasterPart( bandNumber, iterCols, iterRows, rasterBlock, iterLeft, iterTop, &blockExtent ) )
564 {
565 if ( feedback )
566 feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
567
568 if ( feedback && feedback->isCanceled() )
569 break;
570
571 for ( int row = 0; row < iterRows; row++ )
572 {
573 if ( feedback && feedback->isCanceled() )
574 break;
575
576 for ( int column = 0; column < iterCols; column++ )
577 {
578 if ( feedback && feedback->isCanceled() )
579 break;
580
581 const double currentValue = rasterBlock->valueAndNoData( row, column, isNoData );
582 if ( numClasses >= MAX_FLOAT_CLASSES )
583 {
584 QgsMessageLog::logMessage( QStringLiteral( "Number of classes exceeded maximum (%1)." ).arg( MAX_FLOAT_CLASSES ), QStringLiteral( "Raster" ) );
585 break;
586 }
587 if ( !isNoData && values.find( currentValue ) == values.end() )
588 {
589 values.insert( currentValue );
590 data.push_back( Class( currentValue, QColor(), QLocale().toString( currentValue ) ) );
591 numClasses++;
592 }
593 }
594 }
595 }
596 // must be sorted
597 std::sort( data.begin(), data.end(), []( const Class & a, const Class & b ) -> bool
598 {
599 return a.value < b.value;
600 } );
601 }
602 else
603 {
604 // get min and max value from raster
605 const QgsRasterBandStats stats = raster->bandStatistics( bandNumber, QgsRasterBandStats::Min | QgsRasterBandStats::Max, QgsRectangle(), 0, feedback );
606 if ( feedback && feedback->isCanceled() )
607 return ClassData();
608
609 const double min = stats.minimumValue;
610 const double max = stats.maximumValue;
611 // need count of every individual value
612 const int bins = std::ceil( max - min ) + 1;
613 if ( bins <= 0 )
614 return ClassData();
615
616 const QgsRasterHistogram histogram = raster->histogram( bandNumber, bins, min, max, QgsRectangle(), 0, false, feedback );
617 if ( feedback && feedback->isCanceled() )
618 return ClassData();
619
620 const double interval = ( histogram.maximum - histogram.minimum + 1 ) / histogram.binCount;
621 double currentValue = histogram.minimum;
622
623 if ( histogram.valid )
624 {
625 for ( int idx = 0; idx < histogram.binCount; ++idx )
626 {
627 const int count = histogram.histogramVector.at( idx );
628 if ( count > 0 )
629 {
630 data << Class( currentValue, QColor(), QLocale().toString( currentValue ) );
631 numClasses++;
632 }
633 currentValue += interval;
634 }
635 }
636 else if ( histogram.maximum == histogram.minimum && histogram.binCount == 1 ) // Constant raster
637 {
638 data << Class( histogram.maximum, QColor(), QLocale().toString( histogram.maximum ) );
639 }
640
641 }
642
643 // assign colors from ramp
644 if ( ramp && numClasses > 0 )
645 {
646 int i = 0;
647
648 if ( QgsRandomColorRamp *randomRamp = dynamic_cast<QgsRandomColorRamp *>( ramp ) )
649 {
650 //ramp is a random colors ramp, so inform it of the total number of required colors
651 //this allows the ramp to pregenerate a set of visually distinctive colors
652 randomRamp->setTotalColorCount( data.count() );
653 }
654
655 if ( numClasses > 1 )
656 numClasses -= 1; //avoid duplicate first color
657
658 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
659 for ( ; cIt != data.end(); ++cIt )
660 {
661 if ( feedback )
662 {
663 // Show no less than 1%, then the max between class fill and real progress
664 feedback->setProgress( std::max<int>( 1, 100 * ( i + 1 ) / numClasses ) );
665 }
666 cIt->color = ramp->color( i / static_cast<double>( numClasses ) );
667 i++;
668 }
669 }
670 }
671 return data;
672}
673
674void QgsPalettedRasterRenderer::updateArrays()
675{
676 mColors.clear();
677 ClassData::const_iterator it = mClassData.constBegin();
678 for ( ; it != mClassData.constEnd(); ++it )
679 {
680 mColors[it->value] = qPremultiply( it->color.rgba() );
681 }
682}
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
@ Float32
Thirty two bit floating point (float)
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Float64
Sixty four bit floating point (double)
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:63
Layer tree node points to a map layer.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Renderer for paletted raster images.
int band() const
Returns the raster band used for rendering the raster.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Creates a set of legend nodes representing the renderer.
QgsColorRamp * sourceColorRamp() const
Gets the source color ramp.
static QgsPalettedRasterRenderer::ClassData classDataFromString(const QString &string)
Converts a string containing a color table or class data to to paletted renderer class data.
QString label(double idx) const
Returns optional category label.
void setSourceColorRamp(QgsColorRamp *ramp)
Set the source color ramp.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
QList< QgsPalettedRasterRenderer::Class > ClassData
Map of value to class properties.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
Qgis::RasterRendererFlags flags() const override
Returns flags which dictate renderer behavior.
static QgsPalettedRasterRenderer::ClassData classDataFromFile(const QString &path)
Opens a color table file and returns corresponding paletted renderer class data.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
static QgsPalettedRasterRenderer::ClassData colorTableToClassData(const QList< QgsColorRampShader::ColorRampItem > &table)
Converts a raster color table to paletted renderer class data.
ClassData classes() const
Returns a map of value to classes (colors) used by the renderer.
QList< QPair< QString, QColor > > legendSymbologyItems() const override
Returns symbology items if provided by renderer.
QgsPalettedRasterRenderer * clone() const override
Clone itself, create deep copy.
void setLabel(double idx, const QString &label)
Set category label.
static QgsPalettedRasterRenderer::ClassData classDataFromRaster(QgsRasterInterface *raster, int bandNumber, QgsColorRamp *ramp=nullptr, QgsRasterBlockFeedback *feedback=nullptr)
Generates class data from a raster, for the specified bandNumber.
static QString classDataToString(const QgsPalettedRasterRenderer::ClassData &classes)
Converts classes to a string representation, using the .clr/gdal color table file format.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
QgsPalettedRasterRenderer(QgsRasterInterface *input, int bandNumber, const ClassData &classes)
Constructor for QgsPalettedRasterRenderer.
Totally random color ramp.
The RasterBandStats struct is a container for statistics about a single raster band.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
Feedback object tailored for raster block reading.
Raster data container.
The QgsRasterHistogram is a container for histogram of a single raster band.
double minimum
The minimum histogram value.
double maximum
The maximum histogram value.
QgsRasterHistogram::HistogramVector histogramVector
Stores the histogram for a given layer.
bool valid
Histogram is valid.
int binCount
Number of bins (intervals,buckets) in histogram.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
virtual int xSize() const
Gets raster size.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
QString displayBandName(int bandNumber) const
Generates a friendly, descriptive name for the specified bandNumber.
QgsRasterInterface * mInput
virtual int ySize() const
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
virtual QgsRasterHistogram histogram(int bandNo, int binCount=0, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false, QgsRasterBlockFeedback *feedback=nullptr)
Returns a band histogram.
Iterator for sequentially processing raster cells.
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
bool readNextRasterPart(int bandNumber, int &nCols, int &nRows, QgsRasterBlock **block, int &topLeftCol, int &topLeftRow)
Fetches next part of raster data, caller takes ownership of the block and caller should delete the bl...
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
Raster renderer pipe that applies colors to a raster.
double mOpacity
Global alpha value (0-1)
int mAlphaBand
Read alpha value from band.
QRgb renderColorForNodataPixel() const
Returns the color for the renderer to use to represent nodata pixels.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses)
int bandCount() const override
Gets number of bands.
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
bool usesTransparency() const
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
virtual void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Implementation of legend node interface for displaying raster legend entries.
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
A rectangle specified with double values.
Implementation of legend node interface for displaying arbitrary label with icon.
A color ramp entity for QgsStyle databases.
Definition qgsstyle.h:1374
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
Definition qgis.h:3032
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
#define QgsDebugMsg(str)
Definition qgslogger.h:38
Properties of a single value class.
Contains information relating to the style entity currently being visited.