QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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"
25 
26 #include <QDomElement>
27 #include <QPainter>
28 
29 #include <cmath>
30 
32  : QgsFeatureRendererV2( "pointDisplacement" )
33  , mLabelAttributeName( labelAttributeName )
34  , mLabelIndex( -1 )
35  , mTolerance( 0.00001 )
36  , mCircleWidth( 0.4 )
37  , mCircleColor( QColor( 125, 125, 125 ) )
38  , mCircleRadiusAddition( 0 )
39  , mMaxLabelScaleDenominator( -1 )
40 {
42  mCenterSymbol = new QgsMarkerSymbolV2(); //the symbol for the center of a displacement group
43  mDrawLabels = true;
44 }
45 
47 {
48  delete mCenterSymbol;
49  delete mRenderer;
50 }
51 
53 {
63  if ( mCenterSymbol )
64  {
65  r->setCenterSymbol( dynamic_cast<QgsMarkerSymbolV2*>( mCenterSymbol->clone() ) );
66  }
67  return r;
68 }
69 
70 void QgsPointDisplacementRenderer::toSld( QDomDocument& doc, QDomElement &element ) const
71 {
72  mRenderer->toSld( doc, element );
73 }
74 
75 
76 bool QgsPointDisplacementRenderer::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker )
77 {
78  Q_UNUSED( drawVertexMarker );
79  Q_UNUSED( context );
80  Q_UNUSED( layer );
81 
82  //check, if there is already a point at that position
83  if ( !feature.geometry() )
84  return false;
85 
86  //point position in screen coords
87  QgsGeometry* geom = feature.geometry();
88  QGis::WkbType geomType = geom->wkbType();
89  if ( geomType != QGis::WKBPoint && geomType != QGis::WKBPoint25D )
90  {
91  //can only render point type
92  return false;
93  }
94 
95  if ( selected )
96  mSelectedFeatures.insert( feature.id() );
97 
98  QList<QgsFeatureId> intersectList = mSpatialIndex->intersects( searchRect( feature.geometry()->asPoint() ) );
99  if ( intersectList.empty() )
100  {
101  mSpatialIndex->insertFeature( feature );
102  // create new group
103  DisplacementGroup newGroup;
104  newGroup.insert( feature.id(), feature );
105  mDisplacementGroups.push_back( newGroup );
106  // add to group index
107  mGroupIndex.insert( feature.id(), mDisplacementGroups.count() - 1 );
108  return true;
109  }
110 
111  //go through all the displacement group maps and search an entry where the id equals the result of the spatial search
112  QgsFeatureId existingEntry = intersectList.at( 0 );
113 
114  int groupIdx = mGroupIndex[ existingEntry ];
115  DisplacementGroup& group = mDisplacementGroups[groupIdx];
116 
117  // add to a group
118  group.insert( feature.id(), feature );
119  // add to group index
120  mGroupIndex.insert( feature.id(), groupIdx );
121  return true;
122 }
123 
125 {
126  const QgsFeature& feature = group.begin().value();
127  bool selected = mSelectedFeatures.contains( feature.id() ); // maybe we should highlight individual features instead of the whole group?
128 
129  QPointF pt;
130  _getPoint( pt, context, feature.geometry()->asWkb() );
131 
132  //get list of labels and symbols
133  QStringList labelAttributeList;
134  QList<QgsMarkerSymbolV2*> symbolList;
135 
136  for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt )
137  {
138  labelAttributeList << ( mDrawLabels ? getLabel( attIt.value() ) : QString() );
139  QgsFeature& f = const_cast<QgsFeature&>( attIt.value() ); // other parts of API use non-const ref to QgsFeature :-/
140  symbolList << dynamic_cast<QgsMarkerSymbolV2*>( firstSymbolForFeature( mRenderer, f ) );
141  }
142 
143  //draw symbol
144  double diagonal = 0;
145  double currentWidthFactor; //scale symbol size to map unit and output resolution
146 
147  QList<QgsMarkerSymbolV2*>::const_iterator it = symbolList.constBegin();
148  for ( ; it != symbolList.constEnd(); ++it )
149  {
150  if ( *it )
151  {
152  currentWidthFactor = QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, ( *it )->outputUnit(), ( *it )->mapUnitScale() );
153  double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor;
154  if ( currentDiagonal > diagonal )
155  {
156  diagonal = currentDiagonal;
157  }
158  }
159  }
160 
161 
162  QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected );
163  double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition );
164  double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 / M_PI ) + circleAdditionPainterUnits;
165 
166  //draw Circle
167  drawCircle( radius, symbolContext, pt, symbolList.size() );
168 
169  QList<QPointF> symbolPositions;
170  QList<QPointF> labelPositions;
171  calculateSymbolAndLabelPositions( pt, labelAttributeList.size(), radius, diagonal, symbolPositions, labelPositions );
172 
173  //draw mid point
174  if ( labelAttributeList.size() > 1 )
175  {
176  if ( mCenterSymbol )
177  {
178  mCenterSymbol->renderPoint( pt, &feature, context, -1, selected );
179  }
180  else
181  {
182  context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) );
183  }
184  }
185 
186  //draw symbols on the circle
187  drawSymbols( feature, context, symbolList, symbolPositions, selected );
188  //and also the labels
189  drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
190 }
191 
193 {
194  delete mRenderer;
195  mRenderer = r;
196 }
197 
199 {
200  Q_UNUSED( feature );
201  return 0; //not used any more
202 }
203 
205 {
206  mRenderer->startRender( context, fields );
207 
208  mDisplacementGroups.clear();
209  mGroupIndex.clear();
211  mSelectedFeatures.clear();
212 
213  if ( mLabelAttributeName.isEmpty() )
214  {
215  mLabelIndex = -1;
216  }
217  else
218  {
220  }
221 
223  {
224  mDrawLabels = false;
225  }
226  else
227  {
228  mDrawLabels = true;
229  }
230 
231  if ( mCenterSymbol )
232  {
233  mCenterSymbol->startRender( context, &fields );
234  }
235 }
236 
238 {
239  QgsDebugMsg( "QgsPointDisplacementRenderer::stopRender" );
240 
241  //printInfoDisplacementGroups(); //just for debugging
242 
243  for ( QList<DisplacementGroup>::const_iterator it = mDisplacementGroups.begin(); it != mDisplacementGroups.end(); ++it )
244  drawGroup( *it, context );
245 
246  mDisplacementGroups.clear();
247  mGroupIndex.clear();
248  delete mSpatialIndex;
249  mSpatialIndex = 0;
250  mSelectedFeatures.clear();
251 
252  mRenderer->stopRender( context );
253  if ( mCenterSymbol )
254  {
255  mCenterSymbol->stopRender( context );
256  }
257 }
258 
260 {
261  QList<QString> attributeList;
262  if ( !mLabelAttributeName.isEmpty() )
263  {
264  attributeList.push_back( mLabelAttributeName );
265  }
266  if ( mRenderer )
267  {
268  attributeList += mRenderer->usedAttributes();
269  }
270  return attributeList;
271 }
272 
274 {
275  if ( mRenderer )
276  {
277  return mRenderer->symbols();
278  }
279  else
280  {
281  return QgsSymbolV2List();
282  }
283 }
284 
286 {
288  r->setLabelAttributeName( symbologyElem.attribute( "labelAttributeName" ) );
289  QFont labelFont;
290  labelFont.fromString( symbologyElem.attribute( "labelFont", "" ) );
291  r->setLabelFont( labelFont );
292  r->setCircleWidth( symbologyElem.attribute( "circleWidth", "0.4" ).toDouble() );
293  r->setCircleColor( QgsSymbolLayerV2Utils::decodeColor( symbologyElem.attribute( "circleColor", "" ) ) );
294  r->setLabelColor( QgsSymbolLayerV2Utils::decodeColor( symbologyElem.attribute( "labelColor", "" ) ) );
295  r->setCircleRadiusAddition( symbologyElem.attribute( "circleRadiusAddition", "0.0" ).toDouble() );
296  r->setMaxLabelScaleDenominator( symbologyElem.attribute( "maxLabelScaleDenominator", "-1" ).toDouble() );
297  r->setTolerance( symbologyElem.attribute( "tolerance", "0.00001" ).toDouble() );
298 
299  //look for an embedded renderer <renderer-v2>
300  QDomElement embeddedRendererElem = symbologyElem.firstChildElement( "renderer-v2" );
301  if ( !embeddedRendererElem.isNull() )
302  {
303  r->setEmbeddedRenderer( QgsFeatureRendererV2::load( embeddedRendererElem ) );
304  }
305 
306  //center symbol
307  QDomElement centerSymbolElem = symbologyElem.firstChildElement( "symbol" );
308  if ( !centerSymbolElem.isNull() )
309  {
310  r->setCenterSymbol( dynamic_cast<QgsMarkerSymbolV2*>( QgsSymbolLayerV2Utils::loadSymbol( centerSymbolElem ) ) );
311  }
312  return r;
313 }
314 
315 QDomElement QgsPointDisplacementRenderer::save( QDomDocument& doc )
316 {
317  QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
318  rendererElement.setAttribute( "type", "pointDisplacement" );
319  rendererElement.setAttribute( "labelAttributeName", mLabelAttributeName );
320  rendererElement.setAttribute( "labelFont", mLabelFont.toString() );
321  rendererElement.setAttribute( "circleWidth", QString::number( mCircleWidth ) );
322  rendererElement.setAttribute( "circleColor", QgsSymbolLayerV2Utils::encodeColor( mCircleColor ) );
323  rendererElement.setAttribute( "labelColor", QgsSymbolLayerV2Utils::encodeColor( mLabelColor ) );
324  rendererElement.setAttribute( "circleRadiusAddition", QString::number( mCircleRadiusAddition ) );
325  rendererElement.setAttribute( "maxLabelScaleDenominator", QString::number( mMaxLabelScaleDenominator ) );
326  rendererElement.setAttribute( "tolerance", QString::number( mTolerance ) );
327 
328  if ( mRenderer )
329  {
330  QDomElement embeddedRendererElem = mRenderer->save( doc );
331  rendererElement.appendChild( embeddedRendererElem );
332  }
333  if ( mCenterSymbol )
334  {
335  QDomElement centerSymbolElem = QgsSymbolLayerV2Utils::saveSymbol( "centerSymbol", mCenterSymbol, doc );
336  rendererElement.appendChild( centerSymbolElem );
337  }
338  return rendererElement;
339 }
340 
342 {
343  if ( mRenderer )
344  {
345  return mRenderer->legendSymbologyItems( iconSize );
346  }
347  return QgsLegendSymbologyList();
348 }
349 
351 {
352  if ( mRenderer )
353  {
354  return mRenderer->legendSymbolItems( scaleDenominator, rule );
355  }
356  return QgsLegendSymbolList();
357 }
358 
359 
361 {
362  return QgsRectangle( p.x() - mTolerance, p.y() - mTolerance, p.x() + mTolerance, p.y() + mTolerance );
363 }
364 
366 {
367  int nGroups = mDisplacementGroups.size();
368  QgsDebugMsg( "number of displacement groups:" + QString::number( nGroups ) );
369  for ( int i = 0; i < nGroups; ++i )
370  {
371  QgsDebugMsg( "***************displacement group " + QString::number( i ) );
372  QMap<QgsFeatureId, QgsFeature>::const_iterator it = mDisplacementGroups.at( i ).constBegin();
373  for ( ; it != mDisplacementGroups.at( i ).constEnd(); ++it )
374  {
375  QgsDebugMsg( FID_TO_STRING( it.key() ) );
376  }
377  }
378 }
379 
381 {
382  QString attribute;
383  const QgsAttributes& attrs = f.attributes();
384  if ( mLabelIndex >= 0 && mLabelIndex < attrs.count() )
385  {
386  attribute = attrs[mLabelIndex].toString();
387  }
388  return attribute;
389 }
390 
392 {
393  delete mCenterSymbol;
394  mCenterSymbol = symbol;
395 }
396 
397 
398 
399 void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( const QPointF& centerPoint, int nPosition, double radius,
400  double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts ) const
401 {
402  symbolPositions.clear();
403  labelShifts.clear();
404 
405  if ( nPosition < 1 )
406  {
407  return;
408  }
409  else if ( nPosition == 1 ) //If there is only one feature, draw it exactly at the center position
410  {
411  symbolPositions.append( centerPoint );
412  labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
413  return;
414  }
415 
416  double fullPerimeter = 2 * M_PI;
417  double angleStep = fullPerimeter / nPosition;
418  double currentAngle;
419 
420  for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
421  {
422  double sinusCurrentAngle = sin( currentAngle );
423  double cosinusCurrentAngle = cos( currentAngle );
424  QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
425  QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
426  symbolPositions.append( centerPoint + positionShift );
427  labelShifts.append( labelShift );
428  }
429 }
430 
431 void QgsPointDisplacementRenderer::drawCircle( double radiusPainterUnits, QgsSymbolV2RenderContext& context, const QPointF& centerPoint, int nSymbols )
432 {
433  QPainter* p = context.renderContext().painter();
434  if ( nSymbols < 2 || !p ) //draw circle only if multiple features
435  {
436  return;
437  }
438 
439  //draw Circle
440  QPen circlePen( mCircleColor );
441  circlePen.setWidthF( context.outputLineWidth( mCircleWidth ) );
442  p->setPen( circlePen );
443  p->drawArc( QRectF( centerPoint.x() - radiusPainterUnits, centerPoint.y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
444 }
445 
446 void QgsPointDisplacementRenderer::drawSymbols( const QgsFeature& f, QgsRenderContext& context, const QList<QgsMarkerSymbolV2*>& symbolList, const QList<QPointF>& symbolPositions, bool selected )
447 {
448  QList<QPointF>::const_iterator symbolPosIt = symbolPositions.constBegin();
449  QList<QgsMarkerSymbolV2*>::const_iterator symbolIt = symbolList.constBegin();
450  for ( ; symbolPosIt != symbolPositions.constEnd() && symbolIt != symbolList.constEnd(); ++symbolPosIt, ++symbolIt )
451  {
452  if ( *symbolIt )
453  {
454  ( *symbolIt )->renderPoint( *symbolPosIt, &f, context, -1, selected );
455  }
456  }
457 }
458 
459 void QgsPointDisplacementRenderer::drawLabels( const QPointF& centerPoint, QgsSymbolV2RenderContext& context, const QList<QPointF>& labelShifts, const QStringList& labelList )
460 {
461  QPainter* p = context.renderContext().painter();
462  if ( !p )
463  {
464  return;
465  }
466 
467  QPen labelPen( mLabelColor );
468  p->setPen( labelPen );
469 
470  //scale font (for printing)
471  QFont pixelSizeFont = mLabelFont;
472  pixelSizeFont.setPixelSize( context.outputLineWidth( mLabelFont.pointSizeF() * 0.3527 ) );
473  QFont scaledFont = pixelSizeFont;
474  scaledFont.setPixelSize( pixelSizeFont.pixelSize() * context.renderContext().rasterScaleFactor() );
475  p->setFont( scaledFont );
476 
477  QFontMetricsF fontMetrics( pixelSizeFont );
478  QPointF currentLabelShift; //considers the signs to determine the label position
479 
480  QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
481  QStringList::const_iterator text_it = labelList.constBegin();
482 
483  for ( ; labelPosIt != labelShifts.constEnd() && text_it != labelList.constEnd(); ++labelPosIt, ++text_it )
484  {
485  currentLabelShift = *labelPosIt;
486  if ( currentLabelShift.x() < 0 )
487  {
488  currentLabelShift.setX( currentLabelShift.x() - fontMetrics.width( *text_it ) );
489  }
490  if ( currentLabelShift.y() > 0 )
491  {
492  currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
493  }
494 
495  QPointF drawingPoint( centerPoint + currentLabelShift );
496  p->save();
497  p->translate( drawingPoint.x(), drawingPoint.y() );
498  p->scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
499  p->drawText( QPointF( 0, 0 ), *text_it );
500  p->restore();
501  }
502 }
503 
505 {
506  if ( !r )
507  {
508  return 0;
509  }
510 
511  QgsSymbolV2List symbolList = r->symbolsForFeature( f );
512  if ( symbolList.size() < 1 )
513  {
514  return 0;
515  }
516 
517  return symbolList.at( 0 );
518 }
519 
520 
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
void startRender(QgsRenderContext &context, const QgsFields &fields)
#define RENDERER_TAG_NAME
Definition: qgsrendererv2.h:43
A rectangle specified with double values.
Definition: qgsrectangle.h:35
QgsMarkerSymbolV2 * mCenterSymbol
Center symbol for a displacement group.
QList< QgsSymbolV2 * > QgsSymbolV2List
Definition: qgsrendererv2.h:37
static const unsigned char * _getPoint(QPointF &pt, QgsRenderContext &context, const unsigned char *wkb)
static QgsFeatureRendererV2 * create(QDomElement &symbologyElem)
create a renderer from XML element
void drawSymbols(const QgsFeature &f, QgsRenderContext &context, const QList< QgsMarkerSymbolV2 * > &symbolList, const QList< QPointF > &symbolPositions, bool selected=false)
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
void setLabelAttributeName(const QString &name)
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 QDomElement save(QDomDocument &doc)
store renderer info to XML element
QgsSymbolV2List symbols()
for symbol levels
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
#define FID_TO_STRING(fid)
Definition: qgsfeature.h:83
QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
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:163
WkbType
Used for symbology operations.
Definition: qgis.h:53
static QColor decodeColor(QString str)
virtual QList< QString > usedAttributes()=0
QColor mCircleColor
Color to draw the circle.
QgsPointDisplacementRenderer(const QString &labelAttributeName="")
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
void printInfoDisplacementGroups()
This is a debugging function to check the entries in the displacement groups.
double mCircleWidth
Line width for the circle.
QList< QgsFeatureId > intersects(QgsRectangle rect) const
returns features that intersect the specified rectangle
double x() const
Definition: qgspoint.h:110
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize)
return a list of symbology items for the legend
void stopRender(QgsRenderContext &context)
int mLabelIndex
Label attribute index (or -1 if none).
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
static QString encodeColor(QColor color)
virtual void stopRender(QgsRenderContext &context)=0
static QDomElement saveSymbol(QString symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
virtual QgsSymbolV2List symbols()=0
for symbol levels
QFont mLabelFont
Font that is passed to the renderer.
virtual QgsFeatureRendererV2 * clone()=0
QSet< QgsFeatureId > mSelectedFeatures
keeps trask which features are selected
void setEmbeddedRenderer(QgsFeatureRendererV2 *r)
Sets embedded renderer (takes ownership)
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
QDomElement save(QDomDocument &doc)
store renderer info to XML element
double mMaxLabelScaleDenominator
Maximum scale denominator for label display.
bool mDrawLabels
Is set internally from startRender() depending on scale denominator.
void drawCircle(double radiusPainterUnits, QgsSymbolV2RenderContext &context, const QPointF &centerPoint, int nSymbols)
#define M_PI
const QgsAttributes & attributes() const
Definition: qgsfeature.h:142
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
QString mLabelAttributeName
Attribute name for labeling.
void renderPoint(const QPointF &point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
virtual void toSld(QDomDocument &doc, QDomElement &element) const
used from subclasses to create SLD Rule elements following SLD v1.1 specs
A class to represent a point geometry.
Definition: qgspoint.h:63
void drawLabels(const QPointF &centerPoint, QgsSymbolV2RenderContext &context, const QList< QPointF > &labelShifts, const QStringList &labelList)
QList< QPair< QString, QPixmap > > QgsLegendSymbologyList
QString getLabel(const QgsFeature &f)
Returns the label for a feature (using mLabelAttributeName as attribute field)
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.
QMap< QgsFeatureId, QgsFeature > DisplacementGroup
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
QgsSpatialIndex * mSpatialIndex
Spatial index for fast lookup of close points.
QgsSymbolV2 * firstSymbolForFeature(QgsFeatureRendererV2 *r, QgsFeature &f)
Returns first symbol for feature or 0 if none.
Contains information about the context of a rendering operation.
bool insertFeature(const QgsFeature &f)
add feature to index
void calculateSymbolAndLabelPositions(const QPointF &centerPoint, int nPosition, double radius, double symbolDiagonal, QList< QPointF > &symbolPositions, QList< QPointF > &labelShifts) const
QPainter * painter()
double mCircleRadiusAddition
Addition to the default circle radius.
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.
QgsFeatureRendererV2 * mRenderer
Embedded renderer.
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:100
virtual QgsSymbolV2 * clone() const
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:168
QgsRectangle searchRect(const QgsPoint &p) const
Creates a search rectangle with mTolerance.
QMap< QgsFeatureId, int > mGroupIndex
Mapping from feature ID to its group index.
bool renderFeature(QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false)
Reimplemented from QgsFeatureRendererV2.
qint64 QgsFeatureId
Definition: qgsfeature.h:30
double y() const
Definition: qgspoint.h:118
QList< DisplacementGroup > mDisplacementGroups
Groups of features that have the same position.
static QgsSymbolV2 * loadSymbol(QDomElement &element)
double outputLineWidth(double width) const
QgsPoint asPoint() const
return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
Definition: qgsrendererv2.h:41
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
QgsSymbolV2 * symbolForFeature(QgsFeature &feature)
to be overridden
void drawGroup(const DisplacementGroup &group, QgsRenderContext &context)