QGIS API Documentation  2.17.0-Master (f49f7ce)
qgssinglebandcolordatarenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssinglebandcolordatarenderer.cpp
3  ----------------------------------
4  begin : January 2012
5  copyright : (C) 2012 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 <QDomDocument>
22 #include <QDomElement>
23 #include <QImage>
24 
26  QgsRasterRenderer( input, "singlebandcolordata" ), mBand( band )
27 {
28 
29 }
30 
32 {
33 }
34 
36 {
37  QgsSingleBandColorDataRenderer * renderer = new QgsSingleBandColorDataRenderer( nullptr, mBand );
38  renderer->copyCommonProperties( this );
39  return renderer;
40 }
41 
43 {
44  if ( elem.isNull() )
45  {
46  return nullptr;
47  }
48 
49  int band = elem.attribute( "band", "-1" ).toInt();
50  QgsRasterRenderer* r = new QgsSingleBandColorDataRenderer( input, band );
51  r->readXML( elem );
52  return r;
53 }
54 
55 QgsRasterBlock* QgsSingleBandColorDataRenderer::block( int bandNo, QgsRectangle const & extent, int width, int height )
56 {
57  return block2( bandNo, extent, width, height );
58 }
59 
60 QgsRasterBlock* QgsSingleBandColorDataRenderer::block2( int bandNo, QgsRectangle const & extent, int width, int height, QgsRasterBlockFeedback* feedback )
61 {
62  Q_UNUSED( bandNo );
63 
64  QgsRasterBlock *outputBlock = new QgsRasterBlock();
65  if ( !mInput )
66  {
67  return outputBlock;
68  }
69 
70  QgsRasterBlock *inputBlock = mInput->block2( mBand, extent, width, height, feedback );
71  if ( !inputBlock || inputBlock->isEmpty() )
72  {
73  QgsDebugMsg( "No raster data!" );
74  delete inputBlock;
75  return outputBlock;
76  }
77 
78  bool hasTransparency = usesTransparency();
79  if ( !hasTransparency )
80  {
81  // Nothing to do, just retype if necessary
82  inputBlock->convert( QGis::ARGB32_Premultiplied );
83  delete outputBlock;
84  return inputBlock;
85  }
86 
87  if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) )
88  {
89  delete inputBlock;
90  return outputBlock;
91  }
92 
93  // make sure input is also premultiplied!
94  inputBlock->convert( QGis::ARGB32_Premultiplied );
95 
96  QRgb* inputBits = ( QRgb* )inputBlock->bits();
97  QRgb* outputBits = ( QRgb* )outputBlock->bits();
98  for ( qgssize i = 0; i < ( qgssize )width*height; i++ )
99  {
100  QRgb c = inputBits[i];
101  outputBits[i] = qRgba( mOpacity * qRed( c ), mOpacity * qGreen( c ), mOpacity * qBlue( c ), mOpacity * qAlpha( c ) );
102  }
103 
104  delete inputBlock;
105  return outputBlock;
106 }
107 
109 {
110  if ( parentElem.isNull() )
111  return;
112 
113  QDomElement rasterRendererElem = doc.createElement( "rasterrenderer" );
114  _writeXML( doc, rasterRendererElem );
115  rasterRendererElem.setAttribute( "band", mBand );
116  parentElem.appendChild( rasterRendererElem );
117 }
118 
120 {
121  QList<int> bandList;
122  if ( mBand != -1 )
123  {
124  bandList << mBand;
125  }
126  return bandList;
127 }
128 
130 {
131  // Renderer can only work with numerical values in at least 1 band
132  if ( !input ) return false;
133 
134  if ( !mOn )
135  {
136  // In off mode we can connect to anything
137  mInput = input;
138  return true;
139  }
140 
141  if ( input->dataType( 1 ) == QGis::ARGB32 ||
142  input->dataType( 1 ) == QGis::ARGB32_Premultiplied )
143  {
144  mInput = input;
145  return true;
146  }
147  return false;
148 }
A rectangle specified with double values.
Definition: qgsrectangle.h:35
bool setInput(QgsRasterInterface *input) override
Set input.
bool convert(QGis::DataType destDataType)
Convert data to different type.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height) override
Read block of data using given extent and size.
QDomNode appendChild(const QDomNode &newChild)
QString attribute(const QString &name, const QString &defValue) const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void copyCommonProperties(const QgsRasterRenderer *other)
Copies common properties like opacity / transparency data from other renderer.
QgsSingleBandColorDataRenderer * clone() const override
Clone itself, create deep copy.
virtual QgsRasterInterface * input() const
Current input.
QgsSingleBandColorDataRenderer(QgsRasterInterface *input, int band)
void readXML(const QDomElement &rendererElem) override
Sets base class members from xml.
virtual QgsRasterBlock * block2(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)
Read block of data using given extent and size.
Raster renderer pipe for single band color.
bool usesTransparency() const
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:150
Raster data container.
void setAttribute(const QString &name, const QString &value)
int toInt(bool *ok, int base) const
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition: qgis.h:148
virtual QGis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
Base class for processing filters like renderers, reprojector, resampler etc.
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:500
bool reset(QGis::DataType theDataType, int theWidth, int theHeight)
Reset block.
bool isNull() const
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
virtual QgsRectangle extent()
Get the extent of the interface.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
char * bits(int row, int column)
Get pointer to data.
void writeXML(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
QgsRasterBlock * block2(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
double mOpacity
Global alpha value (0-1)
QDomElement createElement(const QString &tagName)
void _writeXML(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXML method of subclasses) ...
QgsRasterInterface * mInput
Feedback object tailored for raster block reading.
Raster renderer pipe that applies colors to a raster.
bool isEmpty() const
Returns true if block is empty, i.e.