Skip to content

Commit 5c068e4

Browse files
committedAug 2, 2012
add support for color ramps to raster layers
1 parent 8c969e2 commit 5c068e4

File tree

5 files changed

+185
-7
lines changed

5 files changed

+185
-7
lines changed
 

‎src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
#include "qgssinglebandpseudocolorrendererwidget.h"
1919
#include "qgssinglebandpseudocolorrenderer.h"
2020
#include "qgsrasterlayer.h"
21+
22+
// for color ramps - todo add rasterStyle and refactor raster vs. vector ramps
23+
#include "qgsstylev2.h"
24+
#include "qgsvectorcolorrampv2.h"
25+
2126
#include <QColorDialog>
2227
#include <QFileDialog>
2328
#include <QMessageBox>
@@ -29,6 +34,8 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
2934
{
3035
setupUi( this );
3136

37+
mColorRampComboBox->populate( QgsStyleV2::defaultStyle() );
38+
3239
if ( !mRasterLayer )
3340
{
3441
return;
@@ -213,19 +220,45 @@ void QgsSingleBandPseudoColorRendererWidget::on_mClassifyButton_clicked()
213220
}
214221
}
215222

223+
#if 0
216224
//hard code color range from blue -> red for now. Allow choice of ramps in future
217225
int colorDiff = 0;
218226
if ( numberOfEntries != 0 )
219227
{
220228
colorDiff = ( int )( 255 / numberOfEntries );
221229
}
222-
223230
for ( int i = 0; i < numberOfEntries; ++i )
224231
{
225232
QColor currentColor;
226233
currentColor.setRgb( colorDiff*i, 0, 255 - colorDiff * i );
227234
entryColors.push_back( currentColor );
228235
}
236+
#endif
237+
238+
QgsVectorColorRampV2* colorRamp = mColorRampComboBox->currentColorRamp();
239+
if ( ! colorRamp )
240+
{
241+
//hard code color range from blue -> red (previous default)
242+
int colorDiff = 0;
243+
if ( numberOfEntries != 0 )
244+
{
245+
colorDiff = ( int )( 255 / numberOfEntries );
246+
}
247+
248+
for ( int i = 0; i < numberOfEntries; ++i )
249+
{
250+
QColor currentColor;
251+
currentColor.setRgb( colorDiff*i, 0, 255 - colorDiff * i );
252+
entryColors.push_back( currentColor );
253+
}
254+
}
255+
else
256+
{
257+
for ( int i = 0; i < numberOfEntries; ++i )
258+
{
259+
entryColors.push_back( colorRamp->color( ( ( double ) i ) / numberOfEntries ) );
260+
}
261+
}
229262

230263
mColormapTreeWidget->clear();
231264

