Skip to content
Permalink
Browse files

Introduce label provider ID to uniquely identify label's settings

Before rule-based labeling, layer ID would identify label settings
of a label as there could be only one configuration per layer.
  • Loading branch information
wonder-sk committed Apr 21, 2016
1 parent a64ea0b commit 03f201d03b5360d7c91a8012b1d02f354af9f8a4
@@ -6,7 +6,7 @@ class QgsLabelPosition
#include <qgsmaprenderer.h>
%End
public:
QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, const QString& labeltext, const QFont& labelfont, bool upside_down, bool diagram = false, bool pinned = false );
QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, const QString& labeltext, const QFont& labelfont, bool upside_down, bool diagram = false, bool pinned = false, const QString& providerId = QString() );
QgsLabelPosition();
int featureId;
double rotation;
@@ -20,6 +20,8 @@ class QgsLabelPosition
bool upsideDown;
bool isDiagram;
bool isPinned;
//! @note added in 2.14
QString providerID;
};

/** Labeling engine interface. */
@@ -978,7 +978,7 @@ void QgsDxfExport::writeEntities()
}
else
{
lp = new QgsDxfLabelProvider( vl, this, nullptr );
lp = new QgsDxfLabelProvider( vl, QString(), this, nullptr );
engine.addProvider( lp );

if ( !lp->prepare( ctx, attributes ) )
@@ -22,8 +22,8 @@
#include "qgslogger.h"


QgsDxfLabelProvider::QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf, const QgsPalLayerSettings *settings )
: QgsVectorLayerLabelProvider( layer, false, settings )
QgsDxfLabelProvider::QgsDxfLabelProvider( QgsVectorLayer* layer, const QString& providerId, QgsDxfExport* dxf, const QgsPalLayerSettings *settings )
: QgsVectorLayerLabelProvider( layer, providerId, false, settings )
, mDxfExport( dxf )
{
}
@@ -52,11 +52,11 @@ void QgsDxfRuleBasedLabelProvider::reinit( QgsVectorLayer* layer )
mRules.rootRule()->createSubProviders( layer, mSubProviders, this );
}

QgsVectorLayerLabelProvider *QgsDxfRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings )
QgsVectorLayerLabelProvider *QgsDxfRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, const QString& providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings )
{
QgsDebugMsg( "Entering." );
Q_UNUSED( withFeatureLoop );
return new QgsDxfLabelProvider( layer, mDxfExport, settings );
return new QgsDxfLabelProvider( layer, providerId, mDxfExport, settings );
}

void QgsDxfRuleBasedLabelProvider::drawLabel( QgsRenderContext &context, pal::LabelPosition *label ) const
@@ -37,7 +37,7 @@ class QgsDxfLabelProvider : public QgsVectorLayerLabelProvider
{
public:
//! construct the provider
explicit QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf, const QgsPalLayerSettings *settings );
explicit QgsDxfLabelProvider( QgsVectorLayer* layer, const QString& providerId, QgsDxfExport* dxf, const QgsPalLayerSettings *settings );

