QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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"
26 #include "qgspainteffect.h"
27 
28 #include <QDomElement>
29 #include <QPainter>
30 
31 #include <cmath>
32 
34  : QgsFeatureRendererV2( "pointDisplacement" )
35  , mLabelAttributeName( labelAttributeName )
36  , mLabelIndex( -1 )
37  , mTolerance( 0.00001 )
38  , mCircleWidth( 0.4 )
39  , mCircleColor( QColor( 125, 125, 125 ) )
40  , mCircleRadiusAddition( 0 )
41  , mMaxLabelScaleDenominator( -1 )
42  , mSpatialIndex( NULL )
43 {
45  mCenterSymbol = new QgsMarkerSymbolV2(); //the symbol for the center of a displacement group
46  mDrawLabels = true;
47 }
48 
50 {
51  delete mCenterSymbol;
52  delete mRenderer;
53 }
54 
56 {
57  QgsPointDisplacementRenderer* r = new QgsPointDisplacementRenderer( mLabelAttributeName );
58  r->setEmbeddedRenderer( mRenderer->clone() );
59  r->setCircleWidth( mCircleWidth );
60  r->setCircleColor( mCircleColor );
61  r->setLabelFont( mLabelFont );
62  r->setLabelColor( mLabelColor );
63  r->setCircleRadiusAddition( mCircleRadiusAddition );
64  r->setMaxLabelScaleDenominator( mMaxLabelScaleDenominator );
65  r->setTolerance( mTolerance );
66  if ( mCenterSymbol )
67  {
68  r->setCenterSymbol( dynamic_cast<QgsMarkerSymbolV2*>( mCenterSymbol->clone() ) );
69  }
70  copyPaintEffect( r );
71  return r;
72 }
73 
74 void QgsPointDisplacementRenderer::toSld( QDomDocument& doc, QDomElement &element ) const
75 {
76  mRenderer->toSld( doc, element );
77 }
78 
79 
80 bool QgsPointDisplacementRenderer::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker )
81 {
82  Q_UNUSED( drawVertexMarker );
83  Q_UNUSED( context );
84  Q_UNUSED( layer );
85 
86  //check, if there is already a point at that position
87  if ( !feature.geometry() )
88  return false;
89 
90  //point position in screen coords
91  QgsGeometry* geom = feature.geometry();
92  QGis::WkbType geomType = geom->wkbType();
93  if ( geomType != QGis::WKBPoint && geomType != QGis::WKBPoint25D )
94  {
95  //can only render point type
96  return false;
97  }
98 
99  if ( selected )
100  mSelectedFeatures.insert( feature.id() );
101 
102  QList<QgsFeatureId> intersectList = mSpatialIndex->intersects( searchRect( feature.geometry()->asPoint() ) );
103  if ( intersectList.empty() )
104  {
105  mSpatialIndex->insertFeature( feature );
106  // create new group
107  DisplacementGroup newGroup;
108  newGroup.insert( feature.id(), feature );
109  mDisplacementGroups.push_back( newGroup );
110  // add to group index
111  mGroupIndex.insert( feature.id(), mDisplacementGroups.count() - 1 );
112  return true;
113  }
114 
115  //go through all the displacement group maps and search an entry where the id equals the result of the spatial search
116  QgsFeatureId existingEntry = intersectList.at( 0 );
117 
118  int groupIdx = mGroupIndex[ existingEntry ];
119  DisplacementGroup& group = mDisplacementGroups[groupIdx];
120 
121  // add to a group
122  group.insert( feature.id(), feature );
123  // add to group index
124  mGroupIndex.insert( feature.id(), groupIdx );
125  return true;
126 }
127 
128 void QgsPointDisplacementRenderer::drawGroup( const DisplacementGroup& group, QgsRenderContext& context )
129 {
130  const QgsFeature& feature = group.begin().value();
131  bool selected = mSelectedFeatures.contains( feature.id() ); // maybe we should highlight individual features instead of the whole group?
132 
133  QPointF pt;
134  _getPoint( pt, context, feature.geometry()->asWkb() );
135 
136  //get list of labels and symbols
137  QStringList labelAttributeList;
138  QList<QgsMarkerSymbolV2*> symbolList;
139 
140  for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt )
141  {
142  labelAttributeList << ( mDrawLabels ? getLabel( attIt.value() ) : QString() );
143  QgsFeature& f = const_cast<QgsFeature&>( attIt.value() ); // other parts of API use non-const ref to QgsFeature :-/
144  symbolList << dynamic_cast<QgsMarkerSymbolV2*>( firstSymbolForFeature( mRenderer, f ) );
145  }
146 
147  //draw symbol
148  double diagonal = 0;
149  double currentWidthFactor; //scale symbol size to map unit and output resolution
150 
151  QList<QgsMarkerSymbolV2*>::const_iterator it = symbolList.constBegin();
152  for ( ; it != symbolList.constEnd(); ++it )
153  {
154  if ( *it )
155  {
156  currentWidthFactor = QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, ( *it )->outputUnit(), ( *it )->mapUnitScale() );
157  double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor;
158  if ( currentDiagonal > diagonal )
159  {
160  diagonal = currentDiagonal;
161  }
162  }
163  }
164 
165 
166  QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected );
167  double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition );
168  double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 / M_PI ) + circleAdditionPainterUnits;
169 
170  //draw Circle
171  drawCircle( radius, symbolContext, pt, symbolList.size() );
172 
173  QList<QPointF> symbolPositions;
174  QList<QPointF> labelPositions;
175  calculateSymbolAndLabelPositions( pt, labelAttributeList.size(), radius, diagonal, symbolPositions, labelPositions );
176 
177  //draw mid point
178  if ( labelAttributeList.size() > 1 )
179  {
180  if ( mCenterSymbol )
181  {
182  mCenterSymbol->renderPoint( pt, &feature, context, -1, selected );
183  }
184  else
185  {
186  context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) );
187  }
188  }
189 
190  //draw symbols on the circle
191  drawSymbols( feature, context, symbolList, symbolPositions, selected );
192  //and also the labels
193  drawLabels( pt, symbolContext, labelPositions, labelAttributeList );
194 }
195 
197 {
198  delete mRenderer;
199  mRenderer = r;
200 }
201 
203 {
204  QList<QString> attributeList;
205  if ( !mLabelAttributeName.isEmpty() )
206  {
207  attributeList.push_back( mLabelAttributeName );
208  }
209  if ( mRenderer )
210  {
211  attributeList += mRenderer->usedAttributes();
212  }
213  return attributeList;
214 }
215 
217 {
218  if ( !mRenderer )
219  {
220  return 0;
221  }
222  return mRenderer->capabilities();
223 }
224 
226 {
227  if ( !mRenderer )
228  {
229  return QgsSymbolV2List();
230  }
231  return mRenderer->symbols();
232 }
233 
235 {
236  if ( !mRenderer )
237  {
238  return 0;
239  }
240  return mRenderer->symbolForFeature( feature );
241 }
242 
244 {
245  if ( !mRenderer )
246  return 0;
247  return mRenderer->originalSymbolForFeature( feat );
248 }
249 
251 {
252  if ( !mRenderer )
253  {
254  return QgsSymbolV2List();
255  }
256  return mRenderer->symbolsForFeature( feature );
257 }
258 
260 {
261  if ( !mRenderer )
262  return QgsSymbolV2List();
263  return mRenderer->originalSymbolsForFeature( feat );
264 }
265 
267 {
268  if ( !mRenderer )
269  {
270  return false;
271  }
272  return mRenderer->willRenderFeature( feat );
273 }
274 
275 
277 {
278  mRenderer->startRender( context, fields );
279 
280  mDisplacementGroups.clear();
281  mGroupIndex.clear();
282  mSpatialIndex = new QgsSpatialIndex;
283  mSelectedFeatures.clear();
284 
285  if ( mLabelAttributeName.isEmpty() )
286  {
287  mLabelIndex = -1;
288  }
289  else
290  {
291  mLabelIndex = fields.fieldNameIndex( mLabelAttributeName );
292  }
293 
294  if ( mMaxLabelScaleDenominator > 0 && context.rendererScale() > mMaxLabelScaleDenominator )
295  {
296  mDrawLabels = false;
297  }
298  else
299  {
300  mDrawLabels = true;
301  }
302 
303  if ( mCenterSymbol )
304  {
305  mCenterSymbol->startRender( context, &fields );
306  }
307 }
308 
310 {
311  QgsDebugMsg( "QgsPointDisplacementRenderer::stopRender" );
312 
313  //printInfoDisplacementGroups(); //just for debugging
314 
315  for ( QList<DisplacementGroup>::const_iterator it = mDisplacementGroups.begin(); it != mDisplacementGroups.end(); ++it )
316  drawGroup( *it, context );
317 
318  mDisplacementGroups.clear();
319  mGroupIndex.clear();
320  delete mSpatialIndex;
321  mSpatialIndex = 0;
322  mSelectedFeatures.clear();
323 
324  mRenderer->stopRender( context );
325  if ( mCenterSymbol )
326  {
327  mCenterSymbol->stopRender( context );
328  }
329 }
330 
332 {
334  r->setLabelAttributeName( symbologyElem.attribute( "labelAttributeName" ) );
335  QFont labelFont;
336  labelFont.fromString( symbologyElem.attribute( "labelFont", "" ) );
337  r->setLabelFont( labelFont );
338  r->setCircleWidth( symbologyElem.attribute( "circleWidth", "0.4" ).toDouble() );
339  r->setCircleColor( QgsSymbolLayerV2Utils::decodeColor( symbologyElem.attribute( "circleColor", "" ) ) );
340  r->setLabelColor( QgsSymbolLayerV2Utils::decodeColor( symbologyElem.attribute( "labelColor", "" ) ) );
341  r->setCircleRadiusAddition( symbologyElem.attribute( "circleRadiusAddition", "0.0" ).toDouble() );
342  r->setMaxLabelScaleDenominator( symbologyElem.attribute( "maxLabelScaleDenominator", "-1" ).toDouble() );
343  r->setTolerance( symbologyElem.attribute( "tolerance", "0.00001" ).toDouble() );
344 
345  //look for an embedded renderer <renderer-v2>
346  QDomElement embeddedRendererElem = symbologyElem.firstChildElement( "renderer-v2" );
347  if ( !embeddedRendererElem.isNull() )
348  {
349  r->setEmbeddedRenderer( QgsFeatureRendererV2::load( embeddedRendererElem ) );
350  }
351 
352  //center symbol
353  QDomElement centerSymbolElem = symbologyElem.firstChildElement( "symbol" );
354  if ( !centerSymbolElem.isNull() )
355  {
356  r->setCenterSymbol( QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( centerSymbolElem ) );
357  }
358  return r;
359 }
360 
361 QDomElement QgsPointDisplacementRenderer::save( QDomDocument& doc )
362 {
363  QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
364  rendererElement.setAttribute( "type", "pointDisplacement" );
365  rendererElement.setAttribute( "labelAttributeName", mLabelAttributeName );
366  rendererElement.setAttribute( "labelFont", mLabelFont.toString() );
367  rendererElement.setAttribute( "circleWidth", QString::number( mCircleWidth ) );
368  rendererElement.setAttribute( "circleColor", QgsSymbolLayerV2Utils::encodeColor( mCircleColor ) );
369  rendererElement.setAttribute( "labelColor", QgsSymbolLayerV2Utils::encodeColor( mLabelColor ) );
370  rendererElement.setAttribute( "circleRadiusAddition", QString::number( mCircleRadiusAddition ) );
371  rendererElement.setAttribute( "maxLabelScaleDenominator", QString::number( mMaxLabelScaleDenominator ) );
372  rendererElement.setAttribute( "tolerance", QString::number( mTolerance ) );
373 
374  if ( mRenderer )
375  {
376  QDomElement embeddedRendererElem = mRenderer->save( doc );
377  rendererElement.appendChild( embeddedRendererElem );
378  }
379  if ( mCenterSymbol )
380  {
381  QDomElement centerSymbolElem = QgsSymbolLayerV2Utils::saveSymbol( "centerSymbol", mCenterSymbol, doc );
382  rendererElement.appendChild( centerSymbolElem );
383  }
384 
385  if ( mPaintEffect )
386  mPaintEffect->saveProperties( doc, rendererElement );
387 
388  return rendererElement;
389 }
390 
392 {
393  if ( mRenderer )
394  {
395  return mRenderer->legendSymbologyItems( iconSize );
396  }
397  return QgsLegendSymbologyList();
398 }
399 
401 {
402  if ( mRenderer )
403  {
404  return mRenderer->legendSymbolItems( scaleDenominator, rule );
405  }
406  return QgsLegendSymbolList();
407 }
408 
409 
410 QgsRectangle QgsPointDisplacementRenderer::searchRect( const QgsPoint& p ) const
411 {
412  return QgsRectangle( p.x() - mTolerance, p.y() - mTolerance, p.x() + mTolerance, p.y() + mTolerance );
413 }
414 
415 void QgsPointDisplacementRenderer::printInfoDisplacementGroups()
416 {
417  int nGroups = mDisplacementGroups.size();
418  QgsDebugMsg( "number of displacement groups:" + QString::number( nGroups ) );
419  for ( int i = 0; i < nGroups; ++i )
420  {
421  QgsDebugMsg( "***************displacement group " + QString::number( i ) );
422  QMap<QgsFeatureId, QgsFeature>::const_iterator it = mDisplacementGroups.at( i ).constBegin();
423  for ( ; it != mDisplacementGroups.at( i ).constEnd(); ++it )
424  {
425  QgsDebugMsg( FID_TO_STRING( it.key() ) );
426  }
427  }
428 }
429 
430 QString QgsPointDisplacementRenderer::getLabel( const QgsFeature& f )
431 {
432  QString attribute;
433  const QgsAttributes& attrs = f.attributes();
434  if ( mLabelIndex >= 0 && mLabelIndex < attrs.count() )
435  {
436  attribute = attrs[mLabelIndex].toString();
437  }
438  return attribute;
439 }
440 
442 {
443  delete mCenterSymbol;
444  mCenterSymbol = symbol;
445 }
446 
447 
448 
449 void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( const QPointF& centerPoint, int nPosition, double radius,
450  double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts ) const
451 {
452  symbolPositions.clear();
453  labelShifts.clear();
454 
455  if ( nPosition < 1 )
456  {
457  return;
458  }
459  else if ( nPosition == 1 ) //If there is only one feature, draw it exactly at the center position
460  {
461  symbolPositions.append( centerPoint );
462  labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) );
463  return;
464  }
465 
466  double fullPerimeter = 2 * M_PI;
467  double angleStep = fullPerimeter / nPosition;
468  double currentAngle;
469 
470  for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep )
471  {
472  double sinusCurrentAngle = sin( currentAngle );
473  double cosinusCurrentAngle = cos( currentAngle );
474  QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
475  QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
476  symbolPositions.append( centerPoint + positionShift );
477  labelShifts.append( labelShift );
478  }
479 }
480 
481 void QgsPointDisplacementRenderer::drawCircle( double radiusPainterUnits, QgsSymbolV2RenderContext& context, const QPointF& centerPoint, int nSymbols )
482 {
483  QPainter* p = context.renderContext().painter();
484  if ( nSymbols < 2 || !p ) //draw circle only if multiple features
485  {
486  return;
487  }
488 
489  //draw Circle
490  QPen circlePen( mCircleColor );
491  circlePen.setWidthF( context.outputLineWidth( mCircleWidth ) );
492  p->setPen( circlePen );
493  p->drawArc( QRectF( centerPoint.x() - radiusPainterUnits, centerPoint.y() - radiusPainterUnits, 2 * radiusPainterUnits, 2 * radiusPainterUnits ), 0, 5760 );
494 }
495 
496 void QgsPointDisplacementRenderer::drawSymbols( const QgsFeature& f, QgsRenderContext& context, const QList<QgsMarkerSymbolV2*>& symbolList, const QList<QPointF>& symbolPositions, bool selected )
497 {
498  QList<QPointF>::const_iterator symbolPosIt = symbolPositions.constBegin();
499  QList<QgsMarkerSymbolV2*>::const_iterator symbolIt = symbolList.constBegin();
500  for ( ; symbolPosIt != symbolPositions.constEnd() && symbolIt != symbolList.constEnd(); ++symbolPosIt, ++symbolIt )
501  {
502  if ( *symbolIt )
503  {
504  ( *symbolIt )->renderPoint( *symbolPosIt, &f, context, -1, selected );
505  }
506  }
507 }
508 
509 void QgsPointDisplacementRenderer::drawLabels( const QPointF& centerPoint, QgsSymbolV2RenderContext& context, const QList<QPointF>& labelShifts, const QStringList& labelList )
510 {
511  QPainter* p = context.renderContext().painter();
512  if ( !p )
513  {
514  return;
515  }
516 
517  QPen labelPen( mLabelColor );
518  p->setPen( labelPen );
519 
520  //scale font (for printing)
521  QFont pixelSizeFont = mLabelFont;
522  pixelSizeFont.setPixelSize( context.outputLineWidth( mLabelFont.pointSizeF() * 0.3527 ) );
523  QFont scaledFont = pixelSizeFont;
524  scaledFont.setPixelSize( pixelSizeFont.pixelSize() * context.renderContext().rasterScaleFactor() );
525  p->setFont( scaledFont );
526 
527  QFontMetricsF fontMetrics( pixelSizeFont );
528  QPointF currentLabelShift; //considers the signs to determine the label position
529 
530  QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
531  QStringList::const_iterator text_it = labelList.constBegin();
532 
533  for ( ; labelPosIt != labelShifts.constEnd() && text_it != labelList.constEnd(); ++labelPosIt, ++text_it )
534  {
535  currentLabelShift = *labelPosIt;
536  if ( currentLabelShift.x() < 0 )
537  {
538  currentLabelShift.setX( currentLabelShift.x() - fontMetrics.width( *text_it ) );
539  }
540  if ( currentLabelShift.y() > 0 )
541  {
542  currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
543  }
544 
545  QPointF drawingPoint( centerPoint + currentLabelShift );
546  p->save();
547  p->translate( drawingPoint.x(), drawingPoint.y() );
548  p->scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
549  p->drawText( QPointF( 0, 0 ), *text_it );
550  p->restore();
551  }
552 }
553 
554 QgsSymbolV2* QgsPointDisplacementRenderer::firstSymbolForFeature( QgsFeatureRendererV2* r, QgsFeature& f )
555 {
556  if ( !r )
557  {
558  return 0;
559  }
560 
561  QgsSymbolV2List symbolList = r->symbolsForFeature( f );
562  if ( symbolList.size() < 1 )
563  {
564  return 0;
565  }
566 
567  return symbolList.at( 0 );
568 }
569 
571 {
572  if ( renderer->type() == "pointDisplacement" )
573  {
574  return dynamic_cast<QgsPointDisplacementRenderer*>( renderer->clone() );
575  }
576 
577  if ( renderer->type() == "singleSymbol" ||
578  renderer->type() == "categorizedSymbol" ||
579  renderer->type() == "graduatedSymbol" ||
580  renderer->type() == "RuleRenderer" )
581  {
583  pointRenderer->setEmbeddedRenderer( renderer->clone() );
584  return pointRenderer;
585  }
586  return 0;
587 }
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
#define RENDERER_TAG_NAME
Definition: qgsrendererv2.h:48
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:96
QList< QgsSymbolV2 * > QgsSymbolV2List
Definition: qgsrendererv2.h:39
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's index from name - case insensitive TODO: sort out case sensitive (indexFromName()) vs...
Definition: qgsfield.cpp:234
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.
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
WkbType
Used for symbology operations.
Definition: qgis.h:53
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 startRender(QgsRenderContext &context, const QgsFields &fields) override
QList< QgsFeatureId > intersects(QgsRectangle rect) const
returns features that intersect the specified rectangle
QgsPaintEffect * mPaintEffect
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:82
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: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
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.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
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)
void copyPaintEffect(QgsFeatureRendererV2 *destRenderer) const
Copies paint effect of this renderer to another renderer.
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.
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:100
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:219
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...
virtual QList< QString > usedAttributes() override
Partial proxy that will call this method on the embedded renderer.
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
Definition: qgsrendererv2.h:43
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.