QGIS API Documentation  3.8.0-Zanzibar (11aff65)
qgspointdistancerenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointdistancerenderer.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 "qgssymbollayerutils.h"
21 #include "qgsspatialindex.h"
22 #include "qgsmultipoint.h"
23 #include "qgslogger.h"
24 
25 #include <QDomElement>
26 #include <QPainter>
27 
28 #include <cmath>
29 
30 QgsPointDistanceRenderer::QgsPointDistanceRenderer( const QString &rendererName, const QString &labelAttributeName )
31  : QgsFeatureRenderer( rendererName )
32  , mLabelAttributeName( labelAttributeName )
33  , mLabelIndex( -1 )
34  , mTolerance( 3 )
35  , mToleranceUnit( QgsUnitTypes::RenderMillimeters )
36  , mDrawLabels( true )
37 
38 {
40 }
41 
42 void QgsPointDistanceRenderer::toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const
43 {
44  mRenderer->toSld( doc, element, props );
45 }
46 
47 
48 bool QgsPointDistanceRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
49 {
50  Q_UNUSED( drawVertexMarker )
51  Q_UNUSED( context )
52  Q_UNUSED( layer )
53 
54  /*
55  * IMPORTANT: This algorithm is ported to Python in the processing "Points Displacement" algorithm.
56  * Please port any changes/improvements to that algorithm too!
57  */
58 
59  //check if there is already a point at that position
60  if ( !feature.hasGeometry() )
61  return false;
62 
63  QgsMarkerSymbol *symbol = firstSymbolForFeature( feature, context );
64 
65  //if the feature has no symbol (e.g., no matching rule in a rule-based renderer), skip it
66  if ( !symbol )
67  return false;
68 
69  //point position in screen coords
70  QgsGeometry geom = feature.geometry();
71  QgsWkbTypes::Type geomType = geom.wkbType();
72  if ( QgsWkbTypes::flatType( geomType ) != QgsWkbTypes::Point )
73  {
74  //can only render point type
75  return false;
76  }
77 
78  QString label;
79  if ( mDrawLabels )
80  {
81  label = getLabel( feature );
82  }
83 
85  QgsFeature transformedFeature = feature;
86  if ( xform.isValid() )
87  {
88  geom.transform( xform );
89  transformedFeature.setGeometry( geom );
90  }
91 
92  double searchDistance = context.convertToMapUnits( mTolerance, mToleranceUnit, mToleranceMapUnitScale );
93  QgsPointXY point = transformedFeature.geometry().asPoint();
94  QList<QgsFeatureId> intersectList = mSpatialIndex->intersects( searchRect( point, searchDistance ) );
95  if ( intersectList.empty() )
96  {
97  mSpatialIndex->addFeature( transformedFeature );
98  // create new group
99  ClusteredGroup newGroup;
100  newGroup << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
101  mClusteredGroups.push_back( newGroup );
102  // add to group index
103  mGroupIndex.insert( transformedFeature.id(), mClusteredGroups.count() - 1 );
104  mGroupLocations.insert( transformedFeature.id(), point );
105  }
106  else
107  {
108  // find group with closest location to this point (may be more than one within search tolerance)
109  QgsFeatureId minDistFeatureId = intersectList.at( 0 );
110  double minDist = mGroupLocations.value( minDistFeatureId ).distance( point );
111  for ( int i = 1; i < intersectList.count(); ++i )
112  {
113  QgsFeatureId candidateId = intersectList.at( i );
114  double newDist = mGroupLocations.value( candidateId ).distance( point );
115  if ( newDist < minDist )
116  {
117  minDist = newDist;
118  minDistFeatureId = candidateId;
119  }
120  }
121 
122  int groupIdx = mGroupIndex[ minDistFeatureId ];
123  ClusteredGroup &group = mClusteredGroups[groupIdx];
124 
125  // calculate new centroid of group
126  QgsPointXY oldCenter = mGroupLocations.value( minDistFeatureId );
127  mGroupLocations[ minDistFeatureId ] = QgsPointXY( ( oldCenter.x() * group.size() + point.x() ) / ( group.size() + 1.0 ),
128  ( oldCenter.y() * group.size() + point.y() ) / ( group.size() + 1.0 ) );
129 
130  // add to a group
131  group << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
132  // add to group index
133  mGroupIndex.insert( transformedFeature.id(), groupIdx );
134  }
135 
136  return true;
137 }
138 
139 void QgsPointDistanceRenderer::drawGroup( const ClusteredGroup &group, QgsRenderContext &context )
140 {
141  //calculate centroid of all points, this will be center of group
142  QgsMultiPoint *groupMultiPoint = new QgsMultiPoint();
143  const auto constGroup = group;
144  for ( const GroupedFeature &f : constGroup )
145  {
146  groupMultiPoint->addGeometry( f.feature.geometry().constGet()->clone() );
147  }
148  QgsGeometry groupGeom( groupMultiPoint );
149  QgsGeometry centroid = groupGeom.centroid();
150  QPointF pt = centroid.asQPointF();
151  context.mapToPixel().transformInPlace( pt.rx(), pt.ry() );
152 
153  context.expressionContext().appendScope( createGroupScope( group ) );
154  drawGroup( pt, context, group );
155  delete context.expressionContext().popScope();
156 }
157 
159 {
160  mRenderer.reset( r );
161 }
162 
164 {
165  return mRenderer.get();
166 }
167 
168 void QgsPointDistanceRenderer::setLegendSymbolItem( const QString &key, QgsSymbol *symbol )
169 {
170  if ( !mRenderer )
171  return;
172 
173  mRenderer->setLegendSymbolItem( key, symbol );
174 }
175 
177 {
178  if ( !mRenderer )
179  return false;
180 
181  return mRenderer->legendSymbolItemsCheckable();
182 }
183 
185 {
186  if ( !mRenderer )
187  return false;
188 
189  return mRenderer->legendSymbolItemChecked( key );
190 }
191 
192 void QgsPointDistanceRenderer::checkLegendSymbolItem( const QString &key, bool state )
193 {
194  if ( !mRenderer )
195  return;
196 
197  mRenderer->checkLegendSymbolItem( key, state );
198 }
199 
201 {
202  if ( !mRenderer )
203  return QgsFeatureRenderer::filter( fields );
204  else
205  return mRenderer->filter( fields );
206 }
207 
208 QSet<QString> QgsPointDistanceRenderer::usedAttributes( const QgsRenderContext &context ) const
209 {
210  QSet<QString> attributeList;
211  if ( !mLabelAttributeName.isEmpty() )
212  {
213  attributeList.insert( mLabelAttributeName );
214  }
215  if ( mRenderer )
216  {
217  attributeList += mRenderer->usedAttributes( context );
218  }
219  return attributeList;
220 }
221 
223 {
224  return mRenderer ? mRenderer->filterNeedsGeometry() : false;
225 }
226 
227 QgsFeatureRenderer::Capabilities QgsPointDistanceRenderer::capabilities()
228 {
229  if ( !mRenderer )
230  {
231  return nullptr;
232  }
233  return mRenderer->capabilities();
234 }
235 
237 {
238  if ( !mRenderer )
239  {
240  return QgsSymbolList();
241  }
242  return mRenderer->symbols( context );
243 }
244 
246 {
247  if ( !mRenderer )
248  {
249  return nullptr;
250  }
251  return mRenderer->symbolForFeature( feature, context );
252 }
253 
255 {
256  if ( !mRenderer )
257  return nullptr;
258  return mRenderer->originalSymbolForFeature( feature, context );
259 }
260 
262 {
263  if ( !mRenderer )
264  {
265  return QgsSymbolList();
266  }
267  return mRenderer->symbolsForFeature( feature, context );
268 }
269 
271 {
272  if ( !mRenderer )
273  return QgsSymbolList();
274  return mRenderer->originalSymbolsForFeature( feature, context );
275 }
276 
277 QSet< QString > QgsPointDistanceRenderer::legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const
278 {
279  if ( !mRenderer )
280  return QSet< QString >() << QString();
281  return mRenderer->legendKeysForFeature( feature, context );
282 }
283 
285 {
286  if ( !mRenderer )
287  {
288  return false;
289  }
290  return mRenderer->willRenderFeature( feature, context );
291 }
292 
293 
295 {
296  QgsFeatureRenderer::startRender( context, fields );
297 
298  mRenderer->startRender( context, fields );
299 
300  mClusteredGroups.clear();
301  mGroupIndex.clear();
302  mGroupLocations.clear();
304 
305  if ( mLabelAttributeName.isEmpty() )
306  {
307  mLabelIndex = -1;
308  }
309  else
310  {
312  }
313 
314  if ( mMinLabelScale <= 0 || context.rendererScale() < mMinLabelScale )
315  {
316  mDrawLabels = true;
317  }
318  else
319  {
320  mDrawLabels = false;
321  }
322 }
323 
325 {
327 
328  //printInfoDisplacementGroups(); //just for debugging
329 
330  if ( !context.renderingStopped() )
331  {
332  const auto constMClusteredGroups = mClusteredGroups;
333  for ( const ClusteredGroup &group : constMClusteredGroups )
334  {
335  drawGroup( group, context );
336  }
337  }
338 
339  mClusteredGroups.clear();
340  mGroupIndex.clear();
341  mGroupLocations.clear();
342  delete mSpatialIndex;
343  mSpatialIndex = nullptr;
344 
345  mRenderer->stopRender( context );
346 }
347 
349 {
350  if ( mRenderer )
351  {
352  return mRenderer->legendSymbolItems();
353  }
354  return QgsLegendSymbolList();
355 }
356 
357 QgsRectangle QgsPointDistanceRenderer::searchRect( const QgsPointXY &p, double distance ) const
358 {
359  return QgsRectangle( p.x() - distance, p.y() - distance, p.x() + distance, p.y() + distance );
360 }
361 
362 void QgsPointDistanceRenderer::printGroupInfo() const
363 {
364 #ifdef QGISDEBUG
365  int nGroups = mClusteredGroups.size();
366  QgsDebugMsg( "number of displacement groups:" + QString::number( nGroups ) );
367  for ( int i = 0; i < nGroups; ++i )
368  {
369  QgsDebugMsg( "***************displacement group " + QString::number( i ) );
370  const auto constAt = mClusteredGroups.at( i );
371  for ( const GroupedFeature &feature : constAt )
372  {
373  QgsDebugMsg( FID_TO_STRING( feature.feature.id() ) );
374  }
375  }
376 #endif
377 }
378 
379 QString QgsPointDistanceRenderer::getLabel( const QgsFeature &feature ) const
380 {
381  QString attribute;
382  QgsAttributes attrs = feature.attributes();
383  if ( mLabelIndex >= 0 && mLabelIndex < attrs.count() )
384  {
385  attribute = attrs.at( mLabelIndex ).toString();
386  }
387  return attribute;
388 }
389 
390 void QgsPointDistanceRenderer::drawLabels( QPointF centerPoint, QgsSymbolRenderContext &context, const QList<QPointF> &labelShifts, const ClusteredGroup &group )
391 {
392  QPainter *p = context.renderContext().painter();
393  if ( !p )
394  {
395  return;
396  }
397 
398  QPen labelPen( mLabelColor );
399  p->setPen( labelPen );
400 
401  //scale font (for printing)
402  QFont pixelSizeFont = mLabelFont;
403 
404  const double fontSizeInPixels = context.renderContext().convertToPainterUnits( mLabelFont.pointSizeF(), QgsUnitTypes::RenderPoints );
405  pixelSizeFont.setPixelSize( static_cast< int >( std::round( fontSizeInPixels ) ) );
406  QFont scaledFont = pixelSizeFont;
407  scaledFont.setPixelSize( pixelSizeFont.pixelSize() );
408  p->setFont( scaledFont );
409 
410  QFontMetricsF fontMetrics( pixelSizeFont );
411  QPointF currentLabelShift; //considers the signs to determine the label position
412 
413  QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
414  ClusteredGroup::const_iterator groupIt = group.constBegin();
415 
416  for ( ; labelPosIt != labelShifts.constEnd() && groupIt != group.constEnd(); ++labelPosIt, ++groupIt )
417  {
418  currentLabelShift = *labelPosIt;
419  if ( currentLabelShift.x() < 0 )
420  {
421  currentLabelShift.setX( currentLabelShift.x() - fontMetrics.width( groupIt->label ) );
422  }
423  if ( currentLabelShift.y() > 0 )
424  {
425  currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
426  }
427 
428  QPointF drawingPoint( centerPoint + currentLabelShift );
429  p->save();
430  p->translate( drawingPoint.x(), drawingPoint.y() );
431  p->drawText( QPointF( 0, 0 ), groupIt->label );
432  p->restore();
433  }
434 }
435 
436 QgsExpressionContextScope *QgsPointDistanceRenderer::createGroupScope( const ClusteredGroup &group ) const
437 {
439  if ( group.size() > 1 )
440  {
441  //scan through symbols to check color, e.g., if all clustered symbols are same color
442  QColor groupColor;
443  ClusteredGroup::const_iterator groupIt = group.constBegin();
444  for ( ; groupIt != group.constEnd(); ++groupIt )
445  {
446  if ( !groupIt->symbol() )
447  continue;
448 
449  if ( !groupColor.isValid() )
450  {
451  groupColor = groupIt->symbol()->color();
452  }
453  else
454  {
455  if ( groupColor != groupIt->symbol()->color() )
456  {
457  groupColor = QColor();
458  break;
459  }
460  }
461  }
462 
463  if ( groupColor.isValid() )
464  {
466  }
467  else
468  {
469  //mixed colors
471  }
472 
474  }
475  if ( !group.empty() )
476  {
477  // data defined properties may require a feature in the expression context, so just use first feature in group
478  clusterScope->setFeature( group.at( 0 ).feature );
479  }
480  return clusterScope;
481 }
482 
483 QgsMarkerSymbol *QgsPointDistanceRenderer::firstSymbolForFeature( const QgsFeature &feature, QgsRenderContext &context )
484 {
485  if ( !mRenderer )
486  {
487  return nullptr;
488  }
489 
490  QgsSymbolList symbolList = mRenderer->symbolsForFeature( feature, context );
491  if ( symbolList.isEmpty() )
492  {
493  return nullptr;
494  }
495 
496  return dynamic_cast< QgsMarkerSymbol * >( symbolList.at( 0 ) );
497 }
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
QgsSpatialIndex * mSpatialIndex
Spatial index for fast lookup of nearby points.
QgsFeatureId id
Definition: qgsfeature.h:64
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
Single variable definition for use within a QgsExpressionContextScope.
double convertToMapUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QString mLabelAttributeName
Attribute name for labeling. An empty string indicates that no labels should be rendered.
double rendererScale() const
Returns the renderer map scale.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
QgsUnitTypes::RenderUnit mToleranceUnit
Unit for distance tolerance.
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns list of symbols used for rendering the feature.
bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:61
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
QgsPointDistanceRenderer(const QString &rendererName, const QString &labelAttributeName=QString())
Constructor for QgsPointDistanceRenderer.
Multi point geometry collection.
Definition: qgsmultipoint.h:29
QgsFeatureRenderer::Capabilities capabilities() override
Returns details about internals of this renderer.
void checkLegendSymbolItem(const QString &key, bool state) override
item in symbology was checked
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
double y
Definition: qgspointxy.h:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
Helper functions for various unit types.
Definition: qgsunittypes.h:38
virtual QString filter(const QgsFields &fields=QgsFields())
If a renderer does not require all the features this method may be overridden and return an expressio...
Definition: qgsrenderer.h:193
qint64 QgsFeatureId
Definition: qgsfeatureid.h:25
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const override
used from subclasses to create SLD Rule elements following SLD v1.1 specs
Container of fields for a vector layer.
Definition: qgsfields.h:42
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
QMap< QgsFeatureId, int > mGroupIndex
Mapping of feature ID to the feature&#39;s group index.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QMap< QString, QString > QgsStringMap
Definition: qgis.h:587
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:766
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
bool mDrawLabels
Whether labels should be drawn for points. This is set internally from startRender() depending on sca...
double mMinLabelScale
Maximum scale denominator for label display. A zero value indicates no scale limitation.
void drawLabels(QPointF centerPoint, QgsSymbolRenderContext &context, const QList< QPointF > &labelShifts, const ClusteredGroup &group)
Renders the labels for a group.
static QString encodeColor(const QColor &color)
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43
double mTolerance
Distance tolerance. Points that are closer together than this distance are considered clustered...
QMap< QgsFeatureId, QgsPointXY > mGroupLocations
Mapping of feature ID to approximate group location.
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns whether the renderer will render a feature or not.
QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
QColor mLabelColor
Label text color.
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
QgsRenderContext & renderContext()
Returns a reference to the context&#39;s render context.
Definition: qgssymbol.h:574
QgsMapUnitScale mToleranceMapUnitScale
Map unit scale for distance tolerance.
double x
Definition: qgspointxy.h:47
bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
QgsExpressionContext & expressionContext()
Gets the expression context.
Contains properties for a feature within a clustered group.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
QString filter(const QgsFields &fields=QgsFields()) override
If a renderer does not require all the features this method may be overridden and return an expressio...
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
A spatial index for QgsFeature objects.
QPainter * painter()
Returns the destination QPainter for the render operation.
const QgsMapToPixel & mapToPixel() const
Returns the context&#39;s map to pixel transform, which transforms between map coordinates and device coo...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
#define FID_TO_STRING(fid)
Definition: qgsfeatureid.h:30
Points (e.g., for font sizes)
Definition: qgsunittypes.h:117
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:93
std::unique_ptr< QgsFeatureRenderer > mRenderer
Embedded base renderer. This can be used for rendering individual, isolated points.
QPointF asQPointF() const
Returns contents of the geometry as a QPointF if wkbType is WKBPoint, otherwise returns a null QPoint...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
Class for doing transforms between two map coordinate systems.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
QList< QgsPointDistanceRenderer::GroupedFeature > ClusteredGroup
A group of clustered points (ie features within the distance tolerance).
bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override SIP_THROW(QgsCsException)
Render a feature using this renderer in the given context.
QgsGeometry geometry
Definition: qgsfeature.h:67
QList< ClusteredGroup > mClusteredGroups
Groups of features that are considered clustered together.
int mLabelIndex
Label attribute index (or -1 if none). This index is not stored, it is requested in the startRender()...
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a feature to the index.
void setEmbeddedRenderer(QgsFeatureRenderer *r) override
Sets an embedded renderer (subrenderer) for this feature renderer.
static QgsFeatureRenderer * defaultRenderer(QgsWkbTypes::GeometryType geomType)
Returns a new renderer - used by default in vector layers.
Definition: qgsrenderer.cpp:76
A vector of attributes.
Definition: qgsattributes.h:57
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:430
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
QgsAttributes attributes
Definition: qgsfeature.h:65
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:1641
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.