Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Simplify code and remove dead code
  • Loading branch information
nyalldawson committed Dec 10, 2019
1 parent 617defd commit a66e575
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 109 deletions.
77 changes: 21 additions & 56 deletions src/core/pal/pal.cpp
Expand Up @@ -81,28 +81,6 @@ Layer *Pal::addLayer( QgsAbstractLabelProvider *provider, const QString &layerNa
return res;
}

struct FeatCallBackCtx
{
Layer *layer = nullptr;

std::list< std::unique_ptr< Feats > > *features = nullptr;

QgsGenericSpatialIndex< FeaturePart > *obstacleIndex = nullptr;
QgsGenericSpatialIndex<LabelPosition> *allCandidateIndex = nullptr;
std::vector< std::unique_ptr< LabelPosition > > *positionsWithNoCandidates = nullptr;
const GEOSPreparedGeometry *mapBoundary = nullptr;
Pal *pal = nullptr;
};


struct ObstacleCallBackCtx
{
QgsGenericSpatialIndex< FeaturePart > *obstacleIndex = nullptr;
int obstacleCount = 0;
Pal *pal = nullptr;
};


std::unique_ptr<Problem> Pal::extract( const QgsRectangle &extent, const QgsGeometry &mapBoundary )
{
// to store obstacles
Expand All @@ -126,23 +104,11 @@ std::unique_ptr<Problem> Pal::extract( const QgsRectangle &extent, const QgsGeom

std::list< std::unique_ptr< Feats > > features;

FeatCallBackCtx context;

// prepare map boundary
geos::unique_ptr mapBoundaryGeos( QgsGeos::asGeos( mapBoundary ) );
geos::prepared_unique_ptr mapBoundaryPrepared( GEOSPrepare_r( QgsGeos::getGEOSHandler(), mapBoundaryGeos.get() ) );

context.features = &features;
context.obstacleIndex = &obstacles;
context.allCandidateIndex = &prob->mAllCandidatesIndex;
context.positionsWithNoCandidates = prob->positionsWithNoCandidates();
context.mapBoundary = mapBoundaryPrepared.get();
context.pal = this;

ObstacleCallBackCtx obstacleContext;
obstacleContext.obstacleIndex = &obstacles;
obstacleContext.obstacleCount = 0;
obstacleContext.pal = this;
int obstacleCount = 0;

// first step : extract features from layers

Expand Down Expand Up @@ -180,18 +146,17 @@ std::unique_ptr<Problem> Pal::extract( const QgsRectangle &extent, const QgsGeom
QMutexLocker locker( &layer->mMutex );

// find features within bounding box and generate candidates list
context.layer = layer;
layer->mFeatureIndex.intersects( QgsRectangle( amin[ 0], amin[1], amax[0], amax[1] ), [&context]( const FeaturePart * constFeaturePart )->bool
layer->mFeatureIndex.intersects( QgsRectangle( amin[ 0], amin[1], amax[0], amax[1] ), [&features, &obstacles, &prob, &mapBoundaryPrepared, this]( const FeaturePart * constFeaturePart )->bool
{
FeaturePart *featurePart = const_cast< FeaturePart * >( constFeaturePart );

if ( context.pal->isCanceled() )
if ( isCanceled() )
return false;

// Holes of the feature are obstacles
for ( int i = 0; i < featurePart->getNumSelfObstacles(); i++ )
{
context.obstacleIndex->insertData( featurePart->getSelfObstacle( i ), featurePart->getSelfObstacle( i )->boundingBox() );
obstacles.insertData( featurePart->getSelfObstacle( i ), featurePart->getSelfObstacle( i )->boundingBox() );

if ( !featurePart->getSelfObstacle( i )->getHoleOf() )
{
Expand All @@ -200,28 +165,28 @@ std::unique_ptr<Problem> Pal::extract( const QgsRectangle &extent, const QgsGeom
}

// generate candidates for the feature part
std::vector< std::unique_ptr< LabelPosition > > candidates = featurePart->createCandidates( context.pal );
std::vector< std::unique_ptr< LabelPosition > > candidates = featurePart->createCandidates( this );

if ( context.pal->isCanceled() )
if ( isCanceled() )
return false;

// purge candidates that are outside the bbox
candidates.erase( std::remove_if( candidates.begin(), candidates.end(), [&context]( std::unique_ptr< LabelPosition > &candidate )
candidates.erase( std::remove_if( candidates.begin(), candidates.end(), [&mapBoundaryPrepared, this]( std::unique_ptr< LabelPosition > &candidate )
{
if ( context.pal->showPartialLabels() )
return !candidate->intersects( context.mapBoundary );
if ( showPartialLabels() )
return !candidate->intersects( mapBoundaryPrepared.get() );
else
return !candidate->within( context.mapBoundary );
return !candidate->within( mapBoundaryPrepared.get() );
} ), candidates.end() );

if ( context.pal->isCanceled() )
if ( isCanceled() )
return false;

if ( !candidates.empty() )
{
for ( std::unique_ptr< LabelPosition > &candidate : candidates )
{
candidate->insertIntoIndex( *context.allCandidateIndex );
candidate->insertIntoIndex( prob->allCandidatesIndex() );
}

std::sort( candidates.begin(), candidates.end(), CostCalculator::candidateSortGrow );
Expand All @@ -232,14 +197,14 @@ std::unique_ptr<Problem> Pal::extract( const QgsRectangle &extent, const QgsGeom
ft->shape = nullptr;
ft->candidates = std::move( candidates );
ft->priority = featurePart->calculatePriority();
context.features->emplace_back( std::move( ft ) );
features.emplace_back( std::move( ft ) );
}
else
{
// features with no candidates are recorded in the unlabeled feature list
std::unique_ptr< LabelPosition > unplacedPosition = featurePart->createCandidatePointOnSurface( featurePart );
if ( unplacedPosition )
context.positionsWithNoCandidates->emplace_back( std::move( unplacedPosition ) );
prob->positionsWithNoCandidates()->emplace_back( std::move( unplacedPosition ) );
}

return true;
Expand All @@ -248,27 +213,27 @@ std::unique_ptr<Problem> Pal::extract( const QgsRectangle &extent, const QgsGeom
return nullptr;

// find obstacles within bounding box
layer->mObstacleIndex.intersects( QgsRectangle( amin[0], amin[1], amax[0], amax[1] ), [&obstacleContext]( const FeaturePart * featurePart )->bool
layer->mObstacleIndex.intersects( QgsRectangle( amin[0], amin[1], amax[0], amax[1] ), [&obstacles, &obstacleCount, this]( const FeaturePart * featurePart )->bool
{
if ( obstacleContext.pal->isCanceled() )
if ( isCanceled() )
return false; // do not continue searching

// insert into obstacles
obstacleContext.obstacleIndex->insertData( featurePart, featurePart->boundingBox() );
obstacleContext.obstacleCount++;
obstacles.insertData( featurePart, featurePart->boundingBox() );
obstacleCount++;
return true;
} );
if ( isCanceled() )
return nullptr;

locker.unlock();

if ( context.features->size() - previousFeatureCount > 0 || obstacleContext.obstacleCount > previousObstacleCount )
if ( features.size() - previousFeatureCount > 0 || obstacleCount > previousObstacleCount )
{
layersWithFeaturesInBBox << layer->name();
}
previousFeatureCount = context.features->size();
previousObstacleCount = obstacleContext.obstacleCount;
previousFeatureCount = features.size();
previousObstacleCount = obstacleCount;
}
palLocker.unlock();

Expand Down
60 changes: 7 additions & 53 deletions src/core/pal/problem.cpp
Expand Up @@ -266,24 +266,8 @@ void Problem::init_sol_falp()
}
}


struct ChainContext
{
LabelPosition *lp = nullptr;
std::vector< int > *tmpsol = nullptr;
int *featWrap = nullptr;
int *feat = nullptr;
int borderSize;
QLinkedList<ElemTrans *> *currentChain;
QLinkedList<int> *conflicts;
double *delta_tmp = nullptr;
std::vector< double > *inactiveCost = nullptr;

} ;

inline Chain *Problem::chain( int seed )
{

int i;
int j;

Expand All @@ -309,16 +293,6 @@ inline Chain *Problem::chain( int seed )

LabelPosition *lp = nullptr;

ChainContext context;
context.featWrap = nullptr;
context.borderSize = 0;
context.tmpsol = &tmpsol;
context.inactiveCost = &mInactiveCost;
context.feat = nullptr;
context.currentChain = &currentChain;
context.conflicts = &conflicts;
context.delta_tmp = &delta_tmp;

double amin[2];
double amax[2];

Expand Down Expand Up @@ -353,47 +327,27 @@ inline Chain *Problem::chain( int seed )

// evaluate conflicts graph in solution after moving seed's label

context.lp = lp;

lp->getBoundingBox( amin, amax );
mActiveCandidatesIndex.intersects( QgsRectangle( amin[0], amin[1], amax[0], amax[1] ), [&context]( const LabelPosition * lp ) -> bool
mActiveCandidatesIndex.intersects( QgsRectangle( amin[0], amin[1], amax[0], amax[1] ), [lp, &delta_tmp, &conflicts, &currentChain, this]( const LabelPosition * lp2 ) -> bool
{
if ( lp->isInConflict( context.lp ) )
if ( lp2->isInConflict( lp ) )
{
int feat, rfeat;
bool sub = nullptr != context.featWrap;

feat = lp->getProblemFeatureId();
if ( sub )
{
rfeat = feat;
feat = context.featWrap[feat];
}
else
rfeat = feat;

if ( feat >= 0 && ( *context.tmpsol )[feat] == lp->getId() )
{
if ( sub && feat < context.borderSize )
{
throw - 2;
}
}
const int feat = lp2->getProblemFeatureId();

// is there any cycles ?
QLinkedList< ElemTrans * >::iterator cur;
for ( cur = context.currentChain->begin(); cur != context.currentChain->end(); ++cur )
for ( cur = currentChain.begin(); cur != currentChain.end(); ++cur )
{
if ( ( *cur )->feat == feat )
{
throw - 1;
}
}

if ( !context.conflicts->contains( feat ) )
if ( !conflicts.contains( feat ) )
{
context.conflicts->append( feat );
*context.delta_tmp += lp->cost() + ( * context.inactiveCost )[rfeat];
conflicts.append( feat );
delta_tmp += lp2->cost() + mInactiveCost[feat];
}
}
return true;
Expand Down

0 comments on commit a66e575

Please sign in to comment.