Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgspallabeling.h
3 : : Smart labeling for vector layers
4 : : -------------------
5 : : begin : June 2009
6 : : copyright : (C) Martin Dobias
7 : : email : wonder dot sk at gmail dot com
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 : :
18 : : //Note: although this file is in the core library, it is not part of the stable API
19 : : //and might change at any time!
20 : :
21 : : #ifndef QGSPALLABELING_H
22 : : #define QGSPALLABELING_H
23 : :
24 : : #include "qgis_core.h"
25 : : #include "qgis_sip.h"
26 : : #include <QString>
27 : : #include <QFont>
28 : : #include <QFontDatabase>
29 : : #include <QColor>
30 : : #include <QHash>
31 : : #include <QList>
32 : : #include <QPainter>
33 : : #include <QRectF>
34 : : #include <QMap>
35 : : #include "qgsfeature.h"
36 : : #include "qgsgeometry.h"
37 : : #include "qgsfields.h"
38 : : #include "qgslabelingenginesettings.h"
39 : : #include "qgspointxy.h"
40 : : #include "qgsmapunitscale.h"
41 : : #include "qgsstringutils.h"
42 : : #include "qgssymbol.h"
43 : : #include "qgstextformat.h"
44 : : #include "qgspropertycollection.h"
45 : : #include "qgslabelobstaclesettings.h"
46 : : #include "qgslabelthinningsettings.h"
47 : : #include "qgslabellinesettings.h"
48 : : #include "qgslabeling.h"
49 : : #include "qgslabelposition.h"
50 : :
51 : : class QgsTextDocument;
52 : :
53 : : namespace pal SIP_SKIP
54 : : {
55 : : class Pal;
56 : : class Layer;
57 : : class LabelPosition;
58 : : }
59 : :
60 : : class QgsDiagramLayerSettings;
61 : : class QgsRectangle;
62 : : class QgsMapToPixel;
63 : : class QgsFeature;
64 : : class QgsTextLabelFeature;
65 : : class QgsVectorLayer;
66 : : class QgsExpression;
67 : : class QFontMetricsF;
68 : : class QPainter;
69 : : class QPicture;
70 : : class QgsGeometry;
71 : : class QgsCoordinateTransform;
72 : : class QgsLabelSearchTree;
73 : : class QgsMapSettings;
74 : : class QgsLabelFeature;
75 : : class QgsLabelingEngine;
76 : : class QgsPalLayerSettings;
77 : : class QgsVectorLayerLabelProvider;
78 : : class QgsDxfExport;
79 : : class QgsVectorLayerDiagramProvider;
80 : : class QgsExpressionContext;
81 : : class QgsCallout;
82 : :
83 : : /**
84 : : * \ingroup core
85 : : * \class QgsPalLayerSettings
86 : : * \brief Contains settings for how a map layer will be labeled.
87 : : */
88 : : class CORE_EXPORT QgsPalLayerSettings
89 : : {
90 : : public:
91 : : QgsPalLayerSettings();
92 : : QgsPalLayerSettings( const QgsPalLayerSettings &s );
93 : : ~QgsPalLayerSettings();
94 : :
95 : : //! copy operator - only copies the permanent members
96 : : QgsPalLayerSettings &operator=( const QgsPalLayerSettings &s );
97 : :
98 : : //TODO QGIS 4.0 - move to QgsLabelingEngine
99 : :
100 : : /**
101 : : * Placement modes which determine how label candidates are generated for a feature.
102 : : */
103 : : enum Placement
104 : : {
105 : : AroundPoint, //!< Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygon layers only.
106 : : OverPoint, //!< Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point. Applies to point or polygon layers only.
107 : : Line, //!< Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon's perimeter. Applies to line or polygon layers only.
108 : : Curved, //!< Arranges candidates following the curvature of a line feature. Applies to line layers only.
109 : : Horizontal, //!< Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only.
110 : : Free, //!< Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the polygon's orientation. Applies to polygon layers only.
111 : : OrderedPositionsAroundPoint, //!< Candidates are placed in predefined positions around a point. Preference is given to positions with greatest cartographic appeal, e.g., top right, bottom right, etc. Applies to point layers only.
112 : : PerimeterCurved, //!< Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
113 : : OutsidePolygons, //!< Candidates are placed outside of polygon boundaries. Applies to polygon layers only. Since QGIS 3.14
114 : : };
115 : :
116 : : //TODO QGIS 4.0 - move to QgsLabelingEngine
117 : : //! Positions for labels when using the QgsPalLabeling::OrderedPositionsAroundPoint placement mode
118 : : enum PredefinedPointPosition
119 : : {
120 : : TopLeft, //!< Label on top-left of point
121 : : TopSlightlyLeft, //!< Label on top of point, slightly left of center
122 : : TopMiddle, //!< Label directly above point
123 : : TopSlightlyRight, //!< Label on top of point, slightly right of center
124 : : TopRight, //!< Label on top-right of point
125 : : MiddleLeft, //!< Label on left of point
126 : : MiddleRight, //!< Label on right of point
127 : : BottomLeft, //!< Label on bottom-left of point
128 : : BottomSlightlyLeft, //!< Label below point, slightly left of center
129 : : BottomMiddle, //!< Label directly below point
130 : : BottomSlightlyRight, //!< Label below point, slightly right of center
131 : : BottomRight, //!< Label on bottom right of point
132 : : };
133 : :
134 : : //TODO QGIS 4.0 - move to QgsLabelingEngine
135 : :
136 : : /**
137 : : * Behavior modifier for label offset and distance, only applies in some
138 : : * label placement modes.
139 : : */
140 : : enum OffsetType
141 : : {
142 : : FromPoint, //!< Offset distance applies from point geometry
143 : : FromSymbolBounds, //!< Offset distance applies from rendered symbol bounds
144 : : };
145 : :
146 : : //TODO QGIS 4.0 - remove, replaced by QgsLabeling::LinePlacementFlags
147 : :
148 : : /**
149 : : * Line placement flags, which control how candidates are generated for a linear feature.
150 : : *
151 : : * \deprecated Use QgsLabeling::LinePlacementFlags instead
152 : : */
153 : : enum LinePlacementFlags
154 : : {
155 : : OnLine = 1, //!< Labels can be placed directly over a line feature.
156 : : AboveLine = 2, /**< Labels can be placed above a line feature. Unless MapOrientation is also specified this mode
157 : : respects the direction of the line feature, so a line from right to left labels will have labels
158 : : placed placed below the line feature. */
159 : : BelowLine = 4, /**< Labels can be placed below a line feature. Unless MapOrientation is also specified this mode
160 : : respects the direction of the line feature, so a line from right to left labels will have labels
161 : : placed placed above the line feature. */
162 : : MapOrientation = 8, /**< Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather
163 : : than the feature's orientation. For example, AboveLine will always result in label's being placed
164 : : above a line, regardless of the line's direction. */
165 : : };
166 : :
167 : : enum QuadrantPosition
168 : : {
169 : : QuadrantAboveLeft,
170 : : QuadrantAbove,
171 : : QuadrantAboveRight,
172 : : QuadrantLeft,
173 : : QuadrantOver,
174 : : QuadrantRight,
175 : : QuadrantBelowLeft,
176 : : QuadrantBelow,
177 : : QuadrantBelowRight,
178 : : };
179 : :
180 : : enum UpsideDownLabels
181 : : {
182 : : Upright, //!< Upside-down labels (90 <= angle < 270) are shown upright
183 : : ShowDefined, //!< Show upside down when rotation is layer- or data-defined
184 : : ShowAll //!< Show upside down for all labels, including dynamic ones
185 : : };
186 : :
187 : : //TODO QGIS 4.0 - Remove -- moved to QgsLabelEngineObstacleSettings
188 : :
189 : : //! \deprecated use QgsLabelLineSettings::DirectionSymbolPlacement instead
190 : : enum DirectionSymbols
191 : : {
192 : : SymbolLeftRight, //!< Place direction symbols on left/right of label
193 : : SymbolAbove, //!< Place direction symbols on above label
194 : : SymbolBelow //!< Place direction symbols on below label
195 : : };
196 : :
197 : : enum MultiLineAlign
198 : : {
199 : : MultiLeft = 0,
200 : : MultiCenter,
201 : : MultiRight,
202 : : MultiFollowPlacement, /*!< Alignment follows placement of label, e.g., labels to the left of a feature
203 : : will be drawn with right alignment*/
204 : : MultiJustify, //!< Justified
205 : : };
206 : :
207 : : //TODO QGIS 4.0 - Remove -- moved to QgsLabelEngineObstacleSettings
208 : :
209 : : /**
210 : : * Valid obstacle types, which affect how features within the layer will act as obstacles
211 : : * for labels.
212 : : */
213 : : enum ObstacleType
214 : : {
215 : : PolygonInterior, /*!< avoid placing labels over interior of polygon (prefer placing labels totally
216 : : outside or just slightly inside polygon) */
217 : : PolygonBoundary, /*!< avoid placing labels over boundary of polygon (prefer placing outside or
218 : : completely inside polygon) */
219 : : PolygonWhole /*!< avoid placing labels over ANY part of polygon. Where PolygonInterior will prefer
220 : : to place labels with the smallest area of intersection between the label and the polygon,
221 : : PolygonWhole will penalise any label which intersects with the polygon by an equal amount, so that
222 : : placing labels over any part of the polygon is avoided.*/
223 : : };
224 : :
225 : : //! Data definable properties.
226 : : enum Property
227 : : {
228 : : // text style
229 : : Size = 0, //!< Label size
230 : : Bold = 1, //!< Use bold style
231 : : Italic = 2, //!< Use italic style
232 : : Underline = 3, //!< Use underline
233 : : Color = 4, //!< Text color
234 : : Strikeout = 5, //!< Use strikeout
235 : : Family = 6, //!< Font family
236 : : FontStyle = 21, //!< Font style name
237 : : FontSizeUnit = 22, //!< Font size units
238 : : FontTransp = 18, //!< Text transparency (deprecated)
239 : : FontOpacity = 92, //!< Text opacity
240 : : FontCase = 27, //!< Label text case
241 : : FontLetterSpacing = 28, //!< Letter spacing
242 : : FontWordSpacing = 29, //!< Word spacing
243 : : FontBlendMode = 30, //!< Text blend mode
244 : :
245 : : // text formatting
246 : : MultiLineWrapChar = 31,
247 : : AutoWrapLength = 101,
248 : : MultiLineHeight = 32,
249 : : MultiLineAlignment = 33,
250 : : TextOrientation = 110,
251 : : DirSymbDraw = 34,
252 : : DirSymbLeft = 35,
253 : : DirSymbRight = 36,
254 : : DirSymbPlacement = 37,
255 : : DirSymbReverse = 38,
256 : : NumFormat = 39,
257 : : NumDecimals = 40,
258 : : NumPlusSign = 41,
259 : :
260 : : // text buffer
261 : : BufferDraw = 42,
262 : : BufferSize = 7,
263 : : BufferUnit = 43,
264 : : BufferColor = 8,
265 : : BufferTransp = 19, //!< Buffer transparency (deprecated)
266 : : BufferOpacity = 94, //!< Buffer opacity
267 : : BufferJoinStyle = 44,
268 : : BufferBlendMode = 45,
269 : :
270 : : // mask buffer
271 : : MaskEnabled = 104, //!< Whether the mask is enabled
272 : : MaskBufferSize = 105, //!< Mask buffer size
273 : : MaskBufferUnit = 106, //!< Mask buffer size unit
274 : : MaskOpacity = 107, //!< Mask opacity
275 : : MaskJoinStyle = 108, //!< Mask join style
276 : :
277 : : // background
278 : : ShapeDraw = 46,
279 : : ShapeKind = 47,
280 : : ShapeSVGFile = 48,
281 : : ShapeSizeType = 49,
282 : : ShapeSizeX = 50,
283 : : ShapeSizeY = 85,
284 : : ShapeSizeUnits = 51,
285 : : ShapeRotationType = 52,
286 : : ShapeRotation = 53,
287 : : ShapeOffset = 54,
288 : : ShapeOffsetUnits = 55,
289 : : ShapeRadii = 56,
290 : : ShapeRadiiUnits = 57,
291 : : ShapeTransparency = 63, //!< Shape transparency (deprecated)
292 : : ShapeOpacity = 93, //!< Shape opacity
293 : : ShapeBlendMode = 64,
294 : : ShapeFillColor = 58,
295 : : ShapeStrokeColor = 59,
296 : : ShapeStrokeWidth = 60,
297 : : ShapeStrokeWidthUnits = 61,
298 : : ShapeJoinStyle = 62,
299 : :
300 : : // drop shadow
301 : : ShadowDraw = 65,
302 : : ShadowUnder = 66,
303 : : ShadowOffsetAngle = 67,
304 : : ShadowOffsetDist = 68,
305 : : ShadowOffsetUnits = 69,
306 : : ShadowRadius = 70,
307 : : ShadowRadiusUnits = 71,
308 : : ShadowTransparency = 72, //!< Shadow transparency (deprecated)
309 : : ShadowOpacity = 95, //!< Shadow opacity
310 : : ShadowScale = 73,
311 : : ShadowColor = 74,
312 : : ShadowBlendMode = 75,
313 : :
314 : : // placement
315 : : CentroidWhole = 76,
316 : : OffsetQuad = 77,
317 : : OffsetXY = 78,
318 : : OffsetUnits = 80,
319 : : LabelDistance = 13,
320 : : DistanceUnits = 81,
321 : : OffsetRotation = 82,
322 : : CurvedCharAngleInOut = 83,
323 : : // (data defined only)
324 : : PositionX = 9, //!< X-coordinate data defined label position
325 : : PositionY = 10, //!< Y-coordinate data defined label position
326 : : Hali = 11, //!< Horizontal alignment for data defined label position (Left, Center, Right)
327 : : Vali = 12, //!< Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
328 : : Rotation = 14, //!< Label rotation (deprecated, for old project compatibility only)
329 : : LabelRotation = 96, //!< Label rotation
330 : : RepeatDistance = 84,
331 : : RepeatDistanceUnit = 86,
332 : : Priority = 87,
333 : : PredefinedPositionOrder = 91,
334 : : LinePlacementOptions = 99, //!< Line placement flags
335 : : OverrunDistance = 102, //!< Distance which labels can extend past either end of linear features
336 : : LabelAllParts = 103, //!< Whether all parts of multi-part features should be labeled
337 : : PolygonLabelOutside = 109, //!< Whether labels outside a polygon feature are permitted, or should be forced (since QGIS 3.14)
338 : : LineAnchorPercent = 111, //!< Portion along line at which labels should be anchored (since QGIS 3.16)
339 : :
340 : : // rendering
341 : : ScaleVisibility = 23,
342 : : MinScale = 16, //!< Min scale (deprecated, for old project compatibility only)
343 : : MinimumScale = 97, //!< Minimum map scale (ie most "zoomed out")
344 : : MaxScale = 17, //!< Max scale (deprecated, for old project compatibility only)
345 : : MaximumScale = 98, //!< Maximum map scale (ie most "zoomed in")
346 : : FontLimitPixel = 24,
347 : : FontMinPixel = 25,
348 : : FontMaxPixel = 26,
349 : : IsObstacle = 88,
350 : : ObstacleFactor = 89,
351 : : ZIndex = 90,
352 : : CalloutDraw = 100, //!< Show callout
353 : :
354 : : // (data defined only)
355 : : Show = 15,
356 : : AlwaysShow = 20
357 : : };
358 : :
359 : :
360 : : /**
361 : : * Prepare for registration of features.
362 : : * The \a context, \a mapSettings and \a fields parameters give more
363 : : * information about the rendering environment.
364 : : * If target \a crs is not specified, the targetCrs from \a mapSettings
365 : : * will be taken.
366 : : * The parameter \a attributeNames should be updated to contain all the field
367 : : * names which the labeling requires for the rendering.
368 : : *
369 : : * \since QGIS 3.8
370 : : */
371 : : bool prepare( QgsRenderContext &context, QSet<QString> &attributeNames SIP_INOUT, const QgsFields &fields, const QgsMapSettings &mapSettings, const QgsCoordinateReferenceSystem &crs );
372 : :
373 : : /**
374 : : * Returns all field names referenced by the configuration (e.g. field name or expression, data defined properties).
375 : : * \since QGIS 3.14
376 : : */
377 : : QSet<QString> referencedFields( const QgsRenderContext &context ) const;
378 : :
379 : : /**
380 : : * Prepares the label settings for rendering.
381 : : *
382 : : * This should be called before rendering any labels, and must be
383 : : * followed by a call to stopRender() in order to gracefully clean up symbols.
384 : : *
385 : : * \since QGIS 3.10
386 : : */
387 : : void startRender( QgsRenderContext &context );
388 : :
389 : : /**
390 : : * Finalises the label settings after use.
391 : : *
392 : : * This must be called after a call to startRender(), in order to gracefully clean up symbols.
393 : : *
394 : : * \since QGIS 3.10
395 : : */
396 : : void stopRender( QgsRenderContext &context );
397 : :
398 : : /**
399 : : * Returns the labeling property definitions.
400 : : * \since QGIS 3.0
401 : : */
402 : : static const QgsPropertiesDefinition &propertyDefinitions();
403 : :
404 : : /**
405 : : * Whether to draw labels for this layer. For some layers it may be desirable
406 : : * to register their features as obstacles for other labels without requiring
407 : : * labels to be drawn for the layer itself. In this case drawLabels can be set
408 : : * to FALSE and obstacle set to TRUE, which will result in the layer acting
409 : : * as an obstacle but having no labels of its own.
410 : : * \since QGIS 2.12
411 : : */
412 : : bool drawLabels = true;
413 : :
414 : : //-- text style
415 : :
416 : : /**
417 : : * Name of field (or an expression) to use for label text.
418 : : * If fieldName is an expression, then isExpression should be set to TRUE.
419 : : * \see isExpression
420 : : */
421 : : QString fieldName;
422 : :
423 : : /**
424 : : * TRUE if this label is made from a expression string, e.g., FieldName || 'mm'
425 : : * \see fieldName
426 : : */
427 : : bool isExpression = false;
428 : :
429 : : /**
430 : : * Returns the QgsExpression for this label settings. May be NULLPTR if isExpression is FALSE.
431 : : */
432 : : QgsExpression *getLabelExpression();
433 : :
434 : : /**
435 : : * \deprecated since QGIS 3.10. Use QgsTextFormat::previewBackgroundColor() instead.
436 : : */
437 : : Q_DECL_DEPRECATED QColor previewBkgrdColor = Qt::white;
438 : :
439 : : //! Substitution collection for automatic text substitution with labels
440 : : QgsStringReplacementCollection substitutions;
441 : : //! True if substitutions should be applied
442 : : bool useSubstitutions = false;
443 : :
444 : : //-- text formatting
445 : :
446 : : /**
447 : : * Wrapping character string. If set, any occurrences of this string in the calculated
448 : : * label text will be replaced with new line characters.
449 : : */
450 : : QString wrapChar;
451 : :
452 : : /**
453 : : * If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified
454 : : * number of characters. If zero, auto wrapping is disabled.
455 : : *
456 : : * \see useMaxLineLengthForAutoWrap
457 : : * \since QGIS 3.4
458 : : */
459 : : int autoWrapLength = 0;
460 : :
461 : : /**
462 : : * If TRUE, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum
463 : : * ideal length of text lines. If FALSE, then autoWrapLength indicates the ideal minimum length of text
464 : : * lines.
465 : : *
466 : : * If autoWrapLength is 0 then this value has no effect.
467 : : *
468 : : * \see autoWrapLength
469 : : * \since QGIS 3.4
470 : : */
471 : : bool useMaxLineLengthForAutoWrap = true;
472 : :
473 : : //! Horizontal alignment of multi-line labels.
474 : : MultiLineAlign multilineAlign = MultiFollowPlacement;
475 : :
476 : : /**
477 : : * Set to TRUE to format numeric label text as numbers (e.g. inserting thousand separators
478 : : * and fixed number of decimal places).
479 : : * \see decimals
480 : : * \see plusSign
481 : : */
482 : : bool formatNumbers = false;
483 : :
484 : : /**
485 : : * Number of decimal places to show for numeric labels. formatNumbers must be TRUE for this
486 : : * setting to have an effect.
487 : : * \see formatNumbers
488 : : */
489 : : int decimals = 3;
490 : :
491 : : /**
492 : : * Whether '+' signs should be prepended to positive numeric labels. formatNumbers must be TRUE for this
493 : : * setting to have an effect.
494 : : * \see formatNumbers
495 : : */
496 : : bool plusSign = false;
497 : :
498 : : //-- placement
499 : :
500 : : Placement placement = AroundPoint;
501 : :
502 : : /**
503 : : * Returns the polygon placement flags, which dictate how polygon labels can be placed.
504 : : *
505 : : * \see setPolygonPlacementFlags()
506 : : * \since QGIS 3.14
507 : : */
508 : : QgsLabeling::PolygonPlacementFlags polygonPlacementFlags() const { return mPolygonPlacementFlags; }
509 : :
510 : : /**
511 : : * Sets the polygon placement \a flags, which dictate how polygon labels can be placed.
512 : : *
513 : : * \see polygonPlacementFlags()
514 : : * \since QGIS 3.14
515 : : */
516 : : void setPolygonPlacementFlags( QgsLabeling::PolygonPlacementFlags flags ) { mPolygonPlacementFlags = flags; }
517 : :
518 : : /**
519 : : * TRUE if feature centroid should be calculated from the whole feature, or
520 : : * FALSE if only the visible part of the feature should be considered.
521 : : */
522 : : bool centroidWhole = false;
523 : :
524 : : /**
525 : : * TRUE if centroid positioned labels must be placed inside their corresponding
526 : : * feature polygon, or FALSE if centroids which fall outside the polygon
527 : : * are permitted.
528 : : */
529 : : bool centroidInside = false;
530 : :
531 : : /**
532 : : * Ordered list of predefined label positions for points. Positions earlier
533 : : * in the list will be prioritized over later positions. Only used when the placement
534 : : * is set to QgsPalLayerSettings::OrderedPositionsAroundPoint.
535 : : * \note not available in Python bindings
536 : : */
537 : : QVector< PredefinedPointPosition > predefinedPositionOrder SIP_SKIP;
538 : :
539 : : /**
540 : : * TRUE if only labels which completely fit within a polygon are allowed.
541 : : */
542 : : bool fitInPolygonOnly = false;
543 : :
544 : : /**
545 : : * Distance from feature to the label. Units are specified via distUnits.
546 : : * \see distUnits
547 : : * \see distMapUnitScale
548 : : */
549 : : double dist = 0;
550 : :
551 : : /**
552 : : * Units the distance from feature to the label.
553 : : * \see dist
554 : : * \see distMapUnitScale
555 : : */
556 : : QgsUnitTypes::RenderUnit distUnits = QgsUnitTypes::RenderMillimeters;
557 : :
558 : : /**
559 : : * Map unit scale for label feature distance.
560 : : * \see dist
561 : : * \see distUnits
562 : : */
563 : : QgsMapUnitScale distMapUnitScale;
564 : :
565 : : //! Offset type for layer (only applies in certain placement modes)
566 : : OffsetType offsetType = FromPoint;
567 : :
568 : : /**
569 : : * Distance for repeating labels for a single feature.
570 : : * \see repeatDistanceUnit
571 : : * \see repeatDistanceMapUnitScale
572 : : */
573 : : double repeatDistance = 0;
574 : :
575 : : /**
576 : : * Units for repeating labels for a single feature.
577 : : * \see repeatDistance
578 : : * \see repeatDistanceMapUnitScale
579 : : */
580 : : QgsUnitTypes::RenderUnit repeatDistanceUnit = QgsUnitTypes::RenderMillimeters;
581 : :
582 : : /**
583 : : * Map unit scale for repeating labels for a single feature.
584 : : * \see repeatDistance
585 : : * \see repeatDistanceUnit
586 : : */
587 : : QgsMapUnitScale repeatDistanceMapUnitScale;
588 : :
589 : : /**
590 : : * Sets the quadrant in which to offset labels from feature.
591 : : */
592 : : QuadrantPosition quadOffset = QuadrantOver;
593 : :
594 : : /**
595 : : * Horizontal offset of label. Units are specified via offsetUnits.
596 : : * \see yOffset
597 : : * \see offsetUnits
598 : : * \see labelOffsetMapUnitScale
599 : : */
600 : : double xOffset = 0;
601 : :
602 : : /**
603 : : * Vertical offset of label. Units are specified via offsetUnits.
604 : : * \see xOffset
605 : : * \see offsetUnits
606 : : * \see labelOffsetMapUnitScale
607 : : */
608 : : double yOffset = 0;
609 : :
610 : : /**
611 : : * Units for offsets of label.
612 : : * \see xOffset
613 : : * \see yOffset
614 : : * \see labelOffsetMapUnitScale
615 : : */
616 : : QgsUnitTypes::RenderUnit offsetUnits = QgsUnitTypes::RenderMillimeters;
617 : :
618 : : /**
619 : : * Map unit scale for label offset.
620 : : * \see xOffset
621 : : * \see yOffset
622 : : * \see offsetUnits
623 : : */
624 : : QgsMapUnitScale labelOffsetMapUnitScale;
625 : :
626 : : //! Label rotation, in degrees clockwise
627 : : double angleOffset = 0;
628 : :
629 : : //! True if label rotation should be preserved during label pin/unpin operations.
630 : : bool preserveRotation = true;
631 : :
632 : : /**
633 : : * Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
634 : : * \see maxCurvedCharAngleOut
635 : : */
636 : : double maxCurvedCharAngleIn = 25.0;
637 : :
638 : : /**
639 : : * Maximum angle between outside curved label characters (valid range -20.0 to -95.0)
640 : : * \see maxCurvedCharAngleIn
641 : : */
642 : : double maxCurvedCharAngleOut = -25.0;
643 : :
644 : : /**
645 : : * Label priority. Valid ranges are from 0 to 10, where 0 = lowest priority
646 : : * and 10 = highest priority.
647 : : */
648 : : int priority = 5;
649 : :
650 : : //-- rendering
651 : :
652 : : /**
653 : : * Set to TRUE to limit label visibility to a range of scales.
654 : : * \see maximumScale
655 : : * \see minimumScale
656 : : */
657 : : bool scaleVisibility = false;
658 : :
659 : : /**
660 : : * The maximum map scale (i.e. most "zoomed in" scale) at which the labels will be visible.
661 : : * The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
662 : : * A scale of 0 indicates no maximum scale visibility.
663 : : *
664 : : * This setting is only considered if scaleVisibility is TRUE.
665 : : *
666 : : * \see minimumScale
667 : : * \see scaleVisibility
668 : : */
669 : : double maximumScale = 0;
670 : :
671 : : /**
672 : : * The minimum map scale (i.e. most "zoomed out" scale) at which the labels will be visible.
673 : : * The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
674 : : * A scale of 0 indicates no minimum scale visibility.
675 : : *
676 : : * This setting is only considered if scaleVisibility is TRUE.
677 : : *
678 : : * \see maximumScale
679 : : * \see scaleVisibility
680 : : */
681 : : double minimumScale = 0;
682 : :
683 : : /**
684 : : * TRUE if label sizes should be limited by pixel size.
685 : : * \see fontMinPixelSize
686 : : * \see fontMaxPixelSize
687 : : */
688 : : bool fontLimitPixelSize = false;
689 : :
690 : : /**
691 : : * Minimum pixel size for showing rendered map unit labels (1 - 1000).
692 : : * \see fontLimitPixelSize
693 : : * \see fontMaxPixelSize
694 : : */
695 : : int fontMinPixelSize = 0;
696 : :
697 : : /**
698 : : * Maximum pixel size for showing rendered map unit labels (1 - 10000).
699 : : * \see fontLimitPixelSize
700 : : * \see fontMinPixelSize
701 : : */
702 : : int fontMaxPixelSize = 10000;
703 : :
704 : : //! If TRUE, all features will be labelled even when overlaps occur.
705 : : bool displayAll = false;
706 : :
707 : : //! Controls whether upside down labels are displayed and how they are handled.
708 : : UpsideDownLabels upsidedownLabels = Upright;
709 : :
710 : : /**
711 : : * TRUE if every part of a multi-part feature should be labeled. If FALSE,
712 : : * only the largest part will be labeled.
713 : : */
714 : : bool labelPerPart = false;
715 : :
716 : : // TODO QGIS 4.0 - remove this junk
717 : :
718 : : #ifdef SIP_RUN
719 : : SIP_PROPERTY( name = limitNumLabels, get = _limitNumLabels, set = _setLimitNumLabels )
720 : : SIP_PROPERTY( name = maxNumLabels, get = _maxNumLabels, set = _setMaxNumLabels )
721 : : SIP_PROPERTY( name = minFeatureSize, get = _minFeatureSize, set = _setMinFeatureSize )
722 : : SIP_PROPERTY( name = obstacle, get = _getIsObstacle, set = _setIsObstacle )
723 : : SIP_PROPERTY( name = obstacleFactor, get = _getObstacleFactor, set = _setObstacleFactor )
724 : : SIP_PROPERTY( name = obstacleType, get = _getObstacleType, set = _setObstacleType )
725 : : SIP_PROPERTY( name = placementFlags, get = _getLinePlacementFlags, set = _setLinePlacementFlags )
726 : : SIP_PROPERTY( name = mergeLines, get = _getMergeLines, set = _setMergeLines )
727 : : SIP_PROPERTY( name = addDirectionSymbol, get = _getAddDirectionSymbol, set = _setAddDirectionSymbol )
728 : : SIP_PROPERTY( name = leftDirectionSymbol, get = _getLeftDirectionSymbol, set = _setLeftDirectionSymbol )
729 : : SIP_PROPERTY( name = rightDirectionSymbol, get = _getRightDirectionSymbol, set = _setRightDirectionSymbol )
730 : : SIP_PROPERTY( name = reverseDirectionSymbol, get = _getReverseDirectionSymbol, set = _setReverseDirectionSymbol )
731 : : SIP_PROPERTY( name = placeDirectionSymbol, get = _getPlaceDirectionSymbol, set = _setPlaceDirectionSymbol )
732 : :
733 : : SIP_PROPERTY( name = overrunDistance, get = _getOverrunDistance, set = _setOverrunDistance )
734 : : SIP_PROPERTY( name = overrunDistanceUnit, get = _getOverrunDistanceUnit, set = _setOverrunDistanceUnit )
735 : : SIP_PROPERTY( name = overrunDistanceMapUnitScale, get = _getOverrunDistanceMapUnitScale, set = _setOverrunDistanceMapUnitScale )
736 : : #endif
737 : :
738 : : ///@cond PRIVATE
739 : : bool _limitNumLabels() const { return mThinningSettings.limitNumberOfLabelsEnabled(); }
740 : : void _setLimitNumLabels( bool limit ) { mThinningSettings.setLimitNumberLabelsEnabled( limit ); }
741 : : int _maxNumLabels() const { return mThinningSettings.maximumNumberLabels(); }
742 : : void _setMaxNumLabels( int max ) { mThinningSettings.setMaximumNumberLabels( max ); }
743 : : double _minFeatureSize() const { return mThinningSettings.minimumFeatureSize(); }
744 : : void _setMinFeatureSize( double size ) { mThinningSettings.setMinimumFeatureSize( size ); }
745 : : bool _getIsObstacle() const { return mObstacleSettings.isObstacle(); }
746 : : void _setIsObstacle( bool obstacle ) { mObstacleSettings.setIsObstacle( obstacle ); }
747 : : double _getObstacleFactor() const { return mObstacleSettings.factor(); }
748 : : void _setObstacleFactor( double factor ) { mObstacleSettings.setFactor( factor ); }
749 : : ObstacleType _getObstacleType() const { return static_cast< ObstacleType>( mObstacleSettings.type() ); }
750 : : void _setObstacleType( ObstacleType type ) { mObstacleSettings.setType( static_cast< QgsLabelObstacleSettings::ObstacleType>( type ) ); }
751 : : unsigned int _getLinePlacementFlags() const { return static_cast< unsigned int >( mLineSettings.placementFlags() ); }
752 : : void _setLinePlacementFlags( unsigned int flags ) { mLineSettings.setPlacementFlags( static_cast< QgsLabeling::LinePlacementFlags >( flags ) ); }
753 : : bool _getMergeLines() const { return mLineSettings.mergeLines(); }
754 : : void _setMergeLines( bool merge ) { mLineSettings.setMergeLines( merge ); }
755 : : bool _getAddDirectionSymbol() const { return mLineSettings.addDirectionSymbol(); }
756 : : void _setAddDirectionSymbol( bool add ) { mLineSettings.setAddDirectionSymbol( add ); }
757 : : QString _getLeftDirectionSymbol() const { return mLineSettings.leftDirectionSymbol(); }
758 : : void _setLeftDirectionSymbol( const QString &symbol ) { mLineSettings.setLeftDirectionSymbol( symbol ); }
759 : : QString _getRightDirectionSymbol() const { return mLineSettings.rightDirectionSymbol(); }
760 : : void _setRightDirectionSymbol( const QString &symbol ) { mLineSettings.setRightDirectionSymbol( symbol ); }
761 : : bool _getReverseDirectionSymbol() const { return mLineSettings.reverseDirectionSymbol(); }
762 : : void _setReverseDirectionSymbol( bool reverse ) { mLineSettings.setReverseDirectionSymbol( reverse ); }
763 : : Q_NOWARN_DEPRECATED_PUSH
764 : : DirectionSymbols _getPlaceDirectionSymbol() const { return static_cast< DirectionSymbols>( mLineSettings.directionSymbolPlacement() ); }
765 : : void _setPlaceDirectionSymbol( DirectionSymbols placement ) { mLineSettings.setDirectionSymbolPlacement( static_cast< QgsLabelLineSettings::DirectionSymbolPlacement>( placement ) ); }
766 : : Q_NOWARN_DEPRECATED_POP
767 : : double _getOverrunDistance() const { return mLineSettings.overrunDistance(); }
768 : : void _setOverrunDistance( double distance ) { mLineSettings.setOverrunDistance( distance ); }
769 : : QgsUnitTypes::RenderUnit _getOverrunDistanceUnit() const { return mLineSettings.overrunDistanceUnit(); }
770 : : void _setOverrunDistanceUnit( QgsUnitTypes::RenderUnit unit ) { mLineSettings.setOverrunDistanceUnit( unit ); }
771 : : QgsMapUnitScale _getOverrunDistanceMapUnitScale() const { return mLineSettings.overrunDistanceMapUnitScale(); }
772 : : void _setOverrunDistanceMapUnitScale( const QgsMapUnitScale &scale ) { mLineSettings.setOverrunDistanceMapUnitScale( scale ); }
773 : : ///@endcond
774 : :
775 : : //! Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-index
776 : : double zIndex = 0;
777 : :
778 : : //! The geometry generator expression. Null if disabled.
779 : : QString geometryGenerator;
780 : :
781 : : //! The type of the result geometry of the geometry generator.
782 : : QgsWkbTypes::GeometryType geometryGeneratorType = QgsWkbTypes::GeometryType::PointGeometry;
783 : :
784 : : //! Defines if the geometry generator is enabled or not. If disabled, the standard geometry will be taken.
785 : : bool geometryGeneratorEnabled = false;
786 : :
787 : : /**
788 : : * Geometry type of layers associated with these settings.
789 : : * \since QGIS 3.10
790 : : */
791 : : QgsWkbTypes::GeometryType layerType = QgsWkbTypes::UnknownGeometry;
792 : :
793 : : /**
794 : : * Calculates the space required to render the provided \a text in map units.
795 : : * Results will be written to \a labelX and \a labelY.
796 : : * If the text orientation is set to rotation-based, the spaced taken to render
797 : : * vertically oriented text will be written to \a rotatedLabelX and \a rotatedLabelY .
798 : : */
799 : : #ifndef SIP_RUN
800 : : void calculateLabelSize( const QFontMetricsF *fm, const QString &text, double &labelX, double &labelY, const QgsFeature *f = nullptr, QgsRenderContext *context = nullptr, double *rotatedLabelX SIP_OUT = nullptr, double *rotatedLabelY SIP_OUT = nullptr,
801 : : QgsTextDocument *document = nullptr );
802 : : #else
803 : : void calculateLabelSize( const QFontMetricsF *fm, const QString &text, double &labelX, double &labelY, const QgsFeature *f = nullptr, QgsRenderContext *context = nullptr, double *rotatedLabelX SIP_OUT = nullptr, double *rotatedLabelY SIP_OUT = nullptr );
804 : : #endif
805 : :
806 : : /**
807 : : * Register a feature for labeling.
808 : : * \param f feature to label
809 : : * \param context render context. The QgsExpressionContext contained within the render context
810 : : * must have already had the feature and fields sets prior to calling this method.
811 : : * \param labelFeature if using QgsLabelingEngine, this will receive the label feature. Not available
812 : : * in Python bindings.
813 : : * \param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
814 : : * should be used as an obstacle for labels (e.g., if the feature has been rendered with an offset point
815 : : * symbol, the obstacle geometry should represent the bounds of the offset symbol). If not set,
816 : : * the feature's original geometry will be used as an obstacle for labels. Not available
817 : : * in Python bindings.
818 : : * \param symbol feature symbol to label (ownership is not transferred, and \a symbol must exist until the labeling is complete)
819 : : */
820 : : void registerFeature( const QgsFeature &f, QgsRenderContext &context,
821 : : QgsLabelFeature **labelFeature SIP_PYARGREMOVE = nullptr,
822 : : QgsGeometry obstacleGeometry SIP_PYARGREMOVE = QgsGeometry(), const QgsSymbol *symbol SIP_PYARGREMOVE = nullptr );
823 : :
824 : : /**
825 : : * Read settings from a DOM element
826 : : * \since QGIS 2.12
827 : : */
828 : : void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
829 : :
830 : : /**
831 : : * Write settings into a DOM element
832 : : * \since QGIS 2.12
833 : : */
834 : : QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const;
835 : :
836 : : /**
837 : : * Returns a reference to the label's property collection, used for data defined overrides.
838 : : * \see setDataDefinedProperties()
839 : : * \since QGIS 3.0
840 : : */
841 : 0 : QgsPropertyCollection &dataDefinedProperties() { return mDataDefinedProperties; }
842 : :
843 : : /**
844 : : * Returns a reference to the label's property collection, used for data defined overrides.
845 : : * \see setDataDefinedProperties()
846 : : * \see Property
847 : : * \note not available in Python bindings
848 : : * \since QGIS 3.0
849 : : */
850 : 0 : const QgsPropertyCollection &dataDefinedProperties() const SIP_SKIP { return mDataDefinedProperties; }
851 : :
852 : : /**
853 : : * Sets the label's property collection, used for data defined overrides.
854 : : * \param collection property collection. Existing properties will be replaced.
855 : : * \see dataDefinedProperties()
856 : : * \see Property
857 : : * \since QGIS 3.0
858 : : */
859 : 0 : void setDataDefinedProperties( const QgsPropertyCollection &collection ) { mDataDefinedProperties = collection; }
860 : :
861 : : /**
862 : : * Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
863 : : * \see setFormat()
864 : : * \since QGIS 3.0
865 : : */
866 : 0 : const QgsTextFormat &format() const { return mFormat; }
867 : :
868 : : /**
869 : : * Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
870 : : * \param format label text format
871 : : * \see format()
872 : : * \since QGIS 3.0
873 : : */
874 : 0 : void setFormat( const QgsTextFormat &format ) { mFormat = format; }
875 : :
876 : : /**
877 : : * Returns the label callout renderer, responsible for drawing label callouts.
878 : : *
879 : : * Ownership is not transferred.
880 : : *
881 : : * \see setCallout()
882 : : * \since QGIS 3.10
883 : : */
884 : 0 : QgsCallout *callout() const { return mCallout.get(); }
885 : :
886 : : /**
887 : : * Sets the label \a callout renderer, responsible for drawing label callouts.
888 : : *
889 : : * Ownership of \a callout is transferred to the settings.
890 : :
891 : : * \see callout()
892 : : * \since QGIS 3.10
893 : : */
894 : : void setCallout( QgsCallout *callout SIP_TRANSFER );
895 : :
896 : : /**
897 : : * Returns the label line settings, which contain settings related to how the label
898 : : * engine places and formats labels for line features (or polygon features which are labeled in
899 : : * a "perimeter" style mode).
900 : : * \see setLineSettings()
901 : : * \note Not available in Python bindings
902 : : * \since QGIS 3.16
903 : : */
904 : : const QgsLabelLineSettings &lineSettings() const { return mLineSettings; } SIP_SKIP
905 : :
906 : : /**
907 : : * Returns the label line settings, which contain settings related to how the label
908 : : * engine places and formats labels for line features (or polygon features which are labeled in
909 : : * a "perimeter" style mode).
910 : : * \see setLineSettings()
911 : : * \since QGIS 3.16
912 : : */
913 : 0 : QgsLabelLineSettings &lineSettings() { return mLineSettings; }
914 : :
915 : : /**
916 : : * Sets the label line \a settings, which contain settings related to how the label
917 : : * engine places and formats labels for line features (or polygon features which are labeled in
918 : : * a "perimeter" style mode).
919 : : * \see lineSettings()
920 : : * \since QGIS 3.16
921 : : */
922 : : void setLineSettings( const QgsLabelLineSettings &settings ) { mLineSettings = settings; }
923 : :
924 : : /**
925 : : * Returns the label obstacle settings.
926 : : * \see setObstacleSettings()
927 : : * \note Not available in Python bindings
928 : : * \since QGIS 3.10.2
929 : : */
930 : : const QgsLabelObstacleSettings &obstacleSettings() const { return mObstacleSettings; } SIP_SKIP
931 : :
932 : : /**
933 : : * Returns the label obstacle settings.
934 : : * \see setObstacleSettings()
935 : : * \since QGIS 3.10.2
936 : : */
937 : 0 : QgsLabelObstacleSettings &obstacleSettings() { return mObstacleSettings; }
938 : :
939 : : /**
940 : : * Sets the label obstacle \a settings.
941 : : * \see obstacleSettings()
942 : : * \since QGIS 3.10.2
943 : : */
944 : : void setObstacleSettings( const QgsLabelObstacleSettings &settings ) { mObstacleSettings = settings; }
945 : :
946 : : /**
947 : : * Returns the label thinning settings.
948 : : * \see setThinningSettings()
949 : : * \note Not available in Python bindings
950 : : * \since QGIS 3.12
951 : : */
952 : : const QgsLabelThinningSettings &thinningSettings() const { return mThinningSettings; } SIP_SKIP
953 : :
954 : : /**
955 : : * Returns the label thinning settings.
956 : : * \see setThinningSettings()
957 : : * \since QGIS 3.12
958 : : */
959 : : QgsLabelThinningSettings &thinningSettings() { return mThinningSettings; }
960 : :
961 : : /**
962 : : * Sets the label thinning \a settings.
963 : : * \see thinningSettings()
964 : : * \since QGIS 3.12
965 : : */
966 : : void setThinningSettings( const QgsLabelThinningSettings &settings ) { mThinningSettings = settings; }
967 : :
968 : : /**
969 : : * Returns a pixmap preview for label \a settings.
970 : : * \param settings label settings
971 : : * \param size target pixmap size
972 : : * \param previewText text to render in preview, or empty for default text
973 : : * \param padding space between icon edge and color ramp
974 : : * \since QGIS 3.10
975 : : */
976 : : static QPixmap labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText = QString(), int padding = 0 );
977 : :
978 : : // temporary stuff: set when layer gets prepared or labeled
979 : : const QgsFeature *mCurFeat = nullptr;
980 : : QgsFields mCurFields;
981 : : int fieldIndex = 0;
982 : : const QgsMapToPixel *xform = nullptr;
983 : : QgsCoordinateTransform ct;
984 : :
985 : : QgsPointXY ptZero;
986 : : QgsPointXY ptOne;
987 : : QgsGeometry extentGeom;
988 : : int mFeaturesToLabel = 0; // total features that will probably be labeled, may be less (figured before PAL)
989 : : int mFeatsSendingToPal = 0; // total features tested for sending into PAL (relative to maxNumLabels)
990 : : int mFeatsRegPal = 0; // number of features registered in PAL, when using limitNumLabels
991 : : private:
992 : :
993 : : friend class QgsVectorLayer; // to allow calling readFromLayerCustomProperties()
994 : :
995 : : /**
996 : : * Reads labeling configuration from layer's custom properties to support loading of simple labeling from QGIS 2.x projects.
997 : : * \since QGIS 3.0
998 : : */
999 : : void readFromLayerCustomProperties( QgsVectorLayer *layer );
1000 : :
1001 : : /**
1002 : : * Reads data defined properties from a QGIS 2.x project.
1003 : : */
1004 : : void readOldDataDefinedPropertyMap( QgsVectorLayer *layer, QDomElement *parentElem );
1005 : :
1006 : : /**
1007 : : * Reads a data defined property from a QGIS 2.x project.
1008 : : */
1009 : : void readOldDataDefinedProperty( QgsVectorLayer *layer, QgsPalLayerSettings::Property p );
1010 : :
1011 : : enum DataDefinedValueType
1012 : : {
1013 : : DDBool,
1014 : : DDInt,
1015 : : DDIntPos,
1016 : : DDDouble,
1017 : : DDDoublePos,
1018 : : DDRotation180,
1019 : : DDOpacity, //!< Data defined opacity (double between 0 and 100)
1020 : : DDString,
1021 : : DDUnits,
1022 : : DDColor,
1023 : : DDJoinStyle,
1024 : : DDBlendMode,
1025 : : DDPointF,
1026 : : DDSizeF, //!< Data defined size
1027 : : };
1028 : :
1029 : : // convenience data defined evaluation function
1030 : : bool dataDefinedValEval( DataDefinedValueType valType,
1031 : : QgsPalLayerSettings::Property p,
1032 : : QVariant &exprVal, QgsExpressionContext &context, const QVariant &originalValue = QVariant() );
1033 : :
1034 : : void parseTextStyle( QFont &labelFont,
1035 : : QgsUnitTypes::RenderUnit fontunits,
1036 : : QgsRenderContext &context );
1037 : :
1038 : : void parseTextBuffer( QgsRenderContext &context );
1039 : :
1040 : : void parseTextMask( QgsRenderContext &context );
1041 : :
1042 : : void parseTextFormatting( QgsRenderContext &context );
1043 : :
1044 : : void parseShapeBackground( QgsRenderContext &context );
1045 : :
1046 : : void parseDropShadow( QgsRenderContext &context );
1047 : :
1048 : : /**
1049 : : * Checks if a feature is larger than a minimum size (in mm)
1050 : : * \returns TRUE if above size, FALSE if below
1051 : : */
1052 : : bool checkMinimumSizeMM( const QgsRenderContext &ct, const QgsGeometry &geom, double minSize ) const;
1053 : :
1054 : : /**
1055 : : * Registers a feature as an obstacle only (no label rendered)
1056 : : */
1057 : : void registerObstacleFeature( const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **obstacleFeature, const QgsGeometry &obstacleGeometry = QgsGeometry() );
1058 : :
1059 : : QMap<Property, QVariant> dataDefinedValues;
1060 : :
1061 : : //! Property collection for data defined label settings
1062 : : QgsPropertyCollection mDataDefinedProperties;
1063 : :
1064 : : QgsExpression *expression = nullptr;
1065 : :
1066 : : QFontDatabase mFontDB;
1067 : :
1068 : : QgsTextFormat mFormat;
1069 : :
1070 : : std::unique_ptr< QgsCallout > mCallout;
1071 : :
1072 : : QgsLabelLineSettings mLineSettings;
1073 : : QgsLabelObstacleSettings mObstacleSettings;
1074 : : QgsLabelThinningSettings mThinningSettings;
1075 : :
1076 : : QgsLabeling::PolygonPlacementFlags mPolygonPlacementFlags = QgsLabeling::PolygonPlacementFlag::AllowPlacementInsideOfPolygon;
1077 : :
1078 : : QgsExpression mGeometryGeneratorExpression;
1079 : :
1080 : : bool mRenderStarted = false;
1081 : :
1082 : : static void initPropertyDefinitions();
1083 : : };
1084 : :
1085 : : /**
1086 : : * \ingroup core
1087 : : * \brief Represents a label candidate.
1088 : : */
1089 : : class CORE_EXPORT QgsLabelCandidate
1090 : : {
1091 : : public:
1092 : 0 : QgsLabelCandidate( const QRectF &r, double c ): rect( r ), cost( c ) {}
1093 : :
1094 : : QRectF rect;
1095 : : double cost;
1096 : : };
1097 : :
1098 : : /**
1099 : : * \ingroup core
1100 : : * \class QgsPalLabeling
1101 : : * \brief PAL labeling utilities.
1102 : : */
1103 : : class CORE_EXPORT QgsPalLabeling
1104 : : {
1105 : : public:
1106 : :
1107 : : /**
1108 : : * Called to find out whether a specified \a layer is used for labeling.
1109 : : * \since QGIS 2.4
1110 : : */
1111 : : static bool staticWillUseLayer( const QgsMapLayer *layer );
1112 : :
1113 : : //! \note not available in Python bindings
1114 : : static void drawLabelCandidateRect( pal::LabelPosition *lp, QPainter *painter, const QgsMapToPixel *xform, QList<QgsLabelCandidate> *candidates = nullptr ) SIP_SKIP;
1115 : :
1116 : : /**
1117 : : * Prepares a geometry for registration with PAL. Handles reprojection, rotation, clipping, etc.
1118 : : * \param geometry geometry to prepare
1119 : : * \param context render context
1120 : : * \param ct coordinate transform, or invalid transform if no transformation required
1121 : : * \param clipGeometry geometry to clip features to, if applicable
1122 : : * \param mergeLines TRUE if touching lines from this layer will be merged and treated as single features during labeling
1123 : : * \returns prepared geometry
1124 : : * \since QGIS 2.9
1125 : : */
1126 : : static QgsGeometry prepareGeometry( const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry = QgsGeometry(), bool mergeLines = false ) SIP_FACTORY;
1127 : :
1128 : : /**
1129 : : * Checks whether a geometry requires preparation before registration with PAL
1130 : : * \param geometry geometry to prepare
1131 : : * \param context render context
1132 : : * \param ct coordinate transform, or invalid transform if no transformation required
1133 : : * \param clipGeometry geometry to clip features to, if applicable
1134 : : * \param mergeLines TRUE if touching lines from this layer will be merged and treated as single features during labeling
1135 : : * \returns TRUE if geometry requires preparation
1136 : : * \since QGIS 2.9
1137 : : */
1138 : : static bool geometryRequiresPreparation( const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry = QgsGeometry(), bool mergeLines = false );
1139 : :
1140 : : /**
1141 : : * Splits a \a text string to a list of separate lines, using a specified wrap character (\a wrapCharacter).
1142 : : * The text string will be split on either newline characters or the wrap character.
1143 : : *
1144 : : * Since QGIS 3.4 the \a autoWrapLength argument can be used to specify an ideal length of line to automatically
1145 : : * wrap text to (automatic wrapping is disabled if \a autoWrapLength is 0). This automatic wrapping is performed
1146 : : * after processing wrapping using \a wrapCharacter. When auto wrapping is enabled, the \a useMaxLineLengthWhenAutoWrapping
1147 : : * argument controls whether the lines should be wrapped to an ideal maximum of \a autoWrapLength characters, or
1148 : : * if FALSE then the lines are wrapped to an ideal minimum length of \a autoWrapLength characters.
1149 : : *
1150 : : * \since QGIS 2.9
1151 : : */
1152 : : static QStringList splitToLines( const QString &text, const QString &wrapCharacter, int autoWrapLength = 0, bool useMaxLineLengthWhenAutoWrapping = true );
1153 : :
1154 : : /**
1155 : : * Splits a text string to a list of graphemes, which are the smallest allowable character
1156 : : * divisions in the string. This accounts for scripts were individual characters are not
1157 : : * allowed to be split apart (e.g., Arabic and Indic based scripts)
1158 : : * \param text string to split
1159 : : * \returns list of graphemes
1160 : : * \since QGIS 2.10
1161 : : */
1162 : : static QStringList splitToGraphemes( const QString &text );
1163 : :
1164 : : private:
1165 : : //! Update temporary QgsPalLayerSettings with any data defined text style values
1166 : : static void dataDefinedTextStyle( QgsPalLayerSettings &tmpLyr,
1167 : : const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1168 : :
1169 : : //! Update temporary QgsPalLayerSettings with any data defined text formatting values
1170 : : static void dataDefinedTextFormatting( QgsPalLayerSettings &tmpLyr,
1171 : : const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1172 : :
1173 : : //! Update temporary QgsPalLayerSettings with any data defined text buffer values
1174 : : static void dataDefinedTextBuffer( QgsPalLayerSettings &tmpLyr,
1175 : : const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1176 : :
1177 : : //! Update temporary QgsPalLayerSettings with any data defined mask values
1178 : : static void dataDefinedTextMask( QgsPalLayerSettings &tmpLyr,
1179 : : const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1180 : :
1181 : : //! Update temporary QgsPalLayerSettings with any data defined shape background values
1182 : : static void dataDefinedShapeBackground( QgsPalLayerSettings &tmpLyr,
1183 : : const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1184 : :
1185 : : //! Update temporary QgsPalLayerSettings with any data defined drop shadow values
1186 : : static void dataDefinedDropShadow( QgsPalLayerSettings &tmpLyr,
1187 : : const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1188 : :
1189 : : friend class QgsVectorLayerLabelProvider; // to allow calling the static methods above
1190 : : friend class QgsDxfExport; // to allow calling the static methods above
1191 : :
1192 : : /**
1193 : : * Checks whether a geometry exceeds the minimum required size for a geometry to be labeled.
1194 : : * \param context render context
1195 : : * \param geom geometry
1196 : : * \param minSize minimum size for geometry
1197 : : * \returns TRUE if geometry exceeds minimum size
1198 : : * \since QGIS 2.9
1199 : : */
1200 : : static bool checkMinimumSizeMM( const QgsRenderContext &context, const QgsGeometry &geom, double minSize );
1201 : :
1202 : : friend class QgsPalLayerSettings;
1203 : : };
1204 : :
1205 : :
1206 : : #endif // QGSPALLABELING_H
|