QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
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( Qgis::RenderUnit::Millimeters )
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 Qgis::WkbType geomType = geom.wkbType();
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 
97  const QgsGeometry transformedGeometry = transformedFeature.geometry();
98  for ( auto partIt = transformedGeometry.const_parts_begin(); partIt != transformedGeometry.const_parts_end(); ++partIt )
99  {
100  const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( *partIt );
101  // create a new feature which is JUST this point, no other parts from the multi-point
102  QgsFeature pointFeature = transformedFeature;
103  pointFeature.setGeometry( QgsGeometry( point->clone() ) );
104  const QList<QgsFeatureId> intersectList = mSpatialIndex->intersects( searchRect( point, searchDistance ) );
105  if ( intersectList.empty() )
106  {
107  mSpatialIndex->addFeature( pointFeature );
108  // create new group
109  ClusteredGroup newGroup;
110  newGroup << GroupedFeature( pointFeature, symbol->clone(), selected, label );
111  mClusteredGroups.push_back( newGroup );
112  // add to group index
113  mGroupIndex.insert( pointFeature.id(), mClusteredGroups.count() - 1 );
114  mGroupLocations.insert( pointFeature.id(), QgsPointXY( *point ) );
115  }
116  else
117  {
118  // find group with closest location to this point (may be more than one within search tolerance)
119  QgsFeatureId minDistFeatureId = intersectList.at( 0 );
120  double minDist = mGroupLocations.value( minDistFeatureId ).distance( point->x(), point->y() );
121  for ( int i = 1; i < intersectList.count(); ++i )
122  {
123  const QgsFeatureId candidateId = intersectList.at( i );
124  const double newDist = mGroupLocations.value( candidateId ).distance( point->x(), point->y() );
125  if ( newDist < minDist )
126  {
127  minDist = newDist;
128  minDistFeatureId = candidateId;
129  }
130  }
131 
132  const int groupIdx = mGroupIndex[ minDistFeatureId ];
133  ClusteredGroup &group = mClusteredGroups[groupIdx];
134 
135  // calculate new centroid of group
136  const QgsPointXY oldCenter = mGroupLocations.value( minDistFeatureId );
137  mGroupLocations[ minDistFeatureId ] = QgsPointXY( ( oldCenter.x() * group.size() + point->x() ) / ( group.size() + 1.0 ),
138  ( oldCenter.y() * group.size() + point->y() ) / ( group.size() + 1.0 ) );
139 
140  // add to a group
141  group << GroupedFeature( pointFeature, symbol->clone(), selected, label );
142  // add to group index
143  mGroupIndex.insert( pointFeature.id(), groupIdx );
144  }
145  }
146 
147  return true;
148 }
149 
150 void QgsPointDistanceRenderer::drawGroup( const ClusteredGroup &group, QgsRenderContext &context ) const
151 {
152  //calculate centroid of all points, this will be center of group
153  QgsMultiPoint *groupMultiPoint = new QgsMultiPoint();
154  const auto constGroup = group;
155  for ( const GroupedFeature &f : constGroup )
156  {
157  groupMultiPoint->addGeometry( f.feature.geometry().constGet()->clone() );
158  }
159  const QgsGeometry groupGeom( groupMultiPoint );
160  const QgsGeometry centroid = groupGeom.centroid();
161  QPointF pt = centroid.asQPointF();
162  context.mapToPixel().transformInPlace( pt.rx(), pt.ry() );
163 
164  const QgsExpressionContextScopePopper scopePopper( context.expressionContext(), createGroupScope( group ) );
165  drawGroup( pt, context, group );
166 }
167 
169 {
170  mRenderer.reset( r );
171 }
172 
174 {
175  return mRenderer.get();
176 }
177 
178 void QgsPointDistanceRenderer::setLegendSymbolItem( const QString &key, QgsSymbol *symbol )
179 {
180  if ( !mRenderer )
181  return;
182 
183  mRenderer->setLegendSymbolItem( key, symbol );
184 }
185 
187 {
188  if ( !mRenderer )
189  return false;
190 
191  return mRenderer->legendSymbolItemsCheckable();
192 }
193 
195 {
196  if ( !mRenderer )
197  return false;
198 
199  return mRenderer->legendSymbolItemChecked( key );
200 }
201 
202 void QgsPointDistanceRenderer::checkLegendSymbolItem( const QString &key, bool state )
203 {
204  if ( !mRenderer )
205  return;
206 
207  mRenderer->checkLegendSymbolItem( key, state );
208 }
209 
211 {
212  if ( !mRenderer )
213  return QgsFeatureRenderer::filter( fields );
214  else
215  return mRenderer->filter( fields );
216 }
217 
219 {
220  if ( mRenderer )
221  if ( !mRenderer->accept( visitor ) )
222  return false;
223 
224  return true;
225 }
226 
227 QSet<QString> QgsPointDistanceRenderer::usedAttributes( const QgsRenderContext &context ) const
228 {
229  QSet<QString> attributeList;
230  if ( !mLabelAttributeName.isEmpty() )
231  {
232  attributeList.insert( mLabelAttributeName );
233  }
234  if ( mRenderer )
235  {
236  attributeList += mRenderer->usedAttributes( context );
237  }
238  return attributeList;
239 }
240 
242 {
243  return mRenderer ? mRenderer->filterNeedsGeometry() : false;
244 }
245 
247 {
248  if ( !mRenderer )
249  {
250  return Capabilities();
251  }
252  return mRenderer->capabilities();
253 }
254 
256 {
257  if ( !mRenderer )
258  {
259  return QgsSymbolList();
260  }
261  return mRenderer->symbols( context );
262 }
263 
265 {
266  if ( !mRenderer )
267  {
268  return nullptr;
269  }
270  return mRenderer->symbolForFeature( feature, context );
271 }
272 
274 {
275  if ( !mRenderer )
276  return nullptr;
277  return mRenderer->originalSymbolForFeature( feature, context );
278 }
279 
281 {
282  if ( !mRenderer )
283  {
284  return QgsSymbolList();
285  }
286  return mRenderer->symbolsForFeature( feature, context );
287 }
288 
290 {
291  if ( !mRenderer )
292  return QgsSymbolList();
293  return mRenderer->originalSymbolsForFeature( feature, context );
294 }
295 
296 QSet< QString > QgsPointDistanceRenderer::legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const
297 {
298  if ( !mRenderer )
299  return QSet< QString >() << QString();
300  return mRenderer->legendKeysForFeature( feature, context );
301 }
302 
303 QString QgsPointDistanceRenderer::legendKeyToExpression( const QString &key, QgsVectorLayer *layer, bool &ok ) const
304 {
305  ok = false;
306  if ( !mRenderer )
307  return QString();
308  return mRenderer->legendKeyToExpression( key, layer, ok );
309 }
310 
312 {
313  if ( !mRenderer )
314  {
315  return false;
316  }
317  return mRenderer->willRenderFeature( feature, context );
318 }
319 
320 
322 {
323  QgsFeatureRenderer::startRender( context, fields );
324 
325  mRenderer->startRender( context, fields );
326 
327  mClusteredGroups.clear();
328  mGroupIndex.clear();
329  mGroupLocations.clear();
331 
332  if ( mLabelAttributeName.isEmpty() )
333  {
334  mLabelIndex = -1;
335  }
336  else
337  {
339  }
340 
341  if ( mMinLabelScale <= 0 || context.rendererScale() < mMinLabelScale )
342  {
343  mDrawLabels = true;
344  }
345  else
346  {
347  mDrawLabels = false;
348  }
349 }
350 
352 {
354 
355  //printInfoDisplacementGroups(); //just for debugging
356 
357  if ( !context.renderingStopped() )
358  {
359  const auto constMClusteredGroups = mClusteredGroups;
360  for ( const ClusteredGroup &group : constMClusteredGroups )
361  {
362  drawGroup( group, context );
363  }
364  }
365 
366  mClusteredGroups.clear();
367  mGroupIndex.clear();
368  mGroupLocations.clear();
369  delete mSpatialIndex;
370  mSpatialIndex = nullptr;
371 
372  mRenderer->stopRender( context );
373 }
374 
376 {
377  if ( mRenderer )
378  {
379  return mRenderer->legendSymbolItems();
380  }
381  return QgsLegendSymbolList();
382 }
383 
384 QgsRectangle QgsPointDistanceRenderer::searchRect( const QgsPoint *p, double distance ) const
385 {
386  return QgsRectangle( p->x() - distance, p->y() - distance, p->x() + distance, p->y() + distance );
387 }
388 
389 void QgsPointDistanceRenderer::printGroupInfo() const
390 {
391 #ifdef QGISDEBUG
392  const int nGroups = mClusteredGroups.size();
393  QgsDebugMsgLevel( "number of displacement groups:" + QString::number( nGroups ), 3 );
394  for ( int i = 0; i < nGroups; ++i )
395  {
396  QgsDebugMsgLevel( "***************displacement group " + QString::number( i ), 3 );
397  const auto constAt = mClusteredGroups.at( i );
398  for ( const GroupedFeature &feature : constAt )
399  {
400  QgsDebugMsgLevel( FID_TO_STRING( feature.feature.id() ), 3 );
401  }
402  }
403 #endif
404 }
405 
406 QString QgsPointDistanceRenderer::getLabel( const QgsFeature &feature ) const
407 {
408  QString attribute;
409  const QgsAttributes attrs = feature.attributes();
410  if ( mLabelIndex >= 0 && mLabelIndex < attrs.count() )
411  {
412  attribute = attrs.at( mLabelIndex ).toString();
413  }
414  return attribute;
415 }
416 
417 void QgsPointDistanceRenderer::drawLabels( QPointF centerPoint, QgsSymbolRenderContext &context, const QList<QPointF> &labelShifts, const ClusteredGroup &group ) const
418 {
419  QPainter *p = context.renderContext().painter();
420  if ( !p )
421  {
422  return;
423  }
424 
425  const QPen labelPen( mLabelColor );
426  p->setPen( labelPen );
427 
428  //scale font (for printing)
429  QFont pixelSizeFont = mLabelFont;
430 
431  const double fontSizeInPixels = context.renderContext().convertToPainterUnits( mLabelFont.pointSizeF(), Qgis::RenderUnit::Points );
432  pixelSizeFont.setPixelSize( static_cast< int >( std::round( fontSizeInPixels ) ) );
433  QFont scaledFont = pixelSizeFont;
434  scaledFont.setPixelSize( pixelSizeFont.pixelSize() );
435  p->setFont( scaledFont );
436 
437  const QFontMetricsF fontMetrics( pixelSizeFont );
438  QPointF currentLabelShift; //considers the signs to determine the label position
439 
440  QList<QPointF>::const_iterator labelPosIt = labelShifts.constBegin();
441  ClusteredGroup::const_iterator groupIt = group.constBegin();
442 
443  for ( ; labelPosIt != labelShifts.constEnd() && groupIt != group.constEnd(); ++labelPosIt, ++groupIt )
444  {
445  currentLabelShift = *labelPosIt;
446  if ( currentLabelShift.x() < 0 )
447  {
448  currentLabelShift.setX( currentLabelShift.x() - fontMetrics.horizontalAdvance( groupIt->label ) );
449  }
450  if ( currentLabelShift.y() > 0 )
451  {
452  currentLabelShift.setY( currentLabelShift.y() + fontMetrics.ascent() );
453  }
454 
455  const QPointF drawingPoint( centerPoint + currentLabelShift );
456  const QgsScopedQPainterState painterState( p );
457  p->translate( drawingPoint.x(), drawingPoint.y() );
458  p->drawText( QPointF( 0, 0 ), groupIt->label );
459  }
460 }
461 
462 QgsExpressionContextScope *QgsPointDistanceRenderer::createGroupScope( const ClusteredGroup &group ) const
463 {
465  if ( group.size() > 1 )
466  {
467  //scan through symbols to check color, e.g., if all clustered symbols are same color
468  QColor groupColor;
469  ClusteredGroup::const_iterator groupIt = group.constBegin();
470  for ( ; groupIt != group.constEnd(); ++groupIt )
471  {
472  if ( !groupIt->symbol() )
473  continue;
474 
475  if ( !groupColor.isValid() )
476  {
477  groupColor = groupIt->symbol()->color();
478  }
479  else
480  {
481  if ( groupColor != groupIt->symbol()->color() )
482  {
483  groupColor = QColor();
484  break;
485  }
486  }
487  }
488 
489  if ( groupColor.isValid() )
490  {
492  }
493  else
494  {
495  //mixed colors
497  }
498 
500  }
501  if ( !group.empty() )
502  {
503  // data defined properties may require a feature in the expression context, so just use first feature in group
504  clusterScope->setFeature( group.at( 0 ).feature );
505  }
506  return clusterScope;
507 }
508 
509 QgsMarkerSymbol *QgsPointDistanceRenderer::firstSymbolForFeature( const QgsFeature &feature, QgsRenderContext &context )
510 {
511  if ( !mRenderer )
512  {
513  return nullptr;
514  }
515 
516  const QgsSymbolList symbolList = mRenderer->symbolsForFeature( feature, context );
517  if ( symbolList.isEmpty() )
518  {
519  return nullptr;
520  }
521 
522  return dynamic_cast< QgsMarkerSymbol * >( symbolList.at( 0 ) );
523 }
524 
525 QgsPointDistanceRenderer::GroupedFeature::GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol, bool isSelected, const QString &label )
526  : feature( feature )
527  , isSelected( isSelected )
528  , label( label )
529  , mSymbol( symbol )
530 {}
531 
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:54
@ Points
Points (e.g., for font sizes)
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:182
virtual QgsPoint centroid() const
Returns the centroid of the geometry.
A vector of attributes.
Definition: qgsattributes.h:59
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.
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:213
static QgsFeatureRenderer * defaultRenderer(Qgis::GeometryType geomType)
Returns a new renderer - used by default in vector layers.
Definition: qgsrenderer.cpp:73
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
QFlags< Capability > Capabilities
Definition: qgsrenderer.h:276
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:90
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:230
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:167
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:359
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:162
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
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:29
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
Returns true if the legend symbology item with the specified key 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.
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 drawLabels(QPointF centerPoint, QgsSymbolRenderContext &context, const QList< QPointF > &labelShifts, const ClusteredGroup &group) const
Renders the labels for a group.
bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override
Render a feature using this renderer in the given context.
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
QString legendKeyToExpression(const QString &key, QgsVectorLayer *layer, bool &ok) const override
Attempts to convert the specified legend rule key to a QGIS expression matching the features displaye...
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
Returns true if symbology items in legend are 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
Sets whether the legend symbology item with the specified ley should be checked.
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.
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).
Qgis::RenderUnit mToleranceUnit
Unit for 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:60
double y
Definition: qgspointxy.h:64
Q_GADGET double x
Definition: qgspointxy.h:63
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Q_GADGET double x
Definition: qgspoint.h:52
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgspoint.cpp:105
double y
Definition: qgspoint.h:53
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Contains information about the context of a rendering operation.
double convertToMapUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
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...
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:94
Represents a vector layer which manages a vector based data sets.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:862
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.