QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgslabelingenginesettings.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslabelingenginesettings.cpp
3 --------------------------------------
4 Date : April 2017
5 Copyright : (C) 2017 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsapplication.h"
19#include "qgscolorutils.h"
22#include "qgsproject.h"
23
27
29
31//****** IMPORTANT! editing this? make sure you update the move constructor too! *****
32 : mFlags( other.mFlags )
33 , mSearchMethod( other.mSearchMethod )
34 , mMaxLineCandidatesPerCm( other.mMaxLineCandidatesPerCm )
35 , mMaxPolygonCandidatesPerCmSquared( other.mMaxPolygonCandidatesPerCmSquared )
36 , mUnplacedLabelColor( other.mUnplacedLabelColor )
37 , mPlacementVersion( other.mPlacementVersion )
38 , mDefaultTextRenderFormat( other.mDefaultTextRenderFormat )
39 //****** IMPORTANT! editing this? make sure you update the move constructor too! *****
40{
41 mEngineRules.reserve( other.mEngineRules.size() );
42 for ( const auto &rule : other.mEngineRules )
43 {
44 mEngineRules.emplace_back( rule->clone() );
45 }
46}
47
49 : mFlags( other.mFlags )
50 , mSearchMethod( other.mSearchMethod )
51 , mMaxLineCandidatesPerCm( other.mMaxLineCandidatesPerCm )
52 , mMaxPolygonCandidatesPerCmSquared( other.mMaxPolygonCandidatesPerCmSquared )
53 , mUnplacedLabelColor( std::move( other.mUnplacedLabelColor ) )
54 , mPlacementVersion( other.mPlacementVersion )
55 , mDefaultTextRenderFormat( other.mDefaultTextRenderFormat )
56 , mEngineRules( std::move( other.mEngineRules ) )
57{
58}
59
61{
62 if ( &other == this )
63 return *this;
64
65 //****** IMPORTANT! editing this? make sure you update the move assignment operator too! *****
66 mFlags = other.mFlags;
67 mSearchMethod = other.mSearchMethod;
68 mMaxLineCandidatesPerCm = other.mMaxLineCandidatesPerCm;
69 mMaxPolygonCandidatesPerCmSquared = other.mMaxPolygonCandidatesPerCmSquared;
70 mUnplacedLabelColor = other.mUnplacedLabelColor;
71 mPlacementVersion = other.mPlacementVersion;
72 mDefaultTextRenderFormat = other.mDefaultTextRenderFormat;
73 mEngineRules.clear();
74 mEngineRules.reserve( other.mEngineRules.size() );
75 for ( const auto &rule : other.mEngineRules )
76 {
77 mEngineRules.emplace_back( rule->clone() );
78 }
79 //****** IMPORTANT! editing this? make sure you update the move assignment operator too! *****
80 return *this;
81}
82
84{
85 if ( &other == this )
86 return *this;
87
88 mFlags = other.mFlags;
89 mSearchMethod = other.mSearchMethod;
90 mMaxLineCandidatesPerCm = other.mMaxLineCandidatesPerCm;
91 mMaxPolygonCandidatesPerCmSquared = other.mMaxPolygonCandidatesPerCmSquared;
92 mUnplacedLabelColor = std::move( other.mUnplacedLabelColor );
93 mPlacementVersion = other.mPlacementVersion;
94 mDefaultTextRenderFormat = other.mDefaultTextRenderFormat;
95 mEngineRules = std::move( other.mEngineRules );
96 return *this;
97}
98
103
105{
106 bool saved = false;
107 mSearchMethod = static_cast< Search >( prj->readNumEntry( QStringLiteral( "PAL" ), QStringLiteral( "/SearchMethod" ), static_cast< int >( Chain ), &saved ) );
108 mMaxLineCandidatesPerCm = prj->readDoubleEntry( QStringLiteral( "PAL" ), QStringLiteral( "/CandidatesLinePerCM" ), 5, &saved );
109 mMaxPolygonCandidatesPerCmSquared = prj->readDoubleEntry( QStringLiteral( "PAL" ), QStringLiteral( "/CandidatesPolygonPerCM" ), 2.5, &saved );
110
111 mFlags = Qgis::LabelingFlags();
112 if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingCandidates" ), false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawCandidates;
113 if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawRectOnly" ), false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawLabelRectOnly;
114 if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingAllLabels" ), false, &saved ) ) mFlags |= Qgis::LabelingFlag::UseAllLabels;
115 if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingPartialsLabels" ), true, &saved ) ) mFlags |= Qgis::LabelingFlag::UsePartialCandidates;
116 if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawUnplaced" ), false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawUnplacedLabels;
117 if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawLabelMetrics" ), false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawLabelMetrics;
118
119 mDefaultTextRenderFormat = Qgis::TextRenderFormat::AlwaysOutlines;
120 // if users have disabled the older PAL "DrawOutlineLabels" setting, respect that
121 if ( !prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawOutlineLabels" ), true ) )
122 mDefaultTextRenderFormat = Qgis::TextRenderFormat::AlwaysText;
123 // otherwise, prefer the new setting
124 const int projectTextFormat = prj->readNumEntry( QStringLiteral( "PAL" ), QStringLiteral( "/TextFormat" ), -1 );
125 if ( projectTextFormat >= 0 )
126 mDefaultTextRenderFormat = static_cast< Qgis::TextRenderFormat >( projectTextFormat );
127
128 mUnplacedLabelColor = QgsColorUtils::colorFromString( prj->readEntry( QStringLiteral( "PAL" ), QStringLiteral( "/UnplacedColor" ), QStringLiteral( "#ff0000" ) ) );
129
130 mPlacementVersion = static_cast< Qgis::LabelPlacementEngineVersion >( prj->readNumEntry( QStringLiteral( "PAL" ), QStringLiteral( "/PlacementEngineVersion" ), static_cast< int >( Qgis::LabelPlacementEngineVersion::Version1 ) ) );
131}
132
134{
135 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/SearchMethod" ), static_cast< int >( mSearchMethod ) );
136 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/CandidatesLinePerCM" ), mMaxLineCandidatesPerCm );
137 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/CandidatesPolygonPerCM" ), mMaxPolygonCandidatesPerCmSquared );
138
139 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingCandidates" ), mFlags.testFlag( Qgis::LabelingFlag::DrawCandidates ) );
140 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawRectOnly" ), mFlags.testFlag( Qgis::LabelingFlag::DrawLabelRectOnly ) );
141 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawUnplaced" ), mFlags.testFlag( Qgis::LabelingFlag::DrawUnplacedLabels ) );
142 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingAllLabels" ), mFlags.testFlag( Qgis::LabelingFlag::UseAllLabels ) );
143 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingPartialsLabels" ), mFlags.testFlag( Qgis::LabelingFlag::UsePartialCandidates ) );
144 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawLabelMetrics" ), mFlags.testFlag( Qgis::LabelingFlag::DrawLabelMetrics ) );
145
146 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/TextFormat" ), static_cast< int >( mDefaultTextRenderFormat ) );
147
148 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/UnplacedColor" ), QgsColorUtils::colorToString( mUnplacedLabelColor ) );
149
150 project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/PlacementEngineVersion" ), static_cast< int >( mPlacementVersion ) );
151}
152
153void QgsLabelingEngineSettings::writeXml( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context ) const
154{
155 if ( !mEngineRules.empty() )
156 {
157 QDomElement rulesElement = doc.createElement( QStringLiteral( "rules" ) );
158 for ( const auto &rule : mEngineRules )
159 {
160 QDomElement ruleElement = doc.createElement( QStringLiteral( "rule" ) );
161 ruleElement.setAttribute( QStringLiteral( "id" ), rule->id() );
162 if ( !rule->name().isEmpty() )
163 ruleElement.setAttribute( QStringLiteral( "name" ), rule->name() );
164 if ( !rule->active() )
165 ruleElement.setAttribute( QStringLiteral( "active" ), QStringLiteral( "0" ) );
166 rule->writeXml( doc, ruleElement, context );
167 rulesElement.appendChild( ruleElement );
168 }
169 element.appendChild( rulesElement );
170 }
171}
172
173void QgsLabelingEngineSettings::readXml( const QDomElement &element, const QgsReadWriteContext &context )
174{
175 mEngineRules.clear();
176 {
177 const QDomElement rulesElement = element.firstChildElement( QStringLiteral( "rules" ) );
178 const QDomNodeList rules = rulesElement.childNodes();
179 for ( int i = 0; i < rules.length(); i++ )
180 {
181 const QDomElement ruleElement = rules.at( i ).toElement();
182 const QString id = ruleElement.attribute( QStringLiteral( "id" ) );
183 const QString name = ruleElement.attribute( QStringLiteral( "name" ) );
184 const bool active = ruleElement.attribute( QStringLiteral( "active" ), QStringLiteral( "1" ) ).toInt();
185 std::unique_ptr< QgsAbstractLabelingEngineRule > rule( QgsApplication::labelingEngineRuleRegistry()->create( id ) );
186 if ( rule )
187 {
188 rule->setName( name );
189 rule->setActive( active );
190 rule->readXml( ruleElement, context );
191 mEngineRules.emplace_back( std::move( rule ) );
192 }
193 }
194 }
195}
196
198{
199 for ( const auto &rule : mEngineRules )
200 {
201 rule->resolveReferences( project );
202 }
203}
204
206{
207 return mUnplacedLabelColor;
208}
209
211{
212 mUnplacedLabelColor = unplacedLabelColor;
213}
214
219
224
225QList<QgsAbstractLabelingEngineRule *> QgsLabelingEngineSettings::rules()
226{
227 QList<QgsAbstractLabelingEngineRule *> res;
228 for ( const auto &it : mEngineRules )
229 {
230 res << it.get();
231 }
232 return res;
233}
234
235QList<const QgsAbstractLabelingEngineRule *> QgsLabelingEngineSettings::rules() const
236{
237 QList<const QgsAbstractLabelingEngineRule *> res;
238 for ( const auto &it : mEngineRules )
239 {
240 res << it.get();
241 }
242 return res;
243}
244
246{
247 mEngineRules.emplace_back( rule );
248}
249
250void QgsLabelingEngineSettings::setRules( const QList<QgsAbstractLabelingEngineRule *> &rules )
251{
252 mEngineRules.clear();
254 {
255 mEngineRules.emplace_back( rule );
256 }
257}
258
259
@ DrawCandidates
Whether to draw rectangles of generated candidates (good for debugging).
Definition qgis.h:2847
@ DrawLabelMetrics
Whether to render label metric guides (for debugging).
Definition qgis.h:2850
@ DrawUnplacedLabels
Whether to render unplaced labels as an indicator/warning for users.
Definition qgis.h:2848
@ UseAllLabels
Whether to draw all labels even if there would be collisions.
Definition qgis.h:2842
@ DrawLabelRectOnly
Whether to only draw the label rect and not the actual label text (used for unit tests).
Definition qgis.h:2846
@ UsePartialCandidates
Whether to use also label candidates that are partially outside of the map view.
Definition qgis.h:2843
TextRenderFormat
Options for rendering text.
Definition qgis.h:2826
@ AlwaysOutlines
Always render text using path objects (AKA outlines/curves). This setting guarantees the best quality...
Definition qgis.h:2827
@ AlwaysText
Always render text as text objects. While this mode preserves text objects as text for post-processin...
Definition qgis.h:2828
QFlags< LabelingFlag > LabelingFlags
Flags that affect drawing and placement of labels.
Definition qgis.h:2861
LabelPlacementEngineVersion
Labeling placement engine version.
Definition qgis.h:2872
@ Version1
Version 1, matches placement from QGIS <= 3.10.1.
Definition qgis.h:2873
Abstract base class for labeling engine rules.
static QgsLabelingEngineRuleRegistry * labelingEngineRuleRegistry()
Gets the registry of available labeling engine rules.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID.
void writeSettingsToProject(QgsProject *project)
Write configuration of the labeling engine to a project.
void setPlacementVersion(Qgis::LabelPlacementEngineVersion version)
Sets the placement engine version, which dictates how the label placement problem is solved.
void setRules(const QList< QgsAbstractLabelingEngineRule * > &rules)
Sets the labeling engine rules which must be satisfied while placing labels.
Search
Search methods in the PAL library to remove colliding labels (methods have different processing speed...
QColor unplacedLabelColor() const
Returns the color to use when rendering unplaced labels.
Qgis::LabelPlacementEngineVersion placementVersion() const
Returns the placement engine version, which dictates how the label placement problem is solved.
void clear()
Returns the configuration to the defaults.
void setUnplacedLabelColor(const QColor &color)
Sets the color to use when rendering unplaced labels.
void addRule(QgsAbstractLabelingEngineRule *rule)
Adds a labeling engine rule which must be satisfied while placing labels.
QList< QgsAbstractLabelingEngineRule * > rules()
Returns a list of labeling engine rules which must be satisfied while placing labels.
void writeXml(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context) const
Writes the label engine settings to an XML element.
QgsLabelingEngineSettings & operator=(const QgsLabelingEngineSettings &other)
void readSettingsFromProject(QgsProject *project)
Read configuration of the labeling engine from a project.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the label engine settings from an XML element.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:109
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
Reads an integer from the specified scope and key.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
Reads a boolean from the specified scope and key.
double readDoubleEntry(const QString &scope, const QString &key, double def=0, bool *ok=nullptr) const
Reads a double from the specified scope and key.
bool writeEntry(const QString &scope, const QString &key, bool value)
Write a boolean value to the project file.
A container for the context for various read/write operations on objects.