‎src/ui/qgssinglebandpseudocolorrendererwidgetbase.ui

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>505</width>
9+
<width>584</width>
1010
<height>400</height>
1111
</rect>
1212
</property>
@@ -146,7 +146,7 @@
146146
<item row="0" column="0">
147147
<widget class="QLabel" name="mNumberOfEntriesLabel">
148148
<property name="text">
149-
<string>Number of entries</string>
149+
<string>Classes</string>
150150
</property>
151151
</widget>
152152
</item>
@@ -163,28 +163,84 @@
163163
</property>
164164
</widget>
165165
</item>
166-
<item row="0" column="2">
166+
<item row="0" column="3">
167167
<widget class="QLabel" name="mClassificationModeLabel">
168168
<property name="text">
169-
<string>Classification mode</string>
169+
<string>Mode</string>
170170
</property>
171171
</widget>
172172
</item>
173-
<item row="0" column="3">
173+
<item row="0" column="4">
174174
<widget class="QComboBox" name="mClassificationModeComboBox"/>
175175
</item>
176-
<item row="0" column="4">
176+
<item row="0" column="9">
177177
<widget class="QPushButton" name="mClassifyButton">
178178
<property name="text">
179179
<string>Classify</string>
180180
</property>
181181
</widget>
182182
</item>
183+
<item row="0" column="5">
184+
<spacer name="horizontalSpacer_3">
185+
<property name="orientation">
186+
<enum>Qt::Horizontal</enum>
187+
</property>
188+
<property name="sizeHint" stdset="0">
189+
<size>
190+
<width>40</width>
191+
<height>20</height>
192+
</size>
193+
</property>
194+
</spacer>
195+
</item>
196+
<item row="0" column="6">
197+
<widget class="QLabel" name="label">
198+
<property name="text">
199+
<string>Color ramp</string>
200+
</property>
201+
</widget>
202+
</item>
203+
<item row="0" column="2">
204+
<spacer name="horizontalSpacer_2">
205+
<property name="orientation">
206+
<enum>Qt::Horizontal</enum>
207+
</property>
208+
<property name="sizeHint" stdset="0">
209+
<size>
210+
<width>40</width>
211+
<height>20</height>
212+
</size>
213+
</property>
214+
</spacer>
215+
</item>
216+
<item row="0" column="7">
217+
<widget class="QgsColorRampComboBox" name="mColorRampComboBox"/>
218+
</item>
219+
<item row="0" column="8">
220+
<spacer name="horizontalSpacer_4">
221+
<property name="orientation">
222+
<enum>Qt::Horizontal</enum>
223+
</property>
224+
<property name="sizeHint" stdset="0">
225+
<size>
226+
<width>40</width>
227+
<height>20</height>
228+
</size>
229+
</property>
230+
</spacer>
231+
</item>
183232
</layout>
184233
</widget>
185234
</item>
186235
</layout>
187236
</widget>
237+
<customwidgets>
238+
<customwidget>
239+
<class>QgsColorRampComboBox</class>
240+
<extends>QComboBox</extends>
241+
<header>qgscolorrampcombobox.h</header>
242+
</customwidget>
243+
</customwidgets>
188244
<resources>
189245
<include location="../../images/images.qrc"/>
190246
</resources>

‎tests/src/core/testqgsrasterlayer.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <qgsmaprenderer.h>
3636
#include <qgsmaplayerregistry.h>
3737
#include "qgssinglebandpseudocolorrenderer.h"
38+
#include "qgsvectorcolorrampv2.h"
3839

3940
//qgis unit test includes
4041
#include <qgsrenderchecker.h>
@@ -54,6 +55,8 @@ class TestQgsRasterLayer: public QObject
5455

5556
void isValid();
5657
void pseudoColor();
58+
void colorRamp1();
59+
void colorRamp2();
5760
void landsatBasic();
5861
void landsatBasic875Qml();
5962
void checkDimensions();
@@ -63,6 +66,11 @@ class TestQgsRasterLayer: public QObject
6366
private:
6467
bool render( QString theFileName );
6568
bool setQml( QString theType );
69+
void populateColorRampShader( QgsColorRampShader* colorRampShader,
70+
QgsVectorColorRampV2* colorRamp,
71+
int numberOfEntries );
72+
bool testColorRamp( QString name, QgsVectorColorRampV2* colorRamp,
73+
QgsColorRampShader::ColorRamp_TYPE type, int numberOfEntries );
6674
QString mTestDataDir;
6775
QgsRasterLayer * mpRasterLayer;
6876
QgsRasterLayer * mpLandsatRasterLayer;
@@ -162,6 +170,87 @@ void TestQgsRasterLayer::pseudoColor()
162170
QVERIFY( render( "raster_pseudo" ) );
163171
}
164172

