Skip to content
Permalink
Browse files

Allow cancellation of PAL labeling computation

  • Loading branch information
wonder-sk committed Nov 18, 2013
1 parent 1110aaf commit 68e29511c3fbe00a23d202bd4ac00acb21cfbc1c
Showing with 75 additions and 0 deletions.
  1. +27 −0 src/core/pal/pal.cpp
  2. +12 −0 src/core/pal/pal.h
  3. +7 −0 src/core/pal/problem.cpp
  4. +27 −0 src/core/qgspallabeling.cpp
  5. +2 −0 src/core/qgspallabeling.h
@@ -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();
@@ -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 );

@@ -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 */
@@ -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
{
@@ -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
@@ -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,
@@ -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] );

@@ -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)


@@ -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;

@@ -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
@@ -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 )
{
@@ -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 )
@@ -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

0 comments on commit 68e2951

Please sign in to comment.
You can’t perform that action at this time.