Skip to content
Permalink
Browse files
Clean up reading/writing of labeling configuration in vector layers
Historically the configuration used to be stored in layer's custom properties, but that does not scale
beyond simple rendering and so rule-based labeling introduced storage of configuration natively in XML elements.
That left us with two different ways of reading/writing labeling configurations. This work makes all configuration
to use native XML elements.

To keep compatibility of 2.x projects, reading of configuration from custom properties is preserved.

This commit also adds Python APIs for direct manipulation of labeling configuration through vector layer's
setLabeling() and labeling() calls.
  • Loading branch information
wonder-sk committed May 16, 2017
1 parent 7e345a7 commit 21f03bc11ccb7908d86f30858253c50347688f68
@@ -1645,6 +1645,7 @@ QgsPalLabeling {#qgis_api_break_3_0_QgsPalLabeling}
- labelsWithinRect() was removed. Use takeResults() and methods of QgsLabelingResults instead.
- isStoredWithProject() and setStoredWithProject() had no effect and were removed.
- staticWillUseLayer(QString) was removed. Use the variant with QgsVectorLayer argument.
- readFromLayer() and writeToLayer() have been removed. Labeling is read/written in QgsAbstractVectorLayerLabeling and its subclasses.


QgsPalLayerSettings {#qgis_api_break_3_0_QgsPalLayerSettings}
@@ -1661,6 +1662,7 @@ dataDefinedUseExpression(), dataDefinedProperties() and dataDefinedNames()
members were removed. Use the QgsProperty framework through dataDefinedProperties()
and setDataDefinedProperties() instead.
- readXml() and writeXml() now expect a reference to QgsReadWriteContext.
- fromLayer() has been reoved. Labeling is read/written in QgsAbstractVectorLayerLabeling and its subclasses.


QgsPanelWidgetStack {#qgis_api_break_3_0_QgsPanelWidgetStack}
@@ -22,6 +22,7 @@ core/qgsrange.sip
core/qgsrelationmanager.sip
core/qgsrenderchecker.sip
core/qgsrendercontext.sip
core/qgsrulebasedlabeling.sip
core/qgsrunprocess.sip
core/qgsruntimeprofiler.sip
core/qgsscalecalculator.sip
@@ -141,6 +141,7 @@
%Include qgsrelationmanager.sip
%Include qgsrenderchecker.sip
%Include qgsrendercontext.sip
%Include qgsrulebasedlabeling.sip
%Include qgsrunprocess.sip
%Include qgsruntimeprofiler.sip
%Include qgsscalecalculator.sip
@@ -170,6 +171,7 @@
%Include qgsvectorlayerfeaturecounter.sip
%Include qgsvectorlayerjoinbuffer.sip
%Include qgsvectorlayerjoininfo.sip
%Include qgsvectorlayerlabeling.sip
%Include qgsvectorlayertools.sip
%Include qgsvectorlayerundocommand.sip
%Include qgsvectorlayerutils.sip
@@ -34,9 +34,6 @@ class QgsPalLayerSettings
QgsPalLayerSettings( const QgsPalLayerSettings &s );
~QgsPalLayerSettings();

//! @note added in 2.4
static QgsPalLayerSettings fromLayer( QgsVectorLayer *layer );

/** Placement modes which determine how label candidates are generated for a feature.
*/
//TODO QGIS 3.0 - move to QgsLabelingEngine
@@ -420,9 +417,6 @@ class QgsPalLayerSettings
*/
void registerFeature( QgsFeature &f, QgsRenderContext &context );

void readFromLayer( QgsVectorLayer *layer );
void writeToLayer( QgsVectorLayer *layer );

/** Read settings from a DOM element
* @note added in 2.12
*/
@@ -0,0 +1,74 @@


class QgsRuleBasedLabeling : QgsAbstractVectorLayerLabeling
{
%TypeHeaderCode
#include "qgsrulebasedlabeling.h"
%End
public:
typedef QList<QgsRuleBasedLabeling::Rule *> RuleList;

class Rule
{
%TypeHeaderCode
#include "qgsrulebasedlabeling.h"
%End
public:
Rule( QgsPalLayerSettings *settings /Transfer/, int scaleMinDenom = 0, int scaleMaxDenom = 0, const QString &filterExp = QString(), const QString &description = QString(), bool elseRule = false );
~Rule();

enum RegisterResult
{
Filtered,
Inactive,
Registered
};

QgsPalLayerSettings *settings() const;
bool dependsOnScale() const;
int scaleMinDenom() const;
int scaleMaxDenom() const;
QString filterExpression() const;
QString description() const;
bool active() const;
bool isElse() const;
QString ruleKey() const;
void setSettings( QgsPalLayerSettings *settings /Transfer/ );
void setScaleMinDenom( int scaleMinDenom );
void setScaleMaxDenom( int scaleMaxDenom );
void setFilterExpression( const QString &filterExp );
void setDescription( const QString &description );
void setActive( bool state );
void setIsElse( bool iselse );
void setRuleKey( const QString &key );
const QgsRuleBasedLabeling::RuleList &children() const;
QgsRuleBasedLabeling::RuleList descendants() const;
QgsRuleBasedLabeling::Rule *parent();
void appendChild( QgsRuleBasedLabeling::Rule *rule /Transfer/ );
void insertChild( int i, QgsRuleBasedLabeling::Rule *rule /Transfer/ );
void removeChildAt( int i );
const QgsRuleBasedLabeling::Rule *findRuleByKey( const QString &key ) const;
QgsRuleBasedLabeling::Rule *clone() const /Factory/;
static QgsRuleBasedLabeling::Rule *create( const QDomElement &ruleElem, const QgsReadWriteContext &context ) /Factory/;
QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
bool requiresAdvancedEffects() const;

private:
Rule( const QgsRuleBasedLabeling::Rule &rh );
};

explicit QgsRuleBasedLabeling( QgsRuleBasedLabeling::Rule *root /Transfer/ );
~QgsRuleBasedLabeling();

QgsRuleBasedLabeling::Rule *rootRule();

static QgsRuleBasedLabeling *create( const QDomElement &element, const QgsReadWriteContext &context ) /Factory/;

virtual QString type() const;
virtual QgsRuleBasedLabeling *clone() const /Factory/;
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
virtual QStringList subProviders() const;
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const;
virtual bool requiresAdvancedEffects() const;

};
@@ -182,16 +182,8 @@ class QgsTextBufferSettings

void readFromLayer( QgsVectorLayer *layer );
%Docstring
Reads settings from a layer's custom properties.
Reads settings from a layer's custom properties (for QGIS 2.x projects).
\param layer source vector layer
.. seealso:: writeToLayer()
%End

void writeToLayer( QgsVectorLayer *layer ) const;
%Docstring
Writes settings to a layer's custom properties.
\param layer target vector layer
.. seealso:: readFromLayer()
%End

void readXml( const QDomElement &elem );
@@ -676,16 +668,8 @@ class QgsTextBackgroundSettings

void readFromLayer( QgsVectorLayer *layer );
%Docstring
Reads settings from a layer's custom properties.
Reads settings from a layer's custom properties (for QGIS 2.x projects).
\param layer source vector layer
.. seealso:: writeToLayer()
%End

void writeToLayer( QgsVectorLayer *layer ) const;
%Docstring
Writes settings to a layer's custom properties.
\param layer target vector layer
.. seealso:: readFromLayer()
%End

void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
@@ -976,16 +960,8 @@ class QgsTextShadowSettings

void readFromLayer( QgsVectorLayer *layer );
%Docstring
Reads settings from a layer's custom properties.
Reads settings from a layer's custom properties (for QGIS 2.x projects).
\param layer source vector layer
.. seealso:: writeToLayer()
%End

void writeToLayer( QgsVectorLayer *layer ) const;
%Docstring
Writes settings to a layer's custom properties.
\param layer target vector layer
.. seealso:: readFromLayer()
%End

void readXml( const QDomElement &elem );
@@ -1239,16 +1215,8 @@ class QgsTextFormat

void readFromLayer( QgsVectorLayer *layer );
%Docstring
Reads settings from a layer's custom properties.
Reads settings from a layer's custom properties (for QGIS 2.x projects).
\param layer source vector layer
.. seealso:: writeToLayer()
%End

void writeToLayer( QgsVectorLayer *layer ) const;
%Docstring
Writes settings to a layer's custom properties.
\param layer target vector layer
.. seealso:: readFromLayer()
%End

void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
@@ -1045,7 +1045,18 @@ changeGeometry() instead.
:rtype: int
%End

const QgsAbstractVectorLayerLabeling *labeling() const;
%Docstring
Access to labeling configuration. May be null if labeling is not used.
.. versionadded:: 3.0
:rtype: QgsAbstractVectorLayerLabeling
%End

void setLabeling( QgsAbstractVectorLayerLabeling *labeling /Transfer/ );
%Docstring
Set labeling configuration. Takes ownership of the object.
.. versionadded:: 3.0
%End

virtual bool isEditable() const;
%Docstring
@@ -0,0 +1,121 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsvectorlayerlabeling.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/






class QgsAbstractVectorLayerLabeling
{
%Docstring
Abstract base class - its implementations define different approaches to the labeling of a vector layer.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsvectorlayerlabeling.h"
%End
public:

QgsAbstractVectorLayerLabeling();
virtual ~QgsAbstractVectorLayerLabeling();

virtual QString type() const = 0;
%Docstring
Unique type string of the labeling configuration implementation
:rtype: str
%End

virtual QgsAbstractVectorLayerLabeling *clone() const = 0 /Factory/;
%Docstring
Return a new copy of the object
:rtype: QgsAbstractVectorLayerLabeling
%End


virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const = 0;
%Docstring
Return labeling configuration as XML element
:rtype: QDomElement
%End

virtual QStringList subProviders() const;
%Docstring
Get list of sub-providers within the layer's labeling.
:rtype: list of str
%End

virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const = 0;
%Docstring
they are identified by their ID (e.g. in case of rule-based labeling, provider ID == rule key)
:rtype: QgsPalLayerSettings
%End

virtual bool requiresAdvancedEffects() const = 0;
%Docstring
Returns true if drawing labels requires advanced effects like composition
modes, which could prevent it being used as an isolated cached image
or exported to a vector format.
.. versionadded:: 3.0
:rtype: bool
%End


static QgsAbstractVectorLayerLabeling *create( const QDomElement &element, const QgsReadWriteContext &context ) /Factory/;
%Docstring
Try to create instance of an implementation based on the XML data
:rtype: QgsAbstractVectorLayerLabeling
%End

private:
QgsAbstractVectorLayerLabeling( const QgsAbstractVectorLayerLabeling &rhs );
};

class QgsVectorLayerSimpleLabeling : QgsAbstractVectorLayerLabeling
{
%Docstring
Basic implementation of the labeling interface.

The configuration is kept in layer's custom properties for backward compatibility.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsvectorlayerlabeling.h"
%End
public:
explicit QgsVectorLayerSimpleLabeling( const QgsPalLayerSettings &settings );
%Docstring
Constructs simple labeling configuration with given initial settings
%End

virtual QString type() const;
virtual QgsAbstractVectorLayerLabeling *clone() const /Factory/;
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const;
virtual bool requiresAdvancedEffects() const;


static QgsVectorLayerSimpleLabeling *create( const QDomElement &element, const QgsReadWriteContext &context );
%Docstring
Create the instance from a DOM element with saved configuration
:rtype: QgsVectorLayerSimpleLabeling
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsvectorlayerlabeling.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -25,6 +25,7 @@
#include "qgisapp.h"
#include "qgsdwgimporter.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerlabeling.h"
#include "qgsvectordataprovider.h"
#include "qgsproject.h"
#include "qgsfeatureiterator.h"
@@ -399,7 +400,7 @@ void QgsDwgImportDialog::createGroup( QgsLayerTreeGroup *group, QString name, QS
pls.dataDefinedProperties().setProperty( QgsPalLayerSettings::Rotation, QgsProperty::fromExpression( QStringLiteral( "angle*180.0/pi()" ) ) );

pls.placement = QgsPalLayerSettings::OrderedPositionsAroundPoint;
pls.writeToLayer( l );
l->setLabeling( new QgsVectorLayerSimpleLabeling( pls ) );
}

l = layer( layerGroup, layerFilter, "points" );

0 comments on commit 21f03bc

Please sign in to comment.