Skip to content

Commit

Permalink
More labeling engine refactoring
Browse files Browse the repository at this point in the history
- 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 d0fcc95
Show file tree
Hide file tree
Showing 16 changed files with 503 additions and 1,257 deletions.
9 changes: 7 additions & 2 deletions python/core/qgsmaprenderer.sip
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion python/core/qgspallabeling.sip
Expand Up @@ -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 );
Expand Down
51 changes: 47 additions & 4 deletions src/core/qgslabelingenginev2.cpp
Expand Up @@ -17,6 +17,7 @@

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

#include "feature.h"
#include "labelposition.h"
Expand All @@ -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 )
Expand All @@ -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;
Expand Down Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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 )
Expand Down
19 changes: 15 additions & 4 deletions src/core/qgslabelingenginev2.h
Expand Up @@ -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;
Expand Down Expand Up @@ -210,7 +210,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAbstractLabelProvider::Flags )
class CORE_EXPORT QgsLabelingEngineV2
{
public:
QgsLabelingEngineV2( const QgsMapSettings& mapSettings );
QgsLabelingEngineV2();
~QgsLabelingEngineV2();

enum Flag
Expand All @@ -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 );

Expand All @@ -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;
Expand Down
10 changes: 8 additions & 2 deletions src/core/qgsmaprenderer.h
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion src/core/qgsmaprenderercustompainterjob.cpp
Expand Up @@ -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();
Expand Down
4 changes: 3 additions & 1 deletion src/core/qgsmaprendererparalleljob.cpp
Expand Up @@ -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();
Expand Down

0 comments on commit d0fcc95

Please sign in to comment.