/** Re-implementation that writes to DXF file instead of drawing with QPainter
* @param context render context
@@ -88,7 +88,7 @@ class QgsDxfRuleBasedLabelProvider : public QgsRuleBasedLabelProvider
void registerDxfFeature( QgsFeature& feature, QgsRenderContext &context, const QString& dxfLayerName );

//! create QgsDxfLabelProvider
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings ) override;
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, const QString& providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings ) override;

protected:
//! pointer to parent DXF export where this instance is used
@@ -381,9 +381,10 @@ QgsAbstractLabelProvider*QgsLabelFeature::provider() const

}

QgsAbstractLabelProvider::QgsAbstractLabelProvider( const QString& layerId )
QgsAbstractLabelProvider::QgsAbstractLabelProvider( const QString& layerId, const QString& providerId )
: mEngine( nullptr )
, mLayerId( layerId )
, mProviderId( providerId )
, mFlags( DrawLabels )
, mPlacement( QgsPalLayerSettings::AroundPoint )
, mLinePlacementFlags( 0 )
@@ -44,7 +44,7 @@ class CORE_EXPORT QgsAbstractLabelProvider

public:
//! Construct the provider with default values
QgsAbstractLabelProvider( const QString& layerId = QString() );
QgsAbstractLabelProvider( const QString& layerId = QString(), const QString& providerId = QString() );
//! Vritual destructor
virtual ~QgsAbstractLabelProvider() {}

@@ -77,6 +77,11 @@ class CORE_EXPORT QgsAbstractLabelProvider
//! Returns ID of associated layer, or empty string if no layer is associated with the provider.
QString layerId() const { return mLayerId; }

//! Returns provider ID - useful in case there is more than one label provider within a layer
//! (e.g. in case of rule-based labeling - provider ID = rule's key). May be empty string if
//! layer ID is sufficient for identification of provider's configuration.
QString providerId() const { return mProviderId; }

//! Flags associated with the provider
Flags flags() const { return mFlags; }

@@ -103,6 +108,8 @@ class CORE_EXPORT QgsAbstractLabelProvider
QString mName;
//! Associated layer's ID, if applicable
QString mLayerId;
//! Associated provider ID (one layer may have multiple providers, e.g. in rule-based labeling)
QString mProviderId;
//! Flags altering drawing and registration of features
Flags mFlags;
//! Placement strategy
@@ -75,7 +75,7 @@ void QgsLabelSearchTree::labelsInRect( const QgsRectangle& r, QList<QgsLabelPosi
}
}

bool QgsLabelSearchTree::insertLabel( pal::LabelPosition* labelPos, int featureId, const QString& layerName, const QString& labeltext, const QFont& labelfont, bool diagram, bool pinned )
bool QgsLabelSearchTree::insertLabel( pal::LabelPosition* labelPos, int featureId, const QString& layerName, const QString& labeltext, const QFont& labelfont, bool diagram, bool pinned, const QString& providerId )
{
if ( !labelPos )
{
@@ -93,7 +93,7 @@ bool QgsLabelSearchTree::insertLabel( pal::LabelPosition* labelPos, int featureI
cornerPoints.push_back( QgsPoint( labelPos->getX( i ), labelPos->getY( i ) ) );
}
QgsLabelPosition* newEntry = new QgsLabelPosition( featureId, labelPos->getAlpha(), cornerPoints, QgsRectangle( c_min[0], c_min[1], c_max[0], c_max[1] ),
labelPos->getWidth(), labelPos->getHeight(), layerName, labeltext, labelfont, labelPos->getUpsideDown(), diagram, pinned );
labelPos->getWidth(), labelPos->getHeight(), layerName, labeltext, labelfont, labelPos->getUpsideDown(), diagram, pinned, providerId );
mSpatialIndex.Insert( c_min, c_max, newEntry );
mOwnedPositions << newEntry;
return true;
@@ -53,7 +53,7 @@ class CORE_EXPORT QgsLabelSearchTree
* @return true in case of success
* @note not available in python bindings
*/
bool insertLabel( pal::LabelPosition* labelPos, int featureId, const QString& layerName, const QString& labeltext, const QFont& labelfont, bool diagram = false, bool pinned = false );
bool insertLabel( pal::LabelPosition* labelPos, int featureId, const QString& layerName, const QString& labeltext, const QFont& labelfont, bool diagram = false, bool pinned = false, const QString& providerId = QString() );

private:
// set as mutable because RTree template is not const-correct
@@ -46,8 +46,8 @@ class QgsDiagramLayerSettings;
class CORE_EXPORT QgsLabelPosition
{
public:
QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, const QString& labeltext, const QFont& labelfont, bool upside_down, bool diagram = false, bool pinned = false )
: featureId( id ), rotation( r ), cornerPoints( corners ), labelRect( rect ), width( w ), height( h ), layerID( layer ), labelText( labeltext ), labelFont( labelfont ), upsideDown( upside_down ), isDiagram( diagram ), isPinned( pinned ) {}
QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, const QString& labeltext, const QFont& labelfont, bool upside_down, bool diagram = false, bool pinned = false, const QString& providerId = QString() )
: featureId( id ), rotation( r ), cornerPoints( corners ), labelRect( rect ), width( w ), height( h ), layerID( layer ), labelText( labeltext ), labelFont( labelfont ), upsideDown( upside_down ), isDiagram( diagram ), isPinned( pinned ), providerID( providerId ) {}
QgsLabelPosition()
: featureId( -1 ), rotation( 0 ), labelRect( QgsRectangle() ), width( 0 ), height( 0 ), layerID( "" ), labelText( "" ), labelFont( QFont() ), upsideDown( false ), isDiagram( false ), isPinned( false ) {}
int featureId;
@@ -62,6 +62,8 @@ class CORE_EXPORT QgsLabelPosition
bool upsideDown;
bool isDiagram;
bool isPinned;
//! @note added in 2.14
QString providerID;
};