173+
void TestQgsRasterLayer::populateColorRampShader( QgsColorRampShader* colorRampShader,
174+
QgsVectorColorRampV2* colorRamp,
175+
int numberOfEntries )
176+
177+
{
178+
// adapted from QgsSingleBandPseudoColorRendererWidget::on_mClassifyButton_clicked()
179+
// and TestQgsRasterLayer::pseudoColor()
180+
// would be better to add a more generic function to api that does this
181+
int bandNr = 1;
182+
QgsRasterBandStats myRasterBandStats = mpRasterLayer->dataProvider()->bandStatistics( bandNr );
183+
184+
QList<double> entryValues;
185+
QList<QColor> entryColors;
186+
double currentValue = myRasterBandStats.minimumValue;
187+
double intervalDiff;
188+
if ( numberOfEntries > 1 )
189+
{
190+
//because the highest value is also an entry, there are (numberOfEntries - 1)
191+
//intervals
192+
intervalDiff = ( myRasterBandStats.maximumValue - myRasterBandStats.minimumValue ) /
193+
( numberOfEntries - 1 );
194+
}
195+
else
196+
{
197+
intervalDiff = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
198+
}
199+
200+
for ( int i = 0; i < numberOfEntries; ++i )
201+
{
202+
entryValues.push_back( currentValue );
203+
currentValue += intervalDiff;
204+
entryColors.push_back( colorRamp->color((( double ) i ) / numberOfEntries ) );
205+
}
206+
207+
//items to imitate old pseudo color renderer
208+
QList<QgsColorRampShader::ColorRampItem> colorRampItems;
209+
QList<double>::const_iterator value_it = entryValues.begin();
210+
QList<QColor>::const_iterator color_it = entryColors.begin();
211+
for ( ; value_it != entryValues.end(); ++value_it, ++color_it )
212+
{
213+
colorRampItems.append( QgsColorRampShader::ColorRampItem( *value_it, *color_it ) );
214+
}
215+
colorRampShader->setColorRampItemList( colorRampItems );
216+
}
217+
218+
bool TestQgsRasterLayer::testColorRamp( QString name, QgsVectorColorRampV2* colorRamp,
219+
QgsColorRampShader::ColorRamp_TYPE type, int numberOfEntries )
220+
{
221+
QgsRasterShader* rasterShader = new QgsRasterShader();
222+
QgsColorRampShader* colorRampShader = new QgsColorRampShader();
223+
colorRampShader->setColorRampType( type );
224+
225+
populateColorRampShader( colorRampShader, colorRamp, numberOfEntries );
226+
227+
rasterShader->setRasterShaderFunction( colorRampShader );
228+
QgsSingleBandPseudoColorRenderer* r = new QgsSingleBandPseudoColorRenderer( mpRasterLayer->dataProvider(), 1, rasterShader );
229+
mpRasterLayer->setRenderer( r );
230+
mpMapRenderer->setExtent( mpRasterLayer->extent() );
231+
return render( name );
232+
}
233+
234+
void TestQgsRasterLayer::colorRamp1()
235+
{
236+
// gradient ramp
237+
QgsVectorGradientColorRampV2* colorRamp = new QgsVectorGradientColorRampV2( QColor( Qt::red ), QColor( Qt::black ) );
238+
QgsVectorGradientColorRampV2::StopsMap stops;
239+
stops[ 0.5 ] = QColor( Qt::white );
240+
colorRamp->setStops( stops );
241+
242+
// QVERIFY( testColorRamp( "raster_colorRamp1", colorRamp, QgsColorRampShader::INTERPOLATED, 5 ) );
243+
QVERIFY( testColorRamp( "raster_colorRamp1", colorRamp, QgsColorRampShader::DISCRETE, 10 ) );
244+
}
245+
246+
void TestQgsRasterLayer::colorRamp2()
247+
{
248+
// ColorBrewer ramp
249+
QgsVectorColorBrewerColorRampV2* cb2Ramp = new QgsVectorColorBrewerColorRampV2( "BrBG", 10 );
250+
251+
QVERIFY( testColorRamp( "raster_colorRamp2", cb2Ramp, QgsColorRampShader::DISCRETE, 10 ) );
252+
}
253+
165254
void TestQgsRasterLayer::landsatBasic()
166255
{
167256
mpLandsatRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, false );
Loading
Loading

0 commit comments

Comments
 (0)
Please sign in to comment.