QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsvectorlayerdiagramprovider.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayerdiagramprovider.cpp
3 --------------------------------------
4 Date : September 2015
5 Copyright : (C) 2015 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "diagram/qgsdiagram.h"
19#include "feature.h"
20#include "labelposition.h"
22#include "qgsgeometry.h"
23#include "qgsgeos.h"
24#include "qgslabelingresults.h"
25#include "qgslabelsearchtree.h"
26#include "qgsrendercontext.h"
27#include "qgsscaleutils.h"
28#include "qgsvectorlayer.h"
30
33 , mSettings( *layer->diagramLayerSettings() )
34 , mDiagRenderer( layer->diagramRenderer()->clone() )
35 , mFields( layer->fields() )
36 , mLayerCrs( layer->crs() )
37 , mSource( ownFeatureLoop ? new QgsVectorLayerFeatureSource( layer ) : nullptr )
38 , mOwnsSource( ownFeatureLoop )
39{
40 init();
41
42 // we have to create an expression context scope for the layer in advance, while we still have access to the layer itself
43 mLayerScope.reset( layer->createExpressionContextScope() );
44}
45
46
48{
50 mPriority = 1 - mSettings.priority() / 10.0; // convert 0..10 --> 1..0
51 mPlacement = static_cast< Qgis::LabelPlacement >( mSettings.placement() );
52}
53
54
56{
57 if ( mOwnsSource )
58 delete mSource;
59
60 qDeleteAll( mFeatures );
61
62 // renderer is owned by mSettings
63}
64
65
67{
68 if ( !mSource )
69 {
70 // we have created the provider with "own feature loop" == false
71 // so it is assumed that prepare() has been already called followed by registerFeature() calls
72 return mFeatures;
73 }
74
75 QSet<QString> attributeNames;
76 if ( !prepare( context, attributeNames ) )
77 return QList<QgsLabelFeature *>();
78
79 QgsRectangle layerExtent = context.extent();
80 if ( !mSettings.coordinateTransform().isShortCircuited() )
81 {
82 QgsCoordinateTransform extentTransform = mSettings.coordinateTransform();
83 extentTransform.setBallparkTransformsAreAppropriate( true );
84 layerExtent = extentTransform.transformBoundingBox( context.extent(), Qgis::TransformDirection::Reverse );
85 }
86
87 QgsFeatureRequest request;
88 request.setFilterRect( layerExtent );
89 request.setSubsetOfAttributes( attributeNames, mFields );
90 const QgsFeatureFilterProvider *featureFilterProvider = context.featureFilterProvider();
91 if ( featureFilterProvider )
92 {
94 if ( featureFilterProvider->isFilterThreadSafe() )
95 {
96 featureFilterProvider->filterFeatures( layerId(), request );
97 }
98 else
99 {
100 featureFilterProvider->filterFeatures( qobject_cast<QgsVectorLayer *>( mLayer ), request );
101 }
103 }
104 QgsFeatureIterator fit = mSource->getFeatures( request );
105
106 QgsFeature fet;
107 while ( fit.nextFeature( fet ) )
108 {
109 context.expressionContext().setFeature( fet );
110 registerFeature( fet, context );
111 }
112
113 return mFeatures;
114}
115
116
118{
119#if 1 // XXX strk
120 // features are pre-rotated but not scaled/translated,
121 // so we only disable rotation here. Ideally, they'd be
122 // also pre-scaled/translated, as suggested here:
123 // https://github.com/qgis/QGIS/issues/20071
124 QgsMapToPixel xform = context.mapToPixel();
125 xform.setMapRotation( 0, 0, 0 );
126#else
127 const QgsMapToPixel &xform = context.mapToPixel();
128#endif
129
130 QgsDiagramLabelFeature *dlf = dynamic_cast<QgsDiagramLabelFeature *>( label->getFeaturePart()->feature() );
131 if ( !dlf )
132 return;
133
134 const QgsFeature feature = dlf->feature();
135
136 // at time of drawing labels the expression context won't contain a layer scope -- so we manually add it here so that
137 // associated variables work correctly
139 context.expressionContext().setFeature( feature );
140
141 //calculate top-left point for diagram
142 //first, calculate the centroid of the label (accounts for PAL creating
143 //rotated labels when we do not want to draw the diagrams rotated)
144 double centerX = 0;
145 double centerY = 0;
146 for ( int i = 0; i < 4; ++i )
147 {
148 centerX += label->getX( i );
149 centerY += label->getY( i );
150 }
151 QgsPointXY outPt( centerX / 4.0, centerY / 4.0 );
152 //then, calculate the top left point for the diagram with this center position
153 QgsPointXY centerPt = xform.transform( outPt.x() - label->getWidth() / 2,
154 outPt.y() - label->getHeight() / 2 );
155
156 mSettings.renderer()->renderDiagram( feature, context, centerPt.toQPointF(), mSettings.dataDefinedProperties() );
157
158 //insert into label search tree to manipulate position interactively
159 mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, QString(), QFont(), true, false );
160}
161
162bool QgsVectorLayerDiagramProvider::prepare( const QgsRenderContext &context, QSet<QString> &attributeNames )
163{
165 const QgsMapSettings &mapSettings = mEngine->mapSettings();
166
167 if ( context.coordinateTransform().isValid() )
168 // this is context for layer rendering
170 else
171 {
172 // otherwise fall back to creating our own CT
174 }
175
177
178 bool result = s2.prepare( context.expressionContext() );
179
180 //add attributes needed by the diagram renderer
181 attributeNames.unite( s2.referencedFields( context.expressionContext() ) );
182
183 return result;
184}
185
186
188{
189 QgsLabelFeature *label = registerDiagram( feature, context, obstacleGeometry );
190 if ( label )
191 mFeatures << label;
192}
193
198
200{
201 const QgsMapSettings &mapSettings = mEngine->mapSettings();
202
203 const QgsDiagramRenderer *dr = mSettings.renderer();
204 if ( dr )
205 {
206 QList<QgsDiagramSettings> settingList = dr->diagramSettings();
207 if ( !settingList.isEmpty() && settingList.at( 0 ).scaleBasedVisibility )
208 {
209 // Note: scale might be a non-round number, so compare with qgsDoubleNear
210 const double rendererScale = context.rendererScale();
211
212 // maxScale is inclusive ( < --> no diagram )
213 double maxScale = settingList.at( 0 ).maximumScale;
214 if ( maxScale > 0 && QgsScaleUtils::lessThanMaximumScale( rendererScale, maxScale ) )
215 {
216 return nullptr;
217 }
218
219 // minScale is exclusive ( >= --> no diagram)
220 double minScale = settingList.at( 0 ).minimumScale;
221 if ( minScale > 0 && QgsScaleUtils::equalToOrGreaterThanMinimumScale( rendererScale, minScale ) )
222 {
223 return nullptr;
224 }
225 }
226 }
227
228 // data defined show diagram? check this before doing any other processing
229 if ( !mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::Property::Show, context.expressionContext(), true ) )
230 return nullptr;
231
232 // data defined obstacle?
233 bool isObstacle = mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::Property::IsObstacle, context.expressionContext(), mSettings.isObstacle() );
234
235 //convert geom to geos
236 QgsGeometry geom = feat.geometry();
237 QgsGeometry extentGeom = QgsGeometry::fromRect( mapSettings.visibleExtent() );
238 if ( !qgsDoubleNear( mapSettings.rotation(), 0.0 ) )
239 {
240 //PAL features are prerotated, so extent also needs to be unrotated
241 extentGeom.rotate( -mapSettings.rotation(), mapSettings.visibleExtent().center() );
242 }
243
244 if ( QgsPalLabeling::geometryRequiresPreparation( geom, context, mSettings.coordinateTransform(), extentGeom ) )
245 {
246 geom = QgsPalLabeling::prepareGeometry( geom, context, mSettings.coordinateTransform(), extentGeom );
247 }
248 if ( geom.isEmpty() )
249 return nullptr;
250
251 const QgsGeometry clipGeometry = mLabelClipFeatureGeom.isNull() ? context.featureClipGeometry() : mLabelClipFeatureGeom;
252 if ( !clipGeometry.isEmpty() )
253 {
254 const Qgis::GeometryType expectedType = geom.type();
255 geom = geom.intersection( clipGeometry );
256 geom.convertGeometryCollectionToSubclass( expectedType );
257 }
258 if ( geom.isEmpty() )
259 return nullptr;
260
261 QgsGeometry preparedObstacleGeom;
262 if ( isObstacle && !obstacleGeometry.isNull() && QgsPalLabeling::geometryRequiresPreparation( obstacleGeometry, context, mSettings.coordinateTransform(), extentGeom ) )
263 {
264 preparedObstacleGeom = QgsPalLabeling::prepareGeometry( obstacleGeometry, context, mSettings.coordinateTransform(), extentGeom );
265 }
266 else if ( mSettings.isObstacle() && !obstacleGeometry.isNull() )
267 {
268 preparedObstacleGeom = obstacleGeometry;
269 }
270
271 double diagramWidth = 0;
272 double diagramHeight = 0;
273 if ( dr )
274 {
275 QSizeF diagSize = dr->sizeMapUnits( feat, context );
276 if ( diagSize.isValid() )
277 {
278 diagramWidth = diagSize.width();
279 diagramHeight = diagSize.height();
280 }
281 }
282
283 // feature to the layer
284 bool alwaysShow = mSettings.showAllDiagrams();
285 context.expressionContext().setOriginalValueVariable( alwaysShow );
286 alwaysShow = mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::Property::AlwaysShow, context.expressionContext(), alwaysShow );
287
288 // new style data defined position
289 bool ddPos = false;
290 double ddPosX = 0.0;
291 double ddPosY = 0.0;
292 if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::Property::PositionX )
293 && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::Property::PositionX ).isActive()
294 && mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::Property::PositionY )
295 && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::Property::PositionY ).isActive() )
296 {
297 ddPosX = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Property::PositionX, context.expressionContext(), std::numeric_limits<double>::quiet_NaN() );
298 ddPosY = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Property::PositionY, context.expressionContext(), std::numeric_limits<double>::quiet_NaN() );
299
300 ddPos = !std::isnan( ddPosX ) && !std::isnan( ddPosY );
301
302 if ( ddPos )
303 {
304 QgsCoordinateTransform ct = mSettings.coordinateTransform();
305 if ( ct.isValid() && !ct.isShortCircuited() )
306 {
307 double z = 0;
308 ct.transformInPlace( ddPosX, ddPosY, z );
309 }
310 //data defined diagram position is always centered
311 ddPosX -= diagramWidth / 2.0;
312 ddPosY -= diagramHeight / 2.0;
313 }
314 }
315
316 QgsDiagramLabelFeature *lf = new QgsDiagramLabelFeature( feat, QgsGeos::asGeos( geom ), QSizeF( diagramWidth, diagramHeight ) );
317 lf->setHasFixedPosition( ddPos );
318 lf->setFixedPosition( QgsPointXY( ddPosX, ddPosY ) );
319 lf->setHasFixedAngle( true );
320 lf->setFixedAngle( 0 );
321 lf->setAlwaysShow( alwaysShow );
323 os.setIsObstacle( isObstacle );
324 os.setObstacleGeometry( preparedObstacleGeom );
325 lf->setObstacleSettings( os );
326
327 // data defined priority?
328 if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::Property::Priority )
329 && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::Property::Priority ).isActive() )
330 {
332 double priorityD = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Property::Priority, context.expressionContext(), mSettings.priority() );
333 priorityD = std::clamp( priorityD, 0.0, 10.0 );
334 priorityD = 1 - priorityD / 10.0; // convert 0..10 --> 1..0
335 lf->setPriority( priorityD );
336 }
337
338 // z-Index
339 double zIndex = mSettings.zIndex();
340 if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::Property::ZIndex )
341 && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::Property::ZIndex ).isActive() )
342 {
344 zIndex = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Property::ZIndex, context.expressionContext(), zIndex );
345 }
346 lf->setZIndex( zIndex );
347
348 // label distance
349 QgsPointXY ptZero = mapSettings.mapToPixel().toMapCoordinates( 0, 0 );
350 QgsPointXY ptOne = mapSettings.mapToPixel().toMapCoordinates( 1, 0 );
351 double dist = mSettings.distance();
352
353 if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::Property::Distance )
354 && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::Property::Distance ).isActive() )
355 {
357 dist = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Property::Distance, context.expressionContext(), dist );
358 }
359
360 dist *= ptOne.distance( ptZero );
361
362 lf->setDistLabel( dist );
363 return lf;
364}
365
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
Definition qgis.h:1194
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:358
@ Reverse
Reverse/inverse transform (from destination to source).
Definition qgis.h:2673
QString mName
Name of the layer.
QString mLayerId
Associated layer's ID, if applicable.
double mPriority
Default priority of labels. 0 = highest priority, 1 = lowest priority.
const QgsLabelingEngine * mEngine
Associated labeling engine.
QgsMapLayer * layer() const
Returns the associated layer, or nullptr if no layer is associated with the provider.
Qgis::LabelPlacement mPlacement
Placement strategy.
QString layerId() const
Returns ID of associated layer, or empty string if no layer is associated with the provider.
QgsWeakMapLayerPointer mLayer
Weak pointer to source layer.
QgsAbstractLabelProvider(QgsMapLayer *layer, const QString &providerId=QString())
Construct the provider with default values.
Handles coordinate transforms between two coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
void transformInPlace(double &x, double &y, double &z, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Transforms an array of x, y and z double coordinates in place, from the source CRS to the destination...
bool isShortCircuited() const
Returns true if the transform short circuits because the source and destination are equivalent.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const
Transforms a rectangle from the source CRS to the destination CRS.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Adds extra information to QgsLabelFeature for labeling of diagrams.
Stores the settings for rendering of all diagrams for a layer.
void setRenderer(QgsDiagramRenderer *diagramRenderer)
Sets the diagram renderer associated with the layer.
@ PositionX
X-coordinate data defined diagram position.
@ Distance
Distance to diagram from feature.
@ PositionY
Y-coordinate data defined diagram position.
@ Show
Whether to show the diagram.
@ Priority
Diagram priority (between 0 and 10).
@ ZIndex
Z-index for diagram ordering.
@ IsObstacle
Whether diagram features act as obstacles for other diagrams/labels.
@ AlwaysShow
Whether the diagram should always be shown, even if it overlaps other diagrams/labels.
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext()) const
Returns the set of any fields referenced by the layer's diagrams.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const
Prepares the diagrams for a specified expression context.
void setCoordinateTransform(const QgsCoordinateTransform &transform)
Sets the coordinate transform associated with the layer.
Evaluates and returns the diagram settings relating to a diagram for a specific feature.
virtual QSizeF sizeMapUnits(const QgsFeature &feature, const QgsRenderContext &c) const
Returns size of the diagram for a feature in map units. Returns an invalid QSizeF in case of error.
virtual QList< QgsDiagramSettings > diagramSettings() const =0
Returns list with all diagram settings in the renderer.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Abstract interface for use by classes that filter the features or attributes of a layer.
virtual Q_DECL_DEPRECATED void filterFeatures(const QgsVectorLayer *layer, QgsFeatureRequest &featureRequest) const
Add additional filters to the feature request to further restrict the features returned by the reques...
virtual Q_DECL_DEPRECATED bool isFilterThreadSafe() const
Returns true if the filterFeature function is thread safe, which will lead to reliance on layer ID in...
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsGeometry geometry
Definition qgsfeature.h:69
A geometry is the spatial representation of a feature.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
Qgis::GeometryType type
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters &parameters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
bool convertGeometryCollectionToSubclass(Qgis::GeometryType geomType)
Converts geometry collection to a the desired geometry type subclass (multi-point,...
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY &center)
Rotate this geometry around the Z axis.
static geos::unique_ptr asGeos(const QgsGeometry &geometry, double precision=0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlags())
Returns a geos geometry - caller takes ownership of the object (should be deleted with GEOSGeom_destr...
Definition qgsgeos.cpp:260
Describes a feature that should be used within the labeling engine.
void setDistLabel(double dist)
Applies to "around point" placement strategy or linestring features.
void setAlwaysShow(bool enabled)
Sets whether label should be always shown (sets very high label priority).
void setZIndex(double zIndex)
Sets the label's z-index.
void setHasFixedAngle(bool enabled)
Sets whether the label should use a fixed angle instead of using angle from automatic placement.
void setObstacleSettings(const QgsLabelObstacleSettings &settings)
Sets the label's obstacle settings.
QgsFeature feature() const
Returns the original feature associated with this label.
void setPriority(double priority)
Sets the priority for labeling the feature.
void setHasFixedPosition(bool enabled)
Sets whether the label should use a fixed position instead of being automatically placed.
void setFixedPosition(const QgsPointXY &point)
Sets coordinates of the fixed position (relevant only if hasFixedPosition() returns true).
void setFixedAngle(double angle)
Sets the angle in radians of the fixed angle (relevant only if hasFixedAngle() returns true).
Contains settings related to how the label engine treats features as obstacles.
void setIsObstacle(bool isObstacle)
Sets whether features are obstacles to labels of other layers.
void setObstacleGeometry(const QgsGeometry &obstacleGeom)
Sets the label's obstacle geometry, if different to the feature geometry.
Contains configuration for rendering maps.
const QgsMapToPixel & mapToPixel() const
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Perform transforms between map coordinates and device coordinates.
void setMapRotation(double degrees, double cx, double cy)
Sets map rotation in degrees (clockwise).
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
static QgsGeometry prepareGeometry(const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry=QgsGeometry(), bool mergeLines=false)
Prepares a geometry for registration with PAL.
static bool geometryRequiresPreparation(const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry=QgsGeometry(), bool mergeLines=false)
Checks whether a geometry requires preparation before registration with PAL.
Represents a 2D point.
Definition qgspointxy.h:60
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
Definition qgspointxy.h:206
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
QPointF toQPointF() const
Converts a point to a QPointF.
Definition qgspointxy.h:165
A rectangle specified with double values.
QgsPointXY center
Contains information about the context of a rendering operation.
double rendererScale() const
Returns the renderer map scale.
QgsExpressionContext & expressionContext()
Gets the expression context.
QgsCoordinateTransformContext transformContext() const
Returns the context's coordinate transform context, which stores various information regarding which ...
QgsGeometry featureClipGeometry() const
Returns the geometry to use to clip features at render time.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
const QgsFeatureFilterProvider * featureFilterProvider() const
Gets the filter feature provider used for additional filtering of rendered features.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
static bool equalToOrGreaterThanMinimumScale(const double scale, const double minScale)
Returns whether the scale is equal to or greater than the minScale, taking non-round numbers into acc...
static bool lessThanMaximumScale(const double scale, const double maxScale)
Returns whether the scale is less than the maxScale, taking non-round numbers into account.
QgsDiagramLayerSettings mSettings
Diagram layer settings.
QgsAbstractFeatureSource * mSource
Layer's feature source.
QList< QgsLabelFeature * > labelFeatures(QgsRenderContext &context) override
Returns list of label features (they are owned by the provider and thus deleted on its destruction).
void init()
initialization method - called from constructors
bool mOwnsSource
Whether layer's feature source is owned.
QgsCoordinateReferenceSystem mLayerCrs
Layer's CRS.
virtual bool prepare(const QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
QgsLabelFeature * registerDiagram(const QgsFeature &feat, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry())
helper method to register one diagram feature
virtual void registerFeature(QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry())
Register a feature for labeling as one or more QgsLabelFeature objects stored into mFeatures.
QgsDiagramRenderer * mDiagRenderer
Diagram renderer instance (owned by mSettings).
QList< QgsLabelFeature * > mFeatures
List of generated label features (owned by the provider).
QgsVectorLayerDiagramProvider(QgsVectorLayer *layer, bool ownFeatureLoop=true)
Convenience constructor to initialize the provider from given vector layer.
void drawLabel(QgsRenderContext &context, pal::LabelPosition *label) const override
Draw this label at the position determined by the labeling engine.
void setClipFeatureGeometry(const QgsGeometry &geometry)
Sets a geometry to use to clip features to when registering them as diagrams.
std::unique_ptr< QgsExpressionContextScope > mLayerScope
Partial snapshot of vector layer's state (only the members necessary for access to features).
Represents a vector layer which manages a vector based dataset.
QgsFeatureId featureId() const
Returns the unique ID of the feature.
Definition feature.cpp:167
LabelPosition is a candidate feature label position.
double getHeight() const
double getWidth() const
FeaturePart * getFeaturePart() const
Returns the feature corresponding to this labelposition.
double getX(int i=0) const
Returns the down-left x coordinate.
double getY(int i=0) const
Returns the down-left y coordinate.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:7170
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7169
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6607