QGIS API Documentation  3.8.0-Zanzibar (11aff65)
pal.cpp
Go to the documentation of this file.
1 /*
2  * libpal - Automated Placement of Labels Library
3  *
4  * Copyright (C) 2008 Maxence Laurent, MIS-TIC, HEIG-VD
5  * University of Applied Sciences, Western Switzerland
6  * http://www.hes-so.ch
7  *
8  * Contact:
9  * maxence.laurent <at> heig-vd <dot> ch
10  * or
11  * eric.taillard <at> heig-vd <dot> ch
12  *
13  * This file is part of libpal.
14  *
15  * libpal is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation, either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * libpal is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with libpal. If not, see <http://www.gnu.org/licenses/>.
27  *
28  */
29 
30 #include "qgsgeometry.h"
31 #include "pal.h"
32 #include "layer.h"
33 #include "palexception.h"
34 #include "palstat.h"
35 #include "rtree.hpp"
36 #include "costcalculator.h"
37 #include "feature.h"
38 #include "geomfunction.h"
39 #include "labelposition.h"
40 #include "problem.h"
41 #include "pointset.h"
42 #include "internalexception.h"
43 #include "util.h"
44 #include <cfloat>
45 
46 using namespace pal;
47 
49 {
50  // do not init and exit GEOS - we do it inside QGIS
51  //initGEOS( geosNotice, geosError );
52 
53  fnIsCanceled = nullptr;
54  fnIsCanceledContext = nullptr;
55 
56  ejChainDeg = 50;
57  tenure = 10;
58  candListSize = 0.2;
59 
60  tabuMinIt = 3;
61  tabuMaxIt = 4;
62  searchMethod = POPMUSIC_CHAIN;
63  popmusic_r = 30;
64 
65  searchMethod = CHAIN;
66 
67  setSearch( CHAIN );
68 
69  point_p = 16;
70  line_p = 50;
71  poly_p = 30;
72 
73  showPartial = true;
74 }
75 
76 void Pal::removeLayer( Layer *layer )
77 {
78  if ( !layer )
79  return;
80 
81  mMutex.lock();
82  if ( QgsAbstractLabelProvider *key = mLayers.key( layer, nullptr ) )
83  {
84  mLayers.remove( key );
85  delete layer;
86  }
87  mMutex.unlock();
88 }
89 
91 {
92 
93  mMutex.lock();
94 
95  qDeleteAll( mLayers );
96  mLayers.clear();
97  mMutex.unlock();
98 
99  // do not init and exit GEOS - we do it inside QGIS
100  //finishGEOS();
101 }
102 
103 Layer *Pal::addLayer( QgsAbstractLabelProvider *provider, const QString &layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll )
104 {
105  mMutex.lock();
106 
107  Q_ASSERT( !mLayers.contains( provider ) );
108 
109  Layer *layer = new Layer( provider, layerName, arrangement, defaultPriority, active, toLabel, this, displayAll );
110  mLayers.insert( provider, layer );
111  mMutex.unlock();
112 
113  return layer;
114 }
115 
116 typedef struct _featCbackCtx
117 {
118  Layer *layer = nullptr;
119  QLinkedList<Feats *> *fFeats;
120  RTree<FeaturePart *, double, 2, double> *obstacles;
121  RTree<LabelPosition *, double, 2, double> *candidates;
122  const GEOSPreparedGeometry *mapBoundary = nullptr;
124 
125 
126 
127 /*
128  * Callback function
129  *
130  * Extract a specific shape from indexes
131  */
132 bool extractFeatCallback( FeaturePart *ft_ptr, void *ctx )
133 {
134  double amin[2], amax[2];
135  FeatCallBackCtx *context = reinterpret_cast< FeatCallBackCtx * >( ctx );
136 
137  // Holes of the feature are obstacles
138  for ( int i = 0; i < ft_ptr->getNumSelfObstacles(); i++ )
139  {
140  ft_ptr->getSelfObstacle( i )->getBoundingBox( amin, amax );
141  context->obstacles->Insert( amin, amax, ft_ptr->getSelfObstacle( i ) );
142 
143  if ( !ft_ptr->getSelfObstacle( i )->getHoleOf() )
144  {
145  //ERROR: SHOULD HAVE A PARENT!!!!!
146  }
147  }
148 
149  // generate candidates for the feature part
150  QList< LabelPosition * > lPos;
151  if ( ft_ptr->createCandidates( lPos, context->mapBoundary, ft_ptr, context->candidates ) )
152  {
153  // valid features are added to fFeats
154  Feats *ft = new Feats();
155  ft->feature = ft_ptr;
156  ft->shape = nullptr;
157  ft->lPos = lPos;
158  ft->priority = ft_ptr->calculatePriority();
159  context->fFeats->append( ft );
160  }
161  else
162  {
163  // Others are deleted
164  qDeleteAll( lPos );
165  }
166 
167  return true;
168 }
169 
170 typedef struct _obstaclebackCtx
171 {
172  RTree<FeaturePart *, double, 2, double> *obstacles;
175 
176 /*
177  * Callback function
178  *
179  * Extract obstacles from indexes
180  */
181 bool extractObstaclesCallback( FeaturePart *ft_ptr, void *ctx )
182 {
183  double amin[2], amax[2];
184  ObstacleCallBackCtx *context = reinterpret_cast< ObstacleCallBackCtx * >( ctx );
185 
186  // insert into obstacles
187  ft_ptr->getBoundingBox( amin, amax );
188  context->obstacles->Insert( amin, amax, ft_ptr );
189  context->obstacleCount++;
190  return true;
191 }
192 
193 typedef struct _filterContext
194 {
195  RTree<LabelPosition *, double, 2, double> *cdtsIndex;
196  Pal *pal = nullptr;
197 } FilterContext;
198 
199 bool filteringCallback( FeaturePart *featurePart, void *ctx )
200 {
201 
202  RTree<LabelPosition *, double, 2, double> *cdtsIndex = ( reinterpret_cast< FilterContext * >( ctx ) )->cdtsIndex;
203  Pal *pal = ( reinterpret_cast< FilterContext * >( ctx ) )->pal;
204 
205  if ( pal->isCanceled() )
206  return false; // do not continue searching
207 
208  double amin[2], amax[2];
209  featurePart->getBoundingBox( amin, amax );
210 
211  LabelPosition::PruneCtx pruneContext;
212  pruneContext.obstacle = featurePart;
213  pruneContext.pal = pal;
214  cdtsIndex->Search( amin, amax, LabelPosition::pruneCallback, static_cast< void * >( &pruneContext ) );
215 
216  return true;
217 }
218 
219 std::unique_ptr<Problem> Pal::extract( const QgsRectangle &extent, const QgsGeometry &mapBoundary )
220 {
221  // to store obstacles
222  RTree<FeaturePart *, double, 2, double> *obstacles = new RTree<FeaturePart *, double, 2, double>();
223 
224  std::unique_ptr< Problem > prob = qgis::make_unique< Problem >();
225 
226  int i, j;
227 
228  double bbx[4];
229  double bby[4];
230 
231  double amin[2];
232  double amax[2];
233 
234  int max_p = 0;
235 
236  LabelPosition *lp = nullptr;
237 
238  bbx[0] = bbx[3] = amin[0] = prob->bbox[0] = extent.xMinimum();
239  bby[0] = bby[1] = amin[1] = prob->bbox[1] = extent.yMinimum();
240  bbx[1] = bbx[2] = amax[0] = prob->bbox[2] = extent.xMaximum();
241  bby[2] = bby[3] = amax[1] = prob->bbox[3] = extent.yMaximum();
242 
243  prob->pal = this;
244 
245  QLinkedList<Feats *> *fFeats = new QLinkedList<Feats *>;
246 
247  FeatCallBackCtx context;
248 
249  // prepare map boundary
250  geos::unique_ptr mapBoundaryGeos( QgsGeos::asGeos( mapBoundary ) );
251  geos::prepared_unique_ptr mapBoundaryPrepared( GEOSPrepare_r( QgsGeos::getGEOSHandler(), mapBoundaryGeos.get() ) );
252 
253  context.fFeats = fFeats;
254  context.obstacles = obstacles;
255  context.candidates = prob->candidates;
256  context.mapBoundary = mapBoundaryPrepared.get();
257 
258  ObstacleCallBackCtx obstacleContext;
259  obstacleContext.obstacles = obstacles;
260  obstacleContext.obstacleCount = 0;
261 
262  // first step : extract features from layers
263 
264  int previousFeatureCount = 0;
265  int previousObstacleCount = 0;
266 
267  QStringList layersWithFeaturesInBBox;
268 
269  mMutex.lock();
270  const auto constMLayers = mLayers;
271  for ( Layer *layer : constMLayers )
272  {
273  if ( !layer )
274  {
275  // invalid layer name
276  continue;
277  }
278 
279  // only select those who are active
280  if ( !layer->active() )
281  continue;
282 
283  // check for connected features with the same label text and join them
284  if ( layer->mergeConnectedLines() )
285  layer->joinConnectedFeatures();
286 
287  layer->chopFeaturesAtRepeatDistance();
288 
289  layer->mMutex.lock();
290 
291  // find features within bounding box and generate candidates list
292  context.layer = layer;
293  layer->mFeatureIndex->Search( amin, amax, extractFeatCallback, static_cast< void * >( &context ) );
294  // find obstacles within bounding box
295  layer->mObstacleIndex->Search( amin, amax, extractObstaclesCallback, static_cast< void * >( &obstacleContext ) );
296 
297  layer->mMutex.unlock();
298 
299  if ( context.fFeats->size() - previousFeatureCount > 0 || obstacleContext.obstacleCount > previousObstacleCount )
300  {
301  layersWithFeaturesInBBox << layer->name();
302  }
303  previousFeatureCount = context.fFeats->size();
304  previousObstacleCount = obstacleContext.obstacleCount;
305  }
306  mMutex.unlock();
307 
308  prob->nbLabelledLayers = layersWithFeaturesInBBox.size();
309  prob->labelledLayersName = layersWithFeaturesInBBox;
310 
311  if ( fFeats->isEmpty() )
312  {
313  delete fFeats;
314  delete obstacles;
315  return nullptr;
316  }
317 
318  prob->nbft = fFeats->size();
319  prob->nblp = 0;
320  prob->featNbLp = new int [prob->nbft];
321  prob->featStartId = new int [prob->nbft];
322  prob->inactiveCost = new double[prob->nbft];
323 
324  Feats *feat = nullptr;
325 
326  // Filtering label positions against obstacles
327  amin[0] = amin[1] = std::numeric_limits<double>::lowest();
328  amax[0] = amax[1] = std::numeric_limits<double>::max();
329  FilterContext filterCtx;
330  filterCtx.cdtsIndex = prob->candidates;
331  filterCtx.pal = this;
332  obstacles->Search( amin, amax, filteringCallback, static_cast< void * >( &filterCtx ) );
333 
334  if ( isCanceled() )
335  {
336  const auto constFFeats = *fFeats;
337  for ( Feats *feat : constFFeats )
338  {
339  qDeleteAll( feat->lPos );
340  feat->lPos.clear();
341  }
342 
343  qDeleteAll( *fFeats );
344  delete fFeats;
345  delete obstacles;
346  return nullptr;
347  }
348 
349  int idlp = 0;
350  for ( i = 0; i < prob->nbft; i++ ) /* foreach feature into prob */
351  {
352  feat = fFeats->takeFirst();
353 
354  prob->featStartId[i] = idlp;
355  prob->inactiveCost[i] = std::pow( 2, 10 - 10 * feat->priority );
356 
357  switch ( feat->feature->getGeosType() )
358  {
359  case GEOS_POINT:
360  max_p = point_p;
361  break;
362  case GEOS_LINESTRING:
363  max_p = line_p;
364  break;
365  case GEOS_POLYGON:
366  max_p = poly_p;
367  break;
368  }
369 
370  // sort candidates by cost, skip less interesting ones, calculate polygon costs (if using polygons)
371  max_p = CostCalculator::finalizeCandidatesCosts( feat, max_p, obstacles, bbx, bby );
372 
373  // only keep the 'max_p' best candidates
374  while ( feat->lPos.count() > max_p )
375  {
376  // TODO remove from index
377  feat->lPos.last()->removeFromIndex( prob->candidates );
378  delete feat->lPos.takeLast();
379  }
380 
381  // update problem's # candidate
382  prob->featNbLp[i] = feat->lPos.count();
383  prob->nblp += feat->lPos.count();
384 
385  // add all candidates into a rtree (to speed up conflicts searching)
386  for ( j = 0; j < feat->lPos.count(); j++, idlp++ )
387  {
388  lp = feat->lPos.at( j );
389  //lp->insertIntoIndex(prob->candidates);
390  lp->setProblemIds( i, idlp ); // bugfix #1 (maxence 10/23/2008)
391  }
392  fFeats->append( feat );
393  }
394 
395  int nbOverlaps = 0;
396 
397  while ( !fFeats->isEmpty() ) // foreach feature
398  {
399  if ( isCanceled() )
400  {
401  const auto constFFeats = *fFeats;
402  for ( Feats *feat : constFFeats )
403  {
404  qDeleteAll( feat->lPos );
405  feat->lPos.clear();
406  }
407 
408  qDeleteAll( *fFeats );
409  delete fFeats;
410  delete obstacles;
411  return nullptr;
412  }
413 
414  feat = fFeats->takeFirst();
415  while ( !feat->lPos.isEmpty() ) // foreach label candidate
416  {
417  lp = feat->lPos.takeFirst();
418  lp->resetNumOverlaps();
419 
420  // make sure that candidate's cost is less than 1
421  lp->validateCost();
422 
423  prob->addCandidatePosition( lp );
424  //prob->feat[idlp] = j;
425 
426  lp->getBoundingBox( amin, amax );
427 
428  // lookup for overlapping candidate
429  prob->candidates->Search( amin, amax, LabelPosition::countOverlapCallback, static_cast< void * >( lp ) );
430 
431  nbOverlaps += lp->getNumOverlaps();
432  }
433  delete feat;
434  }
435  delete fFeats;
436 
437  //delete candidates;
438  delete obstacles;
439 
440  nbOverlaps /= 2;
441  prob->all_nblp = prob->nblp;
442  prob->nbOverlap = nbOverlaps;
443 
444  return prob;
445 }
446 
447 void Pal::registerCancellationCallback( Pal::FnIsCanceled fnCanceled, void *context )
448 {
449  fnIsCanceled = fnCanceled;
450  fnIsCanceledContext = context;
451 }
452 
453 std::unique_ptr<Problem> Pal::extractProblem( const QgsRectangle &extent, const QgsGeometry &mapBoundary )
454 {
455  return extract( extent, mapBoundary );
456 }
457 
458 QList<LabelPosition *> Pal::solveProblem( Problem *prob, bool displayAll )
459 {
460  if ( !prob )
461  return QList<LabelPosition *>();
462 
463  prob->reduce();
464 
465  try
466  {
467  if ( searchMethod == FALP )
468  prob->init_sol_falp();
469  else if ( searchMethod == CHAIN )
470  prob->chain_search();
471  else
472  prob->popmusic();
473  }
474  catch ( InternalException::Empty & )
475  {
476  return QList<LabelPosition *>();
477  }
478 
479  return prob->getSolution( displayAll );
480 }
481 
482 
483 void Pal::setPointP( int point_p )
484 {
485  if ( point_p > 0 )
486  this->point_p = point_p;
487 }
488 
489 void Pal::setLineP( int line_p )
490 {
491  if ( line_p > 0 )
492  this->line_p = line_p;
493 }
494 
495 void Pal::setPolyP( int poly_p )
496 {
497  if ( poly_p > 0 )
498  this->poly_p = poly_p;
499 }
500 
501 
502 void Pal::setMinIt( int min_it )
503 {
504  if ( min_it >= 0 )
505  tabuMinIt = min_it;
506 }
507 
508 void Pal::setMaxIt( int max_it )
509 {
510  if ( max_it > 0 )
511  tabuMaxIt = max_it;
512 }
513 
514 void Pal::setPopmusicR( int r )
515 {
516  if ( r > 0 )
517  popmusic_r = r;
518 }
519 
520 void Pal::setEjChainDeg( int degree )
521 {
522  this->ejChainDeg = degree;
523 }
524 
525 void Pal::setTenure( int tenure )
526 {
527  this->tenure = tenure;
528 }
529 
530 void Pal::setCandListSize( double fact )
531 {
532  this->candListSize = fact;
533 }
534 
535 void Pal::setShowPartial( bool show )
536 {
537  this->showPartial = show;
538 }
539 
541 {
542  return point_p;
543 }
544 
546 {
547  return line_p;
548 }
549 
551 {
552  return poly_p;
553 }
554 
555 int Pal::getMinIt()
556 {
557  return tabuMaxIt;
558 }
559 
560 int Pal::getMaxIt()
561 {
562  return tabuMinIt;
563 }
564 
566 {
567  return showPartial;
568 }
569 
571 {
572  return searchMethod;
573 }
574 
576 {
577  switch ( method )
578  {
579  case POPMUSIC_CHAIN:
580  searchMethod = method;
581  popmusic_r = 30;
582  tabuMinIt = 2;
583  tabuMaxIt = 4;
584  tenure = 10;
585  ejChainDeg = 50;
586  candListSize = 0.2;
587  break;
588  case CHAIN:
589  searchMethod = method;
590  ejChainDeg = 50;
591  break;
592  case POPMUSIC_TABU:
593  searchMethod = method;
594  popmusic_r = 25;
595  tabuMinIt = 2;
596  tabuMaxIt = 4;
597  tenure = 10;
598  ejChainDeg = 50;
599  candListSize = 0.2;
600  break;
601  case POPMUSIC_TABU_CHAIN:
602  searchMethod = method;
603  popmusic_r = 25;
604  tabuMinIt = 2;
605  tabuMaxIt = 4;
606  tenure = 10;
607  ejChainDeg = 50;
608  candListSize = 0.2;
609  break;
610  case FALP:
611  searchMethod = method;
612  break;
613  }
614 }
615 
616 
struct _obstaclebackCtx ObstacleCallBackCtx
Layer * addLayer(QgsAbstractLabelProvider *provider, const QString &layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll=false)
add a new layer
Definition: pal.cpp:103
struct _filterContext FilterContext
A rectangle specified with double values.
Definition: qgsrectangle.h:41
Pal * pal
Definition: pal.cpp:196
PointSet * getHoleOf()
Returns nullptr if this isn&#39;t a hole. Otherwise returns pointer to parent pointset.
Definition: pointset.h:135
FeaturePart * feature
Definition: util.h:56
struct _featCbackCtx FeatCallBackCtx
Only initial solution.
Definition: pal.h:65
void reduce()
Definition: problem.cpp:105
void getBoundingBox(double amin[2], double amax[2]) const
Returns bounding box - amin: xmin,ymin - amax: xmax,ymax.
SearchMethod getSearch()
Returns the search method in use.
Definition: pal.cpp:570
std::unique_ptr< const GEOSPreparedGeometry, GeosDeleter > prepared_unique_ptr
Scoped GEOS prepared geometry pointer.
Definition: qgsgeos.h:84
void registerCancellationCallback(FnIsCanceled fnCanceled, void *context)
Register a function that returns whether this job has been canceled - PAL calls it during the computa...
Definition: pal.cpp:447
A set of features which influence the labeling process.
Definition: layer.h:63
RTree< LabelPosition *, double, 2, double > * candidates
Definition: pal.cpp:121
Main Pal labeling class.
Definition: pal.h:87
Is slower and best than TABU, worse and faster than TABU_CHAIN.
Definition: pal.h:64
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
int getNumSelfObstacles() const
Gets number of holes (inner rings) - they are considered as obstacles.
Definition: feature.h:276
void setShowPartial(bool show)
Set flag show partial label.
Definition: pal.cpp:535
const GEOSPreparedGeometry * mapBoundary
Definition: pal.cpp:122
int getPointP()
Returns the number of candidates to generate for point features.
Definition: pal.cpp:540
PointSet * shape
Definition: util.h:57
Is a little bit better than CHAIN but slower.
Definition: pal.h:63
static GEOSContextHandle_t getGEOSHandler()
Definition: qgsgeos.cpp:2815
void removeLayer(Layer *layer)
remove a layer
Definition: pal.cpp:76
std::unique_ptr< Problem > extractProblem(const QgsRectangle &extent, const QgsGeometry &mapBoundary)
Extracts the labeling problem for the specified map extent - only features within this extent will be...
Definition: pal.cpp:453
RTree< FeaturePart *, double, 2, double, 8, 4 > * mFeatureIndex
Definition: layer.h:287
int getPolyP()
Returns the number of candidates to generate for polygon features.
Definition: pal.cpp:550
void chain_search()
Test with very-large scale neighborhood.
Definition: problem.cpp:2118
bool(* FnIsCanceled)(void *ctx)
Definition: pal.h:129
bool getShowPartial()
Returns whether partial labels should be allowed.
Definition: pal.cpp:565
void getBoundingBox(double min[2], double max[2]) const
Definition: pointset.h:126
Is the best but slowest.
Definition: pal.h:62
bool isCanceled()
Check whether the job has been canceled.
Definition: pal.h:135
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
Definition: qgsgeos.h:79
double calculatePriority() const
Calculates the priority for the feature.
Definition: feature.cpp:1731
void setPointP(int point_p)
set # candidates to generate for points features Higher the value is, longer Pal::labeller will spend...
Definition: pal.cpp:483
void setLineP(int line_p)
set maximum # candidates to generate for lines features Higher the value is, longer Pal::labeller wil...
Definition: pal.cpp:489
int createCandidates(QList< LabelPosition *> &lPos, const GEOSPreparedGeometry *mapBoundary, PointSet *mapShape, RTree< LabelPosition *, double, 2, double > *candidates)
Generic method to generate label candidates for the feature.
Definition: feature.cpp:1537
static int finalizeCandidatesCosts(Feats *feat, int max_p, RTree< pal::FeaturePart *, double, 2, double > *obstacles, double bbx[4], double bby[4])
Sort candidates by costs, skip the worse ones, evaluate polygon candidates.
void validateCost()
Make sure the cost is less than 1.
QList< LabelPosition * > lPos
Definition: util.h:59
For usage in problem solving algorithm.
Definition: util.h:50
void popmusic()
popmusic framework
Definition: problem.cpp:370
double priority
Definition: util.h:58
bool extractObstaclesCallback(FeaturePart *ft_ptr, void *ctx)
Definition: pal.cpp:181
Main class to handle feature.
Definition: feature.h:96
The QgsAbstractLabelProvider class is an interface class.
static bool pruneCallback(LabelPosition *candidatePosition, void *ctx)
Check whether the candidate in ctx overlap with obstacle feat.
QLinkedList< Feats * > * fFeats
Definition: pal.cpp:119
friend class Layer
Definition: pal.h:91
Pal()
Create an new pal instance.
Definition: pal.cpp:48
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
Placement
Placement modes which determine how label candidates are generated for a feature. ...
RTree< LabelPosition *, double, 2, double > * cdtsIndex
Definition: pal.cpp:195
static bool countOverlapCallback(LabelPosition *lp, void *ctx)
static geos::unique_ptr asGeos(const QgsGeometry &geometry, double precision=0)
Returns a geos geometry - caller takes ownership of the object (should be deleted with GEOSGeom_destr...
Definition: qgsgeos.cpp:166
void setPolyP(int poly_p)
set maximum # candidates to generate for polygon features Higher the value is, longer Pal::labeller w...
Definition: pal.cpp:495
int getNumOverlaps() const
RTree< FeaturePart *, double, 2, double > * obstacles
Definition: pal.cpp:120
QList< LabelPosition * > solveProblem(Problem *prob, bool displayAll)
Definition: pal.cpp:458
FeaturePart * getSelfObstacle(int i)
Gets hole (inner ring) - considered as obstacle.
Definition: feature.h:278
int getGeosType() const
Definition: pointset.h:124
int obstacleCount
Definition: pal.cpp:173
bool filteringCallback(FeaturePart *featurePart, void *ctx)
Definition: pal.cpp:199
LabelPosition is a candidate feature label position.
Definition: labelposition.h:55
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
RTree< FeaturePart *, double, 2, double > * obstacles
Definition: pal.cpp:172
Representation of a labeling problem.
Definition: problem.h:107
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
~Pal()
Definition: pal.cpp:90
bool extractFeatCallback(FeaturePart *ft_ptr, void *ctx)
Definition: pal.cpp:132
SearchMethod
Search method to use.
Definition: pal.h:59
void setProblemIds(int probFid, int lpId)
Set problem feature ID and assigned label candidate ID.
Is the worst but fastest method.
Definition: pal.h:61
Thrown when trying to access an empty data set.
Layer * layer
Definition: pal.cpp:118
void setSearch(SearchMethod method)
Select the search method to use.
Definition: pal.cpp:575
QList< LabelPosition * > getSolution(bool returnInactive)
Definition: problem.cpp:2219
int getLineP()
Returns the number of candidates to generate for line features.
Definition: pal.cpp:545
void init_sol_falp()
Definition: problem.cpp:257