Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Single band pseudo color renderer
  • Loading branch information
mhugent committed Jan 6, 2012
1 parent 4809f06 commit ea9a2a8
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -171,6 +171,7 @@ SET(QGIS_CORE_SRCS
raster/qgsmultibandcolorrenderer.cpp
raster/qgssinglebandcolordatarenderer.cpp
raster/qgssinglebandgrayrenderer.cpp
raster/qgssinglebandpseudocolorrenderer.cpp

renderer/qgscontinuouscolorrenderer.cpp
renderer/qgsgraduatedsymbolrenderer.cpp
Expand Down
29 changes: 29 additions & 0 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -42,6 +42,7 @@ email : tim at linfiniti.com
#include "qgscubicrasterresampler.h"
#include "qgsmultibandcolorrenderer.h"
#include "qgssinglebandcolordatarenderer.h"
#include "qgssinglebandpseudocolorrenderer.h"
#include "qgssinglebandgrayrenderer.h"

#include <cstdio>
Expand Down Expand Up @@ -863,8 +864,36 @@ void QgsRasterLayer::draw( QPainter * theQPainter,
}
else
{
//init
int bandNo = bandNumber( mGrayBandName );
QgsRasterBandStats myRasterBandStats = bandStatistics( bandNo );
double myMinimumValue = 0.0;
double myMaximumValue = 0.0;
//Use standard deviations if set, otherwise, use min max of band
if ( mStandardDeviations > 0 )
{
myMinimumValue = ( myRasterBandStats.mean - ( mStandardDeviations * myRasterBandStats.stdDev ) );
myMaximumValue = ( myRasterBandStats.mean + ( mStandardDeviations * myRasterBandStats.stdDev ) );
}
else
{
myMinimumValue = myRasterBandStats.minimumValue;
myMaximumValue = myRasterBandStats.maximumValue;
}

mRasterShader->setMinimumValue( myMinimumValue );
mRasterShader->setMaximumValue( myMaximumValue );

QgsSingleBandPseudoColorRenderer r( mDataProvider, bandNo, mRasterShader, mResampler );
r.setOpacity( mTransparencyLevel / 255.0 );
r.setRasterTransparency( &mRasterTransparency );
r.setInvertColor( mInvertColor );
r.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );

#if 0
drawSingleBandPseudoColor( theQPainter, theRasterViewPort,
theQgsMapToPixel, bandNumber( mGrayBandName ) );
#endif //0
break;
}
// a single band with a color map
Expand Down
128 changes: 128 additions & 0 deletions src/core/raster/qgssinglebandpseudocolorrenderer.cpp
@@ -0,0 +1,128 @@
/***************************************************************************
qgssinglebandpseudocolorrenderer.cpp
------------------------------------
begin : January 2012
copyright : (C) 2012 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgssinglebandpseudocolorrenderer.h"
#include "qgsrastershader.h"
#include "qgsrastertransparency.h"
#include "qgsrasterviewport.h"
#include <QImage>

QgsSingleBandPseudoColorRenderer::QgsSingleBandPseudoColorRenderer( QgsRasterDataProvider* provider, int band, QgsRasterShader* shader, QgsRasterResampler* resampler ):
QgsRasterRenderer( provider, resampler ), mShader( shader ), mBand( band )
{
}

QgsSingleBandPseudoColorRenderer::~QgsSingleBandPseudoColorRenderer()
{
}

void QgsSingleBandPseudoColorRenderer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel )
{
if ( !p || !mProvider || !viewPort || !theQgsMapToPixel || !mShader )
{
return;
}

double oversamplingX, oversamplingY;
QgsRasterDataProvider::DataType transparencyType = QgsRasterDataProvider::UnknownDataType;
if ( mAlphaBand > 0 )
{
transparencyType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mAlphaBand );
}
startRasterRead( mBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY );
//Read alpha band if necessary
if ( mAlphaBand > 0 && mAlphaBand != mBand )
{
startRasterRead( mAlphaBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY );
}

int nCols = 0;
int nRows = 0;
int topLeftCol = 0;
int topLeftRow = 0;
void* rasterData;
void* transparencyData;
double currentOpacity = mOpacity;
QgsRasterDataProvider::DataType rasterType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mBand );
int red, green, blue;
QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );

//rendering is faster without considering user-defined transparency
bool hasTransparency = usesTransparency( viewPort->mSrcCRS, viewPort->mDestCRS );

while ( readNextRasterPart( mBand, viewPort, nCols, nRows, &rasterData, topLeftCol, topLeftRow ) )
{
if ( mAlphaBand > 0 && mAlphaBand != mBand )
{
readNextRasterPart( mAlphaBand, viewPort, nCols, nRows, &transparencyData, topLeftCol, topLeftRow );
}
else if ( mAlphaBand == mBand )
{
transparencyData = rasterData;
}

//create image
QImage img( nCols, nRows, QImage::Format_ARGB32_Premultiplied );
QRgb* imageScanLine = 0;
double val = 0;

int currentRasterPos = 0;
for ( int i = 0; i < nRows; ++i )
{
imageScanLine = ( QRgb* )( img.scanLine( i ) );
for ( int j = 0; j < nCols; ++j )
{
val = readValue( rasterData, rasterType, currentRasterPos );
if ( !mShader->shade( val, &red, &green, &blue ) )
{
imageScanLine[j] = myDefaultColor;
++currentRasterPos;
continue;
}

if ( !hasTransparency )
{
imageScanLine[j] = qRgba( red, green, blue, 255 );
}
else
{
//opacity
currentOpacity = mOpacity;
if ( mRasterTransparency )
{
currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0;
}
if ( mAlphaBand > 0 )
{
currentOpacity *= ( readValue( transparencyData, transparencyType, currentRasterPos ) / 255.0 );
}

imageScanLine[j] = qRgba( currentOpacity * red, currentOpacity * green, currentOpacity * blue, currentOpacity * 255 );
}
++currentRasterPos;
}
}

drawImage( p, viewPort, img, topLeftCol, topLeftRow, nCols, nRows, oversamplingX, oversamplingY );
}

stopRasterRead( mBand );
if ( mAlphaBand > 0 && mAlphaBand != mBand )
{
stopRasterRead( mAlphaBand );
}
}
38 changes: 38 additions & 0 deletions src/core/raster/qgssinglebandpseudocolorrenderer.h
@@ -0,0 +1,38 @@
/***************************************************************************
qgssinglebandpseudocolorrenderer.h
----------------------------------
begin : January 2012
copyright : (C) 2012 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSSINGLEBANDPSEUDOCOLORRENDERER_H
#define QGSSINGLEBANDPSEUDOCOLORRENDERER_H

#include "qgsrasterrenderer.h"

class QgsRasterShader;

class QgsSingleBandPseudoColorRenderer: public QgsRasterRenderer
{
public:
QgsSingleBandPseudoColorRenderer( QgsRasterDataProvider* provider, int band, QgsRasterShader* shader, QgsRasterResampler* resampler = 0 );
~QgsSingleBandPseudoColorRenderer();

virtual void draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel );

private:
QgsRasterShader* mShader;
int mBand;
};

#endif // QGSSINGLEBANDPSEUDOCOLORRENDERER_H

0 comments on commit ea9a2a8

Please sign in to comment.