-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
qgslabelingenginev2.h
274 lines (216 loc) · 11.5 KB
/
qgslabelingenginev2.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/***************************************************************************
qgslabelingenginev2.h
--------------------------------------
Date : September 2015
Copyright : (C) 2015 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSLABELINGENGINEV2_H
#define QGSLABELINGENGINEV2_H
#include "qgsmapsettings.h"
#include "qgspallabeling.h"
#include <QFlags>
class QgsRenderContext;
class QgsGeometry;
/**
* @brief The QgsLabelFeature class describes a feature that
* should be used within the labeling engine. Those may be the usual textual labels,
* diagrams, or any other custom type of map annotations (generated by custom
* label providers).
*
* Instances only contain data relevant to the labeling engine (geometry, label size etc.)
* necessary for the layout. Rendering of labels is done by label providers.
*
* @note added in QGIS 2.12
*/
class CORE_EXPORT QgsLabelFeature
{
public:
QgsLabelFeature( QString id, QgsPalGeometry* geometry, const QSizeF& size );
//! Identifier of the label (unique within the parent label provider)
QString id() const { return mId; }
//! Get access to the associated geometry
QgsPalGeometry* geometry() const { return mGeometry; }
//! Size of the label (in map units)
QSizeF size() const { return mSize; }
//! Priority of the label - between 0 (highest) to 1 (lowest). Value -1 means to use layer default priority
double priority() const { return mPriority; }
void setPriority( double priority ) { mPriority = priority; }
//! Whether the label should use a fixed position instead of being automatically placed
bool hasFixedPosition() const { return mHasFixedPosition; }
void setHasFixedPosition( bool enabled ) { mHasFixedPosition = enabled; }
//! Coordinates of the fixed position (relevant only if hasFixedPosition() returns true)
QgsPoint fixedPosition() const { return mFixedPosition; }
void setFixedPosition( const QgsPoint& point ) { mFixedPosition = point; }
//! Whether the label should use a fixed angle instead of using angle from automatic placement
bool hasFixedAngle() const { return mHasFixedAngle; }
void setHasFixedAngle( bool enabled ) { mHasFixedAngle = enabled; }
//! Angle in degrees of the fixed angle (relevant only if hasFixedAngle() returns true)
double fixedAngle() const { return mFixedAngle; }
void setFixedAngle( double angle ) { mFixedAngle = angle; }
//! Applies to "around point" placement strategy.
//! Determines whether a fixed quadrant (quadOffset()) should be used instead of using automatically chosen one.
bool hasFixedQuadrant() const { return mHasFixedQuadrant; }
void setHasFixedQuadrant( bool enabled ) { mHasFixedQuadrant = enabled; }
//! Applies to "offset from point" placement strategy and "around point" (in case hasFixedQuadrant() returns true).
//! Determines which side of the point to use.
//! For X coordinate, values -1, 0, 1 mean left, center, right.
//! For Y coordinate, values -1, 0, 1 mean above, center, below.
QPointF quadOffset() const { return mQuadOffset; }
void setQuadOffset( const QPointF& quadOffset ) { mQuadOffset = quadOffset; }
//! Applies only to "offset from point" placement strategy - what offset to use from the point
QgsPoint positionOffset() const { return mPositionOffset; }
void setPositionOffset( const QgsPoint& offset ) { mPositionOffset = offset; }
//! Applies to "around point" placement strategy or linestring features.
//! Distance of the label from the feature (in map units)
double distLabel() const { return mDistLabel; }
void setDistLabel( double dist ) { mDistLabel = dist; }
//! Applies only to linestring features - after what distance (in map units)
//! the labels should be repeated (0 = no repetitions)
double repeatDistance() const { return mRepeatDistance; }
void setRepeatDistance( double dist ) { mRepeatDistance = dist; }
//! Whether label should be always shown (sets very high label priority)
bool alwaysShow() const { return mAlwaysShow; }
void setAlwaysShow( bool enabled ) { mAlwaysShow = enabled; }
//! Determine whether the feature geometry acts as an obstacle for other labels
bool isObstacle() const { return mIsObstacle; }
void setIsObstacle( bool enabled ) { mIsObstacle = enabled; }
//! Only applies if isObstacle() returns true: How strong is the obstacle.
//! Larger factors ( > 1.0 ) will result in labels which are less likely to cover this feature,
//! smaller factors ( < 1.0 ) mean labels are more likely to cover this feature (where required)
double obstacleFactor() const { return mObstacleFactor; }
void setObstacleFactor( double factor ) { mObstacleFactor = factor; }
protected:
//! Associated ID unique within the parent label provider
QString mId;
//! Geometry wrapper for the feature
QgsPalGeometry* mGeometry;
//! Width and height of the label
QSizeF mSize;
double mPriority;
bool mHasFixedPosition;
QgsPoint mFixedPosition;
bool mHasFixedAngle;
double mFixedAngle;
bool mHasFixedQuadrant;
QPointF mQuadOffset;
QgsPoint mPositionOffset;
double mDistLabel;
double mRepeatDistance;
bool mAlwaysShow;
bool mIsObstacle;
double mObstacleFactor;
};
class QgsLabelingEngineV2;
/**
* @brief The QgsAbstractLabelProvider class is an interface class. Implementations
* return list of labels and their associated geometries - these are used by
* QgsLabelingEngineV2 to compute the final layout of labels.
*
* @note added in QGIS 2.12
*/
class CORE_EXPORT QgsAbstractLabelProvider
{
public:
QgsAbstractLabelProvider();
virtual ~QgsAbstractLabelProvider() {}
void setEngine( const QgsLabelingEngineV2* engine ) { mEngine = engine; }
enum Flag
{
GeometriesAreObstacles = 1 << 1, //!< whether the geometries of labels by default act as obstacles (may be overriden on feature level)
DrawLabels = 1 << 2, //!< whether the labels should be rendered
DrawAllLabels = 1 << 3, //!< whether all features will be labelled even though overlaps occur
MergeConnectedLines = 1 << 4, //!< whether adjacent lines (with the same label text) should be merged
CentroidMustBeInside = 1 << 5, //!< whether location of centroid must be inside of polygons
FitInPolygonOnly = 1 << 6, //!< whether labels must fall completely within the polygon
LabelPerFeaturePart = 1 << 7, //!< whether to label each part of multi-part features separately
};
Q_DECLARE_FLAGS( Flags, Flag )
//! Return unique identifier of the provider
virtual QString id() const = 0;
//! Return list of labels
virtual QList<QgsLabelFeature*> labelFeatures( const QgsRenderContext& context ) = 0;
//! draw this label at the position determined by the labeling engine
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const = 0;
Flags flags() const { return mFlags; }
//! What placement strategy to use for the labels
QgsPalLayerSettings::Placement placement() const { return mPlacement; }
unsigned int linePlacementFlags() const { return mLinePlacementFlags; }
double priority() const { return mPriority; }
QgsPalLayerSettings::ObstacleType obstacleType() const { return mObstacleType; }
unsigned int upsidedownLabels() const { return mUpsidedownLabels; }
protected:
const QgsLabelingEngineV2* mEngine;
Flags mFlags;
QgsPalLayerSettings::Placement mPlacement;
unsigned int mLinePlacementFlags;
double mPriority;
QgsPalLayerSettings::ObstacleType mObstacleType;
unsigned int mUpsidedownLabels;
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAbstractLabelProvider::Flags )
/**
* @brief The QgsLabelingEngineV2 class provides map labeling functionality.
* The input for the engine is a list of label provider objects and map settings.
* Based on the input, the engine computes layout of labels for the given map view
* with no collisions between the labels. Drawing of resulting labels is done
* again by label providers.
*
* @note added in QGIS 2.12
*/
class CORE_EXPORT QgsLabelingEngineV2
{
public:
QgsLabelingEngineV2();
~QgsLabelingEngineV2();
enum Flag
{
UseAllLabels = 1 << 1, //!< Whether to draw all labels even if there would be collisions
UsePartialCandidates = 1 << 2, //!< Whether to use also label candidates that are partially outside of the map view
RenderOutlineLabels = 1 << 3, //!< Whether to render labels as text or outlines
DrawLabelRectOnly = 1 << 4, //!< Whether to only draw the label rect and not the actual label text (used for unit tests)
DrawCandidates = 1 << 5, //!< Whether to draw rectangles of generated candidates (good for debugging)
DrawShadowRects = 1 << 6, //!< Whether to show debugging rectangles for drop shadows
};
Q_DECLARE_FLAGS( Flags, Flag )
void setMapSettings( const QgsMapSettings& mapSettings ) { mMapSettings = mapSettings; }
const QgsMapSettings& mapSettings() const { return mMapSettings; }
//! Add provider of label features. Takes ownership of the provider
void addProvider( QgsAbstractLabelProvider* provider );
//! Remove provider if the provider's initialization failed. Provider instance is deleted.
void removeProvider( QgsAbstractLabelProvider* provider );
//! Lookup provider by its ID
QgsAbstractLabelProvider* providerById( const QString& id );
//! compute the labeling with given map settings and providers
void run( QgsRenderContext& context );
//! Return pointer to recently computed results and pass the ownership of results to the caller
QgsLabelingResults* takeResults();
//! For internal use by the providers
QgsLabelingResults* results() const { return mResults; }
void setFlags( Flags flags ) { mFlags = flags; }
Flags flags() const { return mFlags; }
bool testFlag( Flag f ) const { return mFlags.testFlag( f ); }
void setFlag( Flag f, bool enabled ) { if ( enabled ) mFlags |= f; else mFlags &= ~f; }
void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon ) { candPoint = mCandPoint; candLine = mCandLine; candPolygon = mCandPolygon; }
void setNumCandidatePositions( int candPoint, int candLine, int candPolygon ) { mCandPoint = candPoint; mCandLine = candLine; mCandPolygon = candPolygon; }
void setSearchMethod( QgsPalLabeling::Search s ) { mSearchMethod = s; }
QgsPalLabeling::Search searchMethod() const { return mSearchMethod; }
void readSettingsFromProject();
void writeSettingsToProject();
protected:
QgsMapSettings mMapSettings;
QList<QgsAbstractLabelProvider*> mProviders;
Flags mFlags;
QgsPalLabeling::Search mSearchMethod;
int mCandPoint, mCandLine, mCandPolygon;
QgsLabelingResults* mResults;
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLabelingEngineV2::Flags )
#endif // QGSLABELINGENGINEV2_H