mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Allow cancellation of PAL labeling computation
This commit is contained in:
parent
1110aafa43
commit
68e29511c3
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user