Skip to content

Commit

Permalink
Allow cancellation of PAL labeling computation
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Nov 18, 2013
1 parent 1110aaf commit 68e2951
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/core/pal/pal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ namespace pal
// do not init and exit GEOS - we do it inside QGIS
//initGEOS( geosNotice, geosError );

fnIsCancelled = 0;
fnIsCancelledContext = 0;

layers = new QList<Layer*>();

lyrsMutex = new SimpleMutex();
Expand Down Expand Up @@ -316,6 +319,9 @@ namespace pal
double scale = (( FilterContext* ) ctx )->scale;
Pal* pal = (( FilterContext* )ctx )->pal;

if ( pal->isCancelled() )
return false; // do not continue searching

double amin[2], amax[2];
pset->getBoundingBox( amin, amax );

Expand Down Expand Up @@ -509,6 +515,13 @@ namespace pal
filterCtx.pal = this;
obstacles->Search( amin, amax, filteringCallback, ( void* ) &filterCtx );

if ( isCancelled() )
{
delete fFeats;
delete prob;
delete obstacles;
return 0;
}

int idlp = 0;
for ( i = 0; i < prob->nbft; i++ ) /* foreach feature into prob */
Expand Down Expand Up @@ -580,6 +593,14 @@ namespace pal
j = 0;
while ( fFeats->size() > 0 ) // foreach feature
{
if ( isCancelled() )
{
delete fFeats;
delete prob;
delete obstacles;
return 0;
}

feat = fFeats->pop_front();
for ( i = 0; i < feat->nblp; i++, idlp++ ) // foreach label candidate
{
Expand Down Expand Up @@ -798,6 +819,12 @@ namespace pal
return solution;
}

void Pal::registerCancellationCallback(Pal::FnIsCancelled fnCancelled, void *context)
{
fnIsCancelled = fnCancelled;
fnIsCancelledContext = context;
}

Problem* Pal::extractProblem( double scale, double bbox[4] )
{
// find out: nbLayers, layersName, layersFactor
Expand Down
12 changes: 12 additions & 0 deletions src/core/pal/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ namespace pal
*/
bool showPartial;


typedef bool (*FnIsCancelled)(void* ctx);
/** Callback that may be called from PAL to check whether the job has not been cancelled in meanwhile */
FnIsCancelled fnIsCancelled;
/** Application-specific context for the cancellation check function */
void* fnIsCancelledContext;

/**
* \brief Problem factory
* Extract features to label and generates candidates for them,
Expand Down Expand Up @@ -339,6 +346,11 @@ namespace pal
PalStat **stat,
bool displayAll );

/** Register a function that returns whether this job has been cancelled - PAL calls it during the computation */
void registerCancellationCallback( FnIsCancelled fnCancelled, void* context );

/** Check whether the job has been cancelled */
inline bool isCancelled() { return fnIsCancelled ? fnIsCancelled( fnIsCancelledContext ) : false; }

Problem* extractProblem( double scale, double bbox[4] );

Expand Down
7 changes: 7 additions & 0 deletions src/core/pal/problem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,13 @@ namespace pal

while ( list->getSize() > 0 ) // O (log size)
{
if ( pal->isCancelled() )
{
delete context;
delete list;
return;
}

label = list->getBest(); // O (log size)


Expand Down
27 changes: 27 additions & 0 deletions src/core/qgspallabeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3818,12 +3818,21 @@ void QgsPalLabeling::dataDefinedDropShadow( QgsPalLayerSettings& tmpLyr,
}
}


// helper function for checking for job cancellation within PAL
static bool _palIsCancelled( void* ctx )
{
return ( ( QgsRenderContext* ) ctx )->renderingStopped();
}

void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
{
Q_ASSERT( mMapSettings != NULL );
QPainter* painter = context.painter();
QgsRectangle extent = context.extent();

mPal->registerCancellationCallback( &_palIsCancelled, &context );

delete mResults;
mResults = new QgsLabelingResults;

Expand All @@ -3849,6 +3858,9 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
return;
}

if ( context.renderingStopped() )
return; // it has been cancelled

const QgsMapToPixel& xform = mMapSettings->mapToPixel();

// draw rectangles with all candidates
Expand Down Expand Up @@ -3876,12 +3888,23 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
QgsDebugMsgLevel( QString( "LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels->size() ), 4 );
t.restart();

if ( context.renderingStopped() )
{
delete problem;
delete labels;
deleteTemporaryData();
return;
}

painter->setRenderHint( QPainter::Antialiasing );

// draw the labels
std::list<LabelPosition*>::iterator it = labels->begin();
for ( ; it != labels->end(); ++it )
{
if ( context.renderingStopped() )
break;

QgsPalGeometry* palGeometry = dynamic_cast< QgsPalGeometry* >(( *it )->getFeaturePart()->getUserGeometry() );
if ( !palGeometry )
{
Expand Down Expand Up @@ -3996,7 +4019,11 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )

delete problem;
delete labels;
deleteTemporaryData();
}

void QgsPalLabeling::deleteTemporaryData()
{
// delete all allocated geometries for features
QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
for ( lit = mActiveLayers.begin(); lit != mActiveLayers.end(); ++lit )
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgspallabeling.h
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,8 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
void dataDefinedDropShadow( QgsPalLayerSettings& tmpLyr,
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );

void deleteTemporaryData();

// hashtable of layer settings, being filled during labeling
QHash<QgsVectorLayer*, QgsPalLayerSettings> mActiveLayers;
// hashtable of active diagram layers
Expand Down

0 comments on commit 68e2951

Please sign in to comment.