Skip to content

Commit

Permalink
Add API to set a label placement engine version, which dictates which
Browse files Browse the repository at this point in the history
placement rules should be followed when solving the pal labeling engine
solution.

For new projects it defaults to version 2, but when loading an older project
version 1 is used.

This allows changes to be made to the label placement problem solving without
affecting the placement of labels in existing projects.
  • Loading branch information
nyalldawson committed Nov 27, 2019
1 parent d953f9e commit ff3b4d5
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 0 deletions.
24 changes: 24 additions & 0 deletions python/core/auto_generated/qgslabelingenginesettings.sip.in
Expand Up @@ -43,6 +43,12 @@ Stores global configuration for labeling engine
Falp
};

enum PlacementEngineVersion
{
PlacementEngineVersion1,
PlacementEngineVersion2,
};

QgsLabelingEngineSettings();

void clear();
Expand Down Expand Up @@ -136,6 +142,24 @@ Sets the ``color`` to use when rendering unplaced labels.
.. seealso:: :py:func:`unplacedLabelColor`

.. versionadded:: 3.10
%End

PlacementEngineVersion placementVersion() const;
%Docstring
Returns the placement engine version, which dictates how the label placement problem is solved.

.. seealso:: :py:func:`setPlacementVersion`

.. versionadded:: 3.10.2
%End

void setPlacementVersion( PlacementEngineVersion version );
%Docstring
Sets the placement engine ``version``, which dictates how the label placement problem is solved.

.. seealso:: :py:func:`placementVersion`

.. versionadded:: 3.10.2
%End

};
Expand Down
10 changes: 10 additions & 0 deletions src/core/pal/pal.cpp
Expand Up @@ -514,6 +514,16 @@ int Pal::getPolyP()
return poly_p;
}

QgsLabelingEngineSettings::PlacementEngineVersion Pal::getPlacementVersion() const
{
return mPlacementVersion;
}

void Pal::setPlacementVersion( QgsLabelingEngineSettings::PlacementEngineVersion placementVersion )
{
mPlacementVersion = placementVersion;
}

int Pal::getMinIt()
{
return tabuMaxIt;
Expand Down
17 changes: 17 additions & 0 deletions src/core/pal/pal.h
Expand Up @@ -37,6 +37,7 @@
#include "qgsgeometry.h"
#include "qgsgeos.h"
#include "qgspallabeling.h"
#include "qgslabelingenginesettings.h"
#include <QList>
#include <iostream>
#include <ctime>
Expand Down Expand Up @@ -208,6 +209,20 @@ namespace pal
*/
int getPolyP();

/**
* Returns the placement engine version, which dictates how the label placement problem is solved.
*
* \see setPlacementVersion()
*/
QgsLabelingEngineSettings::PlacementEngineVersion getPlacementVersion() const;

/**
* Sets the placement engine \a version, which dictates how the label placement problem is solved.
*
* \see placementVersion()
*/
void setPlacementVersion( QgsLabelingEngineSettings::PlacementEngineVersion placementVersion );

private:

QHash< QgsAbstractLabelProvider *, Layer * > mLayers;
Expand Down Expand Up @@ -246,6 +261,8 @@ namespace pal
*/
bool showPartial = true;

QgsLabelingEngineSettings::PlacementEngineVersion mPlacementVersion = QgsLabelingEngineSettings::PlacementEngineVersion2;

//! Callback that may be called from PAL to check whether the job has not been canceled in meanwhile
FnIsCanceled fnIsCanceled = nullptr;
//! Application-specific context for the cancellation check function
Expand Down
14 changes: 14 additions & 0 deletions src/core/qgslabelingenginesettings.cpp
Expand Up @@ -53,6 +53,8 @@ void QgsLabelingEngineSettings::readSettingsFromProject( QgsProject *prj )
mDefaultTextRenderFormat = static_cast< QgsRenderContext::TextRenderFormat >( projectTextFormat );

mUnplacedLabelColor = QgsSymbolLayerUtils::decodeColor( prj->readEntry( QStringLiteral( "PAL" ), QStringLiteral( "/UnplacedColor" ), QStringLiteral( "#ff0000" ) ) );

mPlacementVersion = static_cast< PlacementEngineVersion >( prj->readNumEntry( QStringLiteral( "PAL" ), QStringLiteral( "/PlacementEngineVersion" ), static_cast< int >( PlacementEngineVersion1 ) ) );
}

void QgsLabelingEngineSettings::writeSettingsToProject( QgsProject *project )
Expand All @@ -71,6 +73,8 @@ void QgsLabelingEngineSettings::writeSettingsToProject( QgsProject *project )
project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/TextFormat" ), static_cast< int >( mDefaultTextRenderFormat ) );

project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/UnplacedColor" ), QgsSymbolLayerUtils::encodeColor( mUnplacedLabelColor ) );

project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/PlacementEngineVersion" ), mPlacementVersion );
}

QColor QgsLabelingEngineSettings::unplacedLabelColor() const
Expand All @@ -83,4 +87,14 @@ void QgsLabelingEngineSettings::setUnplacedLabelColor( const QColor &unplacedLab
mUnplacedLabelColor = unplacedLabelColor;
}

