QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 #include "qgsmarkersymbol.h"
27 
28 #include <QDomElement>
29 #include <QPainter>
30 
31 #include <cmath>
32 
33 QgsPointDistanceRenderer::QgsPointDistanceRenderer( const QString &rendererName, const QString &labelAttributeName )
34  : QgsFeatureRenderer( rendererName )
35  , mLabelAttributeName( labelAttributeName )
36  , mLabelIndex( -1 )
37  , mTolerance( 3 )
38  , mToleranceUnit( QgsUnitTypes::RenderMillimeters )
39  , mDrawLabels( true )
40 
41 {
43 }
44 
45 void QgsPointDistanceRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
46 {
47  mRenderer->toSld( doc, element, props );
48 }
49 
50 
51 bool QgsPointDistanceRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
52 {
53  Q_UNUSED( drawVertexMarker )
54  Q_UNUSED( context )
55  Q_UNUSED( layer )
56 
57  /*
58  * IMPORTANT: This algorithm is ported to Python in the processing "Points Displacement" algorithm.
59  * Please port any changes/improvements to that algorithm too!
60  */
61 
62  //check if there is already a point at that position
63  if ( !feature.hasGeometry() )
64  return false;
65 
66  QgsMarkerSymbol *symbol = firstSymbolForFeature( feature, context );
67 
68  //if the feature has no symbol (e.g., no matching rule in a rule-based renderer), skip it
69  if ( !symbol )
70  return false;
71 
72  //point position in screen coords
73  QgsGeometry geom = feature.geometry();
74  const QgsWkbTypes::Type geomType = geom.wkbType();
75  if ( QgsWkbTypes::flatType( geomType ) != QgsWkbTypes::Point )
76  {
77  //can only render point type
78  return false;
79  }
80 
81  QString label;
82  if ( mDrawLabels )
83  {
84  label = getLabel( feature );
85  }
86 
87  const QgsCoordinateTransform xform = context.coordinateTransform();
88  QgsFeature transformedFeature = feature;
89  if ( xform.isValid() )
90  {
91  geom.transform( xform );
92  transformedFeature.setGeometry( geom );
93  }
94 
95  const double searchDistance = context.convertToMapUnits( mTolerance, mToleranceUnit, mToleranceMapUnitScale );
96  const QgsPointXY point = transformedFeature.geometry().asPoint();
97  const QList<QgsFeatureId> intersectList = mSpatialIndex->intersects( searchRect( point, searchDistance ) );
98  if ( intersectList.empty() )
99  {
100  mSpatialIndex->addFeature( transformedFeature );
101  // create new group
102  ClusteredGroup newGroup;
103  newGroup << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
104  mClusteredGroups.push_back( newGroup );
105  // add to group index
106  mGroupIndex.insert( transformedFeature.id(), mClusteredGroups.count() - 1 );
107  mGroupLocations.insert( transformedFeature.id(), point );
108  }
109  else
110  {
111  // find group with closest location to this point (may be more than one within search tolerance)
112  QgsFeatureId minDistFeatureId = intersectList.at( 0 );
113  double minDist = mGroupLocations.value( minDistFeatureId ).distance( point );
114  for ( int i = 1; i < intersectList.count(); ++i )
115  {
116  const QgsFeatureId candidateId = intersectList.at( i );
117  const double newDist = mGroupLocations.value( candidateId ).distance( point );
118  if ( newDist < minDist )
119  {
120  minDist = newDist;
121  minDistFeatureId = candidateId;
122  }
123  }
124 
125  const int groupIdx = mGroupIndex[ minDistFeatureId ];
126  ClusteredGroup &group = mClusteredGroups[groupIdx];
127 
128  // calculate new centroid of group
129  const QgsPointXY oldCenter = mGroupLocations.value( minDistFeatureId );
130  mGroupLocations[ minDistFeatureId ] = QgsPointXY( ( oldCenter.x() * group.size() + point.x() ) / ( group.size() + 1.0 ),
131  ( oldCenter.y() * group.size() + point.y() ) / ( group.size() + 1.0 ) );
132 
133  // add to a group
134  group << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
135  // add to group index
136  mGroupIndex.insert( transformedFeature.id(), groupIdx );
137  }
138 
139  return true;
140 }
141 
142 void QgsPointDistanceRenderer::drawGroup( const ClusteredGroup &group, QgsRenderContext &context )
143 {
144  //calculate centroid of all points, this will be center of group
145  QgsMultiPoint *groupMultiPoint = new QgsMultiPoint();
146  const auto constGroup = group;
147  for ( const GroupedFeature &f : constGroup )
148  {
149  groupMultiPoint->addGeometry( f.feature.geometry().constGet()->clone() );
150  }
151  const QgsGeometry groupGeom( groupMultiPoint );
152  const QgsGeometry centroid = groupGeom.centroid();
153  QPointF pt = centroid.asQPointF();
154  context.mapToPixel().transformInPlace( pt.rx(), pt.ry() );
155 
156  const QgsExpressionContextScopePopper scopePopper( context.expressionContext(), createGroupScope( group ) );
157  drawGroup( pt, context, group );
158 }
159 
161 {
162  mRenderer.reset( r );
163 }
164 
166 {
167  return mRenderer.get();
168 }
169 
170 void QgsPointDistanceRenderer::setLegendSymbolItem( const QString &key, QgsSymbol *symbol )
171 {
172  if ( !mRenderer )
173  return;
174 
175  mRenderer->setLegendSymbolItem( key, symbol );
176 }
177 
179 {
180  if ( !mRenderer )
181  return false;
182 
183  return mRenderer->legendSymbolItemsCheckable();
184 }
185 
187 {
188  if ( !mRenderer )
189  return false;
190 
191  return mRenderer->legendSymbolItemChecked( key );
192 }
193 
194 void QgsPointDistanceRenderer::checkLegendSymbolItem( const QString &key, bool state )
195 {
196  if ( !mRenderer )
197  return;
198 
199  mRenderer->checkLegendSymbolItem( key, state );
200 }
201 
203 {
204  if ( !mRenderer )
205  return QgsFeatureRenderer::filter( fields );
206  else
207  return mRenderer->filter( fields );
208 }
209 
211 {
212  if ( mRenderer )
213  if ( !mRenderer->accept( visitor ) )
214  return false;
215 
216  return true;
217 }
218 
219 QSet<QString> QgsPointDistanceRenderer::usedAttributes( const QgsRenderContext &context ) const
220 {
221  QSet<QString> attributeList;
222  if ( !mLabelAttributeName.isEmpty() )
223  {
224  attributeList.insert( mLabelAttributeName );
225  }
226  if ( mRenderer )
227  {
228  attributeList += mRenderer->usedAttributes( context );
229  }
230  return attributeList;
231 }
232 
234 {
235  return mRenderer ? mRenderer->filterNeedsGeometry() : false;
236 }
237 
238 QgsFeatureRenderer::Capabilities QgsPointDistanceRenderer::capabilities()
239 {
240  if ( !mRenderer )
241  {
242  return Capabilities();
243  }
244  return mRenderer->capabilities();
245 }
246 
248 {
249  if ( !mRenderer )
250  {
251  return QgsSymbolList();
252  }
253  return mRenderer->symbols( context );
254 }
255 
257 {
258  if ( !mRenderer )
259  {
260  return nullptr;
261  }
262  return mRenderer->symbolForFeature( feature, context );
263 }
264 
266 {
267  if ( !mRenderer )
268  return nullptr;
269  return mRenderer->originalSymbolForFeature( feature, context );
270 }
271 
273 {
274  if ( !mRenderer )
275  {
276  return QgsSymbolList();
277  }
278  return mRenderer->symbolsForFeature( feature, context );
279 }
280 
282 {
283  if ( !mRenderer )
284  return QgsSymbolList();
285  return mRenderer->originalSymbolsForFeature( feature, context );
286 }
287 
288 QSet< QString > QgsPointDistanceRenderer::legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const
289 {
290  if ( !mRenderer )
291  return QSet< QString >() << QString();
292  return mRenderer->legendKeysForFeature( feature, context );
293 }
294 
296 {
297  if ( !mRenderer )
298  {
299  return false;
300  }
301  return mRenderer->willRenderFeature( feature, context );
302 }
303 
304 
306 {
307  QgsFeatureRenderer::startRender( context, fields );
308 
309  mRenderer->startRender( context, fields );
310 
311  mClusteredGroups.clear();
312  mGroupIndex.clear();
313  mGroupLocations.clear();
315 
316  if ( mLabelAttributeName.isEmpty() )
317  {
318  mLabelIndex = -1;
319  }
320  else
321  {
323  }
324 
325  if ( mMinLabelScale <= 0 || context.rendererScale() < mMinLabelScale )
326  {
327  mDrawLabels = true;
328  }
329  else
330  {
331  mDrawLabels = false;
332  }
333 }
334 
336 {
338 
339  //printInfoDisplacementGroups(); //just for debugging
340 
341  if ( !context.renderingStopped() )
342  {
343  const auto constMClusteredGroups = mClusteredGroups;
344  for ( const ClusteredGroup &group : constMClusteredGroups )
345  {
346  drawGroup( group, context );
347  }
348  }
349 
350  mClusteredGroups.clear();
351  mGroupIndex.clear();
352  mGroupLocations.clear();
353  delete mSpatialIndex;
354  mSpatialIndex = nullptr;
355 
356  mRenderer->stopRender( context );
357 }
358 
360 {
361  if ( mRenderer )
362  {
363  return mRenderer->legendSymbolItems();
364  }
365  return QgsLegendSymbolList();
366 }
367 
368 QgsRectangle QgsPointDistanceRenderer::searchRect( const QgsPointXY &p, double distance ) const
369 {
370  return QgsRectangle( p.x() - distance, p.y() - distance, p.x() + distance, p.y() + distance );
371 }
372 
373 void QgsPointDistanceRenderer::printGroupInfo() const
374 {
375 #ifdef QGISDEBUG
376  const int nGroups = mClusteredGroups.size();
377  QgsDebugMsgLevel( "number of displacement groups:" + QString::number( nGroups ), 3 );
378  for ( int i = 0; i < nGroups; ++i )
379  {
380  QgsDebugMsgLevel( "***************displacement group " + QString::number( i ), 3 );
381  const auto constAt = mClusteredGroups.at( i );
382  for ( const GroupedFeature &feature : constAt )
383  {
384  QgsDebugMsgLevel( FID_TO_STRING( feature.feature.id() ), 3 );
385  }
386  }
387 #endif
388 }
389 
390 QString QgsPointDistanceRenderer::getLabel( const QgsFeature &feature ) const
391 {
392  QString attribute;
393  const QgsAttributes attrs = feature.attributes();
394  if ( mLabelIndex >= 0 && mLabelIndex < attrs.count() )
395  {
396  attribute = attrs.at( mLabelIndex ).toString();
397  }
398  return attribute;
399 }
400 
401 void QgsPointDistanceRenderer::drawLabels( QPointF centerPoint, QgsSymbolRenderContext &context, const QList<QPointF> &labelShifts, const ClusteredGroup &group )
402 {
403  QPainter *p = context.renderContext().painter();
404  if ( !p )
405  {
406  return;
407  }
408 
409  const QPen labelPen( mLabelColor );
410  p->setPen( labelPen );
411 
412  //scale font (for printing)
413  QFont pixelSizeFont = mLabelFont;
414 
415  const double fontSizeInPixels = context.renderContext().convertToPainterUnits( mLabelFont.pointSizeF(), QgsUnitTypes::RenderPoints );
416  pixelSizeFont.setPixelSize( static_cast< int >( std::round( fontSizeInPixels ) ) );
417  QFont scaledFont = pixelSizeFont;
418  scaledFont.setPixelSize( pixelSizeFont.pixelSize() );
419  p->setFont( scaledFont );
420 
421  const QFontMetricsF fontMetrics( pixelSizeFont );
422  QPointF currentLabelShift; //considers the signs to determine the label position
423 
424  QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
425  ClusteredGroup::const_iterator groupIt = group.constBegin();
426 
427  for ( ; labelPosIt != labelShifts.constEnd() && groupIt != group.constEnd(); ++labelPosIt, ++groupIt )
428  {
429  currentLabelShift = *labelPosIt;
430  if ( currentLabelShift.x() < 0 )
431  {
432  currentLabelShift.setX( currentLabelShift.x() - fontMetrics.horizontalAdvance( groupIt->label ) );
433  }
434  if ( currentLabelShift.y() > 0 )
435  {
436  currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
437  }
438 
439  const QPointF drawingPoint( centerPoint + currentLabelShift );
440  const QgsScopedQPainterState painterState( p );
441  p->translate( drawingPoint.x(), drawingPoint.y() );
442  p->drawText( QPointF( 0, 0 ), groupIt->label );
443  }
444 }
445 
446 QgsExpressionContextScope *QgsPointDistanceRenderer::createGroupScope( const ClusteredGroup &group ) const
447 {
449  if ( group.size() > 1 )
450  {
451  //scan through symbols to check color, e.g., if all clustered symbols are same color
452  QColor groupColor;
453  ClusteredGroup::const_iterator groupIt = group.constBegin();
454  for ( ; groupIt != group.constEnd(); ++groupIt )
455  {
456  if ( !groupIt->symbol() )
457  continue;
458 
459  if ( !groupColor.isValid() )
460  {
461  groupColor = groupIt->symbol()->color();
462  }
463  else
464  {
465  if ( groupColor != groupIt->symbol()->color() )
466  {
467  groupColor = QColor();
468  break;
469  }
470  }
471  }
472 
473  if ( groupColor.isValid() )
474  {
476  }
477  else
478  {
479  //mixed colors
481  }
482 
484  }
485  if ( !group.empty() )
486  {
487  // data defined properties may require a feature in the expression context, so just use first feature in group
488  clusterScope->setFeature( group.at( 0 ).feature );
489  }
490  return clusterScope;
491 }
492 
493 QgsMarkerSymbol *QgsPointDistanceRenderer::firstSymbolForFeature( const QgsFeature &feature, QgsRenderContext &context )
494 {
495  if ( !mRenderer )
496  {
497  return nullptr;
498  }
499 
500  const QgsSymbolList symbolList = mRenderer->symbolsForFeature( feature, context );
501  if ( symbolList.isEmpty() )
502  {
503  return nullptr;
504  }
505 
506  return dynamic_cast< QgsMarkerSymbol * >( symbolList.at( 0 ) );
507 }
508 
509 QgsPointDistanceRenderer::GroupedFeature::GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol, bool isSelected, const QString &label )
510  : feature( feature )
511  , isSelected( isSelected )
512  , label( label )
513  , mSymbol( symbol )
514 {}
515 
virtual QgsPoint centroid() const
Returns the centroid of the geometry.
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:79
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:206
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:96
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
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:223
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:163
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:125
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
void transformInPlace(double &x, double &y) const
Transforms device coordinates to map coordinates.
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
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:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
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 convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
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...
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.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:38
Helper functions for various unit types.
Definition: qgsunittypes.h:39
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
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:732
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
#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:44
Single variable definition for use within a QgsExpressionContextScope.
Contains properties for a feature within a clustered group.
GroupedFeature(const QgsFeature &feature, QgsMarkerSymbol *symbol, bool isSelected, const QString &label=QString())
Constructor for GroupedFeature.