Skip to content

Commit

Permalink
Clean up reading/writing of labeling configuration in vector layers
Browse files Browse the repository at this point in the history
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 21f03bc
Show file tree
Hide file tree
Showing 33 changed files with 471 additions and 300 deletions.
2 changes: 2 additions & 0 deletions doc/api_break.dox
Expand Up @@ -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}
Expand All @@ -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}
Expand Down
1 change: 1 addition & 0 deletions python/auto_sip.blacklist
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions python/core/core.sip
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 0 additions & 6 deletions python/core/qgspallabeling.sip
Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down
74 changes: 74 additions & 0 deletions python/core/qgsrulebasedlabeling.sip
@@ -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;

};
40 changes: 4 additions & 36 deletions python/core/qgstextrenderer.sip
Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down
11 changes: 11 additions & 0 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -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
Expand Down
121 changes: 121 additions & 0 deletions python/core/qgsvectorlayerlabeling.sip
@@ -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 *
************************************************************************/
3 changes: 2 additions & 1 deletion src/app/dwg/qgsdwgimportdialog.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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" );
Expand Down

0 comments on commit 21f03bc

Please sign in to comment.