QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
58Qgis::RasterRendererFlags QgsPalettedRasterRenderer::flags() const
59{
61}
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
109{
110 return mClassData;
111}
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 currentOpacity *= alphaBlock->value( i ) / 255.0;
216 }
217
218 const QRgb c = mColors.value( value );
219 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
220 }
221 }
222
223 return outputBlock.release();
224}
225
226void QgsPalettedRasterRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
227{
228 if ( parentElem.isNull() )
229 {
230 return;
231 }
232
233 QDomElement rasterRendererElem = doc.createElement( QStringLiteral( "rasterrenderer" ) );
234 _writeXml( doc, rasterRendererElem );
235
236 rasterRendererElem.setAttribute( QStringLiteral( "band" ), mBand );
237 QDomElement colorPaletteElem = doc.createElement( QStringLiteral( "colorPalette" ) );
238 ClassData::const_iterator it = mClassData.constBegin();
239 for ( ; it != mClassData.constEnd(); ++it )
240 {
241 const QColor color = it->color;
242 QDomElement colorElem = doc.createElement( QStringLiteral( "paletteEntry" ) );
243 colorElem.setAttribute( QStringLiteral( "value" ), it->value );
244 colorElem.setAttribute( QStringLiteral( "color" ), color.name() );
245 colorElem.setAttribute( QStringLiteral( "alpha" ), color.alpha() );
246 if ( !it->label.isEmpty() )
247 {
248 colorElem.setAttribute( QStringLiteral( "label" ), it->label );
249 }
250 colorPaletteElem.appendChild( colorElem );
251 }
252 rasterRendererElem.appendChild( colorPaletteElem );
253
254 // save source color ramp
255 if ( mSourceColorRamp )
256 {
257 const QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( QStringLiteral( "[source]" ), mSourceColorRamp.get(), doc );
258 rasterRendererElem.appendChild( colorRampElem );
259 }
260
261 parentElem.appendChild( rasterRendererElem );
262}
263
264void QgsPalettedRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
265{
266 // create base structure
267 QgsRasterRenderer::toSld( doc, element, props );
268
269 // look for RasterSymbolizer tag
270 const QDomNodeList elements = element.elementsByTagName( QStringLiteral( "sld:RasterSymbolizer" ) );
271 if ( elements.size() == 0 )
272 return;
273
274 // there SHOULD be only one
275 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
276
277 // add Channel Selection tags
278 QDomElement channelSelectionElem = doc.createElement( QStringLiteral( "sld:ChannelSelection" ) );
279 rasterSymbolizerElem.appendChild( channelSelectionElem );
280
281 // for the mapped band
282 QDomElement channelElem = doc.createElement( QStringLiteral( "sld:GrayChannel" ) );
283 channelSelectionElem.appendChild( channelElem );
284
285 // set band
286 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( "sld:SourceChannelName" ) );
287 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( band() ) ) );
288 channelElem.appendChild( sourceChannelNameElem );
289
290 // add ColorMap tag
291 QDomElement colorMapElem = doc.createElement( QStringLiteral( "sld:ColorMap" ) );
292 colorMapElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "values" ) );
293 if ( this->classes().size() >= 255 )
294 colorMapElem.setAttribute( QStringLiteral( "extended" ), QStringLiteral( "true" ) );
295 rasterSymbolizerElem.appendChild( colorMapElem );
296
297 // for each color set a ColorMapEntry tag nested into "sld:ColorMap" tag
298 // e.g. <ColorMapEntry color="#EEBE2F" quantity="-300" label="label" opacity="0"/>
299 const QList<QgsPalettedRasterRenderer::Class> classes = this->classes();
300 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt = classes.constBegin();
301 for ( ; classDataIt != classes.constEnd(); ++classDataIt )
302 {
303 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral( "sld:ColorMapEntry" ) );
304 colorMapElem.appendChild( colorMapEntryElem );
305
306 // set colorMapEntryElem attributes
307 colorMapEntryElem.setAttribute( QStringLiteral( "color" ), classDataIt->color.name() );
308 colorMapEntryElem.setAttribute( QStringLiteral( "quantity" ), QString::number( classDataIt->value ) );
309 colorMapEntryElem.setAttribute( QStringLiteral( "label" ), classDataIt->label );
310 if ( classDataIt->color.alphaF() != 1.0 )
311 {
312 colorMapEntryElem.setAttribute( QStringLiteral( "opacity" ), QString::number( classDataIt->color.alphaF() ) );
313 }
314 }
315}
316
318{
319 if ( mSourceColorRamp )
320 {
321 QgsStyleColorRampEntity entity( mSourceColorRamp.get() );
322 if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity ) ) )
323 return false;
324 }
325
326 return true;
327}
328
329QList< QPair< QString, QColor > > QgsPalettedRasterRenderer::legendSymbologyItems() const
330{
331 QList< QPair< QString, QColor > > symbolItems;
332 for ( const QgsPalettedRasterRenderer::Class &classData : mClassData )
333 {
334 const QString lab = classData.label.isEmpty() ? QString::number( classData.value ) : classData.label;
335 symbolItems << qMakePair( lab, classData.color );
336 }
337 return symbolItems;
338}
339
340
341QList<QgsLayerTreeModelLegendNode *> QgsPalettedRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
342{
343 QList<QgsLayerTreeModelLegendNode *> res;
344
345 const QString name = displayBandName( mBand );
346 if ( !name.isEmpty() )
347 {
348 res << new QgsSimpleLegendNode( nodeLayer, name );
349 }
350
351 const QList< QPair< QString, QColor > > items = legendSymbologyItems();
352 res.reserve( res.size() + items.size() );
353 for ( const QPair< QString, QColor > &item : items )
354 {
355 res << new QgsRasterSymbolLegendNode( nodeLayer, item.second, item.first );
356 }
357
358 return res;
359}
360
361
363{
364 QList<int> bandList;
365 if ( mBand != -1 )
366 {
367 bandList << mBand;
368 }
369 return bandList;
370}
371
373{
374 mSourceColorRamp.reset( ramp );
375}
376
378{
379 return mSourceColorRamp.get();
380}
381
383{
384 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
386 for ( ; colorIt != table.constEnd(); ++colorIt )
387 {
388 classes << QgsPalettedRasterRenderer::Class( colorIt->value, colorIt->color, colorIt->label );
389 }
390 return classes;
391}
392
394{
396
397 const QRegularExpression linePartRx( QStringLiteral( "[\\s,:]+" ) );
398
399#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
400 const QStringList parts = string.split( '\n', QString::SkipEmptyParts );
401#else
402 const QStringList parts = string.split( '\n', Qt::SkipEmptyParts );
403#endif
404 for ( const QString &part : parts )
405 {
406#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
407 const QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
408#else
409 const QStringList lineParts = part.split( linePartRx, Qt::SkipEmptyParts );
410#endif
411 bool ok = false;
412 switch ( lineParts.count() )
413 {
414 case 1:
415 {
416 const int value = lineParts.at( 0 ).toInt( &ok );
417 if ( !ok )
418 continue;
419
420 classes << Class( value );
421 break;
422 }
423
424 case 2:
425 {
426 const int value = lineParts.at( 0 ).toInt( &ok );
427 if ( !ok )
428 continue;
429
430 const QColor c( lineParts.at( 1 ) );
431
432 classes << Class( value, c );
433 break;
434 }
435
436 default:
437 {
438 if ( lineParts.count() < 4 )
439 continue;
440
441 const int value = lineParts.at( 0 ).toInt( &ok );
442 if ( !ok )
443 continue;
444
445 bool rOk = false;
446 const double r = lineParts.at( 1 ).toDouble( &rOk );
447 bool gOk = false;
448 const double g = lineParts.at( 2 ).toDouble( &gOk );
449 bool bOk = false;
450 const double b = lineParts.at( 3 ).toDouble( &bOk );
451
452 QColor c;
453 if ( rOk && gOk && bOk )
454 {
455 c = QColor( r, g, b );
456 }
457
458 if ( lineParts.count() >= 5 )
459 {
460 const double alpha = lineParts.at( 4 ).toDouble( &ok );
461 if ( ok )
462 c.setAlpha( alpha );
463 }
464
465 QString label;
466 if ( lineParts.count() > 5 )
467 {
468 label = lineParts.mid( 5 ).join( ' ' );
469 }
470
471 classes << Class( value, c, label );
472 break;
473 }
474 }
475
476 }
477 return classes;
478}
479
481{
482 QFile inputFile( path );
483 QString input;
484 if ( inputFile.open( QIODevice::ReadOnly ) )
485 {
486 QTextStream in( &inputFile );
487 input = in.readAll();
488 inputFile.close();
489 }
490 return classDataFromString( input );
491}
492
494{
495 QStringList out;
496 // must be sorted
498 std::sort( cd.begin(), cd.end(), []( const Class & a, const Class & b ) -> bool
499 {
500 return a.value < b.value;
501 } );
502
503 const auto constCd = cd;
504 for ( const Class &c : constCd )
505 {
506 out << QStringLiteral( "%1 %2 %3 %4 %5 %6" ).arg( c.value ).arg( c.color.red() )
507 .arg( c.color.green() ).arg( c.color.blue() ).arg( c.color.alpha() ).arg( c.label );
508 }
509 return out.join( '\n' );
510}
511
513{
514 if ( !raster )
515 return ClassData();
516
517 ClassData data;
518
519 if ( bandNumber > 0 && bandNumber <= raster->bandCount() )
520 {
521 qlonglong numClasses = 0;
522
523 if ( feedback )
524 feedback->setProgress( 0 );
525
526 // Collect unique values for float rasters
527 if ( raster->dataType( bandNumber ) == Qgis::DataType::Float32 || raster->dataType( bandNumber ) == Qgis::DataType::Float64 )
528 {
529
530 if ( feedback && feedback->isCanceled() )
531 {
532 return data;
533 }
534
535 std::set<double> values;
536
539
540 QgsRasterIterator iter( raster );
541 iter.startRasterRead( bandNumber, raster->xSize(), raster->ySize(), raster->extent(), feedback );
542
543 const int nbBlocksWidth = static_cast< int >( std::ceil( 1.0 * raster->xSize() / maxWidth ) );
544 const int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * raster->ySize() / maxHeight ) );
545 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
546
547 int iterLeft = 0;
548 int iterTop = 0;
549 int iterCols = 0;
550 int iterRows = 0;
551 std::unique_ptr< QgsRasterBlock > rasterBlock;
552 QgsRectangle blockExtent;
553 bool isNoData = false;
554 while ( iter.readNextRasterPart( bandNumber, iterCols, iterRows, rasterBlock, iterLeft, iterTop, &blockExtent ) )
555 {
556 if ( feedback )
557 feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
558
559 if ( feedback && feedback->isCanceled() )
560 break;
561
562 for ( int row = 0; row < iterRows; row++ )
563 {
564 if ( feedback && feedback->isCanceled() )
565 break;
566
567 for ( int column = 0; column < iterCols; column++ )
568 {
569 if ( feedback && feedback->isCanceled() )
570 break;
571
572 const double currentValue = rasterBlock->valueAndNoData( row, column, isNoData );
573 if ( numClasses >= MAX_FLOAT_CLASSES )
574 {
575 QgsMessageLog::logMessage( QStringLiteral( "Number of classes exceeded maximum (%1)." ).arg( MAX_FLOAT_CLASSES ), QStringLiteral( "Raster" ) );
576 break;
577 }
578 if ( !isNoData && values.find( currentValue ) == values.end() )
579 {
580 values.insert( currentValue );
581 data.push_back( Class( currentValue, QColor(), QLocale().toString( currentValue ) ) );
582 numClasses++;
583 }
584 }
585 }
586 }
587 // must be sorted
588 std::sort( data.begin(), data.end(), []( const Class & a, const Class & b ) -> bool
589 {
590 return a.value < b.value;
591 } );
592 }
593 else
594 {
595 // get min and max value from raster
596 const QgsRasterBandStats stats = raster->bandStatistics( bandNumber, QgsRasterBandStats::Min | QgsRasterBandStats::Max, QgsRectangle(), 0, feedback );
597 if ( feedback && feedback->isCanceled() )
598 return ClassData();
599
600 const double min = stats.minimumValue;
601 const double max = stats.maximumValue;
602 // need count of every individual value
603 const int bins = std::ceil( max - min ) + 1;
604 if ( bins <= 0 )
605 return ClassData();
606
607 const QgsRasterHistogram histogram = raster->histogram( bandNumber, bins, min, max, QgsRectangle(), 0, false, feedback );
608 if ( feedback && feedback->isCanceled() )
609 return ClassData();
610
611 const double interval = ( histogram.maximum - histogram.minimum + 1 ) / histogram.binCount;
612 double currentValue = histogram.minimum;
613 for ( int idx = 0; idx < histogram.binCount; ++idx )
614 {
615 const int count = histogram.histogramVector.at( idx );
616 if ( count > 0 )
617 {
618 data << Class( currentValue, QColor(), QLocale().toString( currentValue ) );
619 numClasses++;
620 }
621 currentValue += interval;
622 }
623 }
624
625 // assign colors from ramp
626 if ( ramp && numClasses > 0 )
627 {
628 int i = 0;
629
630 if ( QgsRandomColorRamp *randomRamp = dynamic_cast<QgsRandomColorRamp *>( ramp ) )
631 {
632 //ramp is a random colors ramp, so inform it of the total number of required colors
633 //this allows the ramp to pregenerate a set of visually distinctive colors
634 randomRamp->setTotalColorCount( data.count() );
635 }
636
637 if ( numClasses > 1 )
638 numClasses -= 1; //avoid duplicate first color
639
640 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
641 for ( ; cIt != data.end(); ++cIt )
642 {
643 if ( feedback )
644 {
645 // Show no less than 1%, then the max between class fill and real progress
646 feedback->setProgress( std::max<int>( 1, 100 * ( i + 1 ) / numClasses ) );
647 }
648 cIt->color = ramp->color( i / static_cast<double>( numClasses ) );
649 i++;
650 }
651 }
652 }
653 return data;
654}
655
656void QgsPalettedRasterRenderer::updateArrays()
657{
658 mColors.clear();
659 ClassData::const_iterator it = mClassData.constBegin();
660 for ( ; it != mClassData.constEnd(); ++it )
661 {
662 mColors[it->value] = qPremultiply( it->color.rgba() );
663 }
664}
@ 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.
Definition: qgscolorramp.h:30
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
bool isCanceled() const SIP_HOLDGIL
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.
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.
Definition: qgsrectangle.h:42
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.