Skip to content

Commit

Permalink
Move label obstacle settings out to their own class, and monkey patch…
Browse files Browse the repository at this point in the history
… around

to maintain current API

QgsPalLayerSettings is way too heavy, and we need to start refactoring
this into smaller atomic components
  • Loading branch information
nyalldawson committed Dec 3, 2019
1 parent f145fa9 commit 9f63f49
Show file tree
Hide file tree
Showing 18 changed files with 391 additions and 66 deletions.
108 changes: 108 additions & 0 deletions python/core/auto_generated/qgslabelobstaclesettings.sip.in
@@ -0,0 +1,108 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgslabelobstaclesettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsLabelObstacleSettings
{
%Docstring

Contains settings related to how the label engine treats features as obstacles

.. versionadded:: 3.10.2
%End

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

enum ObstacleType
{
PolygonInterior,
PolygonBoundary,
PolygonWhole
};

bool isObstacle() const;
%Docstring
Returns ``True`` if the features are obstacles to labels of other layers.

.. seealso:: :py:func:`setIsObstacle`

.. seealso:: :py:func:`factor`

.. seealso:: :py:func:`type`
%End

void setIsObstacle( bool isObstacle );
%Docstring
Sets whether features are obstacles to labels of other layers.

.. seealso:: :py:func:`isObstacle`

.. seealso:: :py:func:`factor`

.. seealso:: :py:func:`type`
%End

double factor() const;
%Docstring
Returns the obstacle factor, where 1.0 = default, < 1.0 more likely to be covered by labels,
> 1.0 less likely to be covered

.. seealso:: :py:func:`setFactor`

.. seealso:: :py:func:`isObstacle`

.. seealso:: :py:func:`type`
%End

void setFactor( double factor );
%Docstring
Sets the obstacle ``factor``, where 1.0 = default, < 1.0 more likely to be covered by labels,
> 1.0 less likely to be covered

.. seealso:: :py:func:`factor`

.. seealso:: :py:func:`isObstacle`

.. seealso:: :py:func:`type`
%End

ObstacleType type() const;
%Docstring
Returns how features act as obstacles for labels.

.. seealso:: :py:func:`setType`

.. seealso:: :py:func:`isObstacle`

.. seealso:: :py:func:`factor`
%End

void setType( ObstacleType type );
%Docstring
Controls how features act as obstacles for labels.

.. seealso:: :py:func:`type`

.. seealso:: :py:func:`isObstacle`

.. seealso:: :py:func:`factor`
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgslabelobstaclesettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
34 changes: 30 additions & 4 deletions python/core/auto_generated/qgspallabeling.sip.in
Expand Up @@ -76,7 +76,6 @@ Constructor for QgsLabelPosition
bool isUnplaced;
};


class QgsPalLayerSettings
{

Expand Down Expand Up @@ -469,11 +468,18 @@ Returns the QgsExpression for this label settings. May be ``None`` if isExpressi

double minFeatureSize;

bool obstacle;

double obstacleFactor;
%Property( name = obstacle, get = _getIsObstacle, set = _setIsObstacle )
%Property( name = obstacleFactor, get = _getObstacleFactor, set = _setObstacleFactor )
%Property( name = obstacleType, get = _getObstacleType, set = _setObstacleType )

bool _getIsObstacle() const;
void _setIsObstacle( bool obstacle );
double _getObstacleFactor() const;
void _setObstacleFactor( double factor );
ObstacleType _getObstacleType() const;
void _setObstacleType( ObstacleType type );

ObstacleType obstacleType;

double zIndex;

Expand Down Expand Up @@ -585,6 +591,25 @@ Ownership of ``callout`` is transferred to the settings.
.. versionadded:: 3.10
%End


QgsLabelObstacleSettings &obstacleSettings();
%Docstring
Returns the label obstacle settings.

.. seealso:: :py:func:`setObstacleSettings`

.. versionadded:: 3.10.2
%End

void setObstacleSettings( const QgsLabelObstacleSettings &settings );
%Docstring
Sets the label obstacle ``settings``.

.. seealso:: :py:func:`obstacleSettings`

.. versionadded:: 3.10.2
%End

static QPixmap labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText = QString(), int padding = 0 );
%Docstring
Returns a pixmap preview for label ``settings``.
Expand Down Expand Up @@ -738,6 +763,7 @@ allowed to be split apart (e.g., Arabic and Indic based scripts)

};


/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -88,6 +88,7 @@
%Include auto_generated/qgsinterval.sip
%Include auto_generated/qgsjsonutils.sip
%Include auto_generated/qgslabelingenginesettings.sip
%Include auto_generated/qgslabelobstaclesettings.sip
%Include auto_generated/qgslabelsearchtree.sip
%Include auto_generated/qgslayerdefinition.sip
%Include auto_generated/qgslegendrenderer.sip
Expand Down
4 changes: 4 additions & 0 deletions scripts/sipify.pl
Expand Up @@ -530,6 +530,10 @@ sub detect_non_method_member{
write_output("SF1", "%Feature $1$2\n");
next;
}
if ($LINE =~ m/^\s*SIP_PROPERTY\((.*)\)$/){
write_output("SF1", "%Property($1)\n");
next;
}
if ($LINE =~ m/^\s*SIP_IF_FEATURE\( (\!?\w+) \)(.*)$/){
write_output("SF2", "%If ($1)$2\n");
next;
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -754,6 +754,7 @@ SET(QGIS_CORE_HDRS
qgslabelfeature.h
qgslabelingengine.h
qgslabelingenginesettings.h
qgslabelobstaclesettings.h
qgslabelsearchtree.h
qgslayerdefinition.h
qgslegendrenderer.h
Expand Down
1 change: 0 additions & 1 deletion src/core/pal/layer.cpp
Expand Up @@ -45,7 +45,6 @@ Layer::Layer( QgsAbstractLabelProvider *provider, const QString &name, QgsPalLay
: mProvider( provider )
, mName( name )
, pal( pal )
, mObstacleType( QgsPalLayerSettings::PolygonInterior )
, mActive( active )
, mLabelLayer( toLabel )
, mDisplayAll( displayAll )
Expand Down
6 changes: 3 additions & 3 deletions src/core/pal/layer.h
Expand Up @@ -228,15 +228,15 @@ namespace pal
* act as obstacles for labels.
* \see setObstacleType
*/
QgsPalLayerSettings::ObstacleType obstacleType() const { return mObstacleType; }
QgsLabelObstacleSettings::ObstacleType obstacleType() const { return mObstacleType; }

/**
* Sets the obstacle type, which controls how features within the layer
* act as obstacles for labels.
* \param obstacleType new obstacle type
* \see obstacleType
*/
void setObstacleType( QgsPalLayerSettings::ObstacleType obstacleType ) { mObstacleType = obstacleType; }
void setObstacleType( QgsLabelObstacleSettings::ObstacleType obstacleType ) { mObstacleType = obstacleType; }

/**
* Sets the layer's priority.
Expand Down Expand Up @@ -333,7 +333,7 @@ namespace pal

double mDefaultPriority;

QgsPalLayerSettings::ObstacleType mObstacleType;
QgsLabelObstacleSettings::ObstacleType mObstacleType = QgsLabelObstacleSettings::PolygonBoundary;
bool mActive;
bool mLabelLayer;
bool mDisplayAll;
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgis_sip.h
Expand Up @@ -251,5 +251,9 @@
#define SIP_MONKEYPATCH_SCOPEENUM
#define SIP_MONKEYPATCH_SCOPEENUM_UNNEST(OUTSIDE_CLASS,FORMERNAME)

/*
* Directive to define a Python property;
*/
#define SIP_PROPERTY(name,getter,setter)

#endif // QGIS_SIP_H
1 change: 0 additions & 1 deletion src/core/qgslabelingengine.cpp
Expand Up @@ -620,7 +620,6 @@ QgsAbstractLabelProvider::QgsAbstractLabelProvider( QgsMapLayer *layer, const QS
, mFlags( DrawLabels )
, mPlacement( QgsPalLayerSettings::AroundPoint )
, mPriority( 0.5 )
, mObstacleType( QgsPalLayerSettings::PolygonInterior )
, mUpsidedownLabels( QgsPalLayerSettings::Upright )
{
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgslabelingengine.h
Expand Up @@ -142,7 +142,7 @@ class CORE_EXPORT QgsAbstractLabelProvider
double priority() const { return mPriority; }

//! How the feature geometries will work as obstacles
QgsPalLayerSettings::ObstacleType obstacleType() const { return mObstacleType; }
QgsLabelObstacleSettings::ObstacleType obstacleType() const { return mObstacleType; }

//! How to handle labels that would be upside down
QgsPalLayerSettings::UpsideDownLabels upsidedownLabels() const { return mUpsidedownLabels; }
Expand All @@ -166,7 +166,7 @@ class CORE_EXPORT QgsAbstractLabelProvider
//! Default priority of labels
double mPriority;
//! Type of the obstacle of feature geometries
QgsPalLayerSettings::ObstacleType mObstacleType;
QgsLabelObstacleSettings::ObstacleType mObstacleType = QgsLabelObstacleSettings::PolygonBoundary;
//! How to handle labels that would be upside down
QgsPalLayerSettings::UpsideDownLabels mUpsidedownLabels;
};
Expand Down
128 changes: 128 additions & 0 deletions src/core/qgslabelobstaclesettings.h
@@ -0,0 +1,128 @@
/***************************************************************************
qgslabelobstaclesettings.h
--------------------------
Date : December 2019
Copyright : (C) 2019 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSLABELOBSTACLESETTINGS_H
#define QGSLABELOBSTACLESETTINGS_H

#include "qgis_core.h"
#include "qgis_sip.h"

/**
* \ingroup core
* \class QgsLabelObstacleSettings
*
* Contains settings related to how the label engine treats features as obstacles
*
* \since QGIS 3.10.2
*/
class CORE_EXPORT QgsLabelObstacleSettings
{
public:

/**
* Valid obstacle types, which affect how features within the layer will act as obstacles
* for labels.
*/
enum ObstacleType
{
PolygonInterior, /*!< avoid placing labels over interior of polygon (prefer placing labels totally
outside or just slightly inside polygon) */
PolygonBoundary, /*!< avoid placing labels over boundary of polygon (prefer placing outside or
completely inside polygon) */
PolygonWhole /*!< avoid placing labels over ANY part of polygon. Where PolygonInterior will prefer
to place labels with the smallest area of intersection between the label and the polygon,
PolygonWhole will penalise any label which intersects with the polygon by an equal amount, so that
placing labels over any part of the polygon is avoided.*/
};

/**
* Returns TRUE if the features are obstacles to labels of other layers.
* \see setIsObstacle()
* \see factor()
* \see type()
*/
bool isObstacle() const
{
return mIsObstacle;
}

/**
* Sets whether features are obstacles to labels of other layers.
* \see isObstacle()
* \see factor()
* \see type()
*/
void setIsObstacle( bool isObstacle )
{
mIsObstacle = isObstacle;
}

/**
* Returns the obstacle factor, where 1.0 = default, < 1.0 more likely to be covered by labels,
* > 1.0 less likely to be covered
*
* \see setFactor()
* \see isObstacle()
* \see type()
*/
double factor() const
{
return mObstacleFactor;
}

/**
* Sets the obstacle \a factor, where 1.0 = default, < 1.0 more likely to be covered by labels,
* > 1.0 less likely to be covered
*
* \see factor()
* \see isObstacle()
* \see type()
*/
void setFactor( double factor )
{
mObstacleFactor = factor;
}

/**
* Returns how features act as obstacles for labels.
* \see setType()
* \see isObstacle()
* \see factor()
*/
ObstacleType type() const
{
return mObstacleType;
}

/**
* Controls how features act as obstacles for labels.
* \see type()
* \see isObstacle()
* \see factor()
*/
void setType( ObstacleType type )
{
mObstacleType = type;
}

private:

bool mIsObstacle = true;
double mObstacleFactor = 1.0;
ObstacleType mObstacleType = PolygonBoundary;

};

#endif // QGSLABELOBSTACLESETTINGS_H

0 comments on commit 9f63f49

Please sign in to comment.