1 /***************************************************************************
2   qgslabelobstaclesettings.h
3   --------------------------
4   Date                 : December 2019
5   Copyright            : (C) 2019 by Nyall Dawson
6   Email                : nyall dot dawson 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 
16 #ifndef QGSLABELOBSTACLESETTINGS_H
17 #define QGSLABELOBSTACLESETTINGS_H
18 
19 #include "qgis_core.h"
20 #include "qgis_sip.h"
21 #include "qgsgeometry.h"
22 
23 class QgsPropertyCollection;
24 class QgsExpressionContext;
25 
26 /**
27  * \ingroup core
28  * \class QgsLabelObstacleSettings
29  *
30  * \brief Contains settings related to how the label engine treats features as obstacles
31  *
32  * \since QGIS 3.10.2
33  */
34 class CORE_EXPORT QgsLabelObstacleSettings
35 {
36   public:
37 
38     /**
39      * Valid obstacle types, which affect how features within the layer will act as obstacles
40      * for labels.
41      */
42     enum ObstacleType
43     {
44       PolygonInterior, /*!< avoid placing labels over interior of polygon (prefer placing labels totally
45        outside or just slightly inside polygon) */
46       PolygonBoundary, /*!< avoid placing labels over boundary of polygon (prefer placing outside or
47        completely inside polygon) */
48       PolygonWhole /*!< avoid placing labels over ANY part of polygon. Where PolygonInterior will prefer
49        to place labels with the smallest area of intersection between the label and the polygon,
50        PolygonWhole will penalise any label which intersects with the polygon by an equal amount, so that
51        placing labels over any part of the polygon is avoided.*/
52     };
53 
54     /**
55      * Returns TRUE if the features are obstacles to labels of other layers.
56      * \see setIsObstacle()
57      * \see factor()
58      * \see type()
59      */
isObstacle()60     bool isObstacle() const
61     {
62       return mIsObstacle;
63     }
64 
65     /**
66      * Sets whether features are obstacles to labels of other layers.
67      * \see isObstacle()
68      * \see factor()
69      * \see type()
70      */
setIsObstacle(bool isObstacle)71     void setIsObstacle( bool isObstacle )
72     {
73       mIsObstacle = isObstacle;
74     }
75 
76     /**
77      * Returns the obstacle factor, where 1.0 = default, < 1.0 more likely to be covered by labels,
78      * > 1.0 less likely to be covered
79      *
80      * \see setFactor()
81      * \see isObstacle()
82      * \see type()
83      */
factor()84     double factor() const
85     {
86       return mObstacleFactor;
87     }
88 
89     /**
90      * Sets the obstacle \a factor, where 1.0 = default, < 1.0 more likely to be covered by labels,
91      * > 1.0 less likely to be covered
92      *
93      * \see factor()
94      * \see isObstacle()
95      * \see type()
96      */
setFactor(double factor)97     void setFactor( double factor )
98     {
99       mObstacleFactor = factor;
100     }
101 
102     /**
103      * Returns how features act as obstacles for labels.
104      * \see setType()
105      * \see isObstacle()
106      * \see factor()
107      */
type()108     ObstacleType type() const
109     {
110       return mObstacleType;
111     }
112 
113     /**
114      * Controls how features act as obstacles for labels.
115      * \see type()
116      * \see isObstacle()
117      * \see factor()
118      */
setType(ObstacleType type)119     void setType( ObstacleType type )
120     {
121       mObstacleType = type;
122     }
123 
124     /**
125      * Sets the label's obstacle geometry, if different to the feature geometry.
126      * This can be used to override the shape of the feature for obstacle detection, e.g., to
127      * buffer around a point geometry to prevent labels being placed too close to the
128      * point itself. It not set, the feature's geometry is used for obstacle detection.
129      *
130      * \see obstacleGeometry()
131      */
132     void setObstacleGeometry( const QgsGeometry &obstacleGeom );
133 
134     /**
135      * Returns the label's obstacle geometry, if different to the feature geometry.
136      * \see setObstacleGeometry()
137      */
138     QgsGeometry obstacleGeometry() const;
139 
140     /**
141      * Updates the obstacle settings to respect any data defined properties
142      * set within the specified \a properties collection.
143      */
144     void updateDataDefinedProperties( const QgsPropertyCollection &properties, QgsExpressionContext &context );
145 
146   private:
147 
148     bool mIsObstacle = true;
149     double mObstacleFactor = 1.0;
150     ObstacleType mObstacleType = PolygonBoundary;
151 
152     //! Optional geometry to use for label obstacles
153     QgsGeometry mObstacleGeometry;
154 
155 };
156 
157 #endif // QGSLABELOBSTACLESETTINGS_H
158