Skip to content

Commit f8f034c

Browse files
committedAug 3, 2012
Merge branch 'coloramp' of ../qgis-etiennesky
2 parents de5f95b + e39c216 commit f8f034c

20 files changed

+2245
-22
lines changed
 

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ SET(QGIS_CORE_HDRS
410410
symbology/qgssymbologyutils.h
411411

412412
symbology-ng/qgscategorizedsymbolrendererv2.h
413-
symbology-ng/qgscolorbrewerpalette.h
413+
symbology-ng/qgscolorrampv2data.h
414414
symbology-ng/qgsellipsesymbollayerv2.h
415415
symbology-ng/qgsfillsymbollayerv2.h
416416
symbology-ng/qgsgraduatedsymbolrendererv2.h

‎src/core/symbology-ng/qgscolorbrewerpalette.h renamed to ‎src/core/symbology-ng/qgscolorrampv2data.h

Lines changed: 438 additions & 9 deletions
Large diffs are not rendered by default.

‎src/core/symbology-ng/qgssymbollayerv2utils.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,6 +2299,8 @@ QgsVectorColorRampV2* QgsSymbolLayerV2Utils::loadColorRamp( QDomElement& element
22992299
return QgsVectorRandomColorRampV2::create( props );
23002300
else if ( rampType == "colorbrewer" )
23012301
return QgsVectorColorBrewerColorRampV2::create( props );
2302+
else if ( rampType == "cpt-city" )
2303+
return QgsCptCityColorRampV2::create( props );
23022304
else
23032305
{
23042306
QgsDebugMsg( "unknown colorramp type " + rampType );
@@ -2317,6 +2319,20 @@ QDomElement QgsSymbolLayerV2Utils::saveColorRamp( QString name, QgsVectorColorRa
23172319
return rampEl;
23182320
}
23192321

2322+
// parse color definition with format "rgb(0,0,0)" or "0,0,0"
2323+
// should support other formats like FFFFFF
2324+
QColor QgsSymbolLayerV2Utils::parseColor( QString colorStr )
2325+
{
2326+
if ( colorStr.startsWith( "rgb(" ) )
2327+
{
2328+
colorStr = colorStr.mid( 4, colorStr.size() - 5 ).trimmed();
2329+
}
2330+
QStringList p = colorStr.split( QChar( ',' ) );
2331+
if ( p.count() != 3 )
2332+
return QColor();
2333+
return QColor( p[0].toInt(), p[1].toInt(), p[2].toInt() );
2334+
}
2335+
23202336
double QgsSymbolLayerV2Utils::lineWidthScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u )
23212337
{
23222338

‎src/core/symbology-ng/qgssymbollayerv2utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
193193
static QgsVectorColorRampV2* loadColorRamp( QDomElement& element );
194194
static QDomElement saveColorRamp( QString name, QgsVectorColorRampV2* ramp, QDomDocument& doc );
195195

196+
/** parse color definition with format "rgb(0,0,0)" or "0,0,0" */
197+
static QColor parseColor( QString colorStr );
198+
196199
/**Returns the line width scale factor depending on the unit and the paint device*/
197200
static double lineWidthScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
198201
/**Returns scale factor painter units -> pixel dimensions*/

‎src/core/symbology-ng/qgsvectorcolorrampv2.cpp

Lines changed: 536 additions & 2 deletions
Large diffs are not rendered by default.

‎src/core/symbology-ng/qgsvectorcolorrampv2.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,86 @@ class CORE_EXPORT QgsVectorColorBrewerColorRampV2 : public QgsVectorColorRampV2
158158
QList<QColor> mPalette;
159159
};
160160

161+
162+
#define DEFAULT_CPTCITY_SCHEMENAME "cb/div/BrBG_" //change this
163+
#define DEFAULT_CPTCITY_VARIANTNAME "05"
164+
165+
class CORE_EXPORT QgsCptCityColorRampV2 : public QgsVectorColorRampV2
166+
{
167+
public:
168+
QgsCptCityColorRampV2( QString schemeName = DEFAULT_CPTCITY_SCHEMENAME,
169+
QString variantName = DEFAULT_CPTCITY_VARIANTNAME );
170+
171+
static QgsVectorColorRampV2* create( const QgsStringMap& properties = QgsStringMap() );
172+
173+
virtual QColor color( double value ) const;
174+
175+
virtual QString type() const { return "cpt-city"; }
176+
177+
virtual QgsVectorColorRampV2* clone() const;
178+
179+
virtual QgsStringMap properties() const;
180+
181+
int count() const { return mPalette.count(); }
182+
183+
QString schemeName() const { return mSchemeName; }
184+
QString variantName() const { return mVariantName; }
185+
186+
/* void setSchemeName( QString schemeName ) { mSchemeName = schemeName; loadPalette(); } */
187+
/* void setVariantName( QString variantName ) { mVariantName = variantName; loadPalette(); } */
188+
/* lazy loading - have to call loadPalette() explicitly */
189+
void setSchemeName( QString schemeName ) { mSchemeName = schemeName; }
190+
void setVariantName( QString variantName ) { mVariantName = variantName; }
191+
void setName( QString schemeName, QString variantName = "" )
192+
{ mSchemeName = schemeName; mVariantName = variantName; loadPalette(); }
193+
194+
void loadPalette();
195+
bool isContinuous() const { return mContinuous; }
196+
197+
QString getFilename() const;
198+
bool loadFile( QString filename = "" );
199+
200+
/* static QList<QColor> listSchemeColors( QString schemeName, int colors ); */
201+
static QList<int> listSchemeVariants( QString schemeName );
202+
203+
static QString getBaseDir();
204+
static void setBaseDir( QString dirName ) { mBaseDir = dirName; }
205+
static bool loadSchemes( QString rootDir = "", bool reset = false );
206+
/** Is the minimal (free to distribute) set of schemes available? Currently returns hasAllSchemes, because we don't have a minimal set yet. */
207+
static bool hasBasicSchemes();
208+
/** Is the entire archive available? Currently tests that there is at least one scheme. */
209+
static bool hasAllSchemes();
210+
static QStringList listSchemeCollections( QString collectionName = "", bool recursive = false );
211+
static QStringList listSchemeNames( QString collectionName );
212+
static QgsCptCityColorRampV2* colorRampFromSVGFile( QString svgFile );
213+
static QgsCptCityColorRampV2* colorRampFromSVGString( QString svgString );
214+
215+
static const QMap< QString, QStringList > schemeMap() { return mSchemeMap; }
216+
/* static const QMap< QString, int > schemeNumColors() { return mSchemeNumColors; } */
217+
static const QMap< QString, QStringList > schemeVariants() { return mSchemeVariants; }
218+
static const QMap< QString, QString > collectionNames() { return mCollectionNames; }
219+
static const QMap< QString, QStringList > collectionSelections() { return mCollectionSelections; }
220+
221+
protected:
222+
223+
typedef QMap<double, QColor> StopsMap;
224+
225+
QString mSchemeName;
226+
QString mVariantName;
227+
bool mContinuous;
228+
QList< QColor > mPalette;
229+
QList< double > mPaletteStops;
230+
/* QMap< double, QColor > mPalette; */
231+
232+
static QString mBaseDir;
233+
static QStringList mCollections;
234+
static QMap< QString, QStringList > mSchemeMap; //key is collection, value is schemes
235+
/* mSchemeNumColors removed, instead read on demand */
236+
/* static QMap< QString, int > mSchemeNumColors; //key is scheme, value is # colors (if no variants) */
237+
static QMap< QString, QStringList > mSchemeVariants; //key is scheme, value is variants
238+
static QMap< QString, QString > mCollectionNames; //key is name, value is description
239+
static QMap< QString, QStringList > mCollectionSelections;
240+
241+
};
242+
161243
#endif

‎src/gui/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ symbology-ng/qgssymbolv2selectordialog.cpp
2727
symbology-ng/qgsvectorgradientcolorrampv2dialog.cpp
2828
symbology-ng/qgsvectorrandomcolorrampv2dialog.cpp
2929
symbology-ng/qgsvectorcolorbrewercolorrampv2dialog.cpp
30+
symbology-ng/qgscptcitycolorrampv2dialog.cpp
3031
symbology-ng/characterwidget.cpp
3132
symbology-ng/qgsstylev2exportimportdialog.cpp
3233
symbology-ng/qgsellipsesymbollayerv2widget.cpp
@@ -123,6 +124,7 @@ symbology-ng/qgssymbolv2selectordialog.h
123124
symbology-ng/qgsvectorgradientcolorrampv2dialog.h
124125
symbology-ng/qgsvectorrandomcolorrampv2dialog.h
125126
symbology-ng/qgsvectorcolorbrewercolorrampv2dialog.h
127+
symbology-ng/qgscptcitycolorrampv2dialog.h
126128
symbology-ng/qgscolorrampcombobox.h
127129
symbology-ng/characterwidget.h
128130
symbology-ng/qgspenstylecombobox.h

‎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

Lines changed: 385 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,385 @@
1+
/***************************************************************************
2+
qgscptcitycolorrampv2dialog.cpp
3+
---------------------
4+
begin : July 2012
5+
copyright : (C) 2012 by Etienne Tourigny
6+
email : etourigny dot dev at gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgscptcitycolorrampv2dialog.h"
17+
18+
#include "qgsvectorcolorrampv2.h"
19+
#include "qgslogger.h"
20+
#include "qgsapplication.h"
21+
22+
#include <QPushButton>
23+
#include <QTextEdit>
24+
25+
#if 0 // unused
26+
static void updateColorButton( QAbstractButton* button, QColor color )
27+
{
28+
QPixmap p( 20, 20 );
29+
p.fill( color );
30+
button->setIcon( QIcon( p ) );
31+
}
32+
#endif
33+
34+
/////////
35+
36+
QgsCptCityColorRampV2Dialog::QgsCptCityColorRampV2Dialog( QgsCptCityColorRampV2* ramp, QWidget* parent )
37+
: QDialog( parent ), mRamp( ramp )
38+
{
39+
40+
setupUi( this );
41+
42+
QgsCptCityColorRampV2::loadSchemes( "" );
43+
// QgsCptCityColorRampV2::loadSchemes( "cb" );
44+
45+
// show information on how to install cpt-city files if none are found
46+
if ( ! QgsCptCityColorRampV2::hasAllSchemes() )
47+
{
48+
QTextEdit *edit = new QTextEdit();
49+
edit->setReadOnly( true );
50+
// not sure if we want this long string to be translated
51+
QString helpText = tr( "Error - cpt-city gradient files not found.\n\n"
52+
"Please download the complete collection (in svg format) "
53+
"and unzip it to your QGis settings directory [%1] .\n\n"
54+
"This file can be found at [%2]\nand current file is [%3]"
55+
).arg( QgsApplication::qgisSettingsDirPath()
56+
).arg( "http://soliton.vm.bytemark.co.uk/pub/cpt-city/pkg/"
57+
).arg( "http://soliton.vm.bytemark.co.uk/pub/cpt-city/pkg/cpt-city-svg-2.02.zip" );
58+
edit->setText( helpText );
59+
stackedWidget->addWidget( edit );
60+
stackedWidget->setCurrentIndex( 1 );
61+
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
62+
return;
63+
}
64+
65+
populateSchemes( "author" );
66+
treeWidget->setCurrentItem( findPath( ramp->schemeName() ) );
67+
populateVariants();
68+
cboVariantName->setCurrentIndex( cboVariantName->findData( ramp->variantName(), Qt::UserRole ) );
69+
connect( cboVariantName, SIGNAL( currentIndexChanged( int ) ), this, SLOT( setVariantName() ) );
70+
updatePreview();
71+
}
72+
73+
// inspired from QgsBrowserModel::findPath( QString path )
74+
// but using a QTreeWidget instead of QgsBrowserModel
75+
// would be simpler if we used the model/view framework
76+
QTreeWidgetItem* QgsCptCityColorRampV2Dialog::findPath( QString path )
77+
{
78+
QTreeWidgetItem *item = 0, *childItem = 0;
79+
QString itemPath, childPath;
80+
81+
for ( int i = 0; i < treeWidget->topLevelItemCount(); i++ )
82+
{
83+
item = treeWidget->topLevelItem( i );
84+
if ( !item )
85+
return 0; // an error occurred
86+
itemPath = item->data( 0, Qt::UserRole ).toString();
87+
88+
if ( itemPath == path )
89+
{
90+
QgsDebugMsg( "Arrived " + itemPath );
91+
return item; // we have found the item we have been looking for
92+
}
93+
94+
if ( itemPath.endsWith( "/" ) && path.startsWith( itemPath ) )
95+
{
96+
// we have found a preceding item: stop searching on this level and go deeper
97+
bool foundChild = true;
98+
99+
while ( foundChild )
100+
{
101+
foundChild = false; // assume that the next child item will not be found
102+
103+
for ( int j = 0; j < item->childCount(); j++ )
104+
{
105+
childItem = item->child( j );
106+
if ( !childItem )
107+
return 0; // an error occurred
108+
childPath = childItem->data( 0, Qt::UserRole ).toString();
109+
110+
if ( childPath == path )
111+
{
112+
return childItem; // we have found the item we have been looking for
113+
}
114+
115+
if ( childPath.endsWith( "/" ) && path.startsWith( childPath ) )
116+
{
117+
// we have found a preceding item: stop searching on this level and go deeper
118+
foundChild = true;
119+
item = childItem;
120+
break;
121+
}
122+
}
123+
}
124+
break;
125+
}
126+
}
127+
return 0; // not found
128+
}
129+
130+
void QgsCptCityColorRampV2Dialog::populateSchemes( QString view )
131+
{
132+
QStringList collections;
133+
QTreeWidgetItem *item, *childItem;
134+
if ( view == "author" )
135+
{
136+
treeWidget->blockSignals( true );
137+
treeWidget->clear();
138+
foreach( QString collectionName, QgsCptCityColorRampV2::listSchemeCollections() )
139+
{
140+
item = makeCollectionItem( collectionName );
141+
treeWidget->addTopLevelItem( item );
142+
}
143+
treeWidget->blockSignals( false );
144+
}
145+
else if ( view == "selections" )
146+
{
147+
treeWidget->blockSignals( true );
148+
treeWidget->clear();
149+
150+
QMapIterator< QString, QStringList> it( QgsCptCityColorRampV2::collectionSelections() );
151+
while ( it.hasNext() )
152+
{
153+
it.next();
154+
QString path = it.key();
155+
QString descStr = QgsCptCityColorRampV2::collectionNames().value( path );
156+
157+
// TODO shorten child names and fix / at beginning of name
158+
// TODO when collection has only 1 item (e.g. es_skywalker), bring up one level
159+
item = new QTreeWidgetItem( QStringList() << path << descStr << QString() );
160+
QFont font;
161+
font.setBold( true );
162+
item->setData( 0, Qt::FontRole, QVariant( font ) );
163+
item->setData( 1, Qt::FontRole, QVariant( font ) );
164+
165+
// add children schemes and collections
166+
foreach( QString childPath, it.value() )
167+
{
168+
if ( childPath.endsWith( "/" ) )
169+
{
170+
childPath.chop( 1 );
171+
childItem = makeCollectionItem( childPath );
172+
childItem->setText( 0, childPath ); //make sure full path is visible
173+
item->addChild( childItem );
174+
}
175+
else
176+
{
177+
makeSchemeItem( item, "", childPath );
178+
}
179+
}
180+
treeWidget->addTopLevelItem( item );
181+
}
182+
treeWidget->blockSignals( false );
183+
}
184+
else
185+
{
186+
QgsDebugMsg( "invalid view " + view );
187+
return;
188+
}
189+
190+
treeWidget->setColumnWidth( 0, 250 );
191+
}
192+
193+
void QgsCptCityColorRampV2Dialog::populateVariants()
194+
{
195+
if ( ! treeWidget->currentItem() )
196+
return;
197+
198+
cboVariantName->blockSignals( true );
199+
200+
QString oldVariant = cboVariantName->currentText();
201+
cboVariantName->clear();
202+
203+
foreach( QString variant, treeWidget->currentItem()->data( 1, Qt::UserRole ).toString().split( " ", QString::SkipEmptyParts ) )
204+
{
205+
QString variantStr = variant;
206+
if ( variantStr.startsWith( "-" ) || variantStr.startsWith( "_" ) )
207+
variantStr.remove( 0, 1 );
208+
cboVariantName->addItem( variantStr );
209+
cboVariantName->setItemData( cboVariantName->count() - 1, variant, Qt::UserRole );
210+
}
211+
212+
cboVariantName->blockSignals( false );
213+
214+
if ( cboVariantName->count() > 0 )
215+
{
216+
cboVariantName->setEnabled( true );
217+
// try to set the original variant again (if exists)
218+
// TODO - is this really necessary?
219+
int idx = cboVariantName->findText( oldVariant );
220+
if ( idx == -1 ) // not found?
221+
{
222+
// use the item in the middle
223+
idx = cboVariantName->count() / 2;
224+
}
225+
cboVariantName->setCurrentIndex( idx );
226+
}
227+
else
228+
{
229+
cboVariantName->setEnabled( false );
230+
setVariantName();
231+
}
232+
233+
}
234+
235+
void QgsCptCityColorRampV2Dialog::on_treeWidget_currentItemChanged( QTreeWidgetItem * current, QTreeWidgetItem * previous )
236+
{
237+
Q_UNUSED( previous );
238+
// directories have name data that ends with /
239+
if ( ! current->data( 0, Qt::UserRole ).toString().endsWith( "/" ) )
240+
{
241+
lblSchemeName->setText( current->data( 0, Qt::UserRole ).toString() );
242+
setSchemeName();
243+
// populateVariants();
244+
}
245+
}
246+
247+
void QgsCptCityColorRampV2Dialog::on_treeWidget_itemExpanded( QTreeWidgetItem * item )
248+
{
249+
// set color count when item is expanded
250+
QgsCptCityColorRampV2 ramp( "", "" );
251+
QTreeWidgetItem* childItem = 0;
252+
QString itemPath, itemDesc;
253+
254+
for ( int i = 0; i < item->childCount(); i++ )
255+
{
256+
childItem = item->child( i );
257+
258+
// items with null description need information, those with "" (i.e. unnamed collections) not be checked
259+
// TODO set type when there are variants - based on the first file
260+
if ( childItem && childItem->text( 1 ).isNull() )
261+
{
262+
itemPath = childItem->data( 0, Qt::UserRole ).toString();
263+
itemDesc = "";
264+
ramp.setSchemeName( itemPath );
265+
if ( ramp.loadFile() )
266+
{
267+
itemDesc = QString::number( ramp.count() ) + " " + tr( "colors" ) + " - ";
268+
if ( ramp.isContinuous() )
269+
itemDesc += tr( "continuous" );
270+
else
271+
itemDesc += tr( "discrete" );
272+
}
273+
childItem->setText( 1, " " + itemDesc );
274+
}
275+
}
276+
}
277+
278+
void QgsCptCityColorRampV2Dialog::on_buttonGroupView_buttonClicked( QAbstractButton * button )
279+
{
280+
if ( button->objectName() == "rbtnAuthor" )
281+
{
282+
populateSchemes( "author" );
283+
}
284+
else if ( button->objectName() == "rbtnSelections" )
285+
{
286+
populateSchemes( "selections" );
287+
}
288+
else
289+
{
290+
QgsDebugMsg( "invalid button " + button->objectName() );
291+
}
292+
}
293+
294+
void QgsCptCityColorRampV2Dialog::updatePreview()
295+
{
296+
QSize size( 300, 40 );
297+
mRamp->loadFile();
298+
lblPreview->setPixmap( QgsSymbolLayerV2Utils::colorRampPreviewPixmap( mRamp, size ) );
299+
}
300+
301+
void QgsCptCityColorRampV2Dialog::setSchemeName()
302+
{
303+
if ( treeWidget->currentItem() )
304+
{
305+
mRamp->setSchemeName( treeWidget->currentItem()->data( 0, Qt::UserRole ).toString() );
306+
// setVariantName();
307+
308+
// populate list of variants
309+
populateVariants();
310+
311+
// updatePreview();
312+
}
313+
}
314+
315+
void QgsCptCityColorRampV2Dialog::setVariantName()
316+
{
317+
mRamp->setVariantName( cboVariantName->itemData( cboVariantName->currentIndex(), Qt::UserRole ).toString() );
318+
updatePreview();
319+
}
320+
321+
/* collection items have columns name / path/ and desc/null */
322+
QTreeWidgetItem * QgsCptCityColorRampV2Dialog::makeCollectionItem( const QString& path )
323+
{
324+
// add root item
325+
QString descStr = QgsCptCityColorRampV2::collectionNames().value( path );
326+
if ( descStr.isNull() )
327+
descStr = "";
328+
QTreeWidgetItem *item = new QTreeWidgetItem( QStringList() << QFileInfo( path ).baseName() << descStr );
329+
item->setData( 0, Qt::UserRole, QString( path ) + "/" ); // add / to end to identify it as a collection item
330+
//set collections bold to identify them
331+
QFont font;
332+
font.setBold( true );
333+
item->setData( 0, Qt::FontRole, QVariant( font ) );
334+
item->setData( 1, Qt::FontRole, QVariant( font ) );
335+
336+
// add children collections
337+
QTreeWidgetItem *childItem;
338+
foreach( QString childPath, QgsCptCityColorRampV2::listSchemeCollections( path ) )
339+
{
340+
childItem = makeCollectionItem( childPath );
341+
item->addChild( childItem );
342+
}
343+
344+
// add children schemes
345+
foreach( QString schemeName, QgsCptCityColorRampV2::schemeMap().value( path ) )
346+
{
347+
makeSchemeItem( item, path, schemeName );
348+
}
349+
return item;
350+
}
351+
352+
/* scheme items have columns 0 = ( name / path ) and
353+
[if has variants] 1 = ( #variants / variants )
354+
[if has colors] 1 = ( null / null ) which becomes ( <info> / null ) after populating
355+
*/
356+
void QgsCptCityColorRampV2Dialog::makeSchemeItem( QTreeWidgetItem *item, const QString& path, const QString& schemeName )
357+
{
358+
QString descStr, descData;//, variantStr;
359+
QString curName, curVariant;
360+
QStringList listVariant;
361+
QTreeWidgetItem *childItem;
362+
363+
// // descStr = schemeName;
364+
listVariant = QgsCptCityColorRampV2::schemeVariants().value( path + "/" + schemeName );
365+
366+
if ( listVariant.count() > 1 )
367+
{
368+
// variantStr = QString::number( listVariant.count() ) + " " + tr( "variants" );
369+
descStr = " " + QString::number( listVariant.count() ) + " " + tr( "variants" );
370+
descData = listVariant.join( " " );
371+
}
372+
373+
childItem = new QTreeWidgetItem( QStringList() << schemeName << descStr );
374+
childItem->setData( 0, Qt::UserRole, path + "/" + schemeName );
375+
if ( ! descData.isNull() )
376+
childItem->setData( 1, Qt::UserRole, descData );
377+
item->addChild( childItem );
378+
379+
// create a preview icon using five color variant
380+
// QgsCptCityColorRampV2* r = new QgsCptCityColorRampV2( schemeName, 5 );
381+
// QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( r, iconSize );
382+
// delete r;
383+
384+
}
385+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/***************************************************************************
2+
qgscptcitycolorrampv2dialog.h
3+
---------------------
4+
begin : July 2012
5+
copyright : (C) 2012 by Etienne Tourigny
6+
email : etourigny dot dev at gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSCPTCITYCOLORRAMPV2DIALOG_H
17+
#define QGSCPTCITYCOLORRAMPV2DIALOG_H
18+
19+
#include <QDialog>
20+
21+
#include "ui_qgscptcitycolorrampv2dialogbase.h"
22+
23+
class QgsCptCityColorRampV2;
24+
25+
class GUI_EXPORT QgsCptCityColorRampV2Dialog : public QDialog, private Ui::QgsCptCityColorRampV2DialogBase
26+
{
27+
Q_OBJECT
28+
29+
public:
30+
QgsCptCityColorRampV2Dialog( QgsCptCityColorRampV2* ramp, QWidget* parent = NULL );
31+
32+
public slots:
33+
void setSchemeName();
34+
void setVariantName();
35+
void populateSchemes( QString view = "author" );
36+
void populateVariants();
37+
38+
void on_treeWidget_currentItemChanged( QTreeWidgetItem * current, QTreeWidgetItem * previous );
39+
void on_treeWidget_itemExpanded( QTreeWidgetItem * item );
40+
void on_buttonGroupView_buttonClicked ( QAbstractButton * button );
41+
42+
protected:
43+
44+
void updatePreview();
45+
QTreeWidgetItem* findPath( QString path );
46+
QTreeWidgetItem * makeCollectionItem( const QString& path );
47+
// TODO rename Scheme to something else, maybe data
48+
void makeSchemeItem( QTreeWidgetItem *item, const QString& path, const QString& schemeName );
49+
50+
QgsCptCityColorRampV2* mRamp;
51+
};
52+
53+
#endif

‎src/gui/symbology-ng/qgsstylev2managerdialog.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "qgsvectorgradientcolorrampv2dialog.h"
2525
#include "qgsvectorrandomcolorrampv2dialog.h"
2626
#include "qgsvectorcolorbrewercolorrampv2dialog.h"
27+
#include "qgscptcitycolorrampv2dialog.h"
2728
#include "qgsstylev2exportimportdialog.h"
2829

2930
#include <QFile>
@@ -302,6 +303,7 @@ QString QgsStyleV2ManagerDialog::addColorRampStatic( QWidget* parent, QgsStyleV2
302303
// let the user choose the color ramp type
303304
QStringList rampTypes;
304305
rampTypes << tr( "Gradient" ) << tr( "Random" ) << tr( "ColorBrewer" );
306+
rampTypes << tr( "cpt-city" ); // todo, only for rasters?
305307
bool ok;
306308
QString rampType = QInputDialog::getItem( parent, tr( "Color ramp type" ),
307309
tr( "Please select color ramp type:" ), rampTypes, 0, false, &ok );
@@ -342,9 +344,23 @@ QString QgsStyleV2ManagerDialog::addColorRampStatic( QWidget* parent, QgsStyleV2
342344
}
343345
ramp = brewerRamp;
344346
}
347+
else if ( rampType == tr( "cpt-city" ) )
348+
{
349+
QgsCptCityColorRampV2* cptCityRamp = new QgsCptCityColorRampV2();
350+
QgsCptCityColorRampV2Dialog dlg( cptCityRamp, parent );
351+
if ( !dlg.exec() )
352+
{
353+
delete cptCityRamp;
354+
return QString();
355+
}
356+
ramp = cptCityRamp;
357+
}
345358
else
346359
{
347-
Q_ASSERT( 0 && "invalid ramp type" );
360+
// Q_ASSERT( 0 && "invalid ramp type" );
361+
// bailing out is rather harsh!
362+
QgsDebugMsg( "invalid ramp type " + rampType );
363+
return QString();
348364
}
349365

350366
// get name
@@ -456,6 +472,16 @@ bool QgsStyleV2ManagerDialog::editColorRamp()
456472
return false;
457473
}
458474
}
475+
else if ( ramp->type() == "cpt-city" )
476+
{
477+
QgsCptCityColorRampV2* cptCityRamp = static_cast<QgsCptCityColorRampV2*>( ramp );
478+
QgsCptCityColorRampV2Dialog dlg( cptCityRamp, this );
479+
if ( !dlg.exec() )
480+
{
481+
delete ramp;
482+
return false;
483+
}
484+
}
459485
else
460486
{
461487
Q_ASSERT( 0 && "invalid ramp type" );
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>QgsCptCityColorRampV2DialogBase</class>
4+
<widget class="QDialog" name="QgsCptCityColorRampV2DialogBase">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>807</width>
10+
<height>503</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>cpt-city color ramp</string>
15+
</property>
16+
<layout class="QVBoxLayout">
17+
<item>
18+
<widget class="QStackedWidget" name="stackedWidget">
19+
<property name="currentIndex">
20+
<number>0</number>
21+
</property>
22+
<widget class="QWidget" name="page">
23+
<layout class="QVBoxLayout" name="verticalLayout">
24+
<item>
25+
<layout class="QHBoxLayout" name="horizontalLayout_3">
26+
<item>
27+
<spacer name="horizontalSpacer_2">
28+
<property name="orientation">
29+
<enum>Qt::Horizontal</enum>
30+
</property>
31+
<property name="sizeType">
32+
<enum>QSizePolicy::Fixed</enum>
33+
</property>
34+
<property name="sizeHint" stdset="0">
35+
<size>
36+
<width>40</width>
37+
<height>20</height>
38+
</size>
39+
</property>
40+
</spacer>
41+
</item>
42+
<item>
43+
<widget class="QLabel" name="label_3">
44+
<property name="text">
45+
<string>View</string>
46+
</property>
47+
</widget>
48+
</item>
49+
<item>
50+
<spacer name="horizontalSpacer_5">
51+
<property name="orientation">
52+
<enum>Qt::Horizontal</enum>
53+
</property>
54+
<property name="sizeType">
55+
<enum>QSizePolicy::Fixed</enum>
56+
</property>
57+
<property name="sizeHint" stdset="0">
58+
<size>
59+
<width>40</width>
60+
<height>20</height>
61+
</size>
62+
</property>
63+
</spacer>
64+
</item>
65+
<item>
66+
<widget class="QRadioButton" name="rbtnAuthor">
67+
<property name="text">
68+
<string>All by author</string>
69+
</property>
70+
<property name="checked">
71+
<bool>true</bool>
72+
</property>
73+
<attribute name="buttonGroup">
74+
<string notr="true">buttonGroupView</string>
75+
</attribute>
76+
</widget>
77+
</item>
78+
<item>
79+
<widget class="QRadioButton" name="rbtnSelections">
80+
<property name="text">
81+
<string>Selections by theme</string>
82+
</property>
83+
<attribute name="buttonGroup">
84+
<string notr="true">buttonGroupView</string>
85+
</attribute>
86+
</widget>
87+
</item>
88+
<item>
89+
<spacer name="horizontalSpacer">
90+
<property name="orientation">
91+
<enum>Qt::Horizontal</enum>
92+
</property>
93+
<property name="sizeType">
94+
<enum>QSizePolicy::Expanding</enum>
95+
</property>
96+
<property name="sizeHint" stdset="0">
97+
<size>
98+
<width>40</width>
99+
<height>20</height>
100+
</size>
101+
</property>
102+
</spacer>
103+
</item>
104+
</layout>
105+
</item>
106+
<item>
107+
<widget class="QTreeWidget" name="treeWidget">
108+
<attribute name="headerStretchLastSection">
109+
<bool>true</bool>
110+
</attribute>
111+
<column>
112+
<property name="text">
113+
<string>Name</string>
114+
</property>
115+
</column>
116+
<column>
117+
<property name="text">
118+
<string>Info</string>
119+
</property>
120+
</column>
121+
</widget>
122+
</item>
123+
<item>
124+
<layout class="QGridLayout" name="_2">
125+
<item row="1" column="1">
126+
<widget class="QLabel" name="label_2">
127+
<property name="text">
128+
<string>Variant</string>
129+
</property>
130+
</widget>
131+
</item>
132+
<item row="0" column="1">
133+
<widget class="QLabel" name="label">
134+
<property name="text">
135+
<string>Scheme name</string>
136+
</property>
137+
</widget>
138+
</item>
139+
<item row="0" column="4" rowspan="2">
140+
<spacer>
141+
<property name="orientation">
142+
<enum>Qt::Horizontal</enum>
143+
</property>
144+
<property name="sizeType">
145+
<enum>QSizePolicy::Expanding</enum>
146+
</property>
147+
<property name="sizeHint" stdset="0">
148+
<size>
149+
<width>40</width>
150+
<height>71</height>
151+
</size>
152+
</property>
153+
</spacer>
154+
</item>
155+
<item row="0" column="2">
156+
<spacer name="horizontalSpacer_3">
157+
<property name="orientation">
158+
<enum>Qt::Horizontal</enum>
159+
</property>
160+
<property name="sizeType">
161+
<enum>QSizePolicy::Fixed</enum>
162+
</property>
163+
<property name="sizeHint" stdset="0">
164+
<size>
165+
<width>40</width>
166+
<height>20</height>
167+
</size>
168+
</property>
169+
</spacer>
170+
</item>
171+
<item row="0" column="3">
172+
<widget class="QLabel" name="lblSchemeName">
173+
<property name="text">
174+
<string/>
175+
</property>
176+
</widget>
177+
</item>
178+
<item row="1" column="3">
179+
<widget class="QComboBox" name="cboVariantName">
180+
<property name="enabled">
181+
<bool>false</bool>
182+
</property>
183+
</widget>
184+
</item>
185+
<item row="0" column="0">
186+
<spacer name="horizontalSpacer_4">
187+
<property name="orientation">
188+
<enum>Qt::Horizontal</enum>
189+
</property>
190+
<property name="sizeType">
191+
<enum>QSizePolicy::Fixed</enum>
192+
</property>
193+
<property name="sizeHint" stdset="0">
194+
<size>
195+
<width>40</width>
196+
<height>20</height>
197+
</size>
198+
</property>
199+
</spacer>
200+
</item>
201+
</layout>
202+
</item>
203+
<item>
204+
<spacer>
205+
<property name="orientation">
206+
<enum>Qt::Vertical</enum>
207+
</property>
208+
<property name="sizeType">
209+
<enum>QSizePolicy::Fixed</enum>
210+
</property>
211+
<property name="sizeHint" stdset="0">
212+
<size>
213+
<width>20</width>
214+
<height>20</height>
215+
</size>
216+
</property>
217+
</spacer>
218+
</item>
219+
<item>
220+
<widget class="QGroupBox" name="groupBox">
221+
<property name="title">
222+
<string>Preview</string>
223+
</property>
224+
<layout class="QVBoxLayout">
225+
<item>
226+
<widget class="QLabel" name="lblPreview">
227+
<property name="frameShape">
228+
<enum>QFrame::NoFrame</enum>
229+
</property>
230+
<property name="text">
231+
<string/>
232+
</property>
233+
<property name="alignment">
234+
<set>Qt::AlignCenter</set>
235+
</property>
236+
</widget>
237+
</item>
238+
</layout>
239+
</widget>
240+
</item>
241+
</layout>
242+
</widget>
243+
</widget>
244+
</item>
245+
<item>
246+
<widget class="QDialogButtonBox" name="buttonBox">
247+
<property name="orientation">
248+
<enum>Qt::Horizontal</enum>
249+
</property>
250+
<property name="standardButtons">
251+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
252+
</property>
253+
</widget>
254+
</item>
255+
</layout>
256+
</widget>
257+
<tabstops>
258+
<tabstop>buttonBox</tabstop>
259+
</tabstops>
260+
<resources/>
261+
<connections>
262+
<connection>
263+
<sender>buttonBox</sender>
264+
<signal>accepted()</signal>
265+
<receiver>QgsCptCityColorRampV2DialogBase</receiver>
266+
<slot>accept()</slot>
267+
<hints>
268+
<hint type="sourcelabel">
269+
<x>258</x>
270+
<y>281</y>
271+
</hint>
272+
<hint type="destinationlabel">
273+
<x>168</x>
274+
<y>256</y>
275+
</hint>
276+
</hints>
277+
</connection>
278+
<connection>
279+
<sender>buttonBox</sender>
280+
<signal>rejected()</signal>
281+
<receiver>QgsCptCityColorRampV2DialogBase</receiver>
282+
<slot>reject()</slot>
283+
<hints>
284+
<hint type="sourcelabel">
285+
<x>363</x>
286+
<y>273</y>
287+
</hint>
288+
<hint type="destinationlabel">
289+
<x>371</x>
290+
<y>259</y>
291+
</hint>
292+
</hints>
293+
</connection>
294+
</connections>
295+
<buttongroups>
296+
<buttongroup name="buttonGroupView"/>
297+
</buttongroups>
298+
</ui>

‎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/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,4 @@ ADD_QGIS_TEST(rulebasedrenderertest testqgsrulebasedrenderer.cpp)
9797
ADD_QGIS_TEST(ziplayertest testziplayer.cpp)
9898
ADD_QGIS_TEST(dataitemtest testqgsdataitem.cpp)
9999
ADD_QGIS_TEST(composermaptest testqgscomposermap.cpp)
100+
ADD_QGIS_TEST(stylev2test testqgsstylev2.cpp)

‎tests/src/core/testqgsrasterlayer.cpp

Lines changed: 98 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,9 @@ class TestQgsRasterLayer: public QObject
5455

5556
void isValid();
5657
void pseudoColor();
58+
void colorRamp1();
59+
void colorRamp2();
60+
void colorRamp3();
5761
void landsatBasic();
5862
void landsatBasic875Qml();
5963
void checkDimensions();
@@ -63,6 +67,11 @@ class TestQgsRasterLayer: public QObject
6367
private:
6468
bool render( QString theFileName );
6569
bool setQml( QString theType );
70+
void populateColorRampShader( QgsColorRampShader* colorRampShader,
71+
QgsVectorColorRampV2* colorRamp,
72+
int numberOfEntries );
73+
bool testColorRamp( QString name, QgsVectorColorRampV2* colorRamp,
74+
QgsColorRampShader::ColorRamp_TYPE type, int numberOfEntries );
6675
QString mTestDataDir;
6776
QgsRasterLayer * mpRasterLayer;
6877
QgsRasterLayer * mpLandsatRasterLayer;
@@ -162,6 +171,95 @@ void TestQgsRasterLayer::pseudoColor()
162171
QVERIFY( render( "raster_pseudo" ) );
163172
}
164173

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

‎tests/src/core/testqgsstylev2.cpp

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/***************************************************************************
2+
testqgsstylev2.cpp
3+
--------------------------------------
4+
Date : Wed Aug 1 12:13:24 BRT 2012
5+
Copyright : (C) 2012 Etienne Tourigny and Tim Sutton
6+
Email : etourigny dot dev at gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
#include <QtTest>
16+
#include <QObject>
17+
#include <QStringList>
18+
#include <QObject>
19+
#include <QApplication>
20+
#include <QFileInfo>
21+
22+
//qgis includes...
23+
#include <qgsapplication.h>
24+
#include "qgsconfig.h"
25+
#include "qgslogger.h"
26+
#include "qgsvectorcolorrampv2.h"
27+
28+
#include "qgsstylev2.h"
29+
30+
/** \ingroup UnitTests
31+
* This is a unit test to verify that styles are working correctly
32+
*/
33+
class TestStyleV2: public QObject
34+
{
35+
Q_OBJECT;
36+
37+
private:
38+
39+
QgsStyleV2 *mStyle;
40+
41+
bool testValidColor( QgsVectorColorRampV2 *ramp, double value, QColor expected );
42+
43+
private slots:
44+
45+
// init / cleanup
46+
void initTestCase();// will be called before the first testfunction is executed.
47+
void cleanupTestCase();// will be called after the last testfunction was executed.
48+
void init() {};// will be called before each testfunction is executed.
49+
void cleanup() {};// will be called after every testfunction.
50+
// void initStyles();
51+
52+
void testCreateColorRamps();
53+
void testLoadColorRamps();
54+
void testSaveLoad();
55+
};
56+
57+
58+
// slots
59+
void TestStyleV2::initTestCase()
60+
{
61+
// initialize with test directory so we don't mess with user's stuff
62+
QgsApplication::init( QDir::homePath() + QString( "/.qgis_test" ) );
63+
QgsApplication::initQgis();
64+
65+
// output test environment
66+
QgsApplication::showSettings();
67+
68+
// Set up the QSettings environment
69+
QCoreApplication::setOrganizationName( "QuantumGIS" );
70+
QCoreApplication::setOrganizationDomain( "qgis.org" );
71+
QCoreApplication::setApplicationName( "QGIS-TEST" );
72+
73+
// initialize with a clean style
74+
QFile styleFile( QgsApplication::userStyleV2Path() );
75+
if ( styleFile.exists() )
76+
{
77+
styleFile.remove();
78+
QgsDebugMsg( "removed user style file " + styleFile.fileName() );
79+
}
80+
mStyle = QgsStyleV2::defaultStyle();
81+
// mStyle->clear();
82+
}
83+
84+
void TestStyleV2::cleanupTestCase()
85+
{
86+
// don't save
87+
// mStyle->save();
88+
delete mStyle;
89+
}
90+
91+
bool TestStyleV2::testValidColor( QgsVectorColorRampV2 *ramp, double value, QColor expected )
92+
{
93+
QColor result = ramp->color( value );
94+
if ( result != expected )
95+
{
96+
QWARN( QString( "value = %1 result = %2 expected = %3" ).arg( value ).arg(
97+
result.name() ).arg( expected.name() ).toLocal8Bit().data() );
98+
return false;
99+
}
100+
return true;
101+
}
102+
103+
void TestStyleV2::testCreateColorRamps()
104+
{
105+
// gradient ramp
106+
QgsVectorGradientColorRampV2* gradientRamp = new QgsVectorGradientColorRampV2( QColor( Qt::red ), QColor( Qt::blue ) );
107+
QgsVectorGradientColorRampV2::StopsMap stops;
108+
stops[ 0.5 ] = QColor( Qt::white );
109+
gradientRamp->setStops( stops );
110+
QVERIFY( mStyle->addColorRamp( "test_gradient", gradientRamp ) == true );
111+
112+
// random ramp
113+
QgsVectorRandomColorRampV2* randomRamp = new QgsVectorRandomColorRampV2();
114+
QVERIFY( mStyle->addColorRamp( "test_random", randomRamp ) == true );
115+
116+
// color brewer ramp
117+
QgsVectorColorBrewerColorRampV2* cb1Ramp = new QgsVectorColorBrewerColorRampV2();
118+
QVERIFY( mStyle->addColorRamp( "test_cb1", cb1Ramp ) == true );
119+
QgsVectorColorBrewerColorRampV2* cb2Ramp = new QgsVectorColorBrewerColorRampV2( "RdYlGn", 6 );
120+
QVERIFY( mStyle->addColorRamp( "test_cb2", cb2Ramp ) == true );
121+
122+
// cpt-city ramp - use gradients that are free to distribute
123+
// set base dir because we are using a test home path - change this if we distribute a minimal set with qgis
124+
QgsCptCityColorRampV2::setBaseDir( QDir::homePath() + QString( "/.qgis/cpt-city" ) );
125+
QgsCptCityColorRampV2::loadSchemes( "" );
126+
if ( QgsCptCityColorRampV2::hasBasicSchemes() )
127+
{
128+
QgsCptCityColorRampV2* cc1Ramp = new QgsCptCityColorRampV2( "jjg/misc/temperature", "" );
129+
QVERIFY( mStyle->addColorRamp( "test_cc1", cc1Ramp ) == true );
130+
QgsCptCityColorRampV2* cc2Ramp = new QgsCptCityColorRampV2( "cb/div/PiYG", "_10" );
131+
QVERIFY( mStyle->addColorRamp( "test_cc2", cc2Ramp ) == true );
132+
}
133+
else
134+
{
135+
QWARN( "cpt-city support files not found - skipping cpt-city color ramp tests" );
136+
}
137+
}
138+
139+
void TestStyleV2::testLoadColorRamps()
140+
{
141+
QStringList colorRamps = mStyle->colorRampNames();
142+
QStringList colorRampsTest = QStringList() << "BrBG" << "Spectral"
143+
<< "test_gradient" << "test_random"
144+
<< "test_cb1" << "test_cb2";
145+
146+
// values for color tests
147+
QMultiMap< QString, QPair< double, QColor> > colorTests;
148+
colorTests.insert( "test_gradient", qMakePair( 0.25, QColor( "#ff7f7f" ) ) );
149+
colorTests.insert( "test_gradient", qMakePair( 0.66, QColor( "#adadff" ) ) );
150+
// cannot test random colors!
151+
colorTests.insert( "test_cb1", qMakePair( 0.25, QColor( "#fdae61" ) ) );
152+
colorTests.insert( "test_cb1", qMakePair( 0.66, QColor( "#abdda4" ) ) );
153+
colorTests.insert( "test_cb2", qMakePair( 0.25, QColor( "#fc8d59" ) ) );
154+
colorTests.insert( "test_cb2", qMakePair( 0.66, QColor( "#d9ef8b" ) ) );
155+
156+
// cpt-city
157+
if ( QgsCptCityColorRampV2::hasAllSchemes() )
158+
{
159+
colorRampsTest << "test_cc1";
160+
colorTests.insert( "test_cc1", qMakePair( 0.25, QColor( "#466fcf" ) ) );
161+
colorTests.insert( "test_cc1", qMakePair( 0.66, QColor( "#dbc85b" ) ) );
162+
colorRampsTest << "test_cc2";
163+
colorTests.insert( "test_cc2", qMakePair( 0.25, QColor( "#de77ae" ) ) );
164+
colorTests.insert( "test_cc2", qMakePair( 0.66, QColor( "#b8e186" ) ) );
165+
}
166+
167+
foreach( QString name, colorRampsTest )
168+
{
169+
QgsDebugMsg( "colorRamp " + name );
170+
QVERIFY( colorRamps.contains( name ) );
171+
QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
172+
QVERIFY( ramp != 0 );
173+
// test colors
174+
if ( colorTests.contains( name ) )
175+
{
176+
QList< QPair< double, QColor> > values = colorTests.values( name );
177+
for ( int i = 0; i < values.size(); ++i )
178+
{
179+
QVERIFY( testValidColor( ramp, values.at( i ).first, values.at( i ).second ) );
180+
}
181+
}
182+
if ( ramp )
183+
delete ramp;
184+
}
185+
}
186+
187+
void TestStyleV2::testSaveLoad()
188+
{
189+
mStyle->save();
190+
mStyle->clear();
191+
mStyle->load( QgsApplication::userStyleV2Path() );
192+
193+
QStringList colorRamps = mStyle->colorRampNames();
194+
QStringList colorRampsTest = QStringList() << "test_gradient";
195+
196+
foreach( QString name, colorRampsTest )
197+
{
198+
QgsDebugMsg( "colorRamp " + name );
199+
QVERIFY( colorRamps.contains( name ) );
200+
QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
201+
QVERIFY( ramp != 0 );
202+
if ( ramp )
203+
delete ramp;
204+
}
205+
}
206+
207+
208+
QTEST_MAIN( TestStyleV2 )
209+
#include "moc_testqgsstylev2.cxx"
Loading
Loading
Loading

‎tests/testdata/zip/points3.geojson.gz.properties

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.