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