mirror of
https://github.com/qgis/QGIS.git
synced 2025-05-01 00:02:48 -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
|
// do not init and exit GEOS - we do it inside QGIS
|
||||||
//initGEOS( geosNotice, geosError );
|
//initGEOS( geosNotice, geosError );
|
||||||
|
|
||||||
|
fnIsCancelled = 0;
|
||||||
|
fnIsCancelledContext = 0;
|
||||||
|
|
||||||
layers = new QList<Layer*>();
|
layers = new QList<Layer*>();
|
||||||
|
|
||||||
lyrsMutex = new SimpleMutex();
|
lyrsMutex = new SimpleMutex();
|
||||||
@ -316,6 +319,9 @@ namespace pal
|
|||||||
double scale = (( FilterContext* ) ctx )->scale;
|
double scale = (( FilterContext* ) ctx )->scale;
|
||||||
Pal* pal = (( FilterContext* )ctx )->pal;
|
Pal* pal = (( FilterContext* )ctx )->pal;
|
||||||
|
|
||||||
|
if ( pal->isCancelled() )
|
||||||
|
return false; // do not continue searching
|
||||||
|
|
||||||
double amin[2], amax[2];
|
double amin[2], amax[2];
|
||||||
pset->getBoundingBox( amin, amax );
|
pset->getBoundingBox( amin, amax );
|
||||||
|
|
||||||
@ -509,6 +515,13 @@ namespace pal
|
|||||||
filterCtx.pal = this;
|
filterCtx.pal = this;
|
||||||
obstacles->Search( amin, amax, filteringCallback, ( void* ) &filterCtx );
|
obstacles->Search( amin, amax, filteringCallback, ( void* ) &filterCtx );
|
||||||
|
|
||||||
|
if ( isCancelled() )
|
||||||
|
{
|
||||||
|
delete fFeats;
|
||||||
|
delete prob;
|
||||||
|
delete obstacles;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int idlp = 0;
|
int idlp = 0;
|
||||||
for ( i = 0; i < prob->nbft; i++ ) /* foreach feature into prob */
|
for ( i = 0; i < prob->nbft; i++ ) /* foreach feature into prob */
|
||||||
@ -580,6 +593,14 @@ namespace pal
|
|||||||
j = 0;
|
j = 0;
|
||||||
while ( fFeats->size() > 0 ) // foreach feature
|
while ( fFeats->size() > 0 ) // foreach feature
|
||||||
{
|
{
|
||||||
|
if ( isCancelled() )
|
||||||
|
{
|
||||||
|
delete fFeats;
|
||||||
|
delete prob;
|
||||||
|
delete obstacles;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
feat = fFeats->pop_front();
|
feat = fFeats->pop_front();
|
||||||
for ( i = 0; i < feat->nblp; i++, idlp++ ) // foreach label candidate
|
for ( i = 0; i < feat->nblp; i++, idlp++ ) // foreach label candidate
|
||||||
{
|
{
|
||||||
@ -798,6 +819,12 @@ namespace pal
|
|||||||
return solution;
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pal::registerCancellationCallback(Pal::FnIsCancelled fnCancelled, void *context)
|
||||||
|
{
|
||||||
|
fnIsCancelled = fnCancelled;
|
||||||
|
fnIsCancelledContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
Problem* Pal::extractProblem( double scale, double bbox[4] )
|
Problem* Pal::extractProblem( double scale, double bbox[4] )
|
||||||
{
|
{
|
||||||
// find out: nbLayers, layersName, layersFactor
|
// find out: nbLayers, layersName, layersFactor
|
||||||
|
@ -172,6 +172,13 @@ namespace pal
|
|||||||
*/
|
*/
|
||||||
bool showPartial;
|
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
|
* \brief Problem factory
|
||||||
* Extract features to label and generates candidates for them,
|
* Extract features to label and generates candidates for them,
|
||||||
@ -339,6 +346,11 @@ namespace pal
|
|||||||
PalStat **stat,
|
PalStat **stat,
|
||||||
bool displayAll );
|
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] );
|
Problem* extractProblem( double scale, double bbox[4] );
|
||||||
|
|
||||||
|
@ -349,6 +349,13 @@ namespace pal
|
|||||||
|
|
||||||
while ( list->getSize() > 0 ) // O (log size)
|
while ( list->getSize() > 0 ) // O (log size)
|
||||||
{
|
{
|
||||||
|
if ( pal->isCancelled() )
|
||||||
|
{
|
||||||
|
delete context;
|
||||||
|
delete list;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
label = list->getBest(); // O (log size)
|
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 )
|
void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
|
||||||
{
|
{
|
||||||
Q_ASSERT( mMapSettings != NULL );
|
Q_ASSERT( mMapSettings != NULL );
|
||||||
QPainter* painter = context.painter();
|
QPainter* painter = context.painter();
|
||||||
QgsRectangle extent = context.extent();
|
QgsRectangle extent = context.extent();
|
||||||
|
|
||||||
|
mPal->registerCancellationCallback( &_palIsCancelled, &context );
|
||||||
|
|
||||||
delete mResults;
|
delete mResults;
|
||||||
mResults = new QgsLabelingResults;
|
mResults = new QgsLabelingResults;
|
||||||
|
|
||||||
@ -3849,6 +3858,9 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( context.renderingStopped() )
|
||||||
|
return; // it has been cancelled
|
||||||
|
|
||||||
const QgsMapToPixel& xform = mMapSettings->mapToPixel();
|
const QgsMapToPixel& xform = mMapSettings->mapToPixel();
|
||||||
|
|
||||||
// draw rectangles with all candidates
|
// 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 );
|
QgsDebugMsgLevel( QString( "LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels->size() ), 4 );
|
||||||
t.restart();
|
t.restart();
|
||||||
|
|
||||||
|
if ( context.renderingStopped() )
|
||||||
|
{
|
||||||
|
delete problem;
|
||||||
|
delete labels;
|
||||||
|
deleteTemporaryData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
painter->setRenderHint( QPainter::Antialiasing );
|
painter->setRenderHint( QPainter::Antialiasing );
|
||||||
|
|
||||||
// draw the labels
|
// draw the labels
|
||||||
std::list<LabelPosition*>::iterator it = labels->begin();
|
std::list<LabelPosition*>::iterator it = labels->begin();
|
||||||
for ( ; it != labels->end(); ++it )
|
for ( ; it != labels->end(); ++it )
|
||||||
{
|
{
|
||||||
|
if ( context.renderingStopped() )
|
||||||
|
break;
|
||||||
|
|
||||||
QgsPalGeometry* palGeometry = dynamic_cast< QgsPalGeometry* >(( *it )->getFeaturePart()->getUserGeometry() );
|
QgsPalGeometry* palGeometry = dynamic_cast< QgsPalGeometry* >(( *it )->getFeaturePart()->getUserGeometry() );
|
||||||
if ( !palGeometry )
|
if ( !palGeometry )
|
||||||
{
|
{
|
||||||
@ -3996,7 +4019,11 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
|
|||||||
|
|
||||||
delete problem;
|
delete problem;
|
||||||
delete labels;
|
delete labels;
|
||||||
|
deleteTemporaryData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsPalLabeling::deleteTemporaryData()
|
||||||
|
{
|
||||||
// delete all allocated geometries for features
|
// delete all allocated geometries for features
|
||||||
QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
|
QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
|
||||||
for ( lit = mActiveLayers.begin(); lit != mActiveLayers.end(); ++lit )
|
for ( lit = mActiveLayers.begin(); lit != mActiveLayers.end(); ++lit )
|
||||||
|
@ -813,6 +813,8 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
|
|||||||
void dataDefinedDropShadow( QgsPalLayerSettings& tmpLyr,
|
void dataDefinedDropShadow( QgsPalLayerSettings& tmpLyr,
|
||||||
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
|
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
|
||||||
|
|
||||||
|
void deleteTemporaryData();
|
||||||
|
|
||||||
// hashtable of layer settings, being filled during labeling
|
// hashtable of layer settings, being filled during labeling
|
||||||
QHash<QgsVectorLayer*, QgsPalLayerSettings> mActiveLayers;
|
QHash<QgsVectorLayer*, QgsPalLayerSettings> mActiveLayers;
|
||||||
// hashtable of active diagram layers
|
// hashtable of active diagram layers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user