Skip to content
Permalink
Browse files
add support for color ramps to raster layers
  • Loading branch information
etiennesky committed Aug 2, 2012
1 parent 8c969e2 commit 5c068e4
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 7 deletions.
@@ -18,6 +18,11 @@
#include "qgssinglebandpseudocolorrendererwidget.h"
#include "qgssinglebandpseudocolorrenderer.h"
#include "qgsrasterlayer.h"

// for color ramps - todo add rasterStyle and refactor raster vs. vector ramps
#include "qgsstylev2.h"
#include "qgsvectorcolorrampv2.h"

#include <QColorDialog>
#include <QFileDialog>
#include <QMessageBox>
@@ -29,6 +34,8 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
{
setupUi( this );

mColorRampComboBox->populate( QgsStyleV2::defaultStyle() );

if ( !mRasterLayer )
{
return;
@@ -213,19 +220,45 @@ void QgsSingleBandPseudoColorRendererWidget::on_mClassifyButton_clicked()
}
}

#if 0
//hard code color range from blue -> red for now. Allow choice of ramps in future
int colorDiff = 0;
if ( numberOfEntries != 0 )
{
colorDiff = ( int )( 255 / numberOfEntries );
}

for ( int i = 0; i < numberOfEntries; ++i )
{
QColor currentColor;
currentColor.setRgb( colorDiff*i, 0, 255 - colorDiff * i );
entryColors.push_back( currentColor );
}
#endif

QgsVectorColorRampV2* colorRamp = mColorRampComboBox->currentColorRamp();
if ( ! colorRamp )
{
//hard code color range from blue -> red (previous default)
int colorDiff = 0;
if ( numberOfEntries != 0 )
{
colorDiff = ( int )( 255 / numberOfEntries );
}

for ( int i = 0; i < numberOfEntries; ++i )
{
QColor currentColor;
currentColor.setRgb( colorDiff*i, 0, 255 - colorDiff * i );
entryColors.push_back( currentColor );
}
}
else
{
for ( int i = 0; i < numberOfEntries; ++i )
{
entryColors.push_back( colorRamp->color( ( ( double ) i ) / numberOfEntries ) );
}
}

mColormapTreeWidget->clear();

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>505</width>
<width>584</width>
<height>400</height>
</rect>
</property>
@@ -146,7 +146,7 @@
<item row="0" column="0">
<widget class="QLabel" name="mNumberOfEntriesLabel">
<property name="text">
<string>Number of entries</string>
<string>Classes</string>
</property>
</widget>
</item>
@@ -163,28 +163,84 @@
</property>
</widget>
</item>
<item row="0" column="2">
<item row="0" column="3">
<widget class="QLabel" name="mClassificationModeLabel">
<property name="text">
<string>Classification mode</string>
<string>Mode</string>
</property>
</widget>
</item>
<item row="0" column="3">
<item row="0" column="4">
<widget class="QComboBox" name="mClassificationModeComboBox"/>
</item>
<item row="0" column="4">
<item row="0" column="9">
<widget class="QPushButton" name="mClassifyButton">
<property name="text">
<string>Classify</string>
</property>
</widget>
</item>
<item row="0" column="5">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="6">
<widget class="QLabel" name="label">
<property name="text">
<string>Color ramp</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="7">
<widget class="QgsColorRampComboBox" name="mColorRampComboBox"/>
</item>
<item row="0" column="8">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsColorRampComboBox</class>
<extends>QComboBox</extends>
<header>qgscolorrampcombobox.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../images/images.qrc"/>
</resources>
@@ -35,6 +35,7 @@
#include <qgsmaprenderer.h>
#include <qgsmaplayerregistry.h>
#include "qgssinglebandpseudocolorrenderer.h"
#include "qgsvectorcolorrampv2.h"

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

