QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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"
26#include "qgsmarkersymbol.h"
27
28#include <QDomElement>
29#include <QPainter>
30
31#include <cmath>
32
33QgsPointDistanceRenderer::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
45void QgsPointDistanceRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
46{
47 mRenderer->toSld( doc, element, props );
48}
49
50
51bool 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();
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
150void 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
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
202void 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
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
246QgsFeatureRenderer::Capabilities QgsPointDistanceRenderer::capabilities()
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
296QSet< 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
303QString 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
384QgsRectangle 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
389void 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
406QString 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
417void 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(), QgsUnitTypes::RenderPoints );
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
462QgsExpressionContextScope *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
509QgsMarkerSymbol *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
525QgsPointDistanceRenderer::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
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.
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:233
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
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:349
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
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) SIP_THROW(QgsCsException)
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.
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 drawLabels(QPointF centerPoint, QgsSymbolRenderContext &context, const QList< QPointF > &labelShifts, const ClusteredGroup &group) const
Renders the labels for a group.
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
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
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
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:104
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.
QPainter * painter()
Returns the destination QPainter for the render operation.
double rendererScale() const
Returns the renderer map scale.
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).
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...
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:93
Helper functions for various unit types.
Definition: qgsunittypes.h:39
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
Represents a vector layer which manages a vector based data sets.
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:968
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
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.