/** Labeling engine interface. */
@@ -16,7 +16,7 @@


QgsRuleBasedLabelProvider::QgsRuleBasedLabelProvider( const QgsRuleBasedLabeling& rules, QgsVectorLayer* layer, bool withFeatureLoop )
: QgsVectorLayerLabelProvider( layer, withFeatureLoop )
: QgsVectorLayerLabelProvider( layer, QString(), withFeatureLoop )
, mRules( rules )
{
mRules.rootRule()->createSubProviders( layer, mSubProviders, this );
@@ -27,9 +27,9 @@ QgsRuleBasedLabelProvider::~QgsRuleBasedLabelProvider()
// sub-providers owned by labeling engine
}

QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings )
QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, const QString& providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings )
{
return new QgsVectorLayerLabelProvider( layer, withFeatureLoop, settings );
return new QgsVectorLayerLabelProvider( layer, providerId, withFeatureLoop, settings );
}

bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
@@ -67,6 +67,7 @@ QgsRuleBasedLabeling::Rule::Rule( QgsPalLayerSettings* settings, int scaleMinDen
, mIsActive( true )
, mFilter( nullptr )
{
mRuleKey = QUuid::createUuid().toString();
initFilter();
}

@@ -162,11 +163,11 @@ QgsRuleBasedLabeling::Rule*QgsRuleBasedLabeling::Rule::create( const QDomElement
QString description = ruleElem.attribute( "description" );
int scaleMinDenom = ruleElem.attribute( "scalemindenom", "0" ).toInt();
int scaleMaxDenom = ruleElem.attribute( "scalemaxdenom", "0" ).toInt();
//QString ruleKey = ruleElem.attribute( "key" );
QString ruleKey = ruleElem.attribute( "key" );
Rule* rule = new Rule( settings, scaleMinDenom, scaleMaxDenom, filterExp, description );

//if ( !ruleKey.isEmpty() )
// rule->mRuleKey = ruleKey;
if ( !ruleKey.isEmpty() )
rule->mRuleKey = ruleKey;

rule->setActive( ruleElem.attribute( "active", "1" ).toInt() );

@@ -206,7 +207,7 @@ QDomElement QgsRuleBasedLabeling::Rule::save( QDomDocument& doc ) const
ruleElem.setAttribute( "description", mDescription );
if ( !mIsActive )
ruleElem.setAttribute( "active", 0 );
//ruleElem.setAttribute( "key", mRuleKey );
ruleElem.setAttribute( "key", mRuleKey );

for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
{
@@ -221,7 +222,7 @@ void QgsRuleBasedLabeling::Rule::createSubProviders( QgsVectorLayer* layer, QgsR
if ( mSettings )
{
// add provider!
QgsVectorLayerLabelProvider *p = provider->createProvider( layer, false, mSettings );
QgsVectorLayerLabelProvider *p = provider->createProvider( layer, mRuleKey, false, mSettings );
Q_ASSERT( !subProviders.contains( this ) );
subProviders[this] = p;
}
@@ -119,6 +119,9 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
*/
bool isElse() const { return mElseRule; }

//! Unique rule identifier (for identification of rule within labeling, used as provider ID)
QString ruleKey() const { return mRuleKey; }

//! set new settings (or NULL). Deletes old settings if any.
void setSettings( QgsPalLayerSettings* settings );

@@ -160,6 +163,8 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
*/
void setIsElse( bool iselse ) { mElseRule = iselse; }

//! Override the assigned rule key (should be used just internally by rule-based labeling)
void setRuleKey( const QString& key ) { mRuleKey = key; }

// parent / child operations

@@ -260,6 +265,8 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
RuleList mElseRules;
bool mIsActive; // whether it is enabled or not

QString mRuleKey; // string used for unique identification of rule within labeling

// temporary
QgsExpression* mFilter;

@@ -311,7 +318,7 @@ class CORE_EXPORT QgsRuleBasedLabelProvider : public QgsVectorLayerLabelProvider
virtual void registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry = nullptr ) override;

//! create a label provider
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings );
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, const QString& providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings );

//! return subproviders
virtual QList<QgsAbstractLabelProvider*> subProviders() override;
@@ -35,7 +35,6 @@ QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider(
: QgsAbstractLabelProvider( layerId )
, mSettings( *diagSettings )
, mDiagRenderer( diagRenderer->clone() )
, mLayerId( layerId )
, mFields( fields )
, mLayerCrs( crs )
, mSource( source )
@@ -49,7 +48,6 @@ QgsVectorLayerDiagramProvider::QgsVectorLayerDiagramProvider( QgsVectorLayer* la
: QgsAbstractLabelProvider( layer->id() )
, mSettings( *layer->diagramLayerSettings() )
, mDiagRenderer( layer->diagramRenderer()->clone() )
, mLayerId( layer->id() )
, mFields( layer->fields() )
, mLayerCrs( layer->crs() )
, mSource( ownFeatureLoop ? new QgsVectorLayerFeatureSource( layer ) : nullptr )
@@ -113,8 +113,6 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
QgsDiagramLayerSettings mSettings;
//! Diagram renderer instance (owned by mSettings)
QgsDiagramRendererV2* mDiagRenderer;
//! ID of the layer
QString mLayerId;

// these are needed only if using own renderer loop

@@ -39,7 +39,7 @@ QgsAbstractVectorLayerLabeling* QgsAbstractVectorLayerLabeling::create( const QD
QgsVectorLayerLabelProvider* QgsVectorLayerSimpleLabeling::provider( QgsVectorLayer* layer ) const
{
if ( layer->customProperty( "labeling" ).toString() == QLatin1String( "pal" ) && layer->labelsEnabled() )
return new QgsVectorLayerLabelProvider( layer, false );
return new QgsVectorLayerLabelProvider( layer, QString(), false );

return nullptr;
}
@@ -49,8 +49,8 @@ static void _fixQPictureDPI( QPainter* p )



QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer, bool withFeatureLoop, const QgsPalLayerSettings* settings, const QString& layerName )
: QgsAbstractLabelProvider( layer->id() )
QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer, const QString& providerId, bool withFeatureLoop, const QgsPalLayerSettings* settings, const QString& layerName )
: QgsAbstractLabelProvider( layer->id(), providerId )
, mSettings( settings ? *settings : QgsPalLayerSettings::fromLayer( layer ) )
, mLayerGeometryType( layer->geometryType() )
, mRenderer( layer->rendererV2() )
@@ -490,7 +490,7 @@ void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext& context, pal::Lab

// add to the results
QString labeltext = label->getFeaturePart()->feature()->labelText();
mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, dFont, false, lf->hasFixedPosition() );
mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, dFont, false, lf->hasFixedPosition(), mProviderId );
}


@@ -37,7 +37,11 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
public:

//! Convenience constructor to initialize the provider from given vector layer
explicit QgsVectorLayerLabelProvider( QgsVectorLayer* layer, bool withFeatureLoop = true, const QgsPalLayerSettings* settings = nullptr, const QString& layerName = QString() );
explicit QgsVectorLayerLabelProvider( QgsVectorLayer* layer,
const QString& providerId,
bool withFeatureLoop = true,
const QgsPalLayerSettings* settings = nullptr,
const QString& layerName = QString() );

//! Construct diagram provider with all the necessary configuration parameters
QgsVectorLayerLabelProvider( const QgsPalLayerSettings& settings,

0 comments on commit 03f201d

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