Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsrasterrendererregistry.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 : :
18 : : #include "qgsrasterrendererregistry.h"
19 : : #include "qgsrasterdataprovider.h"
20 : : #include "qgsrastershader.h"
21 : : #include "qgsrastertransparency.h"
22 : : #include "qgsmultibandcolorrenderer.h"
23 : : #include "qgspalettedrasterrenderer.h"
24 : : #include "qgsrastercontourrenderer.h"
25 : : #include "qgssinglebandcolordatarenderer.h"
26 : : #include "qgssinglebandgrayrenderer.h"
27 : : #include "qgssinglebandpseudocolorrenderer.h"
28 : : #include "qgshillshaderenderer.h"
29 : : #include "qgsapplication.h"
30 : : #include "qgssettings.h"
31 : :
32 : : #include <QIcon>
33 : :
34 : 35 : QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry( const QString &name, const QString &visibleName,
35 : : QgsRasterRendererCreateFunc rendererFunction,
36 : : QgsRasterRendererWidgetCreateFunc widgetFunction )
37 : 35 : : name( name )
38 : 35 : , visibleName( visibleName )
39 : 35 : , rendererCreateFunction( rendererFunction )
40 : 35 : , widgetCreateFunction( widgetFunction )
41 : : {
42 : 35 : }
43 : :
44 : 0 : QIcon QgsRasterRendererRegistryEntry::icon()
45 : : {
46 : 0 : return QgsApplication::getThemeIcon( QString( "styleicons/%1.svg" ).arg( name ) );
47 : 0 : }
48 : :
49 : 5 : QgsRasterRendererRegistry::QgsRasterRendererRegistry()
50 : : {
51 : : // insert items in a particular order, which is returned in renderersList()
52 : 10 : insert( QgsRasterRendererRegistryEntry( QStringLiteral( "multibandcolor" ), QObject::tr( "Multiband color" ),
53 : : QgsMultiBandColorRenderer::create, nullptr ) );
54 : 10 : insert( QgsRasterRendererRegistryEntry( QStringLiteral( "paletted" ), QObject::tr( "Paletted/Unique values" ), QgsPalettedRasterRenderer::create, nullptr ) );
55 : 10 : insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandgray" ), QObject::tr( "Singleband gray" ),
56 : : QgsSingleBandGrayRenderer::create, nullptr ) );
57 : 10 : insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandpseudocolor" ), QObject::tr( "Singleband pseudocolor" ),
58 : : QgsSingleBandPseudoColorRenderer::create, nullptr ) );
59 : 10 : insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandcolordata" ), QObject::tr( "Singleband color data" ),
60 : : QgsSingleBandColorDataRenderer::create, nullptr ) );
61 : 10 : insert( QgsRasterRendererRegistryEntry( QStringLiteral( "hillshade" ), QObject::tr( "Hillshade" ),
62 : : QgsHillshadeRenderer::create, nullptr ) );
63 : 10 : insert( QgsRasterRendererRegistryEntry( QStringLiteral( "contour" ), QObject::tr( "Contours" ),
64 : : QgsRasterContourRenderer::create, nullptr ) );
65 : 5 : }
66 : :
67 : 35 : void QgsRasterRendererRegistry::insert( const QgsRasterRendererRegistryEntry &entry )
68 : : {
69 : 35 : mEntries.insert( entry.name, entry );
70 : 35 : mSortedEntries.append( entry.name );
71 : 35 : }
72 : :
73 : 0 : void QgsRasterRendererRegistry::insertWidgetFunction( const QString &rendererName, QgsRasterRendererWidgetCreateFunc func )
74 : : {
75 : 0 : if ( !mEntries.contains( rendererName ) )
76 : : {
77 : 0 : return;
78 : : }
79 : 0 : mEntries[rendererName].widgetCreateFunction = func;
80 : 0 : }
81 : :
82 : 0 : bool QgsRasterRendererRegistry::rendererData( const QString &rendererName, QgsRasterRendererRegistryEntry &data ) const
83 : : {
84 : 0 : QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.find( rendererName );
85 : 0 : if ( it == mEntries.constEnd() )
86 : : {
87 : 0 : return false;
88 : : }
89 : 0 : data = it.value();
90 : 0 : return true;
91 : 0 : }
92 : :
93 : 0 : QStringList QgsRasterRendererRegistry::renderersList() const
94 : : {
95 : 0 : return mSortedEntries;
96 : : }
97 : :
98 : 0 : QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() const
99 : : {
100 : 0 : QList< QgsRasterRendererRegistryEntry > result;
101 : :
102 : 0 : QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constBegin();
103 : 0 : for ( ; it != mEntries.constEnd(); ++it )
104 : : {
105 : 0 : result.push_back( it.value() );
106 : 0 : }
107 : 0 : return result;
108 : 0 : }
109 : :
110 : 0 : QgsRasterRenderer *QgsRasterRendererRegistry::defaultRendererForDrawingStyle( QgsRaster::DrawingStyle drawingStyle, QgsRasterDataProvider *provider ) const
111 : : {
112 : 0 : if ( !provider || provider->bandCount() < 1 )
113 : : {
114 : 0 : return nullptr;
115 : : }
116 : :
117 : :
118 : 0 : QgsRasterRenderer *renderer = nullptr;
119 : 0 : switch ( drawingStyle )
120 : : {
121 : : case QgsRaster::PalettedColor:
122 : : {
123 : 0 : int grayBand = 1; //reasonable default
124 : 0 : QgsPalettedRasterRenderer::ClassData classes = QgsPalettedRasterRenderer::colorTableToClassData( provider->colorTable( grayBand ) );
125 : 0 : renderer = new QgsPalettedRasterRenderer( provider,
126 : 0 : grayBand,
127 : : classes );
128 : 0 : }
129 : 0 : break;
130 : : case QgsRaster::MultiBandSingleBandGray:
131 : : case QgsRaster::SingleBandGray:
132 : : {
133 : 0 : int grayBand = 1;
134 : 0 : renderer = new QgsSingleBandGrayRenderer( provider, grayBand );
135 : :
136 : 0 : QgsContrastEnhancement *ce = new QgsContrastEnhancement( ( Qgis::DataType )(
137 : 0 : provider->dataType( grayBand ) ) );
138 : :
139 : : // 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).
140 : 0 : ( ( QgsSingleBandGrayRenderer * )renderer )->setContrastEnhancement( ce );
141 : 0 : break;
142 : : }
143 : : case QgsRaster::SingleBandPseudoColor:
144 : : {
145 : 0 : int bandNo = 1;
146 : 0 : double minValue = 0;
147 : 0 : double maxValue = 0;
148 : : // TODO: avoid calculating statistics if not necessary (default style loaded)
149 : 0 : minMaxValuesForBand( bandNo, provider, minValue, maxValue );
150 : 0 : QgsRasterShader *shader = new QgsRasterShader( minValue, maxValue );
151 : 0 : renderer = new QgsSingleBandPseudoColorRenderer( provider, bandNo, shader );
152 : 0 : break;
153 : : }
154 : : case QgsRaster::MultiBandColor:
155 : : {
156 : 0 : QgsSettings s;
157 : :
158 : 0 : int redBand = s.value( QStringLiteral( "/Raster/defaultRedBand" ), 1 ).toInt();
159 : 0 : if ( redBand < 0 || redBand > provider->bandCount() )
160 : : {
161 : 0 : redBand = -1;
162 : 0 : }
163 : 0 : int greenBand = s.value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt();
164 : 0 : if ( greenBand < 0 || greenBand > provider->bandCount() )
165 : : {
166 : 0 : greenBand = -1;
167 : 0 : }
168 : 0 : int blueBand = s.value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt();
169 : 0 : if ( blueBand < 0 || blueBand > provider->bandCount() )
170 : : {
171 : 0 : blueBand = -1;
172 : 0 : }
173 : :
174 : 0 : renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
175 : : break;
176 : 0 : }
177 : : case QgsRaster::SingleBandColorDataStyle:
178 : : {
179 : 0 : renderer = new QgsSingleBandColorDataRenderer( provider, 1 );
180 : 0 : break;
181 : : }
182 : : default:
183 : 0 : return nullptr;
184 : : }
185 : :
186 : 0 : QgsRasterTransparency *tr = new QgsRasterTransparency(); //renderer takes ownership
187 : 0 : int bandCount = renderer->usesBands().size();
188 : 0 : if ( bandCount == 1 )
189 : : {
190 : 0 : QList<QgsRasterTransparency::TransparentSingleValuePixel> transparentSingleList;
191 : 0 : tr->setTransparentSingleValuePixelList( transparentSingleList );
192 : 0 : }
193 : 0 : else if ( bandCount == 3 )
194 : : {
195 : 0 : QList<QgsRasterTransparency::TransparentThreeValuePixel> transparentThreeValueList;
196 : 0 : tr->setTransparentThreeValuePixelList( transparentThreeValueList );
197 : 0 : }
198 : 0 : renderer->setRasterTransparency( tr );
199 : 0 : return renderer;
200 : 0 : }
201 : :
202 : 0 : bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProvider *provider, double &minValue, double &maxValue ) const
203 : : {
204 : 0 : if ( !provider )
205 : : {
206 : 0 : return false;
207 : : }
208 : :
209 : 0 : minValue = 0;
210 : 0 : maxValue = 0;
211 : :
212 : 0 : QgsSettings s;
213 : 0 : if ( s.value( QStringLiteral( "/Raster/useStandardDeviation" ), false ).toBool() )
214 : : {
215 : 0 : QgsRasterBandStats stats = provider->bandStatistics( band, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev );
216 : :
217 : 0 : double stdDevFactor = s.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble();
218 : 0 : double diff = stdDevFactor * stats.stdDev;
219 : 0 : minValue = stats.mean - diff;
220 : 0 : maxValue = stats.mean + diff;
221 : 0 : }
222 : : else
223 : : {
224 : 0 : QgsRasterBandStats stats = provider->bandStatistics( band, QgsRasterBandStats::Min | QgsRasterBandStats::Max );
225 : 0 : minValue = stats.minimumValue;
226 : 0 : maxValue = stats.maximumValue;
227 : : }
228 : 0 : return true;
229 : 0 : }
|