QgsLabelingEngineSettings::PlacementEngineVersion QgsLabelingEngineSettings::placementVersion() const
{
return mPlacementVersion;
}

void QgsLabelingEngineSettings::setPlacementVersion( PlacementEngineVersion placementVersion )
{
mPlacementVersion = placementVersion;
}


29 changes: 29 additions & 0 deletions src/core/qgslabelingenginesettings.h
Expand Up @@ -58,6 +58,17 @@ class CORE_EXPORT QgsLabelingEngineSettings
Falp
};

/**
* Placement engine version.
*
* \since QGIS 3.10.2
*/
enum PlacementEngineVersion
{
PlacementEngineVersion1, //!< Version 1, matches placement from QGIS <= 3.10.1
PlacementEngineVersion2, //!< Version 2, default for new projects created since 3.10.2
};

QgsLabelingEngineSettings();

//! Returns the configuration to the defaults
Expand Down Expand Up @@ -136,6 +147,22 @@ class CORE_EXPORT QgsLabelingEngineSettings
*/
void setUnplacedLabelColor( const QColor &color );

/**
* Returns the placement engine version, which dictates how the label placement problem is solved.
*
* \see setPlacementVersion()
* \since QGIS 3.10.2
*/
PlacementEngineVersion placementVersion() const;

/**
* Sets the placement engine \a version, which dictates how the label placement problem is solved.
*
* \see placementVersion()
* \since QGIS 3.10.2
*/
void setPlacementVersion( PlacementEngineVersion version );

private:
//! Flags
Flags mFlags;
Expand All @@ -146,6 +173,8 @@ class CORE_EXPORT QgsLabelingEngineSettings

QColor mUnplacedLabelColor = QColor( 255, 0, 0 );

PlacementEngineVersion mPlacementVersion = PlacementEngineVersion2;

QgsRenderContext::TextRenderFormat mDefaultTextRenderFormat = QgsRenderContext::TextFormatAlwaysOutlines;

};
Expand Down
14 changes: 14 additions & 0 deletions tests/src/core/testqgslabelingengine.cpp
Expand Up @@ -133,11 +133,18 @@ void TestQgsLabelingEngine::testEngineSettings()

// getters/setters
QgsLabelingEngineSettings settings;

// default for new projects should be placement engine v2
QCOMPARE( settings.placementVersion(), QgsLabelingEngineSettings::PlacementEngineVersion2 );

settings.setDefaultTextRenderFormat( QgsRenderContext::TextFormatAlwaysText );
QCOMPARE( settings.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysText );
settings.setDefaultTextRenderFormat( QgsRenderContext::TextFormatAlwaysOutlines );
QCOMPARE( settings.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysOutlines );

settings.setPlacementVersion( QgsLabelingEngineSettings::PlacementEngineVersion1 );
QCOMPARE( settings.placementVersion(), QgsLabelingEngineSettings::PlacementEngineVersion1 );

settings.setFlag( QgsLabelingEngineSettings::DrawUnplacedLabels, true );
QVERIFY( settings.testFlag( QgsLabelingEngineSettings::DrawUnplacedLabels ) );
settings.setFlag( QgsLabelingEngineSettings::DrawUnplacedLabels, false );
Expand All @@ -151,6 +158,7 @@ void TestQgsLabelingEngine::testEngineSettings()
settings.setDefaultTextRenderFormat( QgsRenderContext::TextFormatAlwaysText );
settings.setFlag( QgsLabelingEngineSettings::DrawUnplacedLabels, true );
settings.setUnplacedLabelColor( QColor( 0, 255, 0 ) );
settings.setPlacementVersion( QgsLabelingEngineSettings::PlacementEngineVersion2 );
settings.writeSettingsToProject( &p );
QgsLabelingEngineSettings settings2;
settings2.readSettingsFromProject( &p );
Expand All @@ -164,6 +172,7 @@ void TestQgsLabelingEngine::testEngineSettings()
settings2.readSettingsFromProject( &p );
QCOMPARE( settings2.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysOutlines );
QVERIFY( !settings2.testFlag( QgsLabelingEngineSettings::DrawUnplacedLabels ) );
QCOMPARE( settings2.placementVersion(), QgsLabelingEngineSettings::PlacementEngineVersion2 );

// test that older setting is still respected as a fallback
QgsProject p2;
Expand All @@ -175,6 +184,11 @@ void TestQgsLabelingEngine::testEngineSettings()
p2.writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawOutlineLabels" ), true );
settings3.readSettingsFromProject( &p2 );
QCOMPARE( settings3.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysOutlines );

// when opening an older project, labeling engine version should be 1
p2.removeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/PlacementEngineVersion" ) );
settings3.readSettingsFromProject( &p2 );
QCOMPARE( settings3.placementVersion(), QgsLabelingEngineSettings::PlacementEngineVersion1 );
}

void TestQgsLabelingEngine::setDefaultLabelParams( QgsPalLayerSettings &settings )
Expand Down

0 comments on commit ff3b4d5

Please sign in to comment.