Quantum GIS API Documentation  master-ce49b66
src/core/raster/qgssinglebandgrayrenderer.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                          qgssinglebandgrayrenderer.cpp
00003                          -----------------------------
00004     begin                : December 2011
00005     copyright            : (C) 2011 by Marco Hugentobler
00006     email                : marco at sourcepole dot ch
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "qgssinglebandgrayrenderer.h"
00019 #include "qgscontrastenhancement.h"
00020 #include "qgsrastertransparency.h"
00021 #include <QDomDocument>
00022 #include <QDomElement>
00023 #include <QImage>
00024 
00025 QgsSingleBandGrayRenderer::QgsSingleBandGrayRenderer( QgsRasterInterface* input, int grayBand ):
00026     QgsRasterRenderer( input, "singlebandgray" ), mGrayBand( grayBand ), mGradient( BlackToWhite ), mContrastEnhancement( 0 )
00027 {
00028 }
00029 
00030 QgsSingleBandGrayRenderer::~QgsSingleBandGrayRenderer()
00031 {
00032   delete mContrastEnhancement;
00033 }
00034 
00035 QgsRasterInterface * QgsSingleBandGrayRenderer::clone() const
00036 {
00037   QgsSingleBandGrayRenderer * renderer = new QgsSingleBandGrayRenderer( 0, mGrayBand );
00038   renderer->setOpacity( mOpacity );
00039   renderer->setAlphaBand( mAlphaBand );
00040   renderer->setRasterTransparency( mRasterTransparency );
00041   renderer->setGradient( mGradient );
00042   if ( mContrastEnhancement )
00043   {
00044     renderer->setContrastEnhancement( new QgsContrastEnhancement( *mContrastEnhancement ) );
00045   }
00046   return renderer;
00047 }
00048 
00049 QgsRasterRenderer* QgsSingleBandGrayRenderer::create( const QDomElement& elem, QgsRasterInterface* input )
00050 {
00051   if ( elem.isNull() )
00052   {
00053     return 0;
00054   }
00055 
00056   int grayBand = elem.attribute( "grayBand", "-1" ).toInt();
00057   QgsSingleBandGrayRenderer* r = new QgsSingleBandGrayRenderer( input, grayBand );
00058   r->readXML( elem );
00059 
00060   if ( elem.attribute( "gradient" ) == "WhiteToBlack" )
00061   {
00062     r->setGradient( WhiteToBlack );  // BlackToWhite is default
00063   }
00064 
00065   QDomElement contrastEnhancementElem = elem.firstChildElement( "contrastEnhancement" );
00066   if ( !contrastEnhancementElem.isNull() )
00067   {
00068     QgsContrastEnhancement* ce = new QgsContrastEnhancement(( QGis::DataType )(
00069           input->dataType( grayBand ) ) ) ;
00070     ce->readXML( contrastEnhancementElem );
00071     r->setContrastEnhancement( ce );
00072   }
00073   return r;
00074 }
00075 
00076 void QgsSingleBandGrayRenderer::setContrastEnhancement( QgsContrastEnhancement* ce )
00077 {
00078   delete mContrastEnhancement;
00079   mContrastEnhancement = ce;
00080 }
00081 
00082 QgsRasterBlock* QgsSingleBandGrayRenderer::block( int bandNo, QgsRectangle  const & extent, int width, int height )
00083 {
00084   Q_UNUSED( bandNo );
00085   QgsDebugMsg( QString( "width = %1 height = %2" ).arg( width ).arg( height ) );
00086 
00087   QgsRasterBlock *outputBlock = new QgsRasterBlock();
00088   if ( !mInput )
00089   {
00090     return outputBlock;
00091   }
00092 
00093   QgsRasterBlock *inputBlock = mInput->block( mGrayBand, extent, width, height );
00094   if ( !inputBlock || inputBlock->isEmpty() )
00095   {
00096     QgsDebugMsg( "No raster data!" );
00097     delete inputBlock;
00098     return outputBlock;
00099   }
00100 
00101   QgsRasterBlock *alphaBlock = 0;
00102 
00103   if ( mAlphaBand > 0 && mGrayBand != mAlphaBand )
00104   {
00105     alphaBlock = mInput->block( mAlphaBand, extent, width, height );
00106     if ( !alphaBlock || alphaBlock->isEmpty() )
00107     {
00108       // TODO: better to render without alpha
00109       delete inputBlock;
00110       delete alphaBlock;
00111       return outputBlock;
00112     }
00113   }
00114   else if ( mAlphaBand > 0 )
00115   {
00116     alphaBlock = inputBlock;
00117   }
00118 
00119   if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) )
00120   {
00121     delete inputBlock;
00122     delete alphaBlock;
00123     return outputBlock;
00124   }
00125 
00126   QRgb myDefaultColor = NODATA_COLOR;
00127   for ( size_t i = 0; i < ( size_t )width*height; i++ )
00128   {
00129     if ( inputBlock->isNoData( i ) )
00130     {
00131       outputBlock->setColor( i, myDefaultColor );
00132       continue;
00133     }
00134     double grayVal = inputBlock->value( i );
00135 
00136     double currentAlpha = mOpacity;
00137     if ( mRasterTransparency )
00138     {
00139       currentAlpha = mRasterTransparency->alphaValue( grayVal, mOpacity * 255 ) / 255.0;
00140     }
00141     if ( mAlphaBand > 0 )
00142     {
00143       currentAlpha *= alphaBlock->value( i ) / 255.0;
00144     }
00145 
00146     if ( mContrastEnhancement )
00147     {
00148       if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
00149       {
00150         outputBlock->setColor( i, myDefaultColor );
00151         continue;
00152       }
00153       grayVal = mContrastEnhancement->enhanceContrast( grayVal );
00154     }
00155 
00156     if ( mGradient == WhiteToBlack )
00157     {
00158       grayVal = 255 - grayVal;
00159     }
00160 
00161     if ( qgsDoubleNear( currentAlpha, 1.0 ) )
00162     {
00163       outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
00164     }
00165     else
00166     {
00167       outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
00168     }
00169   }
00170 
00171   delete inputBlock;
00172   if ( mAlphaBand > 0 && mGrayBand != mAlphaBand )
00173   {
00174     delete alphaBlock;
00175   }
00176 
00177   return outputBlock;
00178 }
00179 
00180 void QgsSingleBandGrayRenderer::writeXML( QDomDocument& doc, QDomElement& parentElem ) const
00181 {
00182   if ( parentElem.isNull() )
00183   {
00184     return;
00185   }
00186 
00187   QDomElement rasterRendererElem = doc.createElement( "rasterrenderer" );
00188   _writeXML( doc, rasterRendererElem );
00189 
00190   rasterRendererElem.setAttribute( "grayBand", mGrayBand );
00191 
00192   QString gradient;
00193   if ( mGradient == BlackToWhite )
00194   {
00195     gradient = "BlackToWhite";
00196   }
00197   else
00198   {
00199     gradient = "WhiteToBlack";
00200   }
00201   rasterRendererElem.setAttribute( "gradient", gradient );
00202 
00203   if ( mContrastEnhancement )
00204   {
00205     QDomElement contrastElem = doc.createElement( "contrastEnhancement" );
00206     mContrastEnhancement->writeXML( doc, contrastElem );
00207     rasterRendererElem.appendChild( contrastElem );
00208   }
00209   parentElem.appendChild( rasterRendererElem );
00210 }
00211 
00212 void QgsSingleBandGrayRenderer::legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const
00213 {
00214   if ( mContrastEnhancement && mContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement )
00215   {
00216     symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), QColor( 0, 0, 0 ) ) );
00217     symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), QColor( 255, 255, 255 ) ) );
00218   }
00219 }
00220 
00221 QList<int> QgsSingleBandGrayRenderer::usesBands() const
00222 {
00223   QList<int> bandList;
00224   if ( mGrayBand != -1 )
00225   {
00226     bandList << mGrayBand;
00227   }
00228   return bandList;
00229 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines