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