QGIS API Documentation 3.99.0-Master (d270888f95f)
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
24#include <QString>
25
26using namespace Qt::StringLiterals;
27
31
33
35//****** IMPORTANT! editing this? make sure you update the move constructor too! *****
36 : mFlags( other.mFlags )
37 , mSearchMethod( other.mSearchMethod )
38 , mMaxLineCandidatesPerCm( other.mMaxLineCandidatesPerCm )
39 , mMaxPolygonCandidatesPerCmSquared( other.mMaxPolygonCandidatesPerCmSquared )
40 , mUnplacedLabelColor( other.mUnplacedLabelColor )
41 , mPlacementVersion( other.mPlacementVersion )
42 , mDefaultTextRenderFormat( other.mDefaultTextRenderFormat )
43 //****** IMPORTANT! editing this? make sure you update the move constructor too! *****
44{
45 mEngineRules.reserve( other.mEngineRules.size() );
46 for ( const auto &rule : other.mEngineRules )
47 {
48 mEngineRules.emplace_back( rule->clone() );
49 }
50}
51
53 : mFlags( other.mFlags )
54 , mSearchMethod( other.mSearchMethod )
55 , mMaxLineCandidatesPerCm( other.mMaxLineCandidatesPerCm )
56 , mMaxPolygonCandidatesPerCmSquared( other.mMaxPolygonCandidatesPerCmSquared )
57 , mUnplacedLabelColor( std::move( other.mUnplacedLabelColor ) )
58 , mPlacementVersion( other.mPlacementVersion )
59 , mDefaultTextRenderFormat( other.mDefaultTextRenderFormat )
60 , mEngineRules( std::move( other.mEngineRules ) )
61{
62}
63
65{
66 if ( &other == this )
67 return *this;
68
69 //****** IMPORTANT! editing this? make sure you update the move assignment operator too! *****
70 mFlags = other.mFlags;
71 mSearchMethod = other.mSearchMethod;
72 mMaxLineCandidatesPerCm = other.mMaxLineCandidatesPerCm;
73 mMaxPolygonCandidatesPerCmSquared = other.mMaxPolygonCandidatesPerCmSquared;
74 mUnplacedLabelColor = other.mUnplacedLabelColor;
75 mPlacementVersion = other.mPlacementVersion;
76 mDefaultTextRenderFormat = other.mDefaultTextRenderFormat;
77 mEngineRules.clear();
78 mEngineRules.reserve( other.mEngineRules.size() );
79 for ( const auto &rule : other.mEngineRules )
80 {
81 mEngineRules.emplace_back( rule->clone() );
82 }
83 //****** IMPORTANT! editing this? make sure you update the move assignment operator too! *****
84 return *this;
85}
86
88{
89 if ( &other == this )
90 return *this;
91
92 mFlags = other.mFlags;
93 mSearchMethod = other.mSearchMethod;
94 mMaxLineCandidatesPerCm = other.mMaxLineCandidatesPerCm;
95 mMaxPolygonCandidatesPerCmSquared = other.mMaxPolygonCandidatesPerCmSquared;
96 mUnplacedLabelColor = std::move( other.mUnplacedLabelColor );
97 mPlacementVersion = other.mPlacementVersion;
98 mDefaultTextRenderFormat = other.mDefaultTextRenderFormat;
99 mEngineRules = std::move( other.mEngineRules );
100 return *this;
101}
102
107
109{
110 bool saved = false;
111 mSearchMethod = static_cast< Search >( prj->readNumEntry( u"PAL"_s, u"/SearchMethod"_s, static_cast< int >( Chain ), &saved ) );
112 mMaxLineCandidatesPerCm = prj->readDoubleEntry( u"PAL"_s, u"/CandidatesLinePerCM"_s, 5, &saved );
113 mMaxPolygonCandidatesPerCmSquared = prj->readDoubleEntry( u"PAL"_s, u"/CandidatesPolygonPerCM"_s, 2.5, &saved );
114
115 mFlags = Qgis::LabelingFlags();
116 if ( prj->readBoolEntry( u"PAL"_s, u"/ShowingCandidates"_s, false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawCandidates;
117 if ( prj->readBoolEntry( u"PAL"_s, u"/DrawRectOnly"_s, false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawLabelRectOnly;
118 if ( prj->readBoolEntry( u"PAL"_s, u"/ShowingAllLabels"_s, false, &saved ) ) mFlags |= Qgis::LabelingFlag::UseAllLabels;
119 if ( prj->readBoolEntry( u"PAL"_s, u"/ShowingPartialsLabels"_s, true, &saved ) ) mFlags |= Qgis::LabelingFlag::UsePartialCandidates;
120 if ( prj->readBoolEntry( u"PAL"_s, u"/DrawUnplaced"_s, false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawUnplacedLabels;
121 if ( prj->readBoolEntry( u"PAL"_s, u"/DrawLabelMetrics"_s, false, &saved ) ) mFlags |= Qgis::LabelingFlag::DrawLabelMetrics;
122
123 mDefaultTextRenderFormat = Qgis::TextRenderFormat::AlwaysOutlines;
124 // if users have disabled the older PAL "DrawOutlineLabels" setting, respect that
125 if ( !prj->readBoolEntry( u"PAL"_s, u"/DrawOutlineLabels"_s, true ) )
126 mDefaultTextRenderFormat = Qgis::TextRenderFormat::AlwaysText;
127 // otherwise, prefer the new setting
128 const int projectTextFormat = prj->readNumEntry( u"PAL"_s, u"/TextFormat"_s, -1 );
129 if ( projectTextFormat >= 0 )
130 mDefaultTextRenderFormat = static_cast< Qgis::TextRenderFormat >( projectTextFormat );
131
132 mUnplacedLabelColor = QgsColorUtils::colorFromString( prj->readEntry( u"PAL"_s, u"/UnplacedColor"_s, u"#ff0000"_s ) );
133
134 mPlacementVersion = static_cast< Qgis::LabelPlacementEngineVersion >( prj->readNumEntry( u"PAL"_s, u"/PlacementEngineVersion"_s, static_cast< int >( Qgis::LabelPlacementEngineVersion::Version1 ) ) );
135}
136
138{
139 project->writeEntry( u"PAL"_s, u"/SearchMethod"_s, static_cast< int >( mSearchMethod ) );
140 project->writeEntry( u"PAL"_s, u"/CandidatesLinePerCM"_s, mMaxLineCandidatesPerCm );
141 project->writeEntry( u"PAL"_s, u"/CandidatesPolygonPerCM"_s, mMaxPolygonCandidatesPerCmSquared );
142
143 project->writeEntry( u"PAL"_s, u"/ShowingCandidates"_s, mFlags.testFlag( Qgis::LabelingFlag::DrawCandidates ) );
144 project->writeEntry( u"PAL"_s, u"/DrawRectOnly"_s, mFlags.testFlag( Qgis::LabelingFlag::DrawLabelRectOnly ) );
145 project->writeEntry( u"PAL"_s, u"/DrawUnplaced"_s, mFlags.testFlag( Qgis::LabelingFlag::DrawUnplacedLabels ) );
146 project->writeEntry( u"PAL"_s, u"/ShowingAllLabels"_s, mFlags.testFlag( Qgis::LabelingFlag::UseAllLabels ) );
147 project->writeEntry( u"PAL"_s, u"/ShowingPartialsLabels"_s, mFlags.testFlag( Qgis::LabelingFlag::UsePartialCandidates ) );
148 project->writeEntry( u"PAL"_s, u"/DrawLabelMetrics"_s, mFlags.testFlag( Qgis::LabelingFlag::DrawLabelMetrics ) );
149
150 project->writeEntry( u"PAL"_s, u"/TextFormat"_s, static_cast< int >( mDefaultTextRenderFormat ) );
151
152 project->writeEntry( u"PAL"_s, u"/UnplacedColor"_s, QgsColorUtils::colorToString( mUnplacedLabelColor ) );
153
154 project->writeEntry( u"PAL"_s, u"/PlacementEngineVersion"_s, static_cast< int >( mPlacementVersion ) );
155}
156
157void QgsLabelingEngineSettings::writeXml( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context ) const
158{
159 if ( !mEngineRules.empty() )
160 {
161 QDomElement rulesElement = doc.createElement( u"rules"_s );
162 for ( const auto &rule : mEngineRules )
163 {
164 QDomElement ruleElement = doc.createElement( u"rule"_s );
165 ruleElement.setAttribute( u"id"_s, rule->id() );
166 if ( !rule->name().isEmpty() )
167 ruleElement.setAttribute( u"name"_s, rule->name() );
168 if ( !rule->active() )
169 ruleElement.setAttribute( u"active"_s, u"0"_s );
170 rule->writeXml( doc, ruleElement, context );
171 rulesElement.appendChild( ruleElement );
172 }
173 element.appendChild( rulesElement );
174 }
175}
176
177void QgsLabelingEngineSettings::readXml( const QDomElement &element, const QgsReadWriteContext &context )
178{
179 mEngineRules.clear();
180 {
181 const QDomElement rulesElement = element.firstChildElement( u"rules"_s );
182 const QDomNodeList rules = rulesElement.childNodes();
183 for ( int i = 0; i < rules.length(); i++ )
184 {
185 const QDomElement ruleElement = rules.at( i ).toElement();
186 const QString id = ruleElement.attribute( u"id"_s );
187 const QString name = ruleElement.attribute( u"name"_s );
188 const bool active = ruleElement.attribute( u"active"_s, u"1"_s ).toInt();
189 std::unique_ptr< QgsAbstractLabelingEngineRule > rule( QgsApplication::labelingEngineRuleRegistry()->create( id ) );
190 if ( rule )
191 {
192 rule->setName( name );
193 rule->setActive( active );
194 rule->readXml( ruleElement, context );
195 mEngineRules.emplace_back( std::move( rule ) );
196 }
197 }
198 }
199}
200
202{
203 for ( const auto &rule : mEngineRules )
204 {
205 rule->resolveReferences( project );
206 }
207}
208
210{
211 return mUnplacedLabelColor;
212}
213
215{
216 mUnplacedLabelColor = unplacedLabelColor;
217}
218
223
228
229QList<QgsAbstractLabelingEngineRule *> QgsLabelingEngineSettings::rules()
230{
231 QList<QgsAbstractLabelingEngineRule *> res;
232 for ( const auto &it : mEngineRules )
233 {
234 res << it.get();
235 }
236 return res;
237}
238
239QList<const QgsAbstractLabelingEngineRule *> QgsLabelingEngineSettings::rules() const
240{
241 QList<const QgsAbstractLabelingEngineRule *> res;
242 for ( const auto &it : mEngineRules )
243 {
244 res << it.get();
245 }
246 return res;
247}
248
250{
251 mEngineRules.emplace_back( rule );
252}
253
254void QgsLabelingEngineSettings::setRules( const QList<QgsAbstractLabelingEngineRule *> &rules )
255{
256 mEngineRules.clear();
258 {
259 mEngineRules.emplace_back( rule );
260 }
261}
262
263
@ DrawCandidates
Whether to draw rectangles of generated candidates (good for debugging).
Definition qgis.h:2905
@ DrawLabelMetrics
Whether to render label metric guides (for debugging).
Definition qgis.h:2908
@ DrawUnplacedLabels
Whether to render unplaced labels as an indicator/warning for users.
Definition qgis.h:2906
@ UseAllLabels
Whether to draw all labels even if there would be collisions.
Definition qgis.h:2900
@ DrawLabelRectOnly
Whether to only draw the label rect and not the actual label text (used for unit tests).
Definition qgis.h:2904
@ UsePartialCandidates
Whether to use also label candidates that are partially outside of the map view.
Definition qgis.h:2901
TextRenderFormat
Options for rendering text.
Definition qgis.h:2884
@ AlwaysOutlines
Always render text using path objects (AKA outlines/curves). This setting guarantees the best quality...
Definition qgis.h:2885
@ AlwaysText
Always render text as text objects. While this mode preserves text objects as text for post-processin...
Definition qgis.h:2886
QFlags< LabelingFlag > LabelingFlags
Flags that affect drawing and placement of labels.
Definition qgis.h:2919
LabelPlacementEngineVersion
Labeling placement engine version.
Definition qgis.h:2930
@ Version1
Version 1, matches placement from QGIS <= 3.10.1.
Definition qgis.h:2931
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:112
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.