Add API to set a label placement engine version, which dictates which

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.
This commit is contained in:
Nyall Dawson 2019-11-27 13:38:56 +10:00
parent d953f9ed0f
commit ff3b4d5a74
6 changed files with 108 additions and 0 deletions

View File

@ -43,6 +43,12 @@ Stores global configuration for labeling engine
Falp
};
enum PlacementEngineVersion
{
PlacementEngineVersion1,
PlacementEngineVersion2,
};
QgsLabelingEngineSettings();
void clear();
@ -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
};

View File

@ -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;

View File

@ -37,6 +37,7 @@
#include "qgsgeometry.h"
#include "qgsgeos.h"
#include "qgspallabeling.h"
#include "qgslabelingenginesettings.h"
#include <QList>
#include <iostream>
#include <ctime>
@ -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;
@ -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

View File

@ -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 )
@ -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
@ -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;
}

View File

@ -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
@ -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;
@ -146,6 +173,8 @@ class CORE_EXPORT QgsLabelingEngineSettings
QColor mUnplacedLabelColor = QColor( 255, 0, 0 );
PlacementEngineVersion mPlacementVersion = PlacementEngineVersion2;
QgsRenderContext::TextRenderFormat mDefaultTextRenderFormat = QgsRenderContext::TextFormatAlwaysOutlines;
};

View File

@ -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 );
@ -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 );
@ -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;
@ -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 )