QGIS API Documentation  2.4.0-Chugiak
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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 )
36  : mValue( value )
37  , mSymbol( symbol )
38  , mLabel( label )
39 {
40 }
41 
43  : mValue( cat.mValue )
44  , mSymbol( cat.mSymbol.data() ? cat.mSymbol->clone() : NULL )
45  , mLabel( cat.mLabel )
46 {
47 }
48 
49 // copy+swap idion, the copy is done through the 'pass by value'
51 {
52  swap( cat );
53  return *this;
54 }
55 
57 {
58  qSwap( mValue, cat.mValue );
59  qSwap( mSymbol, cat.mSymbol );
60  qSwap( mLabel, cat.mLabel );
61 }
62 
64 {
65  return mValue;
66 }
67 
69 {
70  return mSymbol.data();
71 }
72 
74 {
75  return mLabel;
76 }
77 
78 void QgsRendererCategoryV2::setValue( const QVariant &value )
79 {
80  mValue = value;
81 }
82 
84 {
85  if ( mSymbol.data() != s ) mSymbol.reset( s );
86 }
87 
88 void QgsRendererCategoryV2::setLabel( const QString &label )
89 {
90  mLabel = label;
91 }
92 
94 {
95  return QString( "%1::%2::%3\n" ).arg( mValue.toString() ).arg( mLabel ).arg( mSymbol->dump() );
96 }
97 
98 void QgsRendererCategoryV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
99 {
100  if ( !mSymbol.data() || props.value( "attribute", "" ).isEmpty() )
101  return;
102 
103  QString attrName = props[ "attribute" ];
104 
105  QDomElement ruleElem = doc.createElement( "se:Rule" );
106  element.appendChild( ruleElem );
107 
108  QDomElement nameElem = doc.createElement( "se:Name" );
109  nameElem.appendChild( doc.createTextNode( mLabel ) );
110  ruleElem.appendChild( nameElem );
111 
112  QDomElement descrElem = doc.createElement( "se:Description" );
113  QDomElement titleElem = doc.createElement( "se:Title" );
114  QString descrStr = QString( "%1 is '%2'" ).arg( attrName ).arg( mValue.toString() );
115  titleElem.appendChild( doc.createTextNode( !mLabel.isEmpty() ? mLabel : descrStr ) );
116  descrElem.appendChild( titleElem );
117  ruleElem.appendChild( descrElem );
118 
119  // create the ogc:Filter for the range
120  QString filterFunc = QString( "%1 = '%2'" )
121  .arg( attrName.replace( "\"", "\"\"" ) )
122  .arg( mValue.toString().replace( "'", "''" ) );
123  QgsSymbolLayerV2Utils::createFunctionElement( doc, ruleElem, filterFunc );
124 
125  mSymbol->toSld( doc, ruleElem, props );
126 }
127 
129 
131  : QgsFeatureRendererV2( "categorizedSymbol" )
132  , mAttrName( attrName )
133  , mCategories( categories )
134  , mInvertedColorRamp( false )
135  , mScaleMethod( DEFAULT_SCALE_METHOD )
136 {
137  for ( int i = 0; i < mCategories.count(); ++i )
138  {
140  if ( cat.symbol() == NULL )
141  {
142  QgsDebugMsg( "invalid symbol in a category! ignoring..." );
143  mCategories.removeAt( i-- );
144  }
145  //mCategories.insert(cat.value().toString(), cat);
146  }
147 }
148 
150 {
151 }
152 
154 {
155  mSymbolHash.clear();
156 
157  for ( int i = 0; i < mCategories.count(); ++i )
158  {
160  mSymbolHash.insert( cat.value().toString(), cat.symbol() );
161  }
162 }
163 
165 {
166  // TODO: special case for int, double
167  QHash<QString, QgsSymbolV2*>::iterator it = mSymbolHash.find( value.toString() );
168  if ( it == mSymbolHash.end() )
169  {
170  if ( mSymbolHash.count() == 0 )
171  {
172  QgsDebugMsg( "there are no hashed symbols!!!" );
173  }
174  else
175  {
176  QgsDebugMsgLevel( "attribute value not found: " + value.toString(), 3 );
177  }
178  return NULL;
179  }
180 
181  return *it;
182 }
183 
185 {
186  const QgsAttributes& attrs = feature.attributes();
187  QVariant value;
188  if ( mAttrNum == -1 )
189  {
190  Q_ASSERT( mExpression.data() );
191  value = mExpression->evaluate( &feature );
192  }
193  else
194  {
195  value = attrs.value( mAttrNum );
196  }
197 
198  // find the right symbol for the category
199  QgsSymbolV2* symbol = symbolForValue( value );
200  if ( symbol == NULL )
201  {
202  // if no symbol found use default one
203  return symbolForValue( QVariant( "" ) );
204  }
205 
206  if ( !mRotation.data() && !mSizeScale.data() )
207  return symbol; // no data-defined rotation/scaling - just return the symbol
208 
209  // find out rotation, size scale
210  const double rotation = mRotation.data() ? mRotation->evaluate( feature ).toDouble() : 0;
211  const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( feature ).toDouble() : 1.;
212 
213  // take a temporary symbol (or create it if doesn't exist)
214  QgsSymbolV2* tempSymbol = mTempSymbols[value.toString()];
215 
216  // modify the temporary symbol and return it
217  if ( tempSymbol->type() == QgsSymbolV2::Marker )
218  {
219  QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( tempSymbol );
220  if ( mRotation.data() ) markerSymbol->setAngle( rotation );
221  markerSymbol->setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
222  markerSymbol->setScaleMethod( mScaleMethod );
223  }
224  else if ( tempSymbol->type() == QgsSymbolV2::Line )
225  {
226  QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( tempSymbol );
227  lineSymbol->setWidth( sizeScale * static_cast<QgsLineSymbolV2*>( symbol )->width() );
228  }
229 
230  return tempSymbol;
231 }
232 
234 {
235  for ( int i = 0; i < mCategories.count(); i++ )
236  {
237  if ( mCategories[i].value() == val )
238  return i;
239  }
240  return -1;
241 }
242 
243 bool QgsCategorizedSymbolRendererV2::updateCategoryValue( int catIndex, const QVariant &value )
244 {
245  if ( catIndex < 0 || catIndex >= mCategories.size() )
246  return false;
247  mCategories[catIndex].setValue( value );
248  return true;
249 }
250 
252 {
253  if ( catIndex < 0 || catIndex >= mCategories.size() )
254  return false;
255  mCategories[catIndex].setSymbol( symbol );
256  return true;
257 }
258 
259 bool QgsCategorizedSymbolRendererV2::updateCategoryLabel( int catIndex, QString label )
260 {
261  if ( catIndex < 0 || catIndex >= mCategories.size() )
262  return false;
263  mCategories[catIndex].setLabel( label );
264  return true;
265 }
266 
268 {
269  if ( cat.symbol() == NULL )
270  {
271  QgsDebugMsg( "invalid symbol in a category! ignoring..." );
272  }
273  else
274  {
275  mCategories.append( cat );
276  }
277 }
278 
280 {
281  if ( catIndex < 0 || catIndex >= mCategories.size() )
282  return false;
283 
284  mCategories.removeAt( catIndex );
285  return true;
286 }
287 
289 {
290  mCategories.clear();
291 }
292 
294 {
295  if ( from < 0 || from >= mCategories.size() || to < 0 || to >= mCategories.size() ) return;
296  mCategories.move( from, to );
297 }
298 
300 {
301  return qgsVariantLessThan( c1.value(), c2.value() );
302 }
304 {
305  return qgsVariantGreaterThan( c1.value(), c2.value() );
306 }
307 
309 {
310  if ( order == Qt::AscendingOrder )
311  {
312  qSort( mCategories.begin(), mCategories.end(), valueLessThan );
313  }
314  else
315  {
316  qSort( mCategories.begin(), mCategories.end(), valueGreaterThan );
317  }
318 }
319 
321 {
322  return QString::localeAwareCompare( c1.label(), c2.label() ) < 0;
323 }
324 
326 {
327  return !labelLessThan( c1, c2 );
328 }
329 
331 {
332  if ( order == Qt::AscendingOrder )
333  {
334  qSort( mCategories.begin(), mCategories.end(), labelLessThan );
335  }
336  else
337  {
338  qSort( mCategories.begin(), mCategories.end(), labelGreaterThan );
339  }
340 }
341 
343 {
344  // make sure that the hash table is up to date
345  rebuildHash();
346 
347  // find out classification attribute index from name
348  mAttrNum = fields.fieldNameIndex( mAttrName );
349  if ( mAttrNum == -1 )
350  {
351  mExpression.reset( new QgsExpression( mAttrName ) );
352  mExpression->prepare( fields );
353  }
354 
355  QgsCategoryList::iterator it = mCategories.begin();
356  for ( ; it != mCategories.end(); ++it )
357  {
358  it->symbol()->startRender( context, &fields );
359 
360  if ( mRotation.data() || mSizeScale.data() )
361  {
362  QgsSymbolV2* tempSymbol = it->symbol()->clone();
363  tempSymbol->setRenderHints(( mRotation.data() ? QgsSymbolV2::DataDefinedRotation : 0 ) |
365  tempSymbol->startRender( context, &fields );
366  mTempSymbols[ it->value().toString()] = tempSymbol;
367  }
368  }
369 
370 }
371 
373 {
374  QgsCategoryList::iterator it = mCategories.begin();
375  for ( ; it != mCategories.end(); ++it )
376  it->symbol()->stopRender( context );
377 
378  // cleanup mTempSymbols
379  QHash<QString, QgsSymbolV2*>::iterator it2 = mTempSymbols.begin();
380  for ( ; it2 != mTempSymbols.end(); ++it2 )
381  {
382  it2.value()->stopRender( context );
383  delete it2.value();
384  }
385  mTempSymbols.clear();
386  mExpression.reset();
387 }
388 
390 {
391  QSet<QString> attributes;
392 
393  // mAttrName can contain either attribute name or an expression.
394  // Sometimes it is not possible to distinguish between those two,
395  // e.g. "a - b" can be both a valid attribute name or expression.
396  // Since we do not have access to fields here, try both options.
397  attributes << mAttrName;
398 
399  QgsExpression testExpr( mAttrName );
400  if ( !testExpr.hasParserError() )
401  attributes.unite( testExpr.referencedColumns().toSet() );
402 
403  if ( mRotation.data() ) attributes.unite( mRotation->referencedColumns().toSet() );
404  if ( mSizeScale.data() ) attributes.unite( mSizeScale->referencedColumns().toSet() );
405 
406  QgsCategoryList::const_iterator catIt = mCategories.constBegin();
407  for ( ; catIt != mCategories.constEnd(); ++catIt )
408  {
409  QgsSymbolV2* catSymbol = catIt->symbol();
410  if ( catSymbol )
411  {
412  attributes.unite( catSymbol->usedAttributes() );
413  }
414  }
415  return attributes.toList();
416 }
417 
419 {
420  QString s = QString( "CATEGORIZED: idx %1\n" ).arg( mAttrName );
421  for ( int i = 0; i < mCategories.count(); i++ )
422  s += mCategories[i].dump();
423  return s;
424 }
425 
427 {
429  if ( mSourceSymbol.data() )
430  r->setSourceSymbol( mSourceSymbol->clone() );
431  if ( mSourceColorRamp.data() )
432  {
433  r->setSourceColorRamp( mSourceColorRamp->clone() );
435  }
439  r->setScaleMethod( scaleMethod() );
440  return r;
441 }
442 
443 void QgsCategorizedSymbolRendererV2::toSld( QDomDocument &doc, QDomElement &element ) const
444 {
445  QgsStringMap props;
446  props[ "attribute" ] = mAttrName;
447  if ( mRotation.data() )
448  props[ "angle" ] = mRotation->expression();
449  if ( mSizeScale.data() )
450  props[ "scale" ] = mSizeScale->expression();
451 
452  // create a Rule for each range
453  for ( QgsCategoryList::const_iterator it = mCategories.constBegin(); it != mCategories.constEnd(); ++it )
454  {
455  QgsStringMap catProps( props );
456  it->toSld( doc, element, catProps );
457  }
458 }
459 
461 {
462  QgsSymbolV2List lst;
463  for ( int i = 0; i < mCategories.count(); i++ )
464  lst.append( mCategories[i].symbol() );
465  return lst;
466 }
467 
469 {
470  QDomElement symbolsElem = element.firstChildElement( "symbols" );
471  if ( symbolsElem.isNull() )
472  return NULL;
473 
474  QDomElement catsElem = element.firstChildElement( "categories" );
475  if ( catsElem.isNull() )
476  return NULL;
477 
478  QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
479  QgsCategoryList cats;
480 
481  QDomElement catElem = catsElem.firstChildElement();
482  while ( !catElem.isNull() )
483  {
484  if ( catElem.tagName() == "category" )
485  {
486  QVariant value = QVariant( catElem.attribute( "value" ) );
487  QString symbolName = catElem.attribute( "symbol" );
488  QString label = catElem.attribute( "label" );
489  if ( symbolMap.contains( symbolName ) )
490  {
491  QgsSymbolV2* symbol = symbolMap.take( symbolName );
492  cats.append( QgsRendererCategoryV2( value, symbol, label ) );
493  }
494  }
495  catElem = catElem.nextSiblingElement();
496  }
497 
498  QString attrName = element.attribute( "attr" );
499 
501 
502  // delete symbols if there are any more
504 
505  // try to load source symbol (optional)
506  QDomElement sourceSymbolElem = element.firstChildElement( "source-symbol" );
507  if ( !sourceSymbolElem.isNull() )
508  {
509  QgsSymbolV2Map sourceSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( sourceSymbolElem );
510  if ( sourceSymbolMap.contains( "0" ) )
511  {
512  r->setSourceSymbol( sourceSymbolMap.take( "0" ) );
513  }
514  QgsSymbolLayerV2Utils::clearSymbolMap( sourceSymbolMap );
515  }
516 
517  // try to load color ramp (optional)
518  QDomElement sourceColorRampElem = element.firstChildElement( "colorramp" );
519  if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
520  {
521  r->setSourceColorRamp( QgsSymbolLayerV2Utils::loadColorRamp( sourceColorRampElem ) );
522  QDomElement invertedColorRampElem = element.firstChildElement( "invertedcolorramp" );
523  if ( !invertedColorRampElem.isNull() )
524  r->setInvertedColorRamp( invertedColorRampElem.attribute( "value" ) == "1" );
525  }
526 
527  QDomElement rotationElem = element.firstChildElement( "rotation" );
528  if ( !rotationElem.isNull() )
529  r->setRotationField( rotationElem.attribute( "field" ) );
530 
531  QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
532  if ( !sizeScaleElem.isNull() )
533  {
534  r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
535  r->setScaleMethod( QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ) );
536  }
537 
538  // TODO: symbol levels
539  return r;
540 }
541 
542 QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )
543 {
544  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
545  rendererElem.setAttribute( "type", "categorizedSymbol" );
546  rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
547  rendererElem.setAttribute( "attr", mAttrName );
548 
549  // categories
550  int i = 0;
552  QDomElement catsElem = doc.createElement( "categories" );
553  QgsCategoryList::const_iterator it = mCategories.constBegin();
554  for ( ; it != mCategories.end(); ++it )
555  {
556  const QgsRendererCategoryV2& cat = *it;
557  QString symbolName = QString::number( i );
558  symbols.insert( symbolName, cat.symbol() );
559 
560  QDomElement catElem = doc.createElement( "category" );
561  catElem.setAttribute( "value", cat.value().toString() );
562  catElem.setAttribute( "symbol", symbolName );
563  catElem.setAttribute( "label", cat.label() );
564  catsElem.appendChild( catElem );
565  i++;
566  }
567 
568  rendererElem.appendChild( catsElem );
569 
570  // save symbols
571  QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
572  rendererElem.appendChild( symbolsElem );
573 
574  // save source symbol
575  if ( mSourceSymbol.data() )
576  {
577  QgsSymbolV2Map sourceSymbols;
578  sourceSymbols.insert( "0", mSourceSymbol.data() );
579  QDomElement sourceSymbolElem = QgsSymbolLayerV2Utils::saveSymbols( sourceSymbols, "source-symbol", doc );
580  rendererElem.appendChild( sourceSymbolElem );
581  }
582 
583  // save source color ramp
584  if ( mSourceColorRamp.data() )
585  {
586  QDomElement colorRampElem = QgsSymbolLayerV2Utils::saveColorRamp( "[source]", mSourceColorRamp.data(), doc );
587  rendererElem.appendChild( colorRampElem );
588  QDomElement invertedElem = doc.createElement( "invertedcolorramp" );
589  invertedElem.setAttribute( "value", mInvertedColorRamp );
590  rendererElem.appendChild( invertedElem );
591  }
592 
593  QDomElement rotationElem = doc.createElement( "rotation" );
594  if ( mRotation.data() )
595  rotationElem.setAttribute( "field", QgsSymbolLayerV2Utils::fieldOrExpressionFromExpression( mRotation.data() ) );
596  rendererElem.appendChild( rotationElem );
597 
598  QDomElement sizeScaleElem = doc.createElement( "sizescale" );
599  if ( mSizeScale.data() )
600  sizeScaleElem.setAttribute( "field", QgsSymbolLayerV2Utils::fieldOrExpressionFromExpression( mSizeScale.data() ) );
601  sizeScaleElem.setAttribute( "scalemethod", QgsSymbolLayerV2Utils::encodeScaleMethod( mScaleMethod ) );
602  rendererElem.appendChild( sizeScaleElem );
603 
604  return rendererElem;
605 }
606 
608 {
609  QSettings settings;
610  bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
611 
613  if ( showClassifiers )
614  {
615  lst << qMakePair( classAttribute(), QPixmap() );
616  }
617 
618  int count = categories().count();
619  for ( int i = 0; i < count; i++ )
620  {
621  const QgsRendererCategoryV2& cat = categories()[i];
622  QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( cat.symbol(), iconSize );
623  lst << qMakePair( cat.label(), pix );
624  }
625  return lst;
626 }
627 
629 {
630  Q_UNUSED( scaleDenominator );
631  QSettings settings;
632  bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
633 
635  if ( showClassifiers )
636  {
637  lst << qMakePair( classAttribute(), ( QgsSymbolV2* )0 );
638  }
639 
640  foreach ( const QgsRendererCategoryV2& cat, mCategories )
641  {
642  if ( rule.isEmpty() || cat.label() == rule )
643  {
644  lst << qMakePair( cat.label(), cat.symbol() );
645  }
646  }
647  return lst;
648 }
649 
650 
652 {
653  return mSourceSymbol.data();
654 }
656 {
657  mSourceSymbol.reset( sym );
658 }
659 
661 {
662  return mSourceColorRamp.data();
663 }
665 {
666  mSourceColorRamp.reset( ramp );
667 }
668 
669 void QgsCategorizedSymbolRendererV2::setRotationField( QString fieldOrExpression )
670 {
672 }
673 
675 {
676  return mRotation.data() ? QgsSymbolLayerV2Utils::fieldOrExpressionFromExpression( mRotation.data() ) : QString();
677 }
678 
679 void QgsCategorizedSymbolRendererV2::setSizeScaleField( QString fieldOrExpression )
680 {
682 }
683 
685 {
687 }
688 
690 {
691  int i = 0;
692  foreach ( QgsRendererCategoryV2 cat, mCategories )
693  {
694  QgsSymbolV2* symbol = sym->clone();
695  symbol->setColor( cat.symbol()->color() );
696  updateCategorySymbol( i, symbol );
697  ++i;
698  }
699 }
700 
702 {
704  QgsCategoryList::const_iterator catIt = mCategories.constBegin();
705  for ( ; catIt != mCategories.constEnd(); ++catIt )
706  {
707  setScaleMethodToSymbol( catIt->symbol(), scaleMethod );
708  }
709 }
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:43
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:175
virtual QgsSymbolV2 * clone() const =0
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
QScopedPointer< QgsSymbolV2 > mSourceSymbol
virtual QgsSymbolV2List symbols()
for symbol levels
virtual QString dump() const
for debugging
QScopedPointer< QgsExpression > mRotation
Container of fields for a vector layer.
Definition: qgsfield.h:161
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
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:130
static void clearSymbolMap(QgsSymbolV2Map &symbols)
static QgsSymbolV2::ScaleMethod decodeScaleMethod(QString str)
void swap(QgsRendererCategoryV2 &other)
QgsRendererCategoryV2 & operator=(QgsRendererCategoryV2 cat)
QgsSymbolV2::ScaleMethod scaleMethod() const
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