void isValid();
void pseudoColor();
void colorRamp1();
void colorRamp2();
void landsatBasic();
void landsatBasic875Qml();
void checkDimensions();
@@ -63,6 +66,11 @@ class TestQgsRasterLayer: public QObject
private:
bool render( QString theFileName );
bool setQml( QString theType );
void populateColorRampShader( QgsColorRampShader* colorRampShader,
QgsVectorColorRampV2* colorRamp,
int numberOfEntries );
bool testColorRamp( QString name, QgsVectorColorRampV2* colorRamp,
QgsColorRampShader::ColorRamp_TYPE type, int numberOfEntries );
QString mTestDataDir;
QgsRasterLayer * mpRasterLayer;
QgsRasterLayer * mpLandsatRasterLayer;
@@ -162,6 +170,87 @@ void TestQgsRasterLayer::pseudoColor()
QVERIFY( render( "raster_pseudo" ) );
}

void TestQgsRasterLayer::populateColorRampShader( QgsColorRampShader* colorRampShader,
QgsVectorColorRampV2* colorRamp,
int numberOfEntries )

{
// adapted from QgsSingleBandPseudoColorRendererWidget::on_mClassifyButton_clicked()
// and TestQgsRasterLayer::pseudoColor()
// would be better to add a more generic function to api that does this
int bandNr = 1;
QgsRasterBandStats myRasterBandStats = mpRasterLayer->dataProvider()->bandStatistics( bandNr );

QList<double> entryValues;
QList<QColor> entryColors;
double currentValue = myRasterBandStats.minimumValue;
double intervalDiff;
if ( numberOfEntries > 1 )
{
//because the highest value is also an entry, there are (numberOfEntries - 1)
//intervals
intervalDiff = ( myRasterBandStats.maximumValue - myRasterBandStats.minimumValue ) /
( numberOfEntries - 1 );
}
else
{
intervalDiff = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
}

for ( int i = 0; i < numberOfEntries; ++i )
{
entryValues.push_back( currentValue );
currentValue += intervalDiff;
entryColors.push_back( colorRamp->color((( double ) i ) / numberOfEntries ) );
}

//items to imitate old pseudo color renderer
QList<QgsColorRampShader::ColorRampItem> colorRampItems;
QList<double>::const_iterator value_it = entryValues.begin();
QList<QColor>::const_iterator color_it = entryColors.begin();
for ( ; value_it != entryValues.end(); ++value_it, ++color_it )
{
colorRampItems.append( QgsColorRampShader::ColorRampItem( *value_it, *color_it ) );
}
colorRampShader->setColorRampItemList( colorRampItems );
}

bool TestQgsRasterLayer::testColorRamp( QString name, QgsVectorColorRampV2* colorRamp,
QgsColorRampShader::ColorRamp_TYPE type, int numberOfEntries )
{
QgsRasterShader* rasterShader = new QgsRasterShader();
QgsColorRampShader* colorRampShader = new QgsColorRampShader();
colorRampShader->setColorRampType( type );

populateColorRampShader( colorRampShader, colorRamp, numberOfEntries );

rasterShader->setRasterShaderFunction( colorRampShader );
QgsSingleBandPseudoColorRenderer* r = new QgsSingleBandPseudoColorRenderer( mpRasterLayer->dataProvider(), 1, rasterShader );
mpRasterLayer->setRenderer( r );
mpMapRenderer->setExtent( mpRasterLayer->extent() );
return render( name );
}

void TestQgsRasterLayer::colorRamp1()
{
// gradient ramp
QgsVectorGradientColorRampV2* colorRamp = new QgsVectorGradientColorRampV2( QColor( Qt::red ), QColor( Qt::black ) );
QgsVectorGradientColorRampV2::StopsMap stops;
stops[ 0.5 ] = QColor( Qt::white );
colorRamp->setStops( stops );

// QVERIFY( testColorRamp( "raster_colorRamp1", colorRamp, QgsColorRampShader::INTERPOLATED, 5 ) );
QVERIFY( testColorRamp( "raster_colorRamp1", colorRamp, QgsColorRampShader::DISCRETE, 10 ) );
}

void TestQgsRasterLayer::colorRamp2()
{
// ColorBrewer ramp
QgsVectorColorBrewerColorRampV2* cb2Ramp = new QgsVectorColorBrewerColorRampV2( "BrBG", 10 );

QVERIFY( testColorRamp( "raster_colorRamp2", cb2Ramp, QgsColorRampShader::DISCRETE, 10 ) );
}

void TestQgsRasterLayer::landsatBasic()
{
mpLandsatRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, false );
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5c068e4

Please sign in to comment.