|
Quantum GIS API Documentation
master-ce49b66
|
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 }