QGIS API Documentation  2.8.6-Wien
qgspointdisplacementrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointdisplacementrenderer.cpp
3  --------------------------------
4  begin : January 26, 2010
5  copyright : (C) 2010 by Marco Hugentobler
6  email : marco at hugis dot net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsgeometry.h"
20 #include "qgslogger.h"
21 #include "qgsspatialindex.h"
22 #include "qgssymbolv2.h"
23 #include "qgssymbollayerv2utils.h"
24 #include "qgsvectorlayer.h"
26 
27 #include <QDomElement>
28 #include <QPainter>
29 
30 #include <cmath>
31 
33  : QgsFeatureRendererV2( "pointDisplacement" )
34  , mLabelAttributeName( labelAttributeName )
35  , mLabelIndex( -1 )
36  , mTolerance( 0.00001 )
37  , mCircleWidth( 0.4 )
38  , mCircleColor( QColor( 125, 125, 125 ) )
39  , mCircleRadiusAddition( 0 )
40  , mMaxLabelScaleDenominator( -1 )
41  , mSpatialIndex( NULL )
42 {
44  mCenterSymbol = new QgsMarkerSymbolV2(); //the symbol for the center of a displacement group
45  mDrawLabels = true;
46 }
47 
49 {
50  delete mCenterSymbol;
51  delete mRenderer;
52 }
53 
55 {
56  QgsPointDisplacementRenderer* r = new QgsPointDisplacementRenderer( mLabelAttributeName );
57  r->setEmbeddedRenderer( mRenderer->clone() );
58  r->setCircleWidth( mCircleWidth );
59  r->setCircleColor( mCircleColor );
60  r->setLabelFont( mLabelFont );
61  r->setLabelColor( mLabelColor );
62  r->setCircleRadiusAddition( mCircleRadiusAddition );
63  r->setMaxLabelScaleDenominator( mMaxLabelScaleDenominator );
64  r->setTolerance( mTolerance );
65  if ( mCenterSymbol )
66  {
67  r->setCenterSymbol( dynamic_cast<QgsMarkerSymbolV2*>( mCenterSymbol->clone() ) );
68  }
69  return r;
70 }
71 
72 void QgsPointDisplacementRenderer::toSld( QDomDocument& doc, QDomElement &element ) const
73 {
74  mRenderer->toSld( doc, element );
75 }
76 
77 
78 bool QgsPointDisplacementRenderer::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker )
79 {
80  Q_UNUSED( drawVertexMarker );
81  Q_UNUSED( context );
82  Q_UNUSED( layer );
83 
84  //check, if there is already a point at that position
85  if ( !feature.geometry() )
86  return false;
87 
88  QgsSymbolV2* symbol = firstSymbolForFeature( mRenderer, feature );
89 
90  //if the feature has no symbol (eg, no matching rule in a rule-based renderer), skip it
91  if ( !symbol )
92  return false;
93 
94  //point position in screen coords
95  QgsGeometry* geom = feature.geometry();
96  QGis::WkbType geomType = geom->wkbType();
97  if ( geomType != QGis::WKBPoint && geomType != QGis::WKBPoint25D )
98  {
99  //can only render point type
100  return false;
101  }
102 
103  if ( selected )
104  mSelectedFeatures.insert( feature.id() );
105 
106  QList<QgsFeatureId> intersectList = mSpatialIndex->intersects( searchRect( feature.geometry()->asPoint() ) );
107  if ( intersectList.empty() )
108  {
109  mSpatialIndex->insertFeature( feature );
110  // create new group
111  DisplacementGroup newGroup;
112  newGroup.insert( feature.id(), qMakePair( feature, symbol ) );
113  mDisplacementGroups.push_back( newGroup );
114  // add to group index
115  mGroupIndex.insert( feature.id(), mDisplacementGroups.count() - 1 );
116  return true;
117  }
118 
119  //go through all the displacement group maps and search an entry where the id equals the result of the spatial search
120  QgsFeatureId existingEntry = intersectList.at( 0 );
121 
122  int groupIdx = mGroupIndex[ existingEntry ];
123  DisplacementGroup& group = mDisplacementGroups[groupIdx];
124 
125  // add to a group
126  group.insert( feature.id(), qMakePair( feature, symbol ) );
127  // add to group index
128  mGroupIndex.insert( feature.id(), groupIdx );
129  return true;
130 }
131 
132 void QgsPointDisplacementRenderer::drawGroup( const DisplacementGroup& group, QgsRenderContext& context )
133 {
134  const QgsFeature& feature = group.begin().value().first;
135  bool selected = mSelectedFeatures.contains( feature.id() ); // maybe we should highlight individual features instead of the whole group?
136 
137  QPointF pt;
138  _getPoint( pt, context, feature.geometry()->asWkb() );
139 
140  //get list of labels and symbols
141  QStringList labelAttributeList;
142  QList<QgsMarkerSymbolV2*> symbolList;
143 
144  for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt )
145  {
146  labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) : QString() );
147  symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second );
148  }
149 
150  //draw symbol
151  double diagonal = 0;
152  double currentWidthFactor; //scale symbol size to map unit and output resolution
153 
154  QList<QgsMarkerSymbolV2*>::const_iterator it = symbolList.constBegin();
155  for ( ; it != symbolList.constEnd(); ++it )
156  {
157  if ( *it )
158  {
159  currentWidthFactor = QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, ( *it )->outputUnit(), ( *it )->mapUnitScale() );
160  double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor;
161  if ( currentDiagonal > diagonal )
162  {
163  diagonal = currentDiagonal;
164  }
165  }
166  }
167 
168 
169  QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected );
170  double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition );
171  double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 / M_PI ) + circleAdditionPainterUnits;
172 
173  //draw Circle
174  drawCircle( radius, symbolContext, pt, symbolList.size() );
175 
176  QList<QPointF> symbolPositions;
177  QList<QPointF> labelPositions;
178  calculateSymbolAndLabelPositions( pt, labelAttributeList.size(), radius, diagonal, symbolPositions, labelPositions );
179 
180  //draw mid point
181  if ( labelAttributeList.size() > 1 )
182  {
183  if ( mCenterSymbol )
184  {
185  mCenterSymbol->renderPoint( pt, &feature, context, -1, selected );
186  }
187  else
188  {
189  context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) );
190  }
191  }
192 
193  //draw symbols on the circle
194  drawSymbols( feature, context, symbolList, symbolPositions, selected );
195  //and also the labels
196  drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
197 }
198 
200 {
201  delete mRenderer;
202  mRenderer = r;
203 }
204 
206 {
207  QList<QString> attributeList;
208  if ( !mLabelAttributeName.isEmpty() )
209  {
210  attributeList.push_back( mLabelAttributeName );
211  }
212  if ( mRenderer )
213  {
214  attributeList += mRenderer->usedAttributes();
215  }
216  return attributeList;
217 }
218 
220 {
221  if ( !mRenderer )
222  {
223  return 0;
224  }
225  return mRenderer->capabilities();
226 }
227 
229 {
230  if ( !mRenderer )
231  {
232  return QgsSymbolV2List();
233  }
234  return mRenderer->symbols();
235 }
236 
238 {
239  if ( !mRenderer )
240  {
241  return 0;
242  }
243  return mRenderer->symbolForFeature( feature );
244 }
245 
247 {
248  if ( !mRenderer )
249  return 0;
250  return mRenderer->originalSymbolForFeature( feat );
251 }
252 
254 {
255  if ( !mRenderer )
256  {
257  return QgsSymbolV2List();
258  }
259  return mRenderer->symbolsForFeature( feature );
260 }
261 
263 {
264  if ( !mRenderer )
265  return QgsSymbolV2List();
266  return mRenderer->originalSymbolsForFeature( feat );
267 }
268 
270 {
271  if ( !mRenderer )
272  {
273  return false;
274  }
275  return mRenderer->willRenderFeature( feat );
276 }
277 
278 
280 {
281  mRenderer->startRender( context, fields );
282 
283  mDisplacementGroups.clear();
284  mGroupIndex.clear();
285  mSpatialIndex = new QgsSpatialIndex;
286  mSelectedFeatures.clear();
287 
288  if ( mLabelAttributeName.isEmpty() )
289  {
290  mLabelIndex = -1;
291  }
292  else
293  {
294  mLabelIndex = fields.fieldNameIndex( mLabelAttributeName );
295  }
296 
297  if ( mMaxLabelScaleDenominator > 0 && context.rendererScale() > mMaxLabelScaleDenominator )
298  {
299  mDrawLabels = false;
300  }
301  else
302  {
303  mDrawLabels = true;
304  }
305 
306  if ( mCenterSymbol )
307  {
308  mCenterSymbol->startRender( context, &fields );
309  }
310 }
311 
313 {
314  QgsDebugMsg( "QgsPointDisplacementRenderer::stopRender" );
315 
316  //printInfoDisplacementGroups(); //just for debugging
317 
318  for ( QList<DisplacementGroup>::const_iterator it = mDisplacementGroups.begin(); it != mDisplacementGroups.end(); ++it )
319  drawGroup( *it, context );
320 
321  mDisplacementGroups.clear();
322  mGroupIndex.clear();
323  delete mSpatialIndex;
324  mSpatialIndex = 0;
325  mSelectedFeatures.clear();
326 
327  mRenderer->stopRender( context );
328  if ( mCenterSymbol )
329  {
330  mCenterSymbol->stopRender( context );
331  }
332 }
333 
335 {
337  r->setLabelAttributeName( symbologyElem.attribute( "labelAttributeName" ) );
338  QFont labelFont;
339  labelFont.fromString( symbologyElem.attribute( "labelFont", "" ) );
340  r->setLabelFont( labelFont );
341  r->setCircleWidth( symbologyElem.attribute( "circleWidth", "0.4" ).toDouble() );
342  r->setCircleColor( QgsSymbolLayerV2Utils::decodeColor( symbologyElem.attribute( "circleColor", "" ) ) );
343  r->setLabelColor( QgsSymbolLayerV2Utils::decodeColor( symbologyElem.attribute( "labelColor", "" ) ) );
344  r->setCircleRadiusAddition( symbologyElem.attribute( "circleRadiusAddition", "0.0" ).toDouble() );
345  r->setMaxLabelScaleDenominator( symbologyElem.attribute( "maxLabelScaleDenominator", "-1" ).toDouble() );
346  r->setTolerance( symbologyElem.attribute( "tolerance", "0.00001" ).toDouble() );
347 
348  //look for an embedded renderer <renderer-v2>
349  QDomElement embeddedRendererElem = symbologyElem.firstChildElement( "renderer-v2" );
350  if ( !embeddedRendererElem.isNull() )
351  {
352  r->setEmbeddedRenderer( QgsFeatureRendererV2::load( embeddedRendererElem ) );
353  }
354 
355  //center symbol
356  QDomElement centerSymbolElem = symbologyElem.firstChildElement( "symbol" );
357  if ( !centerSymbolElem.isNull() )
358  {
359  r->setCenterSymbol( QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( centerSymbolElem ) );
360  }
361  return r;
362 }
363 
364 QDomElement QgsPointDisplacementRenderer::save( QDomDocument& doc )
365 {
366  QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
367  rendererElement.setAttribute( "type", "pointDisplacement" );
368  rendererElement.setAttribute( "labelAttributeName", mLabelAttributeName );
369  rendererElement.setAttribute( "labelFont", mLabelFont.toString() );
370  rendererElement.setAttribute( "circleWidth", QString::number( mCircleWidth ) );
371  rendererElement.setAttribute( "circleColor", QgsSymbolLayerV2Utils::encodeColor( mCircleColor ) );
372  rendererElement.setAttribute( "labelColor", QgsSymbolLayerV2Utils::encodeColor( mLabelColor ) );
373  rendererElement.setAttribute( "circleRadiusAddition", QString::number( mCircleRadiusAddition ) );
374  rendererElement.setAttribute( "maxLabelScaleDenominator", QString::number( mMaxLabelScaleDenominator ) );
375  rendererElement.setAttribute( "tolerance", QString::number( mTolerance ) );
376 
377  if ( mRenderer )
378  {
379  QDomElement embeddedRendererElem = mRenderer->save( doc );
380  rendererElement.appendChild( embeddedRendererElem );
381  }
382  if ( mCenterSymbol )
383  {
384  QDomElement centerSymbolElem = QgsSymbolLayerV2Utils::saveSymbol( "centerSymbol", mCenterSymbol, doc );
385  rendererElement.appendChild( centerSymbolElem );
386  }
387  return rendererElement;
388 }
389 
391 {
392  if ( mRenderer )
393  {
394  return mRenderer->legendSymbologyItems( iconSize );
395  }
396  return QgsLegendSymbologyList();
397 }
398 
400 {
401  if ( mRenderer )
402  {
403  return mRenderer->legendSymbolItems( scaleDenominator, rule );
404  }
405  return QgsLegendSymbolList();
406 }
407 
408 
409 QgsRectangle QgsPointDisplacementRenderer::searchRect( const QgsPoint& p ) const
410 {
411  return QgsRectangle( p.x() - mTolerance, p.y() - mTolerance, p.x() + mTolerance, p.y() + mTolerance );
412 }
413 
414 void QgsPointDisplacementRenderer::printInfoDisplacementGroups()
415 {
416  int nGroups = mDisplacementGroups.size();
417  QgsDebugMsg( "number of displacement groups:" + QString::number( nGroups ) );
418  for ( int i = 0; i < nGroups; ++i )
419  {
420  QgsDebugMsg( "***************displacement group " + QString::number( i ) );
421  DisplacementGroup::const_iterator it = mDisplacementGroups.at( i ).constBegin();
422  for ( ; it != mDisplacementGroups.at( i ).constEnd(); ++it )
423  {
424  QgsDebugMsg( FID_TO_STRING( it.key() ) );
425  }
426  }
427 }
428 
429 QString QgsPointDisplacementRenderer::getLabel( const QgsFeature& f )
430 {
431  QString attribute;
432  const QgsAttributes& attrs = f.attributes();
433  if ( mLabelIndex >= 0 && mLabelIndex < attrs.count() )
434  {
435  attribute = attrs[mLabelIndex].toString();
436  }
437  return attribute;
438 }
439 
441 {
442  delete mCenterSymbol;
443  mCenterSymbol = symbol;
444 }
445 
446 
447 
448 void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( const QPointF& centerPoint, int nPosition, double radius,
449  double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts ) const
450 {
451  symbolPositions.clear();
452  labelShifts.clear();
453 
454  if ( nPosition < 1 )
455  {
456  return;
457  }
458  else if ( nPosition == 1 ) //If there is only one feature, draw it exactly at the center position
459  {
460  symbolPositions.append( centerPoint );
461  labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
462  return;
463  }
464 
465  double fullPerimeter = 2 * M_PI;
466  double angleStep = fullPerimeter / nPosition;
467  double currentAngle;
468 
469  for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
470  {
471  double sinusCurrentAngle = sin( currentAngle );
472  double cosinusCurrentAngle = cos( currentAngle );
473  QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
474  QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
475  symbolPositions.append( centerPoint + positionShift );
476  labelShifts.append( labelShift );
477  }
478 }
479 
480 void QgsPointDisplacementRenderer::drawCircle( double radiusPainterUnits, QgsSymbolV2RenderContext& context, const QPointF& centerPoint, int nSymbols )
481 {
482  QPainter* p = context.renderContext().painter();
483  if ( nSymbols < 2 || !p ) //draw circle only if multiple features
484  {
485  return;
486  }
487 
488  //draw Circle
489  QPen circlePen( mCircleColor );
490  circlePen.setWidthF( context.outputLineWidth( mCircleWidth ) );
491  p->setPen( circlePen );
492  p->drawArc( QRectF( centerPoint.x() - radiusPainterUnits, centerPoint.y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
493 }
494 
495 void QgsPointDisplacementRenderer::drawSymbols( const QgsFeature& f, QgsRenderContext& context, const QList<QgsMarkerSymbolV2*>& symbolList, const QList<QPointF>& symbolPositions, bool selected )
496 {
497  QList<QPointF>::const_iterator symbolPosIt = symbolPositions.constBegin();
498  QList<QgsMarkerSymbolV2*>::const_iterator symbolIt = symbolList.constBegin();
499  for ( ; symbolPosIt != symbolPositions.constEnd() && symbolIt != symbolList.constEnd(); ++symbolPosIt, ++symbolIt )
500  {
501  if ( *symbolIt )
502  {
503  ( *symbolIt )->renderPoint( *symbolPosIt, &f, context, -1, selected );
504  }
505  }
506 }
507 
508 void QgsPointDisplacementRenderer::drawLabels( const QPointF& centerPoint, QgsSymbolV2RenderContext& context, const QList<QPointF>& labelShifts, const QStringList& labelList )
509 {
510  QPainter* p = context.renderContext().painter();
511  if ( !p )
512  {
513  return;
514  }
515 
516  QPen labelPen( mLabelColor );
517  p->setPen( labelPen );
518 
519  //scale font (for printing)
520  QFont pixelSizeFont = mLabelFont;
521  pixelSizeFont.setPixelSize( context.outputLineWidth( mLabelFont.pointSizeF() * 0.3527 ) );
522  QFont scaledFont = pixelSizeFont;
523  scaledFont.setPixelSize( pixelSizeFont.pixelSize() * context.renderContext().rasterScaleFactor() );
524  p->setFont( scaledFont );
525 
526  QFontMetricsF fontMetrics( pixelSizeFont );
527  QPointF currentLabelShift; //considers the signs to determine the label position
528 
529  QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
530  QStringList::const_iterator text_it = labelList.constBegin();
531 
532  for ( ; labelPosIt != labelShifts.constEnd() && text_it != labelList.constEnd(); ++labelPosIt, ++text_it )
533  {
534  currentLabelShift = *labelPosIt;
535  if ( currentLabelShift.x() < 0 )
536  {
537  currentLabelShift.setX( currentLabelShift.x() - fontMetrics.width( *text_it ) );
538  }
539  if ( currentLabelShift.y() > 0 )
540  {
541  currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
542  }
543 
544  QPointF drawingPoint( centerPoint + currentLabelShift );
545  p->save();
546  p->translate( drawingPoint.x(), drawingPoint.y() );
547  p->scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
548  p->drawText( QPointF( 0, 0 ), *text_it );
549  p->restore();
550  }
551 }
552 
553 QgsSymbolV2* QgsPointDisplacementRenderer::firstSymbolForFeature( QgsFeatureRendererV2* r, QgsFeature& f )
554 {
555  if ( !r )
556  {
557  return 0;
558  }
559 
560  QgsSymbolV2List symbolList = r->symbolsForFeature( f );
561  if ( symbolList.size() < 1 )
562  {
563  return 0;
564  }
565 
566  return symbolList.at( 0 );
567 }
568 
570 {
571  if ( renderer->type() == "pointDisplacement" )
572  {
573  return dynamic_cast<QgsPointDisplacementRenderer*>( renderer->clone() );
574  }
575 
576  if ( renderer->type() == "singleSymbol" ||
577  renderer->type() == "categorizedSymbol" ||
578  renderer->type() == "graduatedSymbol" ||
579  renderer->type() == "RuleRenderer" )
580  {
582  pointRenderer->setEmbeddedRenderer( renderer->clone() );
583  return pointRenderer;
584  }
585  return 0;
586 }
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
#define RENDERER_TAG_NAME
Definition: qgsrendererv2.h:47
virtual bool willRenderFeature(QgsFeature &feat)
return whether the renderer will render a feature or not.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
virtual QgsSymbolV2 * originalSymbolForFeature(QgsFeature &feature)
Return symbol for feature.
Definition: qgsrendererv2.h:95
QList< QgsSymbolV2 * > QgsSymbolV2List
Definition: qgsrendererv2.h:38
virtual QgsSymbolV2 * originalSymbolForFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.
static const unsigned char * _getPoint(QPointF &pt, QgsRenderContext &context, const unsigned char *wkb)
static QgsFeatureRendererV2 * create(QDomElement &symbologyElem)
create a renderer from XML element
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void setLabelAttributeName(const QString &name)
int fieldNameIndex(const QString &fieldName) const
Look up field&#39;s index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:263
double rendererScale() const
virtual QDomElement save(QDomDocument &doc)
store renderer info to XML element
void setCenterSymbol(QgsMarkerSymbolV2 *symbol)
Sets the center symbol (takes ownership)
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:112
QgsLegendSymbologyList legendSymbologyItems(QSize iconSize) override
return a list of symbology items for the legend
#define FID_TO_STRING(fid)
Definition: qgsfeature.h:83
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
return a list of item text / symbol
Container of fields for a vector layer.
Definition: qgsfield.h:172
static QgsPointDisplacementRenderer * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsPointDisplacementRenderer from an existing renderer.
WkbType
Used for symbology operations.
Definition: qgis.h:53
static QColor decodeColor(QString str)
QDomElement save(QDomDocument &doc) override
store renderer info to XML element
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.
virtual QList< QString > usedAttributes()=0
QgsPointDisplacementRenderer(const QString &labelAttributeName="")
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:156
void startRender(QgsRenderContext &context, const QgsFields &fields) override
QList< QgsFeatureId > intersects(QgsRectangle rect) const
returns features that intersect the specified rectangle
double x() const
Definition: qgspoint.h:126
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
static QString encodeColor(QColor color)
virtual void stopRender(QgsRenderContext &context)=0
QString type() const
Definition: qgsrendererv2.h:81
static QDomElement saveSymbol(QString symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
virtual QgsSymbolV2List symbols()=0
for symbol levels
virtual QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat)
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
virtual QgsFeatureRendererV2 * clone() const =0
void setEmbeddedRenderer(QgsFeatureRendererV2 *r)
Sets embedded renderer (takes ownership)
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
#define M_PI
virtual void toSld(QDomDocument &doc, QDomElement &element) const override
used from subclasses to create SLD Rule elements following SLD v1.1 specs
virtual QgsSymbolV2 * clone() const override
const QgsAttributes & attributes() const
Definition: qgsfeature.h:185
double rasterScaleFactor() const
QGis::WkbType wkbType() const
Returns type of wkb (point / linestring / polygon etc.)
static QgsFeatureRendererV2 * defaultRenderer(QGis::GeometryType geomType)
return a new renderer - used by default in vector layers
void renderPoint(const QPointF &point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="") override
A class to represent a point.
Definition: qgspoint.h:63
bool renderFeature(QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override
Reimplemented from QgsFeatureRendererV2.
QList< QPair< QString, QPixmap > > QgsLegendSymbologyList
void stopRender(QgsRenderContext &context) override
virtual void toSld(QDomDocument &doc, QDomElement &element) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
A renderer that automatically displaces points with the same position.
Contains information about the context of a rendering operation.
bool insertFeature(const QgsFeature &f)
add feature to index
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature) override
Proxy that will call this method on the embedded renderer.
QPainter * painter()
void stopRender(QgsRenderContext &context)
static double lineWidthScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u, const QgsMapUnitScale &scale=QgsMapUnitScale())
Returns the line width scale factor depending on the unit and the paint device.
virtual QgsSymbolV2List symbols() override
Proxy that will call this method on the embedded renderer.
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat)
return list of symbols used for rendering the feature.
static QgsFeatureRendererV2 * load(QDomElement &symbologyElem)
create a renderer from XML element
QgsRenderContext & renderContext()
Definition: qgssymbolv2.h:191
qint64 QgsFeatureId
Definition: qgsfeature.h:30
double y() const
Definition: qgspoint.h:134
virtual int capabilities() override
Proxy that will call this method on the embedded renderer.
virtual bool willRenderFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.
double outputLineWidth(double width) const
virtual int capabilities()
returns bitwise OR-ed capabilities of the renderer
QgsPoint asPoint() const
return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
A vector of attributes.
Definition: qgsfeature.h:103
virtual QList< QString > usedAttributes() override
Partial proxy that will call this method on the embedded renderer.
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
Definition: qgsrendererv2.h:42
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature)=0
to be overridden
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
QgsFeatureRendererV2 * clone() const override
virtual QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat) override
Proxy that will call this method on the embedded renderer.