QGIS API Documentation  master-59fd5e0
src/core/raster/qgsrasterrendererregistry.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                          qgsrasterrendererregistry.cpp
00003                          -----------------------------
00004     begin                : January 2012
00005     copyright            : (C) 2012 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 "qgsrasterrendererregistry.h"
00019 #include "qgsmultibandcolorrenderer.h"
00020 #include "qgspalettedrasterrenderer.h"
00021 #include "qgssinglebandcolordatarenderer.h"
00022 #include "qgssinglebandgrayrenderer.h"
00023 #include "qgssinglebandpseudocolorrenderer.h"
00024 #include <QSettings>
00025 
00026 QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry( const QString& theName, const QString& theVisibleName,
00027     QgsRasterRendererCreateFunc rendererFunction,
00028     QgsRasterRendererWidgetCreateFunc widgetFunction ):
00029     name( theName ), visibleName( theVisibleName ), rendererCreateFunction( rendererFunction ),
00030     widgetCreateFunction( widgetFunction )
00031 {
00032 }
00033 
00034 QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry(): rendererCreateFunction( 0 ), widgetCreateFunction( 0 )
00035 {
00036 }
00037 
00038 QgsRasterRendererRegistry* QgsRasterRendererRegistry::mInstance = 0;
00039 
00040 QgsRasterRendererRegistry* QgsRasterRendererRegistry::instance()
00041 {
00042   if ( !mInstance )
00043   {
00044     mInstance = new QgsRasterRendererRegistry();
00045   }
00046   return mInstance;
00047 }
00048 
00049 QgsRasterRendererRegistry::QgsRasterRendererRegistry()
00050 {
00051   // insert items in a particular order, which is returned in renderersList()
00052   insert( QgsRasterRendererRegistryEntry( "multibandcolor", QObject::tr( "Multiband color" ),
00053                                           QgsMultiBandColorRenderer::create, 0 ) );
00054   insert( QgsRasterRendererRegistryEntry( "paletted", QObject::tr( "Paletted" ), QgsPalettedRasterRenderer::create, 0 ) );
00055   insert( QgsRasterRendererRegistryEntry( "singlebandgray", QObject::tr( "Singleband gray" ),
00056                                           QgsSingleBandGrayRenderer::create, 0 ) );
00057   insert( QgsRasterRendererRegistryEntry( "singlebandpseudocolor", QObject::tr( "Singleband pseudocolor" ),
00058                                           QgsSingleBandPseudoColorRenderer::create, 0 ) );
00059   insert( QgsRasterRendererRegistryEntry( "singlebandcolordata", QObject::tr( "Singleband color data" ),
00060                                           QgsSingleBandColorDataRenderer::create, 0 ) );
00061 }
00062 
00063 QgsRasterRendererRegistry::~QgsRasterRendererRegistry()
00064 {
00065 }
00066 
00067 void QgsRasterRendererRegistry::insert( QgsRasterRendererRegistryEntry entry )
00068 {
00069   mEntries.insert( entry.name, entry );
00070   mSortedEntries.append( entry.name );
00071 }
00072 
00073 void QgsRasterRendererRegistry::insertWidgetFunction( const QString& rendererName, QgsRasterRendererWidgetCreateFunc func )
00074 {
00075   if ( !mEntries.contains( rendererName ) )
00076   {
00077     return;
00078   }
00079   mEntries[rendererName].widgetCreateFunction = func;
00080 }
00081 
00082 bool QgsRasterRendererRegistry::rendererData( const QString& rendererName, QgsRasterRendererRegistryEntry& data ) const
00083 {
00084   QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.find( rendererName );
00085   if ( it == mEntries.constEnd() )
00086   {
00087     return false;
00088   }
00089   data = it.value();
00090   return true;
00091 }
00092 
00093 QStringList QgsRasterRendererRegistry::renderersList() const
00094 {
00095   return mSortedEntries;
00096 }
00097 
00098 QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() const
00099 {
00100   QList< QgsRasterRendererRegistryEntry > result;
00101 
00102   QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constBegin();
00103   for ( ; it != mEntries.constEnd(); ++it )
00104   {
00105     result.push_back( it.value() );
00106   }
00107   return result;
00108 }
00109 
00110 QgsRasterRenderer* QgsRasterRendererRegistry::defaultRendererForDrawingStyle( const QgsRaster::DrawingStyle&  theDrawingStyle, QgsRasterDataProvider* provider ) const
00111 {
00112   if ( !provider || provider->bandCount() < 1 )
00113   {
00114     return 0;
00115   }
00116 
00117 
00118   QgsRasterRenderer* renderer = 0;
00119   switch ( theDrawingStyle )
00120   {
00121     case QgsRaster::PalettedColor:
00122     {
00123       int grayBand = 1; //reasonable default
00124       QList<QgsColorRampShader::ColorRampItem> colorEntries = provider->colorTable( grayBand );
00125 
00126       //go through list and take maximum value (it could be that entries don't start at 0 or indices are not contiguous)
00127       int colorArraySize = 0;
00128       QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = colorEntries.constBegin();
00129       for ( ; colorIt != colorEntries.constEnd(); ++colorIt )
00130       {
00131         if ( colorIt->value > colorArraySize )
00132         {
00133           colorArraySize = ( int )( colorIt->value );
00134         }
00135       }
00136 
00137       colorArraySize += 1; //usually starts at 0
00138       QColor* colorArray = new QColor[ colorArraySize ];
00139       colorIt = colorEntries.constBegin();
00140       for ( ; colorIt != colorEntries.constEnd(); ++colorIt )
00141       {
00142         colorArray[( int )( colorIt->value )] = colorIt->color;
00143       }
00144 
00145       renderer = new QgsPalettedRasterRenderer( provider,
00146           grayBand,
00147           colorArray,
00148           colorArraySize );
00149     }
00150     break;
00151     case QgsRaster::MultiBandSingleBandGray:
00152     case QgsRaster::SingleBandGray:
00153     {
00154       int grayBand = 1;
00155       renderer = new QgsSingleBandGrayRenderer( provider, grayBand );
00156 
00157       QgsContrastEnhancement* ce = new QgsContrastEnhancement(( QGis::DataType )(
00158             provider->dataType( grayBand ) ) );
00159 
00160 // Default contrast enhancement is set from QgsRasterLayer, it has already setContrastEnhancementAlgorithm(). Default enhancement must only be set if default style was not loaded (to avoid stats calculation).
00161       (( QgsSingleBandGrayRenderer* )renderer )->setContrastEnhancement( ce );
00162       break;
00163     }
00164     case QgsRaster::SingleBandPseudoColor:
00165     {
00166       int bandNo = 1;
00167       double minValue = 0;
00168       double maxValue = 0;
00169       // TODO: avoid calculating statistics if not necessary (default style loaded)
00170       minMaxValuesForBand( bandNo, provider, minValue, maxValue );
00171       QgsRasterShader* shader = new QgsRasterShader( minValue, maxValue );
00172       renderer = new QgsSingleBandPseudoColorRenderer( provider, bandNo, shader );
00173       break;
00174     }
00175     case QgsRaster::MultiBandColor:
00176     {
00177       QSettings s;
00178 
00179       int redBand = s.value( "/Raster/defaultRedBand", 1 ).toInt();
00180       if ( redBand < 0 || redBand > provider->bandCount() )
00181       {
00182         redBand = -1;
00183       }
00184       int greenBand = s.value( "/Raster/defaultGreenBand", 2 ).toInt();
00185       if ( greenBand < 0 || greenBand > provider->bandCount() )
00186       {
00187         greenBand = -1;
00188       }
00189       int blueBand = s.value( "/Raster/defaultBlueBand", 3 ).toInt();
00190       if ( blueBand < 0 || blueBand > provider->bandCount() )
00191       {
00192         blueBand = -1;
00193       }
00194 
00195       renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
00196       break;
00197     }
00198     case QgsRaster::SingleBandColorDataStyle:
00199     {
00200       renderer = new QgsSingleBandColorDataRenderer( provider, 1 );
00201       break;
00202     }
00203     default:
00204       break;
00205   }
00206 
00207   QgsRasterTransparency* tr = new QgsRasterTransparency(); //renderer takes ownership
00208   int bandCount = renderer->usesBands().size();
00209   if ( bandCount == 1 )
00210   {
00211     QList<QgsRasterTransparency::TransparentSingleValuePixel> transparentSingleList;
00212     tr->setTransparentSingleValuePixelList( transparentSingleList );
00213   }
00214   else if ( bandCount == 3 )
00215   {
00216     QList<QgsRasterTransparency::TransparentThreeValuePixel> transparentThreeValueList;
00217     tr->setTransparentThreeValuePixelList( transparentThreeValueList );
00218   }
00219   renderer->setRasterTransparency( tr );
00220   return renderer;
00221 }
00222 
00223 bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider* provider, double& minValue, double& maxValue ) const
00224 {
00225   if ( !provider )
00226   {
00227     return false;
00228   }
00229 
00230   minValue = 0;
00231   maxValue = 0;
00232 
00233   QSettings s;
00234   if ( s.value( "/Raster/useStandardDeviation", false ).toBool() )
00235   {
00236     QgsRasterBandStats stats = provider->bandStatistics( band, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev );
00237 
00238     double stdDevFactor = s.value( "/Raster/defaultStandardDeviation", 2.0 ).toDouble();
00239     double diff = stdDevFactor * stats.stdDev;
00240     minValue = stats.mean - diff;
00241     maxValue = stats.mean + diff;
00242   }
00243   else
00244   {
00245     QgsRasterBandStats stats = provider->bandStatistics( band, QgsRasterBandStats::Min | QgsRasterBandStats::Max );
00246     minValue = stats.minimumValue;
00247     maxValue = stats.maximumValue;
00248   }
00249   return true;
00250 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines