QGIS API Documentation 3.27.0-Master (0a97e3138f)
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
59{
60 if ( elem.isNull() )
61 {
62 return nullptr;
63 }
64
65 const int bandNumber = elem.attribute( QStringLiteral( "band" ), QStringLiteral( "-1" ) ).toInt();
66 ClassData classData;
67
68 const QDomElement paletteElem = elem.firstChildElement( QStringLiteral( "colorPalette" ) );
69 if ( !paletteElem.isNull() )
70 {
71 const QDomNodeList paletteEntries = paletteElem.elementsByTagName( QStringLiteral( "paletteEntry" ) );
72
73 QDomElement entryElem;
74 double value;
75
76 for ( int i = 0; i < paletteEntries.size(); ++i )
77 {
78 QColor color;
79 QString label;
80 entryElem = paletteEntries.at( i ).toElement();
81 value = entryElem.attribute( QStringLiteral( "value" ), QStringLiteral( "0" ) ).toDouble();
82 color = QColor( entryElem.attribute( QStringLiteral( "color" ), QStringLiteral( "#000000" ) ) );
83 color.setAlpha( entryElem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "255" ) ).toInt() );
84 label = entryElem.attribute( QStringLiteral( "label" ) );
85 QgsDebugMsgLevel( QStringLiteral( "Value: %1, label: %2, color: %3" ).arg( value ).arg( label, entryElem.attribute( QStringLiteral( "color" ) ) ), 4 );
86 classData << Class( value, color, label );
87 }
88 }
89
90 QgsPalettedRasterRenderer *r = new QgsPalettedRasterRenderer( input, bandNumber, classData );
91 r->readXml( elem );
92
93 // try to load color ramp (optional)
94 QDomElement sourceColorRampElem = elem.firstChildElement( QStringLiteral( "colorramp" ) );
95 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral( "name" ) ) == QLatin1String( "[source]" ) )
96 {
97 r->setSourceColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ) );
98 }
99
100 return r;
101}
102
104{
105 return mClassData;
106}
107
108QString QgsPalettedRasterRenderer::label( double idx ) const
109{
110 const auto constMClassData = mClassData;
111 for ( const Class &c : constMClassData )
112 {
113 if ( c.value == idx )
114 return c.label;
115 }
116
117 return QString();
118}
119
120void QgsPalettedRasterRenderer::setLabel( double idx, const QString &label )
121{
122 ClassData::iterator cIt = mClassData.begin();
123 for ( ; cIt != mClassData.end(); ++cIt )
124 {
125 if ( cIt->value == idx )
126 {
127 cIt->label = label;
128 return;
129 }
130 }
131}
132
133QgsRasterBlock *QgsPalettedRasterRenderer::block( int, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback )
134{
135 std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() );
136 if ( !mInput || mClassData.isEmpty() )
137 {
138 return outputBlock.release();
139 }
140
141 const std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( mBand, extent, width, height, feedback ) );
142
143 if ( !inputBlock || inputBlock->isEmpty() )
144 {
145 QgsDebugMsg( QStringLiteral( "No raster data!" ) );
146 return outputBlock.release();
147 }
148
149 double currentOpacity = mOpacity;
150
151 //rendering is faster without considering user-defined transparency
152 const bool hasTransparency = usesTransparency();
153
154 std::shared_ptr< QgsRasterBlock > alphaBlock;
155
156 if ( mAlphaBand > 0 && mAlphaBand != mBand )
157 {
158 alphaBlock.reset( mInput->block( mAlphaBand, extent, width, height, feedback ) );
159 if ( !alphaBlock || alphaBlock->isEmpty() )
160 {
161 return outputBlock.release();
162 }
163 }
164 else if ( mAlphaBand == mBand )
165 {
166 alphaBlock = inputBlock;
167 }
168
169 if ( !outputBlock->reset( Qgis::DataType::ARGB32_Premultiplied, width, height ) )
170 {
171 return outputBlock.release();
172 }
173
174 const QRgb myDefaultColor = renderColorForNodataPixel();
175
176 //use direct data access instead of QgsRasterBlock::setValue
177 //because of performance
178 Q_ASSERT( outputBlock ); // to make cppcheck happy
179 unsigned int *outputData = ( unsigned int * )( outputBlock->bits() );
180
181 const qgssize rasterSize = ( qgssize )width * height;
182 bool isNoData = false;
183 for ( qgssize i = 0; i < rasterSize; ++i )
184 {
185 const double value = inputBlock->valueAndNoData( i, isNoData );
186 if ( isNoData )
187 {
188 outputData[i] = myDefaultColor;
189 continue;
190 }
191 if ( !mColors.contains( value ) )
192 {
193 outputData[i] = myDefaultColor;
194 continue;
195 }
196
197 if ( !hasTransparency )
198 {
199 outputData[i] = mColors.value( value );
200 }
201 else
202 {
203 currentOpacity = mOpacity;
205 {
206 currentOpacity = mRasterTransparency->alphaValue( value, mOpacity * 255 ) / 255.0;
207 }
208 if ( mAlphaBand > 0 )
209 {
210 currentOpacity *= alphaBlock->value( i ) / 255.0;
211 }
212
213 const QRgb c = mColors.value( value );
214 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
215 }
216 }
217
218 return outputBlock.release();
219}
220
221void QgsPalettedRasterRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
222{
223 if ( parentElem.isNull() )
224 {
225 return;
226 }
227
228 QDomElement rasterRendererElem = doc.createElement( QStringLiteral( "rasterrenderer" ) );
229 _writeXml( doc, rasterRendererElem );
230
231 rasterRendererElem.setAttribute( QStringLiteral( "band" ), mBand );
232 QDomElement colorPaletteElem = doc.createElement( QStringLiteral( "colorPalette" ) );
233 ClassData::const_iterator it = mClassData.constBegin();
234 for ( ; it != mClassData.constEnd(); ++it )
235 {
236 const QColor color = it->color;
237 QDomElement colorElem = doc.createElement( QStringLiteral( "paletteEntry" ) );
238 colorElem.setAttribute( QStringLiteral( "value" ), it->value );
239 colorElem.setAttribute( QStringLiteral( "color" ), color.name() );
240 colorElem.setAttribute( QStringLiteral( "alpha" ), color.alpha() );
241 if ( !it->label.isEmpty() )
242 {
243 colorElem.setAttribute( QStringLiteral( "label" ), it->label );
244 }
245 colorPaletteElem.appendChild( colorElem );
246 }
247 rasterRendererElem.appendChild( colorPaletteElem );
248
249 // save source color ramp
250 if ( mSourceColorRamp )
251 {
252 const QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( QStringLiteral( "[source]" ), mSourceColorRamp.get(), doc );
253 rasterRendererElem.appendChild( colorRampElem );
254 }
255
256 parentElem.appendChild( rasterRendererElem );
257}
258
259void QgsPalettedRasterRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
260{
261 // create base structure
262 QgsRasterRenderer::toSld( doc, element, props );
263
264 // look for RasterSymbolizer tag
265 const QDomNodeList elements = element.elementsByTagName( QStringLiteral( "sld:RasterSymbolizer" ) );
266 if ( elements.size() == 0 )
267 return;
268
269 // there SHOULD be only one
270 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
271
272 // add Channel Selection tags
273 QDomElement channelSelectionElem = doc.createElement( QStringLiteral( "sld:ChannelSelection" ) );
274 rasterSymbolizerElem.appendChild( channelSelectionElem );
275
276 // for the mapped band
277 QDomElement channelElem = doc.createElement( QStringLiteral( "sld:GrayChannel" ) );
278 channelSelectionElem.appendChild( channelElem );
279
280 // set band
281 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( "sld:SourceChannelName" ) );
282 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( band() ) ) );
283 channelElem.appendChild( sourceChannelNameElem );
284
285 // add ColorMap tag
286 QDomElement colorMapElem = doc.createElement( QStringLiteral( "sld:ColorMap" ) );
287 colorMapElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "values" ) );
288 if ( this->classes().size() >= 255 )
289 colorMapElem.setAttribute( QStringLiteral( "extended" ), QStringLiteral( "true" ) );
290 rasterSymbolizerElem.appendChild( colorMapElem );
291
292 // for each color set a ColorMapEntry tag nested into "sld:ColorMap" tag
293 // e.g. <ColorMapEntry color="#EEBE2F" quantity="-300" label="label" opacity="0"/>
294 const QList<QgsPalettedRasterRenderer::Class> classes = this->classes();
295 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt = classes.constBegin();
296 for ( ; classDataIt != classes.constEnd(); ++classDataIt )
297 {
298 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral( "sld:ColorMapEntry" ) );
299 colorMapElem.appendChild( colorMapEntryElem );
300
301 // set colorMapEntryElem attributes
302 colorMapEntryElem.setAttribute( QStringLiteral( "color" ), classDataIt->color.name() );
303 colorMapEntryElem.setAttribute( QStringLiteral( "quantity" ), QString::number( classDataIt->value ) );
304 colorMapEntryElem.setAttribute( QStringLiteral( "label" ), classDataIt->label );
305 if ( classDataIt->color.alphaF() != 1.0 )
306 {
307 colorMapEntryElem.setAttribute( QStringLiteral( "opacity" ), QString::number( classDataIt->color.alphaF() ) );
308 }
309 }
310}
311
313{
314 if ( mSourceColorRamp )
315 {
316 QgsStyleColorRampEntity entity( mSourceColorRamp.get() );
317 if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity ) ) )
318 return false;
319 }
320
321 return true;
322}
323
324QList< QPair< QString, QColor > > QgsPalettedRasterRenderer::legendSymbologyItems() const
325{
326 QList< QPair< QString, QColor > > symbolItems;
327 for ( const QgsPalettedRasterRenderer::Class &classData : mClassData )
328 {
329 const QString lab = classData.label.isEmpty() ? QString::number( classData.value ) : classData.label;
330 symbolItems << qMakePair( lab, classData.color );
331 }
332 return symbolItems;
333}
334
335
336QList<QgsLayerTreeModelLegendNode *> QgsPalettedRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
337{
338 QList<QgsLayerTreeModelLegendNode *> res;
339
340 const QString name = displayBandName( mBand );
341 if ( !name.isEmpty() )
342 {
343 res << new QgsSimpleLegendNode( nodeLayer, name );
344 }
345
346 const QList< QPair< QString, QColor > > items = legendSymbologyItems();
347 res.reserve( res.size() + items.size() );
348 for ( const QPair< QString, QColor > &item : items )
349 {
350 res << new QgsRasterSymbolLegendNode( nodeLayer, item.second, item.first );
351 }
352
353 return res;
354}
355
356
358{
359 QList<int> bandList;
360 if ( mBand != -1 )
361 {
362 bandList << mBand;
363 }
364 return bandList;
365}
366
368{
369 mSourceColorRamp.reset( ramp );
370}
371
373{
374 return mSourceColorRamp.get();
375}
376
378{
379 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
381 for ( ; colorIt != table.constEnd(); ++colorIt )
382 {
383 classes << QgsPalettedRasterRenderer::Class( colorIt->value, colorIt->color, colorIt->label );
384 }
385 return classes;
386}
387
389{
391
392 const QRegularExpression linePartRx( QStringLiteral( "[\\s,:]+" ) );
393
394#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
395 const QStringList parts = string.split( '\n', QString::SkipEmptyParts );
396#else
397 const QStringList parts = string.split( '\n', Qt::SkipEmptyParts );
398#endif
399 for ( const QString &part : parts )
400 {
401#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
402 const QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
403#else
404 const QStringList lineParts = part.split( linePartRx, Qt::SkipEmptyParts );
405#endif
406 bool ok = false;
407 switch ( lineParts.count() )
408 {
409 case 1:
410 {
411 const int value = lineParts.at( 0 ).toInt( &ok );
412 if ( !ok )
413 continue;
414
415 classes << Class( value );
416 break;
417 }
418
419 case 2:
420 {
421 const int value = lineParts.at( 0 ).toInt( &ok );
422 if ( !ok )
423 continue;
424
425 const QColor c( lineParts.at( 1 ) );
426
427 classes << Class( value, c );
428 break;
429 }
430
431 default:
432 {
433 if ( lineParts.count() < 4 )
434 continue;
435
436 const int value = lineParts.at( 0 ).toInt( &ok );
437 if ( !ok )
438 continue;
439
440 bool rOk = false;
441 const double r = lineParts.at( 1 ).toDouble( &rOk );
442 bool gOk = false;
443 const double g = lineParts.at( 2 ).toDouble( &gOk );
444 bool bOk = false;
445 const double b = lineParts.at( 3 ).toDouble( &bOk );
446
447 QColor c;
448 if ( rOk && gOk && bOk )
449 {
450 c = QColor( r, g, b );
451 }
452
453 if ( lineParts.count() >= 5 )
454 {
455 const double alpha = lineParts.at( 4 ).toDouble( &ok );
456 if ( ok )
457 c.setAlpha( alpha );
458 }
459
460 QString label;
461 if ( lineParts.count() > 5 )
462 {
463 label = lineParts.mid( 5 ).join( ' ' );
464 }
465
466 classes << Class( value, c, label );
467 break;
468 }
469 }
470
471 }
472 return classes;
473}
474
476{
477 QFile inputFile( path );
478 QString input;
479 if ( inputFile.open( QIODevice::ReadOnly ) )
480 {
481 QTextStream in( &inputFile );
482 input = in.readAll();
483 inputFile.close();
484 }
485 return classDataFromString( input );
486}
487
489{
490 QStringList out;
491 // must be sorted
493 std::sort( cd.begin(), cd.end(), []( const Class & a, const Class & b ) -> bool
494 {
495 return a.value < b.value;
496 } );
497
498 const auto constCd = cd;
499 for ( const Class &c : constCd )
500 {
501 out << QStringLiteral( "%1 %2 %3 %4 %5 %6" ).arg( c.value ).arg( c.color.red() )
502 .arg( c.color.green() ).arg( c.color.blue() ).arg( c.color.alpha() ).arg( c.label );
503 }
504 return out.join( '\n' );
505}
506
508{
509 if ( !raster )
510 return ClassData();
511
512 ClassData data;
513
514 if ( bandNumber > 0 && bandNumber <= raster->bandCount() )
515 {
516 qlonglong numClasses = 0;
517
518 if ( feedback )
519 feedback->setProgress( 0 );
520
521 // Collect unique values for float rasters
522 if ( raster->dataType( bandNumber ) == Qgis::DataType::Float32 || raster->dataType( bandNumber ) == Qgis::DataType::Float64 )
523 {
524
525 if ( feedback && feedback->isCanceled() )
526 {
527 return data;
528 }
529
530 std::set<double> values;
531
534
535 QgsRasterIterator iter( raster );
536 iter.startRasterRead( bandNumber, raster->xSize(), raster->ySize(), raster->extent(), feedback );
537
538 const int nbBlocksWidth = static_cast< int >( std::ceil( 1.0 * raster->xSize() / maxWidth ) );
539 const int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * raster->ySize() / maxHeight ) );
540 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
541
542 int iterLeft = 0;
543 int iterTop = 0;
544 int iterCols = 0;
545 int iterRows = 0;
546 std::unique_ptr< QgsRasterBlock > rasterBlock;
547 QgsRectangle blockExtent;
548 bool isNoData = false;
549 while ( iter.readNextRasterPart( bandNumber, iterCols, iterRows, rasterBlock, iterLeft, iterTop, &blockExtent ) )
550 {
551 if ( feedback )
552 feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
553
554 if ( feedback && feedback->isCanceled() )
555 break;
556
557 for ( int row = 0; row < iterRows; row++ )
558 {
559 if ( feedback && feedback->isCanceled() )
560 break;
561
562 for ( int column = 0; column < iterCols; column++ )
563 {
564 if ( feedback && feedback->isCanceled() )
565 break;
566
567 const double currentValue = rasterBlock->valueAndNoData( row, column, isNoData );
568 if ( numClasses >= MAX_FLOAT_CLASSES )
569 {
570 QgsMessageLog::logMessage( QStringLiteral( "Number of classes exceeded maximum (%1)." ).arg( MAX_FLOAT_CLASSES ), QStringLiteral( "Raster" ) );
571 break;
572 }
573 if ( !isNoData && values.find( currentValue ) == values.end() )
574 {
575 values.insert( currentValue );
576 data.push_back( Class( currentValue, QColor(), QLocale().toString( currentValue ) ) );
577 numClasses++;
578 }
579 }
580 }
581 }
582 // must be sorted
583 std::sort( data.begin(), data.end(), []( const Class & a, const Class & b ) -> bool
584 {
585 return a.value < b.value;
586 } );
587 }
588 else
589 {
590 // get min and max value from raster
591 const QgsRasterBandStats stats = raster->bandStatistics( bandNumber, QgsRasterBandStats::Min | QgsRasterBandStats::Max, QgsRectangle(), 0, feedback );
592 if ( feedback && feedback->isCanceled() )
593 return ClassData();
594
595 const double min = stats.minimumValue;
596 const double max = stats.maximumValue;
597 // need count of every individual value
598 const int bins = std::ceil( max - min ) + 1;
599 if ( bins <= 0 )
600 return ClassData();
601
602 const QgsRasterHistogram histogram = raster->histogram( bandNumber, bins, min, max, QgsRectangle(), 0, false, feedback );
603 if ( feedback && feedback->isCanceled() )
604 return ClassData();
605
606 const double interval = ( histogram.maximum - histogram.minimum + 1 ) / histogram.binCount;
607 double currentValue = histogram.minimum;
608 for ( int idx = 0; idx < histogram.binCount; ++idx )
609 {
610 const int count = histogram.histogramVector.at( idx );
611 if ( count > 0 )
612 {
613 data << Class( currentValue, QColor(), QLocale().toString( currentValue ) );
614 numClasses++;
615 }
616 currentValue += interval;
617 }
618 }
619
620 // assign colors from ramp
621 if ( ramp && numClasses > 0 )
622 {
623 int i = 0;
624
625 if ( QgsRandomColorRamp *randomRamp = dynamic_cast<QgsRandomColorRamp *>( ramp ) )
626 {
627 //ramp is a random colors ramp, so inform it of the total number of required colors
628 //this allows the ramp to pregenerate a set of visually distinctive colors
629 randomRamp->setTotalColorCount( data.count() );
630 }
631
632 if ( numClasses > 1 )
633 numClasses -= 1; //avoid duplicate first color
634
635 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
636 for ( ; cIt != data.end(); ++cIt )
637 {
638 if ( feedback )
639 {
640 // Show no less than 1%, then the max between class fill and real progress
641 feedback->setProgress( std::max<int>( 1, 100 * ( i + 1 ) / numClasses ) );
642 }
643 cIt->color = ramp->color( i / static_cast<double>( numClasses ) );
644 i++;
645 }
646 }
647 }
648 return data;
649}
650
651void QgsPalettedRasterRenderer::updateArrays()
652{
653 mColors.clear();
654 ClassData::const_iterator it = mClassData.constBegin();
655 for ( ; it != mClassData.constEnd(); ++it )
656 {
657 mColors[it->value] = qPremultiply( it->color.rgba() );
658 }
659}
@ 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...
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:2930
#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.