2
#include "qgscategorizedsymbolrendererv2.h"
4
#include "qgssymbolv2.h"
5
#include "qgssymbollayerv2utils.h"
6
#include "qgsvectorcolorrampv2.h"
8
#include "qgsfeature.h"
9
#include "qgsvectorlayer.h"
10
#include "qgslogger.h"
12
#include <QDomDocument>
13
#include <QDomElement>
14
#include <QSettings> // for legend
16
QgsRendererCategoryV2::QgsRendererCategoryV2( QVariant value, QgsSymbolV2* symbol, QString label )
17
: mValue( value ), mSymbol( symbol ), mLabel( label )
21
QgsRendererCategoryV2::QgsRendererCategoryV2( const QgsRendererCategoryV2& cat )
22
: mValue( cat.mValue ), mLabel( cat.mLabel )
24
mSymbol = cat.mSymbol->clone();
28
QgsRendererCategoryV2::~QgsRendererCategoryV2()
33
QVariant QgsRendererCategoryV2::value() const
38
QgsSymbolV2* QgsRendererCategoryV2::symbol() const
43
QString QgsRendererCategoryV2::label() const
48
void QgsRendererCategoryV2::setSymbol( QgsSymbolV2* s )
56
void QgsRendererCategoryV2::setLabel( QString label )
61
QString QgsRendererCategoryV2::dump()
63
return QString( "%1::%2::%3\n" ).arg( mValue.toString() ).arg( mLabel ).arg( mSymbol->dump() );
68
QgsCategorizedSymbolRendererV2::QgsCategorizedSymbolRendererV2( QString attrName, QgsCategoryList categories )
69
: QgsFeatureRendererV2( "categorizedSymbol" ),
70
mAttrName( attrName ),
71
mCategories( categories ),
72
mSourceSymbol( NULL ),
73
mSourceColorRamp( NULL )
75
for ( int i = 0; i < mCategories.count(); ++i )
77
QgsRendererCategoryV2& cat = mCategories[i];
78
if ( cat.symbol() == NULL )
80
QgsDebugMsg( "invalid symbol in a category! ignoring..." );
81
mCategories.removeAt( i-- );
83
//mCategories.insert(cat.value().toString(), cat);
87
QgsCategorizedSymbolRendererV2::~QgsCategorizedSymbolRendererV2()
89
mCategories.clear(); // this should also call destructors of symbols
91
delete mSourceColorRamp;
94
void QgsCategorizedSymbolRendererV2::rebuildHash()
98
for ( int i = 0; i < mCategories.count(); ++i )
100
QgsRendererCategoryV2& cat = mCategories[i];
101
mSymbolHash.insert( cat.value().toString(), cat.symbol() );
105
QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForValue( QVariant value )
107
// TODO: special case for int, double
109
QHash<QString, QgsSymbolV2*>::iterator it = mSymbolHash.find( value.toString() );
110
if ( it == mSymbolHash.end() )
112
if ( mSymbolHash.count() == 0 )
113
QgsDebugMsg( "there are no hashed symbols!!!" );
115
QgsDebugMsg( "attribute value not found: " + value.toString() );
122
QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature( QgsFeature& feature )
124
const QgsAttributeMap& attrMap = feature.attributeMap();
125
QgsAttributeMap::const_iterator ita = attrMap.find( mAttrNum );
126
if ( ita == attrMap.end() )
128
QgsDebugMsg( "attribute '" + mAttrName + "' (index " + QString::number( mAttrNum ) + ") required by renderer not found" );
132
// find the right category
133
return symbolForValue( *ita );
136
int QgsCategorizedSymbolRendererV2::categoryIndexForValue( QVariant val )
138
for ( int i = 0; i < mCategories.count(); i++ )
140
if ( mCategories[i].value() == val )
146
bool QgsCategorizedSymbolRendererV2::updateCategorySymbol( int catIndex, QgsSymbolV2* symbol )
148
if ( catIndex < 0 || catIndex >= mCategories.size() )
150
mCategories[catIndex].setSymbol( symbol );
154
bool QgsCategorizedSymbolRendererV2::updateCategoryLabel( int catIndex, QString label )
156
if ( catIndex < 0 || catIndex >= mCategories.size() )
158
mCategories[catIndex].setLabel( label );
162
bool QgsCategorizedSymbolRendererV2::deleteCategory( int catIndex )
164
if ( catIndex < 0 || catIndex >= mCategories.size() )
167
mCategories.removeAt( catIndex );
171
void QgsCategorizedSymbolRendererV2::deleteAllCategories()
176
void QgsCategorizedSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
178
// make sure that the hash table is up to date
181
// find out classification attribute index from name
182
mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
184
QgsCategoryList::iterator it = mCategories.begin();
185
for ( ; it != mCategories.end(); ++it )
186
it->symbol()->startRender( context );
189
void QgsCategorizedSymbolRendererV2::stopRender( QgsRenderContext& context )
191
QgsCategoryList::iterator it = mCategories.begin();
192
for ( ; it != mCategories.end(); ++it )
193
it->symbol()->stopRender( context );
196
QList<QString> QgsCategorizedSymbolRendererV2::usedAttributes()
199
lst.append( mAttrName );
203
QString QgsCategorizedSymbolRendererV2::dump()
205
QString s = QString( "CATEGORIZED: idx %1\n" ).arg( mAttrName );
206
for ( int i = 0; i < mCategories.count(); i++ )
207
s += mCategories[i].dump();
211
QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone()
213
QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( mAttrName, mCategories );
215
r->setSourceSymbol( mSourceSymbol->clone() );
216
if ( mSourceColorRamp )
217
r->setSourceColorRamp( mSourceColorRamp->clone() );
218
r->setUsingSymbolLevels( usingSymbolLevels() );
222
QgsSymbolV2List QgsCategorizedSymbolRendererV2::symbols()
225
for ( int i = 0; i < mCategories.count(); i++ )
226
lst.append( mCategories[i].symbol() );
230
QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::create( QDomElement& element )
232
QDomElement symbolsElem = element.firstChildElement( "symbols" );
233
if ( symbolsElem.isNull() )
236
QDomElement catsElem = element.firstChildElement( "categories" );
237
if ( catsElem.isNull() )
240
QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
241
QgsCategoryList cats;
243
QDomElement catElem = catsElem.firstChildElement();
244
while ( !catElem.isNull() )
246
if ( catElem.tagName() == "category" )
248
QVariant value = QVariant( catElem.attribute( "value" ) );
249
QString symbolName = catElem.attribute( "symbol" );
250
QString label = catElem.attribute( "label" );
251
if ( symbolMap.contains( symbolName ) )
253
QgsSymbolV2* symbol = symbolMap.take( symbolName );
254
cats.append( QgsRendererCategoryV2( value, symbol, label ) );
257
catElem = catElem.nextSiblingElement();
260
QString attrName = element.attribute( "attr" );
262
QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( attrName, cats );
264
// delete symbols if there are any more
265
QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );
267
// try to load source symbol (optional)
268
QDomElement sourceSymbolElem = element.firstChildElement( "source-symbol" );
269
if ( !sourceSymbolElem.isNull() )
271
QgsSymbolV2Map sourceSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( sourceSymbolElem );
272
if ( sourceSymbolMap.contains( "0" ) )
274
r->setSourceSymbol( sourceSymbolMap.take( "0" ) );
276
QgsSymbolLayerV2Utils::clearSymbolMap( sourceSymbolMap );
279
// try to load color ramp (optional)
280
QDomElement sourceColorRampElem = element.firstChildElement( "colorramp" );
281
if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
283
r->setSourceColorRamp( QgsSymbolLayerV2Utils::loadColorRamp( sourceColorRampElem ) );
286
// TODO: symbol levels
290
QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )
292
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
293
rendererElem.setAttribute( "type", "categorizedSymbol" );
294
rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
295
rendererElem.setAttribute( "attr", mAttrName );
299
QgsSymbolV2Map symbols;
300
QDomElement catsElem = doc.createElement( "categories" );
301
QgsCategoryList::const_iterator it = mCategories.constBegin();
302
for ( ; it != mCategories.end(); it++ )
304
const QgsRendererCategoryV2& cat = *it;
305
QString symbolName = QString::number( i );
306
symbols.insert( symbolName, cat.symbol() );
308
QDomElement catElem = doc.createElement( "category" );
309
catElem.setAttribute( "value", cat.value().toString() );
310
catElem.setAttribute( "symbol", symbolName );
311
catElem.setAttribute( "label", cat.label() );
312
catsElem.appendChild( catElem );
316
rendererElem.appendChild( catsElem );
319
QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
320
rendererElem.appendChild( symbolsElem );
322
// save source symbol
325
QgsSymbolV2Map sourceSymbols;
326
sourceSymbols.insert( "0", mSourceSymbol );
327
QDomElement sourceSymbolElem = QgsSymbolLayerV2Utils::saveSymbols( sourceSymbols, "source-symbol", doc );
328
rendererElem.appendChild( sourceSymbolElem );
331
// save source color ramp
332
if ( mSourceColorRamp )
334
QDomElement colorRampElem = QgsSymbolLayerV2Utils::saveColorRamp( "[source]", mSourceColorRamp, doc );
335
rendererElem.appendChild( colorRampElem );
341
QgsLegendSymbologyList QgsCategorizedSymbolRendererV2::legendSymbologyItems( QSize iconSize )
344
bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
346
QgsLegendSymbologyList lst;
347
if ( showClassifiers )
349
lst << qMakePair( classAttribute(), QPixmap() );
352
int count = categories().count();
353
for ( int i = 0; i < count; i++ )
355
const QgsRendererCategoryV2& cat = categories()[i];
356
QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( cat.symbol(), iconSize );
357
lst << qMakePair( cat.label(), pix );
363
QgsSymbolV2* QgsCategorizedSymbolRendererV2::sourceSymbol()
365
return mSourceSymbol;
367
void QgsCategorizedSymbolRendererV2::setSourceSymbol( QgsSymbolV2* sym )
369
delete mSourceSymbol;
373
QgsVectorColorRampV2* QgsCategorizedSymbolRendererV2::sourceColorRamp()
375
return mSourceColorRamp;
377
void QgsCategorizedSymbolRendererV2::setSourceColorRamp( QgsVectorColorRampV2* ramp )
379
delete mSourceColorRamp;
380
mSourceColorRamp = ramp;