Skip to content
Permalink
Browse files

More labeling engine refactoring

- QgsPalLabeling now internally uses new engine
- label/diagram providers can hook into rendering loop to avoid extra feature loops
- map rendering uses the new engine instead of QgsPalLabeling

This code has been funded by Tuscany Region (Italy) - SITA (CIG: 63526840AE) and commissioned to Gis3W s.a.s.
  • Loading branch information
wonder-sk committed Sep 21, 2015
1 parent 8100495 commit d0fcc9557f7609dc7d8d0f409219138bc000ebf1
@@ -47,9 +47,14 @@ class QgsLabelingEngineInterface
//! called when starting rendering of a layer
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
//! returns PAL layer settings for a registered layer
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0 /Deprecated/;
//! adds a diagram layer to the labeling engine
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s );
//! @note added in QGIS 2.12
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx );
//! adds a diagram layer to the labeling engine
//! @deprecated since 2.12 - use prepareDiagramLayer()
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s ) /Deprecated/;
//! called for every feature
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext(), QString dxfLayer = QString::null ) = 0;
//! called for every diagram feature
@@ -699,7 +699,8 @@ class QgsPalLabeling : QgsLabelingEngineInterface

bool isShowingCandidates() const;
void setShowingCandidates( bool showing );
const QList<QgsLabelCandidate>& candidates();
//! @deprecated since 2.12
const QList<QgsLabelCandidate>& candidates() /Deprecated/;

bool isShowingShadowRectangles() const;
void setShowingShadowRectangles( bool showing );
@@ -17,6 +17,7 @@

#include "qgslogger.h"
#include "qgspalgeometry.h"
#include "qgsproject.h"

#include "feature.h"
#include "labelposition.h"
@@ -33,9 +34,8 @@ static bool _palIsCancelled( void* ctx )
}


QgsLabelingEngineV2::QgsLabelingEngineV2( const QgsMapSettings& mapSettings )
: mMapSettings( mapSettings )
, mFlags( RenderOutlineLabels | UsePartialCandidates )
QgsLabelingEngineV2::QgsLabelingEngineV2()
: mFlags( RenderOutlineLabels | UsePartialCandidates )
, mSearchMethod( QgsPalLabeling::Chain )
, mCandPoint( 8 )
, mCandLine( 8 )
@@ -57,6 +57,15 @@ void QgsLabelingEngineV2::addProvider( QgsAbstractLabelProvider* provider )
mProviders << provider;
}

void QgsLabelingEngineV2::removeProvider( QgsAbstractLabelProvider* provider )
{
int idx = mProviders.indexOf( provider );
if ( idx >= 0 )
{
delete mProviders.takeAt( idx );
}
}

void QgsLabelingEngineV2::run( QgsRenderContext& context )
{
pal::Pal p;
@@ -146,7 +155,7 @@ void QgsLabelingEngineV2::run( QgsRenderContext& context )
l->setUpsidedownLabels( upsdnlabels );


QList<QgsLabelFeature*> features = provider->labelFeatures( mMapSettings, context );
QList<QgsLabelFeature*> features = provider->labelFeatures( context );

foreach ( QgsLabelFeature* feature, features )
{
@@ -286,6 +295,40 @@ QgsLabelingResults* QgsLabelingEngineV2::takeResults()
return res;
}


void QgsLabelingEngineV2::readSettingsFromProject()
{
bool saved = false;
QgsProject* prj = QgsProject::instance();
mSearchMethod = ( QgsPalLabeling::Search )( prj->readNumEntry( "PAL", "/SearchMethod", ( int ) QgsPalLabeling::Chain, &saved ) );
mCandPoint = prj->readNumEntry( "PAL", "/CandidatesPoint", 8, &saved );
mCandLine = prj->readNumEntry( "PAL", "/CandidatesLine", 8, &saved );
mCandPolygon = prj->readNumEntry( "PAL", "/CandidatesPolygon", 8, &saved );

mFlags = 0;
if ( prj->readBoolEntry( "PAL", "/ShowingCandidates", false, &saved ) ) mFlags |= DrawCandidates;
if ( prj->readBoolEntry( "PAL", "/DrawRectOnly", false, &saved ) ) mFlags |= DrawLabelRectOnly;
if ( prj->readBoolEntry( "PAL", "/ShowingShadowRects", false, &saved ) ) mFlags |= DrawShadowRects;
if ( prj->readBoolEntry( "PAL", "/ShowingAllLabels", false, &saved ) ) mFlags |= UseAllLabels;
if ( prj->readBoolEntry( "PAL", "/ShowingPartialsLabels", true, &saved ) ) mFlags |= UsePartialCandidates;
if ( prj->readBoolEntry( "PAL", "/DrawOutlineLabels", true, &saved ) ) mFlags |= RenderOutlineLabels;
}

void QgsLabelingEngineV2::writeSettingsToProject()
{
QgsProject::instance()->writeEntry( "PAL", "/SearchMethod", ( int )mSearchMethod );
QgsProject::instance()->writeEntry( "PAL", "/CandidatesPoint", mCandPoint );
QgsProject::instance()->writeEntry( "PAL", "/CandidatesLine", mCandLine );
QgsProject::instance()->writeEntry( "PAL", "/CandidatesPolygon", mCandPolygon );

QgsProject::instance()->writeEntry( "PAL", "/ShowingCandidates", mFlags.testFlag( DrawCandidates ) );
QgsProject::instance()->writeEntry( "PAL", "/DrawRectOnly", mFlags.testFlag( DrawLabelRectOnly ) );
QgsProject::instance()->writeEntry( "PAL", "/ShowingShadowRects", mFlags.testFlag( DrawShadowRects ) );
QgsProject::instance()->writeEntry( "PAL", "/ShowingAllLabels", mFlags.testFlag( UseAllLabels ) );
QgsProject::instance()->writeEntry( "PAL", "/ShowingPartialsLabels", mFlags.testFlag( UsePartialCandidates ) );
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", mFlags.testFlag( RenderOutlineLabels ) );
}

QgsAbstractLabelProvider* QgsLabelingEngineV2::providerById( const QString& id )
{
Q_FOREACH ( QgsAbstractLabelProvider* provider, mProviders )
@@ -164,7 +164,7 @@ class CORE_EXPORT QgsAbstractLabelProvider
virtual QString id() const = 0;

//! Return list of labels
virtual QList<QgsLabelFeature*> labelFeatures( const QgsMapSettings& mapSettings, const QgsRenderContext& context ) = 0;
virtual QList<QgsLabelFeature*> labelFeatures( const QgsRenderContext& context ) = 0;

//! draw this label at the position determined by the labeling engine
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const = 0;
@@ -210,7 +210,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAbstractLabelProvider::Flags )
class CORE_EXPORT QgsLabelingEngineV2
{
public:
QgsLabelingEngineV2( const QgsMapSettings& mapSettings );
QgsLabelingEngineV2();
~QgsLabelingEngineV2();

enum Flag
@@ -224,9 +224,18 @@ class CORE_EXPORT QgsLabelingEngineV2
};
Q_DECLARE_FLAGS( Flags, Flag )

void setMapSettings( const QgsMapSettings& mapSettings ) { mMapSettings = mapSettings; }
const QgsMapSettings& mapSettings() const { return mMapSettings; }

//! Add provider of label features. Takes ownership of the provider
void addProvider( QgsAbstractLabelProvider* provider );

//! Remove provider if the provider's initialization failed. Provider instance is deleted.
void removeProvider( QgsAbstractLabelProvider* provider );

//! Lookup provider by its ID
QgsAbstractLabelProvider* providerById( const QString& id );

//! compute the labeling with given map settings and providers
void run( QgsRenderContext& context );

@@ -238,15 +247,17 @@ class CORE_EXPORT QgsLabelingEngineV2

void setFlags( Flags flags ) { mFlags = flags; }
Flags flags() const { return mFlags; }
bool testFlag( Flag f ) const { return mFlags.testFlag( f ); }
void setFlag( Flag f, bool enabled ) { if ( enabled ) mFlags |= f; else mFlags &= ~f; }

void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon ) { candPoint = mCandPoint; candLine = mCandLine; candPolygon = mCandPolygon; }
void setNumCandidatePositions( int candPoint, int candLine, int candPolygon ) { mCandPoint = candPoint; mCandLine = candLine; mCandPolygon = candPolygon; }

void setSearchMethod( QgsPalLabeling::Search s ) { mSearchMethod = s; }
QgsPalLabeling::Search searchMethod() const { return mSearchMethod; }

protected:
QgsAbstractLabelProvider* providerById( const QString& id );
void readSettingsFromProject();
void writeSettingsToProject();

protected:
QgsMapSettings mMapSettings;
@@ -84,9 +84,15 @@ class CORE_EXPORT QgsLabelingEngineInterface
//! called when starting rendering of a layer
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
//! returns PAL layer settings for a registered layer
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
Q_DECL_DEPRECATED virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
//! adds a diagram layer to the labeling engine
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s )
//! @note added in QGIS 2.12
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx )
{ Q_UNUSED( layer ); Q_UNUSED( attrNames ); Q_UNUSED( ctx ); return 0; }
//! adds a diagram layer to the labeling engine
//! @deprecated since 2.12 - use prepareDiagramLayer()
Q_DECL_DEPRECATED virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s )
{ Q_UNUSED( layer ); Q_UNUSED( s ); return 0; }
//! called for every feature
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext(), QString dxfLayer = QString::null ) = 0;
@@ -85,7 +85,9 @@ void QgsMapRendererCustomPainterJob::start()
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
{
#ifdef LABELING_V2
mLabelingEngineV2 = new QgsLabelingEngineV2( mSettings );
mLabelingEngineV2 = new QgsLabelingEngineV2();
mLabelingEngineV2->readSettingsFromProject();
mLabelingEngineV2->setMapSettings( mSettings );
#else
mLabelingEngine = new QgsPalLabeling;
mLabelingEngine->loadEngineSettings();
@@ -64,7 +64,9 @@ void QgsMapRendererParallelJob::start()
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
{
#ifdef LABELING_V2
mLabelingEngineV2 = new QgsLabelingEngineV2( mSettings );
mLabelingEngineV2 = new QgsLabelingEngineV2();
mLabelingEngineV2->readSettingsFromProject();
mLabelingEngineV2->setMapSettings( mSettings );
#else
mLabelingEngine = new QgsPalLabeling;
mLabelingEngine->loadEngineSettings();

0 comments on commit d0fcc95

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