QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgscategorizedsymbolrendererv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscategorizedsymbolrendererv2.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot 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 <algorithm>
16 
18 
19 #include "qgssymbolv2.h"
20 #include "qgssymbollayerv2utils.h"
21 #include "qgsvectorcolorrampv2.h"
22 
23 #include "qgsfeature.h"
24 #include "qgsvectorlayer.h"
25 #include "qgslogger.h"
26 
27 #include <QDomDocument>
28 #include <QDomElement>
29 #include <QSettings> // for legend
30 
32 {
33 }
34 
35 QgsRendererCategoryV2::QgsRendererCategoryV2( QVariant value, QgsSymbolV2* symbol, QString label, bool render )
36  : mValue( value )
37  , mSymbol( symbol )
38  , mLabel( label )
39  , mRender( render )
40 {
41 }
42 
44  : mValue( cat.mValue )
45  , mSymbol( cat.mSymbol.data() ? cat.mSymbol->clone() : NULL )
46  , mLabel( cat.mLabel )
47  , mRender( cat.mRender )
48 {
49 }
50 
51 // copy+swap idion, the copy is done through the 'pass by value'
53 {
54  swap( cat );
55  return *this;
56 }
57 
59 {
60  qSwap( mValue, cat.mValue );
61  qSwap( mSymbol, cat.mSymbol );
62  qSwap( mLabel, cat.mLabel );
63 }
64 
66 {
67  return mValue;
68 }
69 
71 {
72  return mSymbol.data();
73 }
74 
76 {
77  return mLabel;
78 }
79 
81 {
82  return mRender;
83 }
84 
85 void QgsRendererCategoryV2::setValue( const QVariant &value )
86 {
87  mValue = value;
88 }
89 
91 {
92  if ( mSymbol.data() != s ) mSymbol.reset( s );
93 }
94 
95 void QgsRendererCategoryV2::setLabel( const QString &label )
96 {
97  mLabel = label;
98 }
99 
101 {
102  mRender = render;
103 }
104 
106 {
107  return QString( "%1::%2::%3:%4\n" ).arg( mValue.toString() ).arg( mLabel ).arg( mSymbol->dump() ).arg( mRender );
108 }
109 
110 void QgsRendererCategoryV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
111 {
112  if ( !mSymbol.data() || props.value( "attribute", "" ).isEmpty() )
113  return;
114 
115  QString attrName = props[ "attribute" ];
116 
117  QDomElement ruleElem = doc.createElement( "se:Rule" );
118  element.appendChild( ruleElem );
119 
120  QDomElement nameElem = doc.createElement( "se:Name" );
121  nameElem.appendChild( doc.createTextNode( mLabel ) );
122  ruleElem.appendChild( nameElem );
123 
124  QDomElement descrElem = doc.createElement( "se:Description" );
125  QDomElement titleElem = doc.createElement( "se:Title" );
126  QString descrStr = QString( "%1 is '%2'" ).arg( attrName ).arg( mValue.toString() );
127  titleElem.appendChild( doc.createTextNode( !mLabel.isEmpty() ? mLabel : descrStr ) );
128  descrElem.appendChild( titleElem );
129  ruleElem.appendChild( descrElem );
130 
131  // create the ogc:Filter for the range
132  QString filterFunc = QString( "%1 = '%2'" )
133  .arg( attrName.replace( "\"", "\"\"" ) )
134  .arg( mValue.toString().replace( "'", "''" ) );
135  QgsSymbolLayerV2Utils::createFunctionElement( doc, ruleElem, filterFunc );
136 
137  mSymbol->toSld( doc, ruleElem, props );
138 }
139 
141 
143  : QgsFeatureRendererV2( "categorizedSymbol" )
144  , mAttrName( attrName )
145  , mCategories( categories )
146  , mInvertedColorRamp( false )
147  , mScaleMethod( DEFAULT_SCALE_METHOD )
148 {
149  for ( int i = 0; i < mCategories.count(); ++i )
150  {
152  if ( cat.symbol() == NULL )
153  {
154  QgsDebugMsg( "invalid symbol in a category! ignoring..." );
155  mCategories.removeAt( i-- );
156  }
157  //mCategories.insert(cat.value().toString(), cat);
158  }
159 }
160 
162 {
163 }
164 
166 {
167  mSymbolHash.clear();
168 
169  for ( int i = 0; i < mCategories.count(); ++i )
170  {
172  mSymbolHash.insert( cat.value().toString(), ( cat.renderState() || mCounting ) ? cat.symbol() : &sSkipRender );
173  }
174 }
175 
177 {
178  // TODO: special case for int, double
179  QHash<QString, QgsSymbolV2*>::iterator it = mSymbolHash.find( value.toString() );
180  if ( it == mSymbolHash.end() )
181  {
182  if ( mSymbolHash.count() == 0 )
183  {
184  QgsDebugMsg( "there are no hashed symbols!!!" );
185  }
186  else
187  {
188  QgsDebugMsgLevel( "attribute value not found: " + value.toString(), 3 );
189  }
190  return NULL;
191  }
192 
193  return *it;
194 }
195 
197 {
198  const QgsAttributes& attrs = feature.attributes();
199  QVariant value;
200  if ( mAttrNum == -1 )
201  {
202  Q_ASSERT( mExpression.data() );
203  value = mExpression->evaluate( &feature );
204  }
205  else
206  {
207  value = attrs.value( mAttrNum );
208  }
209 
210  // find the right symbol for the category
211  QgsSymbolV2 *symbol = symbolForValue( value );
212  if ( symbol == &sSkipRender )
213  return 0;
214 
215  if ( !symbol )
216  {
217  // if no symbol found use default one
218  return symbolForValue( QVariant( "" ) );
219  }
220 
221  if ( !mRotation.data() && !mSizeScale.data() )
222  return symbol; // no data-defined rotation/scaling - just return the symbol
223 
224  // find out rotation, size scale
225  const double rotation = mRotation.data() ? mRotation->evaluate( feature ).toDouble() : 0;
226  const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( feature ).toDouble() : 1.;
227 
228  // take a temporary symbol (or create it if doesn't exist)
229  QgsSymbolV2* tempSymbol = mTempSymbols[value.toString()];
230 
231  // modify the temporary symbol and return it
232  if ( tempSymbol->type() == QgsSymbolV2::Marker )
233  {
234  QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( tempSymbol );
235  if ( mRotation.data() ) markerSymbol->setAngle( rotation );
236  markerSymbol->setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
237  markerSymbol->setScaleMethod( mScaleMethod );
238  }
239  else if ( tempSymbol->type() == QgsSymbolV2::Line )
240  {
241  QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( tempSymbol );
242  lineSymbol->setWidth( sizeScale * static_cast<QgsLineSymbolV2*>( symbol )->width() );
243  }
244 
245  return tempSymbol;
246 }
247 
249 {
250  for ( int i = 0; i < mCategories.count(); i++ )
251  {
252  if ( mCategories[i].value() == val )
253  return i;
254  }
255  return -1;
256 }
257 
259 {
260  int idx = -1;
261  for ( int i = 0; i < mCategories.count(); i++ )
262  {
263  if ( mCategories[i].label() == val )
264  {
265  if ( idx != -1 )
266  return -1;
267  else
268  idx = i;
269  }
270  }
271  return idx;
272 }
273 
274 bool QgsCategorizedSymbolRendererV2::updateCategoryValue( int catIndex, const QVariant &value )
275 {
276  if ( catIndex < 0 || catIndex >= mCategories.size() )
277  return false;
278  mCategories[catIndex].setValue( value );
279  return true;
280 }
281 
283 {
284  if ( catIndex < 0 || catIndex >= mCategories.size() )
285  return false;
286  mCategories[catIndex].setSymbol( symbol );
287  return true;
288 }
289 
290 bool QgsCategorizedSymbolRendererV2::updateCategoryLabel( int catIndex, QString label )
291 {
292  if ( catIndex < 0 || catIndex >= mCategories.size() )
293  return false;
294  mCategories[catIndex].setLabel( label );
295  return true;
296 }
297 
299 {
300  if ( catIndex < 0 || catIndex >= mCategories.size() )
301  return false;
302  mCategories[catIndex].setRenderState( render );
303  return true;
304 }
305 
307 {
308  if ( !cat.symbol() )
309  {
310  QgsDebugMsg( "invalid symbol in a category! ignoring..." );
311  return;
312  }
313 
314  mCategories.append( cat );
315 }
316 
318 {
319  if ( catIndex < 0 || catIndex >= mCategories.size() )
320  return false;
321 
322  mCategories.removeAt( catIndex );
323  return true;
324 }
325 
327 {
328  mCategories.clear();
329 }
330 
332 {
333  if ( from < 0 || from >= mCategories.size() || to < 0 || to >= mCategories.size() ) return;
334  mCategories.move( from, to );
335 }
336 
338 {
339  return qgsVariantLessThan( c1.value(), c2.value() );
340 }
342 {
343  return qgsVariantGreaterThan( c1.value(), c2.value() );
344 }
345 
347 {
348  if ( order == Qt::AscendingOrder )
349  {
350  qSort( mCategories.begin(), mCategories.end(), valueLessThan );
351  }
352  else
353  {
354  qSort( mCategories.begin(), mCategories.end(), valueGreaterThan );
355  }
356 }
357 
359 {
360  return QString::localeAwareCompare( c1.label(), c2.label() ) < 0;
361 }
362 
364 {
365  return !labelLessThan( c1, c2 );
366 }
367 
369 {
370  if ( order == Qt::AscendingOrder )
371  {
372  qSort( mCategories.begin(), mCategories.end(), labelLessThan );
373  }
374  else
375  {
376  qSort( mCategories.begin(), mCategories.end(), labelGreaterThan );
377  }
378 }
379 
381 {
382  mCounting = context.rendererScale() == 0.0;
383 
384  // make sure that the hash table is up to date
385  rebuildHash();
386 
387  // find out classification attribute index from name
388  mAttrNum = fields.fieldNameIndex( mAttrName );
389  if ( mAttrNum == -1 )
390  {
391  mExpression.reset( new QgsExpression( mAttrName ) );
392  mExpression->prepare( fields );
393  }
394 
395  QgsCategoryList::iterator it = mCategories.begin();
396  for ( ; it != mCategories.end(); ++it )
397  {
398  it->symbol()->startRender( context, &fields );
399 
400  if ( mRotation.data() || mSizeScale.data() )
401  {
402  QgsSymbolV2* tempSymbol = it->symbol()->clone();
403  tempSymbol->setRenderHints(( mRotation.data() ? QgsSymbolV2::DataDefinedRotation : 0 ) |
405  tempSymbol->startRender( context, &fields );
406  mTempSymbols[ it->value().toString()] = tempSymbol;
407  }
408  }
409 }
410 
412 {
413  QgsCategoryList::iterator it = mCategories.begin();
414  for ( ; it != mCategories.end(); ++it )
415  it->symbol()->stopRender( context );
416 
417  // cleanup mTempSymbols
418  QHash<QString, QgsSymbolV2*>::iterator it2 = mTempSymbols.begin();
419  for ( ; it2 != mTempSymbols.end(); ++it2 )
420  {
421  it2.value()->stopRender( context );
422  delete it2.value();
423  }
424  mTempSymbols.clear();
425  mExpression.reset();
426 }
427 
429 {
430  QSet<QString> attributes;
431 
432  // mAttrName can contain either attribute name or an expression.
433  // Sometimes it is not possible to distinguish between those two,
434  // e.g. "a - b" can be both a valid attribute name or expression.
435  // Since we do not have access to fields here, try both options.
436  attributes << mAttrName;
437 
438  QgsExpression testExpr( mAttrName );
439  if ( !testExpr.hasParserError() )
440  attributes.unite( testExpr.referencedColumns().toSet() );
441 
442  if ( mRotation.data() ) attributes.unite( mRotation->referencedColumns().toSet() );
443  if ( mSizeScale.data() ) attributes.unite( mSizeScale->referencedColumns().toSet() );
444 
445  QgsCategoryList::const_iterator catIt = mCategories.constBegin();
446  for ( ; catIt != mCategories.constEnd(); ++catIt )
447  {
448  QgsSymbolV2* catSymbol = catIt->symbol();
449  if ( catSymbol )
450  {
451  attributes.unite( catSymbol->usedAttributes() );
452  }
453  }
454  return attributes.toList();
455 }
456 
458 {
459  QString s = QString( "CATEGORIZED: idx %1\n" ).arg( mAttrName );
460  for ( int i = 0; i < mCategories.count(); i++ )
461  s += mCategories[i].dump();
462  return s;
463 }
464 
466 {
468  if ( mSourceSymbol.data() )
469  r->setSourceSymbol( mSourceSymbol->clone() );
470  if ( mSourceColorRamp.data() )
471  {
472  r->setSourceColorRamp( mSourceColorRamp->clone() );
474  }
478  r->setScaleMethod( scaleMethod() );
479  return r;
480 }
481 
482 void QgsCategorizedSymbolRendererV2::toSld( QDomDocument &doc, QDomElement &element ) const
483 {
484  QgsStringMap props;
485  props[ "attribute" ] = mAttrName;
486  if ( mRotation.data() )
487  props[ "angle" ] = mRotation->expression();
488  if ( mSizeScale.data() )
489  props[ "scale" ] = mSizeScale->expression();
490 
491  // create a Rule for each range
492  for ( QgsCategoryList::const_iterator it = mCategories.constBegin(); it != mCategories.constEnd(); ++it )
493  {
494  QgsStringMap catProps( props );
495  it->toSld( doc, element, catProps );
496  }
497 }
498 
500 {
501  QgsSymbolV2List lst;
502  for ( int i = 0; i < mCategories.count(); i++ )
503  lst.append( mCategories[i].symbol() );
504  return lst;
505 }
506 
508 {
509  QDomElement symbolsElem = element.firstChildElement( "symbols" );
510  if ( symbolsElem.isNull() )
511  return NULL;
512 
513  QDomElement catsElem = element.firstChildElement( "categories" );
514  if ( catsElem.isNull() )
515  return NULL;
516 
517  QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
518  QgsCategoryList cats;
519 
520  QDomElement catElem = catsElem.firstChildElement();
521  while ( !catElem.isNull() )
522  {
523  if ( catElem.tagName() == "category" )
524  {
525  QVariant value = QVariant( catElem.attribute( "value" ) );
526  QString symbolName = catElem.attribute( "symbol" );
527  QString label = catElem.attribute( "label" );
528  bool render = catElem.attribute( "render" ) != "false";
529  if ( symbolMap.contains( symbolName ) )
530  {
531  QgsSymbolV2* symbol = symbolMap.take( symbolName );
532  cats.append( QgsRendererCategoryV2( value, symbol, label, render ) );
533  }
534  }
535  catElem = catElem.nextSiblingElement();
536  }
537 
538  QString attrName = element.attribute( "attr" );
539 
541 
542  // delete symbols if there are any more
544 
545  // try to load source symbol (optional)
546  QDomElement sourceSymbolElem = element.firstChildElement( "source-symbol" );
547  if ( !sourceSymbolElem.isNull() )
548  {
549  QgsSymbolV2Map sourceSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( sourceSymbolElem );
550  if ( sourceSymbolMap.contains( "0" ) )
551  {
552  r->setSourceSymbol( sourceSymbolMap.take( "0" ) );
553  }
554  QgsSymbolLayerV2Utils::clearSymbolMap( sourceSymbolMap );
555  }
556 
557  // try to load color ramp (optional)
558  QDomElement sourceColorRampElem = element.firstChildElement( "colorramp" );
559  if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
560  {
561  r->setSourceColorRamp( QgsSymbolLayerV2Utils::loadColorRamp( sourceColorRampElem ) );
562  QDomElement invertedColorRampElem = element.firstChildElement( "invertedcolorramp" );
563  if ( !invertedColorRampElem.isNull() )
564  r->setInvertedColorRamp( invertedColorRampElem.attribute( "value" ) == "1" );
565  }
566 
567  QDomElement rotationElem = element.firstChildElement( "rotation" );
568  if ( !rotationElem.isNull() )
569  r->setRotationField( rotationElem.attribute( "field" ) );
570 
571  QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
572  if ( !sizeScaleElem.isNull() )
573  {
574  r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
575  r->setScaleMethod( QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ) );
576  }
577 
578  // TODO: symbol levels
579  return r;
580 }
581 
582 QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )
583 {
584  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
585  rendererElem.setAttribute( "type", "categorizedSymbol" );
586  rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
587  rendererElem.setAttribute( "attr", mAttrName );
588 
589  // categories
590  int i = 0;
592  QDomElement catsElem = doc.createElement( "categories" );
593  QgsCategoryList::const_iterator it = mCategories.constBegin();
594  for ( ; it != mCategories.end(); ++it )
595  {
596  const QgsRendererCategoryV2& cat = *it;
597  QString symbolName = QString::number( i );
598  symbols.insert( symbolName, cat.symbol() );
599 
600  QDomElement catElem = doc.createElement( "category" );
601  catElem.setAttribute( "value", cat.value().toString() );
602  catElem.setAttribute( "symbol", symbolName );
603  catElem.setAttribute( "label", cat.label() );
604  catElem.setAttribute( "render", cat.renderState() ? "true" : "false" );
605  catsElem.appendChild( catElem );
606  i++;
607  }
608 
609  rendererElem.appendChild( catsElem );
610 
611  // save symbols
612  QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
613  rendererElem.appendChild( symbolsElem );
614 
615  // save source symbol
616  if ( mSourceSymbol.data() )
617  {
618  QgsSymbolV2Map sourceSymbols;
619  sourceSymbols.insert( "0", mSourceSymbol.data() );
620  QDomElement sourceSymbolElem = QgsSymbolLayerV2Utils::saveSymbols( sourceSymbols, "source-symbol", doc );
621  rendererElem.appendChild( sourceSymbolElem );
622  }
623 
624  // save source color ramp
625  if ( mSourceColorRamp.data() )
626  {
627  QDomElement colorRampElem = QgsSymbolLayerV2Utils::saveColorRamp( "[source]", mSourceColorRamp.data(), doc );
628  rendererElem.appendChild( colorRampElem );
629  QDomElement invertedElem = doc.createElement( "invertedcolorramp" );
630  invertedElem.setAttribute( "value", mInvertedColorRamp );
631  rendererElem.appendChild( invertedElem );
632  }
633 
634  QDomElement rotationElem = doc.createElement( "rotation" );
635  if ( mRotation.data() )
636  rotationElem.setAttribute( "field", QgsSymbolLayerV2Utils::fieldOrExpressionFromExpression( mRotation.data() ) );
637  rendererElem.appendChild( rotationElem );
638 
639  QDomElement sizeScaleElem = doc.createElement( "sizescale" );
640  if ( mSizeScale.data() )
641  sizeScaleElem.setAttribute( "field", QgsSymbolLayerV2Utils::fieldOrExpressionFromExpression( mSizeScale.data() ) );
642  sizeScaleElem.setAttribute( "scalemethod", QgsSymbolLayerV2Utils::encodeScaleMethod( mScaleMethod ) );
643  rendererElem.appendChild( sizeScaleElem );
644 
645  return rendererElem;
646 }
647 
649 {
651  int count = categories().count();
652  for ( int i = 0; i < count; i++ )
653  {
654  const QgsRendererCategoryV2& cat = categories()[i];
655  QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( cat.symbol(), iconSize );
656  lst << qMakePair( cat.label(), pix );
657  }
658  return lst;
659 }
660 
662 {
663  Q_UNUSED( scaleDenominator );
665 
666  foreach ( const QgsRendererCategoryV2& cat, mCategories )
667  {
668  if ( rule.isEmpty() || cat.label() == rule )
669  {
670  lst << qMakePair( cat.label(), cat.symbol() );
671  }
672  }
673  return lst;
674 }
675 
676 
678 {
679  return mSourceSymbol.data();
680 }
682 {
683  mSourceSymbol.reset( sym );
684 }
685 
687 {
688  return mSourceColorRamp.data();
689 }
691 {
692  mSourceColorRamp.reset( ramp );
693 }
694 
695 void QgsCategorizedSymbolRendererV2::setRotationField( QString fieldOrExpression )
696 {
698 }
699 
701 {
702  return mRotation.data() ? QgsSymbolLayerV2Utils::fieldOrExpressionFromExpression( mRotation.data() ) : QString();
703 }
704 
705 void QgsCategorizedSymbolRendererV2::setSizeScaleField( QString fieldOrExpression )
706 {
708 }
709 
711 {
713 }
714 
716 {
717  int i = 0;
718  foreach ( QgsRendererCategoryV2 cat, mCategories )
719  {
720  QgsSymbolV2* symbol = sym->clone();
721  symbol->setColor( cat.symbol()->color() );
722  updateCategorySymbol( i, symbol );
723  ++i;
724  }
725 }
726 
728 {
730  QgsCategoryList::const_iterator catIt = mCategories.constBegin();
731  for ( ; catIt != mCategories.constEnd(); ++catIt )
732  {
733  setScaleMethodToSymbol( catIt->symbol(), scaleMethod );
734  }
735 }
736 
738 {
739  return true;
740 }
741 
743 {
744  bool ok;
745  int index = key.toInt( &ok );
746  if ( ok && index >= 0 && index < mCategories.size() )
747  return mCategories[ index ].renderState();
748  else
749  return true;
750 }
751 
753 {
754  bool ok;
755  int index = key.toInt( &ok );
756  if ( ok )
757  updateCategoryRenderState( index, state );
758 }
759 
QMap< QString, QgsSymbolV2 * > QgsSymbolV2Map
Definition: qgsrendererv2.h:38
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:89
static QgsSymbolV2Map loadSymbols(QDomElement &element)
void setValue(const QVariant &value)
void setLabel(const QString &label)
#define RENDERER_TAG_NAME
Definition: qgsrendererv2.h:46
static unsigned index
virtual QgsFeatureRendererV2 * clone()
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.h:96
const QgsCategoryList & categories() const
static QgsVectorColorRampV2 * loadColorRamp(QDomElement &element)
QList< QgsSymbolV2 * > QgsSymbolV2List
Definition: qgsrendererv2.h:37
SymbolType type() const
Definition: qgssymbolv2.h:79
void setRotationField(QString fieldOrExpression)
QSet< QString > usedAttributes() const
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name - case insensitive TODO: sort out case sensitive (indexFromName()) vs...
Definition: qgsfield.cpp:186
double rendererScale() const
virtual QgsSymbolV2 * clone() const =0
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
int categoryIndexForLabel(QString val)
return index of category with specified label (-1 if not found or not unique)
QScopedPointer< QgsSymbolV2 > mSourceSymbol
virtual QgsSymbolV2List symbols()
for symbol levels
bool updateCategoryRenderState(int catIndex, bool render)
virtual QString dump() const
for debugging
QScopedPointer< QgsExpression > mRotation
virtual void checkLegendSymbolItem(QString key, bool state=true)
item in symbology was checked
Container of fields for a vector layer.
Definition: qgsfield.h:163
void moveCategory(int from, int to)
Moves the category at index position from to index position to.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Definition: qgis.cpp:237
void setSizeScaleField(QString fieldOrExpression)
QScopedPointer< QgsSymbolV2 > mSymbol
QMap< QString, QString > QgsStringMap
Definition: qgis.h:416
void setSourceColorRamp(QgsVectorColorRampV2 *ramp)
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Definition: qgis.cpp:210
void setWidth(double width)
QHash< QString, QgsSymbolV2 * > mSymbolHash
hashtable for faster access to symbols
QScopedPointer< QgsExpression > mSizeScale
virtual bool legendSymbolItemChecked(QString key)
item in symbology was checked
void sortByLabel(Qt::SortOrder order=Qt::AscendingOrder)
void setColor(const QColor &color)
QList< QgsRendererCategoryV2 > QgsCategoryList
static QDomElement saveColorRamp(QString name, QgsVectorColorRampV2 *ramp, QDomDocument &doc)
QScopedPointer< QgsVectorColorRampV2 > mSourceColorRamp
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:37
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
bool labelGreaterThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
#define DEFAULT_SCALE_METHOD
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, QString function)
QgsSymbolV2 * symbolForValue(QVariant value)
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule=QString())
return a list of item text / symbol
static QDomElement saveSymbols(QgsSymbolV2Map &symbols, QString tagName, QDomDocument &doc)
static QgsFeatureRendererV2 * create(QDomElement &element)
create renderer from XML element
QStringList referencedColumns()
Get list of columns referenced by the expression.
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature)
to be overridden
int categoryIndexForValue(QVariant val)
return index of category with specified value (-1 if not found)
void setAngle(double angle)
const QgsAttributes & attributes() const
Definition: qgsfeature.h:142
void setSize(double size)
virtual void stopRender(QgsRenderContext &context)
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
bool labelLessThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
QHash< QString, QgsSymbolV2 * > mTempSymbols
temporary symbols, used for data-defined rotation and scaling
QList< QPair< QString, QPixmap > > QgsLegendSymbologyList
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props) const
bool updateCategoryLabel(int catIndex, QString label)
void setUsingSymbolLevels(bool usingSymbolLevels)
bool valueLessThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
Contains information about the context of a rendering operation.
QgsCategorizedSymbolRendererV2(QString attrName=QString(), QgsCategoryList categories=QgsCategoryList())
static QgsExpression * fieldOrExpressionToExpression(const QString &fieldOrExpression)
Return a new valid expression instance for given field or expression string.
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:100
virtual QDomElement save(QDomDocument &doc)
store renderer info to XML element
static QString encodeScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
bool updateCategoryValue(int catIndex, const QVariant &value)
bool valueGreaterThan(const QgsRendererCategoryV2 &c1, const QgsRendererCategoryV2 &c2)
static QString fieldOrExpressionFromExpression(QgsExpression *expression)
Return a field name if the whole expression is just a name of the field .
bool usingSymbolLevels() const
void setScaleMethodToSymbol(QgsSymbolV2 *symbol, int scaleMethod)
bool updateCategorySymbol(int catIndex, QgsSymbolV2 *symbol)
int mAttrNum
attribute index (derived from attribute name in startRender)
static QPixmap symbolPreviewPixmap(QgsSymbolV2 *symbol, QSize size)
void setRenderHints(int hints)
Definition: qgssymbolv2.h:133
static void clearSymbolMap(QgsSymbolV2Map &symbols)
static QgsSymbolV2::ScaleMethod decodeScaleMethod(QString str)
void swap(QgsRendererCategoryV2 &other)
QgsRendererCategoryV2 & operator=(QgsRendererCategoryV2 cat)
QgsSymbolV2::ScaleMethod scaleMethod() const
virtual bool legendSymbolItemsCheckable() const
items of symbology items in legend should be checkable
void addCategory(const QgsRendererCategoryV2 &category)
virtual void toSld(QDomDocument &doc, QDomElement &element) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
double size
Definition: qgssvgcache.cpp:77
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
Definition: qgsrendererv2.h:41
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
QScopedPointer< QgsExpression > mExpression
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
QColor color() const