32 #define _CRT_SECURE_NO_DEPRECATE
68 fnIsCancelledContext = 0;
89 std::cout.precision( 12 );
90 std::cerr.precision( 12 );
102 mLayers.remove( key );
113 qDeleteAll( mLayers );
125 Q_ASSERT( !mLayers.contains( provider ) );
127 Layer* layer =
new Layer( provider, layerName, arrangement, defaultPriority, active, toLabel,
this, displayAll );
128 mLayers.insert( provider, layer );
153 double amin[2], amax[2];
158 std::cout <<
"extract feat : " << ft_ptr->getLayer()->getName() <<
"/" << ft_ptr->getUID() << std::endl;
165 context->
obstacles->Insert( amin, amax, ft_ptr );
188 std::cout <<
"ERROR: SHOULD HAVE A PARENT!!!!!" << std::endl;
202 context->
fFeats->append( ft );
231 double amin[2], amax[2];
235 pruneContext.
obstacle = featurePart;
236 pruneContext.
pal = pal;
242 Problem* Pal::extract(
double lambda_min,
double phi_min,
double lambda_max,
double phi_max )
245 RTree<FeaturePart*, double, 2, double> *obstacles =
new RTree<FeaturePart*, double, 2, double>();
261 bbx[0] = bbx[3] = amin[0] = prob->bbox[0] = lambda_min;
262 bby[0] = bby[1] = amin[1] = prob->bbox[1] = phi_min;
263 bbx[1] = bbx[2] = amax[0] = prob->bbox[2] = lambda_max;
264 bby[2] = bby[3] = amax[1] = prob->bbox[3] = phi_max;
271 context->fFeats = fFeats;
272 context->obstacles = obstacles;
273 context->candidates = prob->candidates;
275 context->bbox_min[0] = amin[0];
276 context->bbox_min[1] = amin[1];
278 context->bbox_max[0] = amax[0];
279 context->bbox_max[1] = amax[1];
283 int previousFeatureCount = 0;
288 Q_FOREACH (
Layer* layer, mLayers.values() )
297 if ( !layer->active() )
301 if ( layer->mergeConnectedLines() )
302 layer->joinConnectedFeatures();
304 layer->chopFeaturesAtRepeatDistance();
307 context->layer = layer;
308 context->layer->mMutex.lock();
310 context->layer->mMutex.unlock();
312 if ( context->fFeats->size() - previousFeatureCount > 0 )
314 layersWithFeaturesInBBox << layer->name();
316 previousFeatureCount = context->fFeats->
size();
321 prob->nbLabelledLayers = layersWithFeaturesInBBox.
size();
322 prob->labelledLayersName = layersWithFeaturesInBBox;
324 if ( fFeats->
size() == 0 )
327 std::cout << std::endl <<
"Empty problem" << std::endl;
335 prob->nbft = fFeats->
size();
337 prob->featNbLp =
new int [prob->nbft];
338 prob->featStartId =
new int [prob->nbft];
339 prob->inactiveCost =
new double[prob->nbft];
344 std::cout <<
"FIRST NBFT : " << prob->nbft << std::endl;
348 amin[0] = amin[1] = -DBL_MAX;
349 amax[0] = amax[1] = DBL_MAX;
352 filterCtx.pal =
this;
357 Q_FOREACH ( Feats* feat, *fFeats )
359 qDeleteAll( feat->lPos );
363 qDeleteAll( *fFeats );
371 for ( i = 0; i < prob->nbft; i++ )
375 prob->featStartId[i] = idlp;
376 prob->inactiveCost[i] = pow( 2, 10 - 10 * feat->priority );
378 switch ( feat->feature->getGeosType() )
383 case GEOS_LINESTRING:
395 while ( feat->lPos.count() > max_p )
398 feat->lPos.last()->removeFromIndex( prob->candidates );
399 delete feat->lPos.takeLast();
403 prob->featNbLp[i] = feat->lPos.count();
404 prob->nblp += feat->lPos.count();
407 for ( j = 0; j < feat->lPos.count(); j++, idlp++ )
411 lp->setProblemIds( i, idlp );
418 while ( fFeats->
size() > 0 )
422 Q_FOREACH ( Feats* feat, *fFeats )
424 qDeleteAll( feat->lPos );
428 qDeleteAll( *fFeats );
436 while ( !feat->lPos.isEmpty() )
438 lp = feat->lPos.takeFirst();
439 lp->resetNumOverlaps();
444 prob->addCandidatePosition( lp );
447 lp->getBoundingBox( amin, amax );
452 nbOverlaps += lp->getNumOverlaps();
463 prob->all_nblp = prob->nblp;
464 prob->nbOverlap = nbOverlaps;
468 std::cout <<
"nbOverlap: " << prob->nbOverlap << std::endl;
469 std::cerr << prob->nbft <<
"\t"
470 << prob->nblp <<
"\t"
471 << prob->nbOverlap <<
"\t";
483 std::cout <<
"LABELLER (selection)" << std::endl;
496 clock_t start = clock();
498 std::cout << std::endl <<
"bbox: " << bbox[0] <<
" " << bbox[1] <<
" " << bbox[2] <<
" " << bbox[3] << std::endl;
505 if (( prob = extract( bbox[0], bbox[1], bbox[2], bbox[3] ) ) == NULL )
510 return new std::list<LabelPosition*>();
513 std::cout <<
"PAL EXTRACT: " << t.
elapsed() / 1000.0 <<
" s" << std::endl;
521 std::cerr << prob->nblp <<
"\t"
526 prob->displayAll = displayAll;
529 create_time = double( clock() - start ) / double( CLOCKS_PER_SEC );
531 std::cout << std::endl <<
"Problem : " << prob->nblp <<
" candidates for " << prob->nbft <<
" features makes " << prob->nbOverlap <<
" overlaps" << std::endl;
532 std::cout << std::endl <<
"Times:" << std::endl <<
" to create problem: " << create_time << std::endl;
536 if ( searchMethod ==
FALP )
538 else if ( searchMethod ==
CHAIN )
543 std::cout <<
"PAL SEARCH (" << searchMethod <<
"): " << t.
elapsed() / 1000.0 <<
" s" << std::endl;
550 std::list<LabelPosition*> * solution = prob->
getSolution( displayAll );
556 clock_t total_time = clock() - start;
557 std::cout <<
" Total time: " << double( total_time ) / double( CLOCKS_PER_SEC ) << std::endl;
558 std::cerr <<
"\t" << create_time <<
"\t" << double( total_time ) / double( CLOCKS_PER_SEC ) << std::endl;
574 fnIsCancelled = fnCancelled;
575 fnIsCancelledContext = context;
580 return extract( bbox[0], bbox[1], bbox[2], bbox[3] );
586 return new std::list<LabelPosition*>();
592 if ( searchMethod ==
FALP )
594 else if ( searchMethod ==
CHAIN )
601 return new std::list<LabelPosition*>();
611 this->point_p = point_p;
617 this->line_p = line_p;
623 this->poly_p = poly_p;
627 void Pal::setMinIt(
int min_it )
633 void Pal::setMaxIt(
int max_it )
639 void Pal::setPopmusicR(
int r )
645 void Pal::setEjChainDeg(
int degree )
647 this->ejChainDeg = degree;
650 void Pal::setTenure(
int tenure )
652 this->tenure = tenure;
655 void Pal::setCandListSize(
double fact )
657 this->candListSize = fact;
662 this->showPartial = show;
705 searchMethod = method;
714 searchMethod = method;
718 searchMethod = method;
727 searchMethod = method;
736 searchMethod = method;
739 std::cerr <<
"Unknown search method..." << std::endl;
void removeLayer(Layer *layer)
remove a layer
PointSet * getHoleOf()
Returns NULL if this isn't a hole.
std::list< LabelPosition * > * solveProblem(Problem *prob, bool displayAll)
double getLabelHeight() const
double calculatePriority() const
Calculates the priority for the feature.
bool labelLayer() const
Returns whether the layer will be labeled or not.
int getNumSelfObstacles() const
Get number of holes (inner rings) - they are considered as obstacles.
static bool countOverlapCallback(LabelPosition *lp, void *ctx)
A layer of spacial entites.
void setPointP(int point_p)
set # candidates to generate for points features Higher the value is, longer Pal::labeller will spend...
RTree< LabelPosition *, double, 2, double > * cdtsIndex
void setPolyP(int poly_p)
set maximum # candidates to generate for polygon features Higher the value is, longer Pal::labeller w...
void popmusic()
popmusic framework
bool isCancelled()
Check whether the job has been cancelled.
is slower and best than TABU, worse and faster than TABU_CHAIN
double getLabelWidth() const
QLinkedList< Feats * > * fFeats
int getLineP()
get maximum # candidates to generate for line features
std::list< LabelPosition * > * getSolution(bool returnInactive)
is a little bit better than CHAIN but slower
bool(* FnIsCancelled)(void *ctx)
int setPosition(QList< LabelPosition * > &lPos, double bbox_min[2], double bbox_max[2], PointSet *mapShape, RTree< LabelPosition *, double, 2, double > *candidates)
Generic method to generate candidates.
void chain_search()
Test with very-large scale neighborhood.
void setSearch(SearchMethod method)
Select the search method to use.
RTree< FeaturePart *, double, 2, double > * obstacles
int getPointP()
get # candidates to generate for point features
Problem * extractProblem(double bbox[4])
GEOSContextHandle_t geosContext()
Get GEOS context handle to be used in all GEOS library calls with reentrant API.
For usage in problem solving algorithm.
Main class to handle feature.
The QgsAbstractLabelProvider class is an interface class.
static bool pruneCallback(LabelPosition *lp, void *ctx)
Check whether the candidate in ctx overlap with obstacle feat.
RTree< LabelPosition *, double, 2, double > * candidates
bool extractFeatCallback(FeaturePart *ft_ptr, void *ctx)
void setShowPartial(bool show)
Set flag show partial label.
void getBoundingBox(double min[2], double max[2]) const
std::list< LabelPosition * > * labeller(double bbox[4], PalStat **stats, bool displayAll)
the labeling machine Will extract all active layers
bool getShowPartial()
Get flag show partial label.
Arrangement
The way to arrange labels against spatial entities.
static GEOSContextHandle_t getGEOSHandler()
Return GEOS context handle.
struct pal::_filterContext FilterContext
FeaturePart * getSelfObstacle(int i)
Get hole (inner ring) - considered as obstacle.
Layer * addLayer(QgsAbstractLabelProvider *provider, const QString &layerName, Arrangement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll=false)
add a new layer
SearchMethod getSearch()
get the search method in use
Pal()
Create an new pal instance.
bool filteringCallback(FeaturePart *featurePart, void *ctx)
void setLineP(int line_p)
set maximum # candidates to generate for lines features Higher the value is, longer Pal::labeller wil...
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.
int getPolyP()
get maximum # candidates to generate for polygon features
SearchMethod
Search method to use.
struct pal::_featCbackCtx FeatCallBackCtx
is the worst but fastest method
QList< LabelPosition * > lPos
Thrown when trying to access an empty dada set.
void registerCancellationCallback(FnIsCancelled fnCancelled, void *context)
Register a function that returns whether this job has been cancelled - PAL calls it during the comput...
void append(const T &value)