~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include "qgscategorizedsymbolrendererv2.h"
 
3
 
 
4
#include "qgssymbolv2.h"
 
5
#include "qgssymbollayerv2utils.h"
 
6
#include "qgsvectorcolorrampv2.h"
 
7
 
 
8
#include "qgsfeature.h"
 
9
#include "qgsvectorlayer.h"
 
10
#include "qgslogger.h"
 
11
 
 
12
#include <QDomDocument>
 
13
#include <QDomElement>
 
14
#include <QSettings> // for legend
 
15
 
 
16
QgsRendererCategoryV2::QgsRendererCategoryV2( QVariant value, QgsSymbolV2* symbol, QString label )
 
17
    : mValue( value ), mSymbol( symbol ), mLabel( label )
 
18
{
 
19
}
 
20
 
 
21
QgsRendererCategoryV2::QgsRendererCategoryV2( const QgsRendererCategoryV2& cat )
 
22
    : mValue( cat.mValue ), mLabel( cat.mLabel )
 
23
{
 
24
  mSymbol = cat.mSymbol->clone();
 
25
}
 
26
 
 
27
 
 
28
QgsRendererCategoryV2::~QgsRendererCategoryV2()
 
29
{
 
30
  delete mSymbol;
 
31
}
 
32
 
 
33
QVariant QgsRendererCategoryV2::value() const
 
34
{
 
35
  return mValue;
 
36
}
 
37
 
 
38
QgsSymbolV2* QgsRendererCategoryV2::symbol() const
 
39
{
 
40
  return mSymbol;
 
41
}
 
42
 
 
43
QString QgsRendererCategoryV2::label() const
 
44
{
 
45
  return mLabel;
 
46
}
 
47
 
 
48
void QgsRendererCategoryV2::setSymbol( QgsSymbolV2* s )
 
49
{
 
50
  if ( mSymbol == s )
 
51
    return;
 
52
  delete mSymbol;
 
53
  mSymbol = s;
 
54
}
 
55
 
 
56
void QgsRendererCategoryV2::setLabel( QString label )
 
57
{
 
58
  mLabel = label;
 
59
}
 
60
 
 
61
QString QgsRendererCategoryV2::dump()
 
62
{
 
63
  return QString( "%1::%2::%3\n" ).arg( mValue.toString() ).arg( mLabel ).arg( mSymbol->dump() );
 
64
}
 
65
 
 
66
///////////////////
 
67
 
 
68
QgsCategorizedSymbolRendererV2::QgsCategorizedSymbolRendererV2( QString attrName, QgsCategoryList categories )
 
69
    : QgsFeatureRendererV2( "categorizedSymbol" ),
 
70
    mAttrName( attrName ),
 
71
    mCategories( categories ),
 
72
    mSourceSymbol( NULL ),
 
73
    mSourceColorRamp( NULL )
 
74
{
 
75
  for ( int i = 0; i < mCategories.count(); ++i )
 
76
  {
 
77
    QgsRendererCategoryV2& cat = mCategories[i];
 
78
    if ( cat.symbol() == NULL )
 
79
    {
 
80
      QgsDebugMsg( "invalid symbol in a category! ignoring..." );
 
81
      mCategories.removeAt( i-- );
 
82
    }
 
83
    //mCategories.insert(cat.value().toString(), cat);
 
84
  }
 
85
}
 
86
 
 
87
QgsCategorizedSymbolRendererV2::~QgsCategorizedSymbolRendererV2()
 
88
{
 
89
  mCategories.clear(); // this should also call destructors of symbols
 
90
  delete mSourceSymbol;
 
91
  delete mSourceColorRamp;
 
92
}
 
93
 
 
94
void QgsCategorizedSymbolRendererV2::rebuildHash()
 
95
{
 
96
  mSymbolHash.clear();
 
97
 
 
98
  for ( int i = 0; i < mCategories.count(); ++i )
 
99
  {
 
100
    QgsRendererCategoryV2& cat = mCategories[i];
 
101
    mSymbolHash.insert( cat.value().toString(), cat.symbol() );
 
102
  }
 
103
}
 
104
 
 
105
QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForValue( QVariant value )
 
106
{
 
107
  // TODO: special case for int, double
 
108
 
 
109
  QHash<QString, QgsSymbolV2*>::iterator it = mSymbolHash.find( value.toString() );
 
110
  if ( it == mSymbolHash.end() )
 
111
  {
 
112
    if ( mSymbolHash.count() == 0 )
 
113
      QgsDebugMsg( "there are no hashed symbols!!!" );
 
114
    else
 
115
      QgsDebugMsg( "attribute value not found: " + value.toString() );
 
116
    return NULL;
 
117
  }
 
118
  else
 
119
    return *it;
 
120
}
 
121
 
 
122
QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature( QgsFeature& feature )
 
123
{
 
124
  const QgsAttributeMap& attrMap = feature.attributeMap();
 
125
  QgsAttributeMap::const_iterator ita = attrMap.find( mAttrNum );
 
126
  if ( ita == attrMap.end() )
 
127
  {
 
128
    QgsDebugMsg( "attribute '" + mAttrName + "' (index " + QString::number( mAttrNum ) + ") required by renderer not found" );
 
129
    return NULL;
 
130
  }
 
131
 
 
132
  // find the right category
 
133
  return symbolForValue( *ita );
 
134
}
 
135
 
 
136
int QgsCategorizedSymbolRendererV2::categoryIndexForValue( QVariant val )
 
137
{
 
138
  for ( int i = 0; i < mCategories.count(); i++ )
 
139
  {
 
140
    if ( mCategories[i].value() == val )
 
141
      return i;
 
142
  }
 
143
  return -1;
 
144
}
 
145
 
 
146
bool QgsCategorizedSymbolRendererV2::updateCategorySymbol( int catIndex, QgsSymbolV2* symbol )
 
147
{
 
148
  if ( catIndex < 0 || catIndex >= mCategories.size() )
 
149
    return false;
 
150
  mCategories[catIndex].setSymbol( symbol );
 
151
  return true;
 
152
}
 
153
 
 
154
bool QgsCategorizedSymbolRendererV2::updateCategoryLabel( int catIndex, QString label )
 
155
{
 
156
  if ( catIndex < 0 || catIndex >= mCategories.size() )
 
157
    return false;
 
158
  mCategories[catIndex].setLabel( label );
 
159
  return true;
 
160
}
 
161
 
 
162
bool QgsCategorizedSymbolRendererV2::deleteCategory( int catIndex )
 
163
{
 
164
  if ( catIndex < 0 || catIndex >= mCategories.size() )
 
165
    return false;
 
166
 
 
167
  mCategories.removeAt( catIndex );
 
168
  return true;
 
169
}
 
170
 
 
171
void QgsCategorizedSymbolRendererV2::deleteAllCategories()
 
172
{
 
173
  mCategories.clear();
 
174
}
 
175
 
 
176
void QgsCategorizedSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
 
177
{
 
178
  // make sure that the hash table is up to date
 
179
  rebuildHash();
 
180
 
 
181
  // find out classification attribute index from name
 
182
  mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
 
183
 
 
184
  QgsCategoryList::iterator it = mCategories.begin();
 
185
  for ( ; it != mCategories.end(); ++it )
 
186
    it->symbol()->startRender( context );
 
187
}
 
188
 
 
189
void QgsCategorizedSymbolRendererV2::stopRender( QgsRenderContext& context )
 
190
{
 
191
  QgsCategoryList::iterator it = mCategories.begin();
 
192
  for ( ; it != mCategories.end(); ++it )
 
193
    it->symbol()->stopRender( context );
 
194
}
 
195
 
 
196
QList<QString> QgsCategorizedSymbolRendererV2::usedAttributes()
 
197
{
 
198
  QList<QString> lst;
 
199
  lst.append( mAttrName );
 
200
  return lst;
 
201
}
 
202
 
 
203
QString QgsCategorizedSymbolRendererV2::dump()
 
204
{
 
205
  QString s = QString( "CATEGORIZED: idx %1\n" ).arg( mAttrName );
 
206
  for ( int i = 0; i < mCategories.count(); i++ )
 
207
    s += mCategories[i].dump();
 
208
  return s;
 
209
}
 
210
 
 
211
QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone()
 
212
{
 
213
  QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( mAttrName, mCategories );
 
214
  if ( mSourceSymbol )
 
215
    r->setSourceSymbol( mSourceSymbol->clone() );
 
216
  if ( mSourceColorRamp )
 
217
    r->setSourceColorRamp( mSourceColorRamp->clone() );
 
218
  r->setUsingSymbolLevels( usingSymbolLevels() );
 
219
  return r;
 
220
}
 
221
 
 
222
QgsSymbolV2List QgsCategorizedSymbolRendererV2::symbols()
 
223
{
 
224
  QgsSymbolV2List lst;
 
225
  for ( int i = 0; i < mCategories.count(); i++ )
 
226
    lst.append( mCategories[i].symbol() );
 
227
  return lst;
 
228
}
 
229
 
 
230
QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::create( QDomElement& element )
 
231
{
 
232
  QDomElement symbolsElem = element.firstChildElement( "symbols" );
 
233
  if ( symbolsElem.isNull() )
 
234
    return NULL;
 
235
 
 
236
  QDomElement catsElem = element.firstChildElement( "categories" );
 
237
  if ( catsElem.isNull() )
 
238
    return NULL;
 
239
 
 
240
  QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
 
241
  QgsCategoryList cats;
 
242
 
 
243
  QDomElement catElem = catsElem.firstChildElement();
 
244
  while ( !catElem.isNull() )
 
245
  {
 
246
    if ( catElem.tagName() == "category" )
 
247
    {
 
248
      QVariant value = QVariant( catElem.attribute( "value" ) );
 
249
      QString symbolName = catElem.attribute( "symbol" );
 
250
      QString label = catElem.attribute( "label" );
 
251
      if ( symbolMap.contains( symbolName ) )
 
252
      {
 
253
        QgsSymbolV2* symbol = symbolMap.take( symbolName );
 
254
        cats.append( QgsRendererCategoryV2( value, symbol, label ) );
 
255
      }
 
256
    }
 
257
    catElem = catElem.nextSiblingElement();
 
258
  }
 
259
 
 
260
  QString attrName = element.attribute( "attr" );
 
261
 
 
262
  QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( attrName, cats );
 
263
 
 
264
  // delete symbols if there are any more
 
265
  QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );
 
266
 
 
267
  // try to load source symbol (optional)
 
268
  QDomElement sourceSymbolElem = element.firstChildElement( "source-symbol" );
 
269
  if ( !sourceSymbolElem.isNull() )
 
270
  {
 
271
    QgsSymbolV2Map sourceSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( sourceSymbolElem );
 
272
    if ( sourceSymbolMap.contains( "0" ) )
 
273
    {
 
274
      r->setSourceSymbol( sourceSymbolMap.take( "0" ) );
 
275
    }
 
276
    QgsSymbolLayerV2Utils::clearSymbolMap( sourceSymbolMap );
 
277
  }
 
278
 
 
279
  // try to load color ramp (optional)
 
280
  QDomElement sourceColorRampElem = element.firstChildElement( "colorramp" );
 
281
  if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
 
282
  {
 
283
    r->setSourceColorRamp( QgsSymbolLayerV2Utils::loadColorRamp( sourceColorRampElem ) );
 
284
  }
 
285
 
 
286
  // TODO: symbol levels
 
287
  return r;
 
288
}
 
289
 
 
290
QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )
 
291
{
 
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 );
 
296
 
 
297
  // categories
 
298
  int i = 0;
 
299
  QgsSymbolV2Map symbols;
 
300
  QDomElement catsElem = doc.createElement( "categories" );
 
301
  QgsCategoryList::const_iterator it = mCategories.constBegin();
 
302
  for ( ; it != mCategories.end(); it++ )
 
303
  {
 
304
    const QgsRendererCategoryV2& cat = *it;
 
305
    QString symbolName = QString::number( i );
 
306
    symbols.insert( symbolName, cat.symbol() );
 
307
 
 
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 );
 
313
    i++;
 
314
  }
 
315
 
 
316
  rendererElem.appendChild( catsElem );
 
317
 
 
318
  // save symbols
 
319
  QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
 
320
  rendererElem.appendChild( symbolsElem );
 
321
 
 
322
  // save source symbol
 
323
  if ( mSourceSymbol )
 
324
  {
 
325
    QgsSymbolV2Map sourceSymbols;
 
326
    sourceSymbols.insert( "0", mSourceSymbol );
 
327
    QDomElement sourceSymbolElem = QgsSymbolLayerV2Utils::saveSymbols( sourceSymbols, "source-symbol", doc );
 
328
    rendererElem.appendChild( sourceSymbolElem );
 
329
  }
 
330
 
 
331
  // save source color ramp
 
332
  if ( mSourceColorRamp )
 
333
  {
 
334
    QDomElement colorRampElem = QgsSymbolLayerV2Utils::saveColorRamp( "[source]", mSourceColorRamp, doc );
 
335
    rendererElem.appendChild( colorRampElem );
 
336
  }
 
337
 
 
338
  return rendererElem;
 
339
}
 
340
 
 
341
QgsLegendSymbologyList QgsCategorizedSymbolRendererV2::legendSymbologyItems( QSize iconSize )
 
342
{
 
343
  QSettings settings;
 
344
  bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
 
345
 
 
346
  QgsLegendSymbologyList lst;
 
347
  if ( showClassifiers )
 
348
  {
 
349
    lst << qMakePair( classAttribute(), QPixmap() );
 
350
  }
 
351
 
 
352
  int count = categories().count();
 
353
  for ( int i = 0; i < count; i++ )
 
354
  {
 
355
    const QgsRendererCategoryV2& cat = categories()[i];
 
356
    QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( cat.symbol(), iconSize );
 
357
    lst << qMakePair( cat.label(), pix );
 
358
  }
 
359
  return lst;
 
360
}
 
361
 
 
362
 
 
363
QgsSymbolV2* QgsCategorizedSymbolRendererV2::sourceSymbol()
 
364
{
 
365
  return mSourceSymbol;
 
366
}
 
367
void QgsCategorizedSymbolRendererV2::setSourceSymbol( QgsSymbolV2* sym )
 
368
{
 
369
  delete mSourceSymbol;
 
370
  mSourceSymbol = sym;
 
371
}
 
372
 
 
373
QgsVectorColorRampV2* QgsCategorizedSymbolRendererV2::sourceColorRamp()
 
374
{
 
375
  return mSourceColorRamp;
 
376
}
 
377
void QgsCategorizedSymbolRendererV2::setSourceColorRamp( QgsVectorColorRampV2* ramp )
 
378
{
 
379
  delete mSourceColorRamp;
 
380
  mSourceColorRamp = ramp;
 
381
}