QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 
48 GEOSContextHandle_t pal::geosContext()
49 {
51 }
52 
54 {
55  // do not init and exit GEOS - we do it inside QGIS
56  //initGEOS( geosNotice, geosError );
57 
58  fnIsCancelled = nullptr;
59  fnIsCancelledContext = nullptr;
60 
61  ejChainDeg = 50;
62  tenure = 10;
63  candListSize = 0.2;
64 
65  tabuMinIt = 3;
66  tabuMaxIt = 4;
67  searchMethod = POPMUSIC_CHAIN;
68  popmusic_r = 30;
69 
70  searchMethod = CHAIN;
71 
72  setSearch( CHAIN );
73 
74  point_p = 16;
75  line_p = 50;
76  poly_p = 30;
77 
78  showPartial = true;
79 }
80 
81 void Pal::removeLayer( Layer *layer )
82 {
83  if ( !layer )
84  return;
85 
86  mMutex.lock();
87  if ( QgsAbstractLabelProvider* key = mLayers.key( layer, nullptr ) )
88  {
89  mLayers.remove( key );
90  delete layer;
91  }
92  mMutex.unlock();
93 }
94 
96 {
97 
98  mMutex.lock();
99 
100  qDeleteAll( mLayers );
101  mLayers.clear();
102  mMutex.unlock();
103 
104  // do not init and exit GEOS - we do it inside QGIS
105  //finishGEOS();
106 }
107 
108 Layer* Pal::addLayer( QgsAbstractLabelProvider* provider, const QString& layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll )
109 {
110  mMutex.lock();
111 
112  Q_ASSERT( !mLayers.contains( provider ) );
113 
114  Layer* layer = new Layer( provider, layerName, arrangement, defaultPriority, active, toLabel, this, displayAll );
115  mLayers.insert( provider, layer );
116  mMutex.unlock();
117 
118  return layer;
119 }
120 
121 typedef struct _featCbackCtx
122 {
125  RTree<FeaturePart*, double, 2, double> *obstacles;
126  RTree<LabelPosition*, double, 2, double> *candidates;
127  double bbox_min[2];
128  double bbox_max[2];
130 
131 
132 
133 /*
134  * Callback function
135  *
136  * Extract a specific shape from indexes
137  */
138 bool extractFeatCallback( FeaturePart *ft_ptr, void *ctx )
139 {
140  double amin[2], amax[2];
141  FeatCallBackCtx *context = reinterpret_cast< FeatCallBackCtx* >( ctx );
142 
143  // Holes of the feature are obstacles
144  for ( int i = 0; i < ft_ptr->getNumSelfObstacles(); i++ )
145  {
146  ft_ptr->getSelfObstacle( i )->getBoundingBox( amin, amax );
147  context->obstacles->Insert( amin, amax, ft_ptr->getSelfObstacle( i ) );
148 
149  if ( !ft_ptr->getSelfObstacle( i )->getHoleOf() )
150  {
151  //ERROR: SHOULD HAVE A PARENT!!!!!
152  }
153  }
154 
155  // generate candidates for the feature part
157  if ( ft_ptr->createCandidates( lPos, context->bbox_min, context->bbox_max, ft_ptr, context->candidates ) )
158  {
159  // valid features are added to fFeats
160  Feats *ft = new Feats();
161  ft->feature = ft_ptr;
162  ft->shape = nullptr;
163  ft->lPos = lPos;
164  ft->priority = ft_ptr->calculatePriority();
165  context->fFeats->append( ft );
166  }
167  else
168  {
169  // Others are deleted
170  qDeleteAll( lPos );
171  }
172 
173  return true;
174 }
175 
176 typedef struct _obstaclebackCtx
177 {
178  RTree<FeaturePart*, double, 2, double> *obstacles;
181 
182 /*
183  * Callback function
184  *
185  * Extract obstacles from indexes
186  */
187 bool extractObstaclesCallback( FeaturePart *ft_ptr, void *ctx )
188 {
189  double amin[2], amax[2];
190  ObstacleCallBackCtx *context = reinterpret_cast< ObstacleCallBackCtx* >( ctx );
191 
192  // insert into obstacles
193  ft_ptr->getBoundingBox( amin, amax );
194  context->obstacles->Insert( amin, amax, ft_ptr );
195  context->obstacleCount++;
196  return true;
197 }
198 
199 typedef struct _filterContext
200 {
201  RTree<LabelPosition*, double, 2, double> *cdtsIndex;
203 } FilterContext;
204 
205 bool filteringCallback( FeaturePart *featurePart, void *ctx )
206 {
207 
208  RTree<LabelPosition*, double, 2, double> *cdtsIndex = ( reinterpret_cast< FilterContext* >( ctx ) )->cdtsIndex;
209  Pal* pal = ( reinterpret_cast< FilterContext* >( ctx ) )->pal;
210 
211  if ( pal->isCancelled() )
212  return false; // do not continue searching
213 
214  double amin[2], amax[2];
215  featurePart->getBoundingBox( amin, amax );
216 
217  LabelPosition::PruneCtx pruneContext;
218  pruneContext.obstacle = featurePart;
219  pruneContext.pal = pal;
220  cdtsIndex->Search( amin, amax, LabelPosition::pruneCallback, static_cast< void* >( &pruneContext ) );
221 
222  return true;
223 }
224 
225 Problem* Pal::extract( double lambda_min, double phi_min, double lambda_max, double phi_max )
226 {
227  // to store obstacles
228  RTree<FeaturePart*, double, 2, double> *obstacles = new RTree<FeaturePart*, double, 2, double>();
229 
230  Problem *prob = new Problem();
231 
232  int i, j;
233 
234  double bbx[4];
235  double bby[4];
236 
237  double amin[2];
238  double amax[2];
239 
240  int max_p = 0;
241 
242  LabelPosition* lp;
243 
244  bbx[0] = bbx[3] = amin[0] = prob->bbox[0] = lambda_min;
245  bby[0] = bby[1] = amin[1] = prob->bbox[1] = phi_min;
246  bbx[1] = bbx[2] = amax[0] = prob->bbox[2] = lambda_max;
247  bby[2] = bby[3] = amax[1] = prob->bbox[3] = phi_max;
248 
249  prob->pal = this;
250 
252 
253  FeatCallBackCtx context;
254  context.fFeats = fFeats;
255  context.obstacles = obstacles;
256  context.candidates = prob->candidates;
257  context.bbox_min[0] = amin[0];
258  context.bbox_min[1] = amin[1];
259  context.bbox_max[0] = amax[0];
260  context.bbox_max[1] = amax[1];
261 
262  ObstacleCallBackCtx obstacleContext;
263  obstacleContext.obstacles = obstacles;
264  obstacleContext.obstacleCount = 0;
265 
266  // first step : extract features from layers
267 
268  int previousFeatureCount = 0;
269  int previousObstacleCount = 0;
270 
271  QStringList layersWithFeaturesInBBox;
272 
273  mMutex.lock();
274  Q_FOREACH ( Layer* layer, mLayers )
275  {
276  if ( !layer )
277  {
278  // invalid layer name
279  continue;
280  }
281 
282  // only select those who are active
283  if ( !layer->active() )
284  continue;
285 
286  // check for connected features with the same label text and join them
287  if ( layer->mergeConnectedLines() )
288  layer->joinConnectedFeatures();
289 
291 
292  layer->mMutex.lock();
293 
294  // find features within bounding box and generate candidates list
295  context.layer = layer;
296  layer->mFeatureIndex->Search( amin, amax, extractFeatCallback, static_cast< void* >( &context ) );
297  // find obstacles within bounding box
298  layer->mObstacleIndex->Search( amin, amax, extractObstaclesCallback, static_cast< void* >( &obstacleContext ) );
299 
300  layer->mMutex.unlock();
301 
302  if ( context.fFeats->size() - previousFeatureCount > 0 || obstacleContext.obstacleCount > previousObstacleCount )
303  {
304  layersWithFeaturesInBBox << layer->name();
305  }
306  previousFeatureCount = context.fFeats->size();
307  previousObstacleCount = obstacleContext.obstacleCount;
308  }
309  mMutex.unlock();
310 
311  prob->nbLabelledLayers = layersWithFeaturesInBBox.size();
312  prob->labelledLayersName = layersWithFeaturesInBBox;
313 
314  if ( fFeats->isEmpty() )
315  {
316  delete fFeats;
317  delete prob;
318  delete obstacles;
319  return nullptr;
320  }
321 
322  prob->nbft = fFeats->size();
323  prob->nblp = 0;
324  prob->featNbLp = new int [prob->nbft];
325  prob->featStartId = new int [prob->nbft];
326  prob->inactiveCost = new double[prob->nbft];
327 
328  Feats *feat;
329 
330  // Filtering label positions against obstacles
331  amin[0] = amin[1] = -DBL_MAX;
332  amax[0] = amax[1] = DBL_MAX;
333  FilterContext filterCtx;
334  filterCtx.cdtsIndex = prob->candidates;
335  filterCtx.pal = this;
336  obstacles->Search( amin, amax, filteringCallback, static_cast< void* >( &filterCtx ) );
337 
338  if ( isCancelled() )
339  {
340  Q_FOREACH ( Feats* feat, *fFeats )
341  {
342  qDeleteAll( feat->lPos );
343  feat->lPos.clear();
344  }
345 
346  qDeleteAll( *fFeats );
347  delete fFeats;
348  delete prob;
349  delete obstacles;
350  return nullptr;
351  }
352 
353  int idlp = 0;
354  for ( i = 0; i < prob->nbft; i++ ) /* foreach feature into prob */
355  {
356  feat = fFeats->takeFirst();
357 
358  prob->featStartId[i] = idlp;
359  prob->inactiveCost[i] = pow( 2, 10 - 10 * feat->priority );
360 
361  switch ( feat->feature->getGeosType() )
362  {
363  case GEOS_POINT:
364  max_p = point_p;
365  break;
366  case GEOS_LINESTRING:
367  max_p = line_p;
368  break;
369  case GEOS_POLYGON:
370  max_p = poly_p;
371  break;
372  }
373 
374  // sort candidates by cost, skip less interesting ones, calculate polygon costs (if using polygons)
375  max_p = CostCalculator::finalizeCandidatesCosts( feat, max_p, obstacles, bbx, bby );
376 
377  // only keep the 'max_p' best candidates
378  while ( feat->lPos.count() > max_p )
379  {
380  // TODO remove from index
381  feat->lPos.last()->removeFromIndex( prob->candidates );
382  delete feat->lPos.takeLast();
383  }
384 
385  // update problem's # candidate
386  prob->featNbLp[i] = feat->lPos.count();
387  prob->nblp += feat->lPos.count();
388 
389  // add all candidates into a rtree (to speed up conflicts searching)
390  for ( j = 0; j < feat->lPos.count(); j++, idlp++ )
391  {
392  lp = feat->lPos.at( j );
393  //lp->insertIntoIndex(prob->candidates);
394  lp->setProblemIds( i, idlp ); // bugfix #1 (maxence 10/23/2008)
395  }
396  fFeats->append( feat );
397  }
398 
399  int nbOverlaps = 0;
400 
401  while ( !fFeats->isEmpty() ) // foreach feature
402  {
403  if ( isCancelled() )
404  {
405  Q_FOREACH ( Feats* feat, *fFeats )
406  {
407  qDeleteAll( feat->lPos );
408  feat->lPos.clear();
409  }
410 
411  qDeleteAll( *fFeats );
412  delete fFeats;
413  delete prob;
414  delete obstacles;
415  return nullptr;
416  }
417 
418  feat = fFeats->takeFirst();
419  while ( !feat->lPos.isEmpty() ) // foreach label candidate
420  {
421  lp = feat->lPos.takeFirst();
422  lp->resetNumOverlaps();
423 
424  // make sure that candidate's cost is less than 1
425  lp->validateCost();
426 
427  prob->addCandidatePosition( lp );
428  //prob->feat[idlp] = j;
429 
430  lp->getBoundingBox( amin, amax );
431 
432  // lookup for overlapping candidate
433  prob->candidates->Search( amin, amax, LabelPosition::countOverlapCallback, static_cast< void* >( lp ) );
434 
435  nbOverlaps += lp->getNumOverlaps();
436  }
437  delete feat;
438  }
439  delete fFeats;
440 
441  //delete candidates;
442  delete obstacles;
443 
444  nbOverlaps /= 2;
445  prob->all_nblp = prob->nblp;
446  prob->nbOverlap = nbOverlaps;
447 
448  return prob;
449 }
450 
451 /*
452  * BIG MACHINE
453  */
454 QList<LabelPosition*>* Pal::labeller( double bbox[4], PalStat **stats, bool displayAll )
455 {
456  Problem *prob;
457 
458  SearchMethod old_searchMethod = searchMethod;
459 
460  if ( displayAll )
461  {
463  }
464 
465  // First, extract the problem
466  if ( !( prob = extract( bbox[0], bbox[1], bbox[2], bbox[3] ) ) )
467  {
468  // nothing to be done => return an empty result set
469  if ( stats )
470  ( *stats ) = new PalStat();
471  return new QList<LabelPosition*>();
472  }
473 
474  // reduce number of candidates
475  // (remove candidates which surely won't be used)
476  prob->reduce();
477  prob->displayAll = displayAll;
478 
479  // search a solution
480  if ( searchMethod == FALP )
481  prob->init_sol_falp();
482  else if ( searchMethod == CHAIN )
483  prob->chain_search();
484  else
485  prob->popmusic();
486 
487  // Post-Optimization
488  //prob->post_optimization();
489 
490 
491  QList<LabelPosition*> * solution = prob->getSolution( displayAll );
492 
493  if ( stats )
494  *stats = prob->getStats();
495 
496  delete prob;
497 
498  if ( displayAll )
499  {
500  setSearch( old_searchMethod );
501  }
502 
503  return solution;
504 }
505 
506 void Pal::registerCancellationCallback( Pal::FnIsCancelled fnCancelled, void *context )
507 {
508  fnIsCancelled = fnCancelled;
509  fnIsCancelledContext = context;
510 }
511 
512 Problem* Pal::extractProblem( double bbox[4] )
513 {
514  return extract( bbox[0], bbox[1], bbox[2], bbox[3] );
515 }
516 
518 {
519  if ( !prob )
520  return new QList<LabelPosition*>();
521 
522  prob->reduce();
523 
524  try
525  {
526  if ( searchMethod == FALP )
527  prob->init_sol_falp();
528  else if ( searchMethod == CHAIN )
529  prob->chain_search();
530  else
531  prob->popmusic();
532  }
533  catch ( InternalException::Empty )
534  {
535  return new QList<LabelPosition*>();
536  }
537 
538  return prob->getSolution( displayAll );
539 }
540 
541 
542 void Pal::setPointP( int point_p )
543 {
544  if ( point_p > 0 )
545  this->point_p = point_p;
546 }
547 
548 void Pal::setLineP( int line_p )
549 {
550  if ( line_p > 0 )
551  this->line_p = line_p;
552 }
553 
554 void Pal::setPolyP( int poly_p )
555 {
556  if ( poly_p > 0 )
557  this->poly_p = poly_p;
558 }
559 
560 
561 void Pal::setMinIt( int min_it )
562 {
563  if ( min_it >= 0 )
564  tabuMinIt = min_it;
565 }
566 
567 void Pal::setMaxIt( int max_it )
568 {
569  if ( max_it > 0 )
570  tabuMaxIt = max_it;
571 }
572 
573 void Pal::setPopmusicR( int r )
574 {
575  if ( r > 0 )
576  popmusic_r = r;
577 }
578 
579 void Pal::setEjChainDeg( int degree )
580 {
581  this->ejChainDeg = degree;
582 }
583 
584 void Pal::setTenure( int tenure )
585 {
586  this->tenure = tenure;
587 }
588 
589 void Pal::setCandListSize( double fact )
590 {
591  this->candListSize = fact;
592 }
593 
594 void Pal::setShowPartial( bool show )
595 {
596  this->showPartial = show;
597 }
598 
600 {
601  return point_p;
602 }
603 
605 {
606  return line_p;
607 }
608 
610 {
611  return poly_p;
612 }
613 
614 int Pal::getMinIt()
615 {
616  return tabuMaxIt;
617 }
618 
619 int Pal::getMaxIt()
620 {
621  return tabuMinIt;
622 }
623 
625 {
626  return showPartial;
627 }
628 
630 {
631  return searchMethod;
632 }
633 
635 {
636  switch ( method )
637  {
638  case POPMUSIC_CHAIN:
639  searchMethod = method;
640  popmusic_r = 30;
641  tabuMinIt = 2;
642  tabuMaxIt = 4;
643  tenure = 10;
644  ejChainDeg = 50;
645  candListSize = 0.2;
646  break;
647  case CHAIN:
648  searchMethod = method;
649  ejChainDeg = 50;
650  break;
651  case POPMUSIC_TABU:
652  searchMethod = method;
653  popmusic_r = 25;
654  tabuMinIt = 2;
655  tabuMaxIt = 4;
656  tenure = 10;
657  ejChainDeg = 50;
658  candListSize = 0.2;
659  break;
660  case POPMUSIC_TABU_CHAIN:
661  searchMethod = method;
662  popmusic_r = 25;
663  tabuMinIt = 2;
664  tabuMaxIt = 4;
665  tenure = 10;
666  ejChainDeg = 50;
667  candListSize = 0.2;
668  break;
669  case FALP:
670  searchMethod = method;
671  break;
672  }
673 }
674 
675 
int createCandidates(QList< LabelPosition *> &lPos, double bboxMin[2], double bboxMax[2], PointSet *mapShape, RTree< LabelPosition *, double, 2, double > *candidates)
Generic method to generate label candidates for the feature.
Definition: feature.cpp:1517
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:108
struct _filterContext FilterContext
bool mergeConnectedLines() const
Returns whether connected lines will be merged before labeling.
Definition: layer.h:193
Pal * pal
Definition: pal.cpp:202
PointSet * getHoleOf()
Returns NULL if this isn&#39;t a hole.
Definition: pointset.h:127
FeaturePart * feature
Definition: util.h:59
struct _featCbackCtx FeatCallBackCtx
Definition: pal.h:63
void reduce()
Definition: problem.cpp:127
void getBoundingBox(double amin[2], double amax[2]) const
Return bounding box - amin: xmin,ymin - amax: xmax,ymax.
SearchMethod getSearch()
get the search method in use
Definition: pal.cpp:629
void registerCancellationCallback(FnIsCancelled fnCancelled, void *context)
Register a function that returns whether this job has been cancelled - PAL calls it during the comput...
Definition: pal.cpp:506
friend class Problem
Definition: pal.h:86
A set of features which influence the labelling process.
Definition: layer.h:58
Main Pal labelling class.
Definition: pal.h:84
void chopFeaturesAtRepeatDistance()
Chop layer features at the repeat distance.
Definition: layer.cpp:419
bool isCancelled()
Check whether the job has been cancelled.
Definition: pal.h:144
is slower and best than TABU, worse and faster than TABU_CHAIN
Definition: pal.h:62
int getNumSelfObstacles() const
Get number of holes (inner rings) - they are considered as obstacles.
Definition: feature.h:252
void setShowPartial(bool show)
Set flag show partial label.
Definition: pal.cpp:594
void unlock()
int getPointP()
get # candidates to generate for point features
Definition: pal.cpp:599
PointSet * shape
Definition: util.h:60
is a little bit better than CHAIN but slower
Definition: pal.h:61
int size() const
void removeLayer(Layer *layer)
remove a layer
Definition: pal.cpp:81
bool(* FnIsCancelled)(void *ctx)
Definition: pal.h:138
int getPolyP()
get maximum # candidates to generate for polygon features
Definition: pal.cpp:609
RTree< FeaturePart *, double, 2, double > * obstacles
Definition: pal.cpp:125
void chain_search()
Test with very-large scale neighborhood.
Definition: problem.cpp:2146
double bbox_min[2]
Definition: pal.cpp:127
QList< LabelPosition * > * getSolution(bool returnInactive)
Definition: problem.cpp:2252
bool getShowPartial()
Get flag show partial label.
Definition: pal.cpp:624
bool isEmpty() const
void joinConnectedFeatures()
Join connected features with the same label text.
Definition: layer.cpp:351
QLinkedList< Feats * > * fFeats
Definition: pal.cpp:124
void getBoundingBox(double min[2], double max[2]) const
Definition: pointset.h:118
RTree< LabelPosition *, double, 2, double > * cdtsIndex
Definition: pal.cpp:201
is the best but slowest
Definition: pal.h:60
double calculatePriority() const
Calculates the priority for the feature.
Definition: feature.cpp:1719
void setPointP(int point_p)
set # candidates to generate for points features Higher the value is, longer Pal::labeller will spend...
Definition: pal.cpp:542
void setLineP(int line_p)
set maximum # candidates to generate for lines features Higher the value is, longer Pal::labeller wil...
Definition: pal.cpp:548
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.
GEOSContextHandle_t geosContext()
Get GEOS context handle to be used in all GEOS library calls with reentrant API.
Definition: pal.cpp:48
For usage in problem solving algorithm.
Definition: util.h:50
void popmusic()
popmusic framework
Definition: problem.cpp:393
double priority
Definition: util.h:61
bool extractObstaclesCallback(FeaturePart *ft_ptr, void *ctx)
Definition: pal.cpp:187
Main class to handle feature.
Definition: feature.h:91
PalStat * getStats()
Definition: problem.cpp:2286
The QgsAbstractLabelProvider class is an interface class.
double bbox_max[2]
Definition: pal.cpp:128
static bool pruneCallback(LabelPosition *candidatePosition, void *ctx)
Check whether the candidate in ctx overlap with obstacle feat.
friend class Layer
Definition: pal.h:88
RTree< FeaturePart *, double, 2, double, 8, 4 > * mObstacleIndex
Definition: layer.h:276
Pal()
Create an new pal instance.
Definition: pal.cpp:53
void lock()
RTree< LabelPosition *, double, 2, double > * candidates
Definition: pal.cpp:126
QList< LabelPosition * > * labeller(double bbox[4], PalStat **stats, bool displayAll)
the labeling machine Will extract all active layers
Definition: pal.cpp:454
Placement
Placement modes which determine how label candidates are generated for a feature. ...
static bool countOverlapCallback(LabelPosition *lp, void *ctx)
Problem * extractProblem(double bbox[4])
Definition: pal.cpp:512
static GEOSContextHandle_t getGEOSHandler()
Return GEOS context handle.
void setPolyP(int poly_p)
set maximum # candidates to generate for polygon features Higher the value is, longer Pal::labeller w...
Definition: pal.cpp:554
QList< LabelPosition * > * solveProblem(Problem *prob, bool displayAll)
Definition: pal.cpp:517
int getNumOverlaps() const
RTree< FeaturePart *, double, 2, double, 8, 4 > * mFeatureIndex
Definition: layer.h:271
FeaturePart * getSelfObstacle(int i)
Get hole (inner ring) - considered as obstacle.
Definition: feature.h:254
QMutex mMutex
Definition: layer.h:282
int getGeosType() const
Definition: pointset.h:116
int obstacleCount
Definition: pal.cpp:179
QString name() const
Returns the layer&#39;s name.
Definition: layer.h:89
Summary statistics of labelling problem.
Definition: palstat.h:44
bool active() const
Returns whether the layer is currently active.
Definition: layer.h:132
bool filteringCallback(FeaturePart *featurePart, void *ctx)
Definition: pal.cpp:205
LabelPosition is a candidate feature label position.
Definition: labelposition.h:51
Representation of a labeling problem.
Definition: problem.h:101
~Pal()
delete an instance
Definition: pal.cpp:95
bool extractFeatCallback(FeaturePart *ft_ptr, void *ctx)
Definition: pal.cpp:138
SearchMethod
Search method to use.
Definition: pal.h:57
void setProblemIds(int probFid, int lpId)
Set problem feature ID and assigned label candidate ID.
is the worst but fastest method
Definition: pal.h:59
RTree< FeaturePart *, double, 2, double > * obstacles
Definition: pal.cpp:178
QList< LabelPosition * > lPos
Definition: util.h:62
Thrown when trying to access an empty dada set.
Layer * layer
Definition: pal.cpp:123
int size() const
void setSearch(SearchMethod method)
Select the search method to use.
Definition: pal.cpp:634
void append(const T &value)
int getLineP()
get maximum # candidates to generate for line features
Definition: pal.cpp:604
void init_sol_falp()
Definition: problem.cpp:280