mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-05 00:04:40 -05:00
Move label obstacle settings out to their own class, and monkey patch around
to maintain current API QgsPalLayerSettings is way too heavy, and we need to start refactoring this into smaller atomic components
This commit is contained in:
parent
f145fa96c8
commit
9f63f49230
108
python/core/auto_generated/qgslabelobstaclesettings.sip.in
Normal file
108
python/core/auto_generated/qgslabelobstaclesettings.sip.in
Normal file
@ -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 *
|
||||
************************************************************************/
|
||||
@ -76,7 +76,6 @@ Constructor for QgsLabelPosition
|
||||
bool isUnplaced;
|
||||
};
|
||||
|
||||
|
||||
class QgsPalLayerSettings
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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``.
|
||||
@ -738,6 +763,7 @@ allowed to be split apart (e.g., Arabic and Indic based scripts)
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
|
||||
@ -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
|
||||
|
||||
@ -530,6 +530,10 @@ while ($LINE_IDX < $LINE_COUNT){
|
||||
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;
|
||||
|
||||
@ -754,6 +754,7 @@ SET(QGIS_CORE_HDRS
|
||||
qgslabelfeature.h
|
||||
qgslabelingengine.h
|
||||
qgslabelingenginesettings.h
|
||||
qgslabelobstaclesettings.h
|
||||
qgslabelsearchtree.h
|
||||
qgslayerdefinition.h
|
||||
qgslegendrenderer.h
|
||||
|
||||
@ -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 )
|
||||
|
||||
@ -228,7 +228,7 @@ 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
|
||||
@ -236,7 +236,7 @@ namespace pal
|
||||
* \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.
|
||||
@ -333,7 +333,7 @@ namespace pal
|
||||
|
||||
double mDefaultPriority;
|
||||
|
||||
QgsPalLayerSettings::ObstacleType mObstacleType;
|
||||
QgsLabelObstacleSettings::ObstacleType mObstacleType = QgsLabelObstacleSettings::PolygonBoundary;
|
||||
bool mActive;
|
||||
bool mLabelLayer;
|
||||
bool mDisplayAll;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -620,7 +620,6 @@ QgsAbstractLabelProvider::QgsAbstractLabelProvider( QgsMapLayer *layer, const QS
|
||||
, mFlags( DrawLabels )
|
||||
, mPlacement( QgsPalLayerSettings::AroundPoint )
|
||||
, mPriority( 0.5 )
|
||||
, mObstacleType( QgsPalLayerSettings::PolygonInterior )
|
||||
, mUpsidedownLabels( QgsPalLayerSettings::Upright )
|
||||
{
|
||||
}
|
||||
|
||||
@ -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; }
|
||||
@ -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;
|
||||
};
|
||||
|
||||
128
src/core/qgslabelobstaclesettings.h
Normal file
128
src/core/qgslabelobstaclesettings.h
Normal file
@ -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
|
||||
@ -347,9 +347,6 @@ QgsPalLayerSettings &QgsPalLayerSettings::operator=( const QgsPalLayerSettings &
|
||||
minFeatureSize = s.minFeatureSize;
|
||||
limitNumLabels = s.limitNumLabels;
|
||||
maxNumLabels = s.maxNumLabels;
|
||||
obstacle = s.obstacle;
|
||||
obstacleFactor = s.obstacleFactor;
|
||||
obstacleType = s.obstacleType;
|
||||
zIndex = s.zIndex;
|
||||
|
||||
mFormat = s.mFormat;
|
||||
@ -357,6 +354,8 @@ QgsPalLayerSettings &QgsPalLayerSettings::operator=( const QgsPalLayerSettings &
|
||||
|
||||
mCallout.reset( s.mCallout ? s.mCallout->clone() : nullptr );
|
||||
|
||||
mObstacleSettings = s.mObstacleSettings;
|
||||
|
||||
geometryGenerator = s.geometryGenerator;
|
||||
geometryGeneratorEnabled = s.geometryGeneratorEnabled;
|
||||
geometryGeneratorType = s.geometryGeneratorType;
|
||||
@ -395,7 +394,7 @@ bool QgsPalLayerSettings::prepare( QgsRenderContext &context, QSet<QString> &att
|
||||
|
||||
mCurFields = fields;
|
||||
|
||||
if ( drawLabels || obstacle )
|
||||
if ( drawLabels || mObstacleSettings.isObstacle() )
|
||||
{
|
||||
if ( drawLabels )
|
||||
{
|
||||
@ -812,9 +811,9 @@ void QgsPalLayerSettings::readFromLayerCustomProperties( QgsVectorLayer *layer )
|
||||
minFeatureSize = layer->customProperty( QStringLiteral( "labeling/minFeatureSize" ) ).toDouble();
|
||||
limitNumLabels = layer->customProperty( QStringLiteral( "labeling/limitNumLabels" ), QVariant( false ) ).toBool();
|
||||
maxNumLabels = layer->customProperty( QStringLiteral( "labeling/maxNumLabels" ), QVariant( 2000 ) ).toInt();
|
||||
obstacle = layer->customProperty( QStringLiteral( "labeling/obstacle" ), QVariant( true ) ).toBool();
|
||||
obstacleFactor = layer->customProperty( QStringLiteral( "labeling/obstacleFactor" ), QVariant( 1.0 ) ).toDouble();
|
||||
obstacleType = static_cast< ObstacleType >( layer->customProperty( QStringLiteral( "labeling/obstacleType" ), QVariant( PolygonInterior ) ).toUInt() );
|
||||
mObstacleSettings.setIsObstacle( layer->customProperty( QStringLiteral( "labeling/obstacle" ), QVariant( true ) ).toBool() );
|
||||
mObstacleSettings.setFactor( layer->customProperty( QStringLiteral( "labeling/obstacleFactor" ), QVariant( 1.0 ) ).toDouble() );
|
||||
mObstacleSettings.setType( static_cast< QgsLabelObstacleSettings::ObstacleType >( layer->customProperty( QStringLiteral( "labeling/obstacleType" ), QVariant( PolygonInterior ) ).toUInt() ) );
|
||||
zIndex = layer->customProperty( QStringLiteral( "labeling/zIndex" ), QVariant( 0.0 ) ).toDouble();
|
||||
|
||||
mDataDefinedProperties.clear();
|
||||
@ -1038,9 +1037,9 @@ void QgsPalLayerSettings::readXml( const QDomElement &elem, const QgsReadWriteCo
|
||||
minFeatureSize = renderingElem.attribute( QStringLiteral( "minFeatureSize" ) ).toDouble();
|
||||
limitNumLabels = renderingElem.attribute( QStringLiteral( "limitNumLabels" ), QStringLiteral( "0" ) ).toInt();
|
||||
maxNumLabels = renderingElem.attribute( QStringLiteral( "maxNumLabels" ), QStringLiteral( "2000" ) ).toInt();
|
||||
obstacle = renderingElem.attribute( QStringLiteral( "obstacle" ), QStringLiteral( "1" ) ).toInt();
|
||||
obstacleFactor = renderingElem.attribute( QStringLiteral( "obstacleFactor" ), QStringLiteral( "1" ) ).toDouble();
|
||||
obstacleType = static_cast< ObstacleType >( renderingElem.attribute( QStringLiteral( "obstacleType" ), QString::number( PolygonInterior ) ).toUInt() );
|
||||
mObstacleSettings.setIsObstacle( renderingElem.attribute( QStringLiteral( "obstacle" ), QStringLiteral( "1" ) ).toInt() );
|
||||
mObstacleSettings.setFactor( renderingElem.attribute( QStringLiteral( "obstacleFactor" ), QStringLiteral( "1" ) ).toDouble() );
|
||||
mObstacleSettings.setType( static_cast< QgsLabelObstacleSettings::ObstacleType >( renderingElem.attribute( QStringLiteral( "obstacleType" ), QString::number( PolygonInterior ) ).toUInt() ) );
|
||||
zIndex = renderingElem.attribute( QStringLiteral( "zIndex" ), QStringLiteral( "0.0" ) ).toDouble();
|
||||
|
||||
QDomElement ddElem = elem.firstChildElement( QStringLiteral( "dd_properties" ) );
|
||||
@ -1185,9 +1184,9 @@ QDomElement QgsPalLayerSettings::writeXml( QDomDocument &doc, const QgsReadWrite
|
||||
renderingElem.setAttribute( QStringLiteral( "minFeatureSize" ), minFeatureSize );
|
||||
renderingElem.setAttribute( QStringLiteral( "limitNumLabels" ), limitNumLabels );
|
||||
renderingElem.setAttribute( QStringLiteral( "maxNumLabels" ), maxNumLabels );
|
||||
renderingElem.setAttribute( QStringLiteral( "obstacle" ), obstacle );
|
||||
renderingElem.setAttribute( QStringLiteral( "obstacleFactor" ), obstacleFactor );
|
||||
renderingElem.setAttribute( QStringLiteral( "obstacleType" ), static_cast< unsigned int >( obstacleType ) );
|
||||
renderingElem.setAttribute( QStringLiteral( "obstacle" ), mObstacleSettings.isObstacle() );
|
||||
renderingElem.setAttribute( QStringLiteral( "obstacleFactor" ), mObstacleSettings.factor() );
|
||||
renderingElem.setAttribute( QStringLiteral( "obstacleType" ), static_cast< unsigned int >( mObstacleSettings.type() ) );
|
||||
renderingElem.setAttribute( QStringLiteral( "zIndex" ), zIndex );
|
||||
|
||||
QDomElement ddElem = doc.createElement( QStringLiteral( "dd_properties" ) );
|
||||
@ -1583,9 +1582,9 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
|
||||
mCurFeat = &f;
|
||||
|
||||
// data defined is obstacle? calculate this first, to avoid wasting time working with obstacles we don't require
|
||||
bool isObstacle = obstacle;
|
||||
bool isObstacle = mObstacleSettings.isObstacle();
|
||||
if ( mDataDefinedProperties.isActive( QgsPalLayerSettings::IsObstacle ) )
|
||||
isObstacle = mDataDefinedProperties.valueAsBool( QgsPalLayerSettings::IsObstacle, context.expressionContext(), obstacle ); // default to layer default
|
||||
isObstacle = mDataDefinedProperties.valueAsBool( QgsPalLayerSettings::IsObstacle, context.expressionContext(), isObstacle ); // default to layer default
|
||||
|
||||
if ( !drawLabels )
|
||||
{
|
||||
@ -2481,7 +2480,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
|
||||
|
||||
( *labelFeature )->setIsObstacle( isObstacle );
|
||||
|
||||
double featObstacleFactor = obstacleFactor;
|
||||
double featObstacleFactor = mObstacleSettings.factor();
|
||||
if ( isObstacle && mDataDefinedProperties.isActive( QgsPalLayerSettings::ObstacleFactor ) )
|
||||
{
|
||||
context.expressionContext().setOriginalValueVariable( featObstacleFactor );
|
||||
@ -2566,7 +2565,7 @@ void QgsPalLayerSettings::registerObstacleFeature( const QgsFeature &f, QgsRende
|
||||
( *obstacleFeature )->setIsObstacle( true );
|
||||
( *obstacleFeature )->setFeature( f );
|
||||
|
||||
double featObstacleFactor = obstacleFactor;
|
||||
double featObstacleFactor = mObstacleSettings.factor();
|
||||
if ( mDataDefinedProperties.isActive( QgsPalLayerSettings::ObstacleFactor ) )
|
||||
{
|
||||
context.expressionContext().setOriginalValueVariable( featObstacleFactor );
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "qgssymbol.h"
|
||||
#include "qgstextrenderer.h"
|
||||
#include "qgspropertycollection.h"
|
||||
#include "qgslabelobstaclesettings.h"
|
||||
|
||||
namespace pal SIP_SKIP
|
||||
{
|
||||
@ -193,7 +194,6 @@ class CORE_EXPORT QgsLabelPosition
|
||||
bool isUnplaced = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsPalLayerSettings
|
||||
@ -311,7 +311,7 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
will be drawn with right alignment*/
|
||||
};
|
||||
|
||||
//TODO QGIS 4.0 - Move to QgsLabelingEngine
|
||||
//TODO QGIS 4.0 - Remove -- moved to QgsLabelEngineObstacleSettings
|
||||
|
||||
/**
|
||||
* Valid obstacle types, which affect how features within the layer will act as obstacles
|
||||
@ -885,27 +885,23 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
*/
|
||||
double minFeatureSize = 0;
|
||||
|
||||
/**
|
||||
* TRUE if features for layer are obstacles to labels of other layers.
|
||||
* \see obstacleFactor
|
||||
* \see obstacleType
|
||||
*/
|
||||
bool obstacle = true;
|
||||
// TODO QGIS 4.0 - remove this junk
|
||||
|
||||
/**
|
||||
* Obstacle factor, where 1.0 = default, < 1.0 more likely to be covered by labels,
|
||||
* > 1.0 less likely to be covered
|
||||
* \see obstacle
|
||||
* \see obstacleType
|
||||
*/
|
||||
double obstacleFactor = 1.0;
|
||||
#ifdef SIP_RUN
|
||||
SIP_PROPERTY( name = obstacle, get = _getIsObstacle, set = _setIsObstacle )
|
||||
SIP_PROPERTY( name = obstacleFactor, get = _getObstacleFactor, set = _setObstacleFactor )
|
||||
SIP_PROPERTY( name = obstacleType, get = _getObstacleType, set = _setObstacleType )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Controls how features act as obstacles for labels.
|
||||
* \see obstacle
|
||||
* \see obstacleFactor
|
||||
*/
|
||||
ObstacleType obstacleType = PolygonBoundary;
|
||||
///@cond PRIVATE
|
||||
bool _getIsObstacle() const { return mObstacleSettings.isObstacle(); }
|
||||
void _setIsObstacle( bool obstacle ) { mObstacleSettings.setIsObstacle( obstacle ); }
|
||||
double _getObstacleFactor() const { return mObstacleSettings.factor(); }
|
||||
void _setObstacleFactor( double factor ) { mObstacleSettings.setFactor( factor ); }
|
||||
ObstacleType _getObstacleType() const { return static_cast< ObstacleType>( mObstacleSettings.type() ); }
|
||||
void _setObstacleType( ObstacleType type ) { mObstacleSettings.setType( static_cast< QgsLabelObstacleSettings::ObstacleType>( type ) ); }
|
||||
|
||||
///@endcond
|
||||
|
||||
//! Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-index
|
||||
double zIndex = 0;
|
||||
@ -1023,6 +1019,28 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
*/
|
||||
void setCallout( QgsCallout *callout SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* Returns the label obstacle settings.
|
||||
* \see setObstacleSettings()
|
||||
* \note Not available in Python bindings
|
||||
* \since QGIS 3.10.2
|
||||
*/
|
||||
const QgsLabelObstacleSettings &obstacleSettings() const { return mObstacleSettings; } SIP_SKIP
|
||||
|
||||
/**
|
||||
* Returns the label obstacle settings.
|
||||
* \see setObstacleSettings()
|
||||
* \since QGIS 3.10.2
|
||||
*/
|
||||
QgsLabelObstacleSettings &obstacleSettings() { return mObstacleSettings; }
|
||||
|
||||
/**
|
||||
* Sets the label obstacle \a settings.
|
||||
* \see obstacleSettings()
|
||||
* \since QGIS 3.10.2
|
||||
*/
|
||||
void setObstacleSettings( const QgsLabelObstacleSettings &settings ) { mObstacleSettings = settings; }
|
||||
|
||||
/**
|
||||
* Returns a pixmap preview for label \a settings.
|
||||
* \param settings label settings
|
||||
@ -1126,6 +1144,8 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
|
||||
std::unique_ptr< QgsCallout > mCallout;
|
||||
|
||||
QgsLabelObstacleSettings mObstacleSettings;
|
||||
|
||||
QgsExpression mGeometryGeneratorExpression;
|
||||
|
||||
bool mRenderStarted = false;
|
||||
@ -1293,4 +1313,5 @@ class CORE_EXPORT QgsPalLabeling
|
||||
friend class QgsPalLayerSettings;
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSPALLABELING_H
|
||||
|
||||
@ -75,11 +75,11 @@ void QgsVectorLayerLabelProvider::init()
|
||||
if ( mLayerGeometryType == QgsWkbTypes::PointGeometry && mRenderer )
|
||||
{
|
||||
//override obstacle type to treat any intersection of a label with the point symbol as a high cost conflict
|
||||
mObstacleType = QgsPalLayerSettings::PolygonWhole;
|
||||
mObstacleType = QgsLabelObstacleSettings::PolygonWhole;
|
||||
}
|
||||
else
|
||||
{
|
||||
mObstacleType = mSettings.obstacleType;
|
||||
mObstacleType = mSettings.obstacleSettings().type();
|
||||
}
|
||||
|
||||
mUpsidedownLabels = mSettings.upsidedownLabels;
|
||||
|
||||
@ -287,11 +287,11 @@ void QgsLabelingGui::setLayer( QgsMapLayer *mapLayer )
|
||||
mOverrunDistanceUnitWidget->setMapUnitScale( mSettings.overrunDistanceMapUnitScale );
|
||||
|
||||
mPrioritySlider->setValue( mSettings.priority );
|
||||
mChkNoObstacle->setChecked( mSettings.obstacle );
|
||||
mObstacleFactorSlider->setValue( mSettings.obstacleFactor * 5 );
|
||||
mObstacleTypeComboBox->setCurrentIndex( mObstacleTypeComboBox->findData( mSettings.obstacleType ) );
|
||||
mPolygonObstacleTypeFrame->setEnabled( mSettings.obstacle );
|
||||
mObstaclePriorityFrame->setEnabled( mSettings.obstacle );
|
||||
mChkNoObstacle->setChecked( mSettings.obstacleSettings().isObstacle() );
|
||||
mObstacleFactorSlider->setValue( mSettings.obstacleSettings().factor() * 5 );
|
||||
mObstacleTypeComboBox->setCurrentIndex( mObstacleTypeComboBox->findData( mSettings.obstacleSettings().type() ) );
|
||||
mPolygonObstacleTypeFrame->setEnabled( mSettings.obstacleSettings().isObstacle() );
|
||||
mObstaclePriorityFrame->setEnabled( mSettings.obstacleSettings().isObstacle() );
|
||||
chkLabelPerFeaturePart->setChecked( mSettings.labelPerPart );
|
||||
mPalShowAllLabelsForLayerChkBx->setChecked( mSettings.displayAll );
|
||||
chkMergeLines->setChecked( mSettings.mergeLines );
|
||||
@ -488,9 +488,9 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
|
||||
lyr.overrunDistanceMapUnitScale = mOverrunDistanceUnitWidget->getMapUnitScale();
|
||||
|
||||
lyr.priority = mPrioritySlider->value();
|
||||
lyr.obstacle = mChkNoObstacle->isChecked() || mMode == ObstaclesOnly;
|
||||
lyr.obstacleFactor = mObstacleFactorSlider->value() / 5.0;
|
||||
lyr.obstacleType = ( QgsPalLayerSettings::ObstacleType )mObstacleTypeComboBox->currentData().toInt();
|
||||
lyr.obstacleSettings().setIsObstacle( mChkNoObstacle->isChecked() || mMode == ObstaclesOnly );
|
||||
lyr.obstacleSettings().setFactor( mObstacleFactorSlider->value() / 5.0 );
|
||||
lyr.obstacleSettings().setType( static_cast< QgsLabelObstacleSettings::ObstacleType >( mObstacleTypeComboBox->currentData().toInt() ) );
|
||||
lyr.labelPerPart = chkLabelPerFeaturePart->isChecked();
|
||||
lyr.displayAll = mPalShowAllLabelsForLayerChkBx->isChecked();
|
||||
lyr.mergeLines = chkMergeLines->isChecked();
|
||||
|
||||
@ -169,8 +169,8 @@ void QgsTextFormatWidget::initWidget()
|
||||
mZIndexSpinBox->setClearValue( 0.0 );
|
||||
mLineDistanceSpnBx->setClearValue( 0.0 );
|
||||
|
||||
mObstacleTypeComboBox->addItem( tr( "Over the Feature's Interior" ), QgsPalLayerSettings::PolygonInterior );
|
||||
mObstacleTypeComboBox->addItem( tr( "Over the Feature's Boundary" ), QgsPalLayerSettings::PolygonBoundary );
|
||||
mObstacleTypeComboBox->addItem( tr( "Over the Feature's Interior" ), QgsLabelObstacleSettings::PolygonInterior );
|
||||
mObstacleTypeComboBox->addItem( tr( "Over the Feature's Boundary" ), QgsLabelObstacleSettings::PolygonBoundary );
|
||||
|
||||
mOffsetTypeComboBox->addItem( tr( "From Point" ), QgsPalLayerSettings::FromPoint );
|
||||
mOffsetTypeComboBox->addItem( tr( "From Symbol Bounds" ), QgsPalLayerSettings::FromSymbolBounds );
|
||||
|
||||
@ -321,7 +321,7 @@ void TestQgsLabelingEngine::testRuleBased()
|
||||
|
||||
QgsPalLayerSettings s1;
|
||||
s1.fieldName = QStringLiteral( "Class" );
|
||||
s1.obstacle = false;
|
||||
s1.obstacleSettings().setIsObstacle( false );
|
||||
s1.dist = 2;
|
||||
QgsTextFormat format = s1.format();
|
||||
format.setColor( QColor( 200, 0, 200 ) );
|
||||
@ -336,7 +336,7 @@ void TestQgsLabelingEngine::testRuleBased()
|
||||
|
||||
QgsPalLayerSettings s2;
|
||||
s2.fieldName = QStringLiteral( "Class" );
|
||||
s2.obstacle = false;
|
||||
s2.obstacleSettings().setIsObstacle( false );
|
||||
s2.dist = 2;
|
||||
format = s2.format();
|
||||
format.setColor( Qt::red );
|
||||
@ -1707,7 +1707,7 @@ void TestQgsLabelingEngine::drawUnplaced()
|
||||
settings.isExpression = true;
|
||||
settings.placement = QgsPalLayerSettings::OverPoint;
|
||||
settings.priority = 3;
|
||||
settings.obstacleFactor = 0;
|
||||
settings.obstacleSettings().setFactor( 0 );
|
||||
|
||||
std::unique_ptr< QgsVectorLayer> vl1( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:4326&field=id:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
|
||||
vl1->setRenderer( new QgsNullSymbolRenderer() );
|
||||
@ -1725,7 +1725,7 @@ void TestQgsLabelingEngine::drawUnplaced()
|
||||
settings.isExpression = true;
|
||||
settings.placement = QgsPalLayerSettings::OverPoint;
|
||||
settings.priority = 5; // higher priority - YY should be placed, not XX
|
||||
settings.obstacleFactor = 0;
|
||||
settings.obstacleSettings().setFactor( 0 );
|
||||
format.setSize( 90 );
|
||||
settings.setFormat( format );
|
||||
|
||||
|
||||
@ -26,7 +26,8 @@ from qgis.core import (QgsLabelingEngineSettings,
|
||||
QgsSingleSymbolRenderer,
|
||||
QgsMarkerSymbol,
|
||||
QgsProperty,
|
||||
QgsVectorLayerSimpleLabeling)
|
||||
QgsVectorLayerSimpleLabeling,
|
||||
QgsLabelObstacleSettings)
|
||||
from utilities import getTempfilePath, renderMapToImage, mapSettingsString
|
||||
|
||||
from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
|
||||
@ -108,6 +109,40 @@ class TestPointPlacement(TestPlacementBase):
|
||||
TestPlacementBase.setUpClass()
|
||||
cls.layer = None
|
||||
|
||||
def test_obstacle_settings(self):
|
||||
"""
|
||||
Test obstacle settings
|
||||
"""
|
||||
|
||||
settings = QgsLabelObstacleSettings()
|
||||
settings.setIsObstacle(True)
|
||||
self.assertTrue(settings.isObstacle())
|
||||
settings.setIsObstacle(False)
|
||||
self.assertFalse(settings.isObstacle())
|
||||
|
||||
settings.setFactor(0.1)
|
||||
self.assertEqual(settings.factor(), 0.1)
|
||||
|
||||
settings.setType(QgsLabelObstacleSettings.PolygonWhole)
|
||||
self.assertEqual(settings.type(), QgsLabelObstacleSettings.PolygonWhole)
|
||||
|
||||
# check that compatibility code works
|
||||
pal_settings = QgsPalLayerSettings()
|
||||
pal_settings.obstacle = True
|
||||
self.assertTrue(pal_settings.obstacle)
|
||||
self.assertTrue(pal_settings.obstacleSettings().isObstacle())
|
||||
pal_settings.obstacle = False
|
||||
self.assertFalse(pal_settings.obstacle)
|
||||
self.assertFalse(pal_settings.obstacleSettings().isObstacle())
|
||||
|
||||
pal_settings.obstacleFactor = 0.2
|
||||
self.assertEqual(pal_settings.obstacleFactor, 0.2)
|
||||
self.assertEqual(pal_settings.obstacleSettings().factor(), 0.2)
|
||||
|
||||
pal_settings.obstacleType = QgsPalLayerSettings.PolygonWhole
|
||||
self.assertEqual(pal_settings.obstacleType, QgsPalLayerSettings.PolygonWhole)
|
||||
self.assertEqual(pal_settings.obstacleSettings().type(), QgsLabelObstacleSettings.PolygonWhole)
|
||||
|
||||
def test_point_placement_around(self):
|
||||
# Default point label placement
|
||||
self.layer = TestQgsPalLabeling.loadFeatureLayer('point')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user