/
pal.h
329 lines (271 loc) · 9.6 KB
/
pal.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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/*
* libpal - Automated Placement of Labels Library
*
* Copyright (C) 2008 Maxence Laurent, MIS-TIC, HEIG-VD
* University of Applied Sciences, Western Switzerland
* http://www.hes-so.ch
*
* Contact:
* maxence.laurent <at> heig-vd <dot> ch
* or
* eric.taillard <at> heig-vd <dot> ch
*
* This file is part of libpal.
*
* libpal 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 3 of the License, or
* (at your option) any later version.
*
* libpal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libpal. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PAL_H
#define PAL_H
#define SIP_NO_FILE
#include "qgis_core.h"
#include "qgsgeometry.h"
#include "qgspallabeling.h"
#include <QList>
#include <iostream>
#include <ctime>
#include <QMutex>
#include <QStringList>
// TODO ${MAJOR} ${MINOR} etc instead of 0.2
class QgsAbstractLabelProvider;
namespace pal
{
//! Get GEOS context handle to be used in all GEOS library calls with reentrant API
GEOSContextHandle_t geosContext();
class Layer;
class LabelPosition;
class PalStat;
class Problem;
class PointSet;
//! Search method to use
enum SearchMethod
{
CHAIN = 0, //!< Is the worst but fastest method
POPMUSIC_TABU_CHAIN = 1, //!< Is the best but slowest
POPMUSIC_TABU = 2, //!< Is a little bit better than CHAIN but slower
POPMUSIC_CHAIN = 3, //!< Is slower and best than TABU, worse and faster than TABU_CHAIN
FALP = 4 //! only initial solution
};
//! Enumeration line arrangement flags. Flags can be combined.
enum LineArrangementFlag
{
FLAG_ON_LINE = 1,
FLAG_ABOVE_LINE = 2,
FLAG_BELOW_LINE = 4,
FLAG_MAP_ORIENTATION = 8
};
Q_DECLARE_FLAGS( LineArrangementFlags, LineArrangementFlag )
/**
* \ingroup core
* \brief Main Pal labeling class
*
* A pal object will contains layers and global information such as which search method
* will be used.
* \class pal::Pal
* \note not available in Python bindings
*/
class CORE_EXPORT Pal
{
friend class Problem;
friend class FeaturePart;
friend class Layer;
public:
/**
* \brief Create an new pal instance
*/
Pal();
~Pal();
//! Pal cannot be copied.
Pal( const Pal &other ) = delete;
//! Pal cannot be copied.
Pal &operator=( const Pal &other ) = delete;
/**
* \brief add a new layer
*
* \param provider Provider associated with the layer
* \param layerName layer's name
* \param arrangement Howto place candidates
* \param defaultPriority layer's prioriry (0 is the best, 1 the worst)
* \param active is the layer is active (currently displayed)
* \param toLabel the layer will be labeled only if toLablel is true
* \param displayAll if true, all features will be labelled even though overlaps occur
*
* \throws PalException::LayerExists
*
* @todo add symbolUnit
*/
Layer *addLayer( QgsAbstractLabelProvider *provider, const QString &layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll = false );
/**
* \brief remove a layer
*
* \param layer layer to remove
*/
void removeLayer( Layer *layer );
typedef bool ( *FnIsCanceled )( void *ctx );
//! Register a function that returns whether this job has been canceled - PAL calls it during the computation
void registerCancelationCallback( FnIsCanceled fnCanceled, void *context );
//! Check whether the job has been canceled
inline bool isCanceled() { return fnIsCanceled ? fnIsCanceled( fnIsCanceledContext ) : false; }
/**
* Extracts the labeling problem for the specified map \a extent - only features within this
* extent will be considered. The \a mapBoundary argument specifies the actual geometry of the map
* boundary, which will be used to detect whether a label is visible (or partially visible) in
* the rendered map. This may differ from \a extent in the case of rotated or non-rectangular
* maps.
*/
std::unique_ptr< Problem > extractProblem( const QgsRectangle &extent, const QgsGeometry &mapBoundary );
QList<LabelPosition *> solveProblem( Problem *prob, bool displayAll );
/**
*\brief Set flag show partial label
*
* \param show flag value
*/
void setShowPartial( bool show );
/**
* \brief Get flag show partial label
*
* \returns value of flag
*/
bool getShowPartial();
/**
* \brief set # candidates to generate for points features
* Higher the value is, longer Pal::labeller will spend time
*
* \param point_p # candidates for a point
*/
void setPointP( int point_p );
/**
* \brief set maximum # candidates to generate for lines features
* Higher the value is, longer Pal::labeller will spend time
*
* \param line_p maximum # candidates for a line
*/
void setLineP( int line_p );
/**
* \brief set maximum # candidates to generate for polygon features
* Higher the value is, longer Pal::labeller will spend time
*
* \param poly_p maximum # candidate for a polygon
*/
void setPolyP( int poly_p );
/**
* \brief get # candidates to generate for point features
*/
int getPointP();
/**
* \brief get maximum # candidates to generate for line features
*/
int getLineP();
/**
* \brief get maximum # candidates to generate for polygon features
*/
int getPolyP();
/**
* \brief Select the search method to use.
*
* For interactive mapping using CHAIN is a good
* idea because it is the fastest. Other methods, ordered by speedness, are POPMUSIC_TABU,
* POPMUSIC_CHAIN and POPMUSIC_TABU_CHAIN, defined in pal::_searchMethod enumeration
* \param method the method to use
*/
void setSearch( SearchMethod method );
/**
* \brief get the search method in use
*
* \returns the search method
*/
SearchMethod getSearch();
private:
QHash< QgsAbstractLabelProvider *, Layer * > mLayers;
QMutex mMutex;
/**
* \brief maximum # candidates for a point
*/
int point_p;
/**
* \brief maximum # candidates for a line
*/
int line_p;
/**
* \brief maximum # candidates for a polygon
*/
int poly_p;
SearchMethod searchMethod;
/*
* POPMUSIC Tuning
*/
int popmusic_r;
int tabuMaxIt;
int tabuMinIt;
int ejChainDeg;
int tenure;
double candListSize;
/**
* \brief show partial labels (cut-off by the map canvas) or not
*/
bool showPartial;
//! Callback that may be called from PAL to check whether the job has not been canceled in meanwhile
FnIsCanceled fnIsCanceled;
//! Application-specific context for the cancelation check function
void *fnIsCanceledContext = nullptr;
/**
* Creates a Problem, by extracting labels and generating candidates from the given \a extent.
* The \a mapBoundary geometry specifies the actual visible region of the map, and is used
* for pruning candidates which fall outside the visible region.
*/
std::unique_ptr< Problem > extract( const QgsRectangle &extent, const QgsGeometry &mapBoundary );
/**
* \brief Choose the size of popmusic subpart's
* \param r subpart size
*/
void setPopmusicR( int r );
/**
* \brief minimum # of iteration for search method POPMUSIC_TABU, POPMUSIC_CHAIN and POPMUSIC_TABU_CHAIN
* \param min_it Sub part optimization min # of iteration
*/
void setMinIt( int min_it );
/**
* \brief maximum \# of iteration for search method POPMUSIC_TABU, POPMUSIC_CHAIN and POPMUSIC_TABU_CHAIN
* \param max_it Sub part optimization max # of iteration
*/
void setMaxIt( int max_it );
/**
* \brief For tabu search : how many iteration a feature will be tabu
* \param tenure consiser a feature as tabu for tenure iteration after updating feature in solution
*/
void setTenure( int tenure );
/**
* \brief For *CHAIN, select the max size of a transformation chain
* \param degree maximum soze of a transformation chain
*/
void setEjChainDeg( int degree );
/**
* \brief How many candidates will be tested by a tabu iteration
* \param fact the ration (0..1) of candidates to test
*/
void setCandListSize( double fact );
/**
* \brief Get the minimum # of iteration doing in POPMUSIC_TABU, POPMUSIC_CHAIN and POPMUSIC_TABU_CHAIN
* \returns minimum # of iteration
*/
int getMinIt();
/**
* \brief Get the maximum # of iteration doing in POPMUSIC_TABU, POPMUSIC_CHAIN and POPMUSIC_TABU_CHAIN
* \returns maximum # of iteration
*/
int getMaxIt();
};
} // end namespace pal
Q_DECLARE_OPERATORS_FOR_FLAGS( pal::LineArrangementFlags )
#endif