QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
qgsvectorlayerlabeling.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayerlabeling.cpp
3 ---------------------
4 begin : September 2015
5 copyright : (C) 2015 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 ***************************************************************************/
16
17#include "qgspallabeling.h"
19#include "qgsvectorlayer.h"
20#include "qgssymbollayerutils.h"
21#include "qgssymbollayer.h"
23#include "qgis.h"
25#include "qgsmarkersymbol.h"
26
28{
29 const QString type = element.attribute( QStringLiteral( "type" ) );
30 if ( type == QLatin1String( "rule-based" ) )
31 {
32 return QgsRuleBasedLabeling::create( element, context );
33 }
34 else if ( type == QLatin1String( "simple" ) )
35 {
36 return QgsVectorLayerSimpleLabeling::create( element, context );
37 }
38 else
39 {
40 return nullptr;
41 }
42}
43
45{
46 return true;
47}
48
50{
54
55 switch ( layer->geometryType() )
56 {
57 case Qgis::GeometryType::Point:
60 break;
61 case Qgis::GeometryType::Line:
63 break;
64 case Qgis::GeometryType::Polygon:
66 break;
67
68 case Qgis::GeometryType::Unknown:
69 case Qgis::GeometryType::Null:
70 break;
71 }
72 return settings;
73}
74
76{
77 return new QgsVectorLayerLabelProvider( layer, QString(), false, mSettings.get() );
78}
79
81 : mSettings( new QgsPalLayerSettings( settings ) )
82{
83
84}
85
87{
88 return QStringLiteral( "simple" );
89}
90
92{
93 return new QgsVectorLayerSimpleLabeling( *mSettings );
94}
95
96QDomElement QgsVectorLayerSimpleLabeling::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
97{
98 QDomElement elem = doc.createElement( QStringLiteral( "labeling" ) );
99 elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "simple" ) );
100 elem.appendChild( mSettings->writeXml( doc, context ) );
101 return elem;
102}
103
105{
106 Q_UNUSED( providerId )
107 return *mSettings;
108}
109
111{
112 if ( mSettings )
113 {
114 QgsStyleLabelSettingsEntity entity( *mSettings );
115 if ( !visitor->visit( &entity ) )
116 return false;
117 }
118 return true;
119}
120
122{
123 return mSettings->containsAdvancedEffects();
124}
125
127{
128 const QDomElement settingsElem = element.firstChildElement( QStringLiteral( "settings" ) );
129 if ( !settingsElem.isNull() )
130 {
132 settings.readXml( settingsElem, context );
134 }
135
137}
138
140{
141 double quadOffsetX = 0.5, quadOffsetY = 0.5;
142
143 // adjust quadrant offset of labels
144 switch ( quadrantPosition )
145 {
146 case Qgis::LabelQuadrantPosition::AboveLeft:
147 quadOffsetX = 1;
148 quadOffsetY = 0;
149 break;
150 case Qgis::LabelQuadrantPosition::Above:
151 quadOffsetX = 0.5;
152 quadOffsetY = 0;
153 break;
154 case Qgis::LabelQuadrantPosition::AboveRight:
155 quadOffsetX = 0;
156 quadOffsetY = 0;
157 break;
158 case Qgis::LabelQuadrantPosition::Left:
159 quadOffsetX = 1;
160 quadOffsetY = 0.5;
161 break;
162 case Qgis::LabelQuadrantPosition::Right:
163 quadOffsetX = 0;
164 quadOffsetY = 0.5;
165 break;
166 case Qgis::LabelQuadrantPosition::BelowLeft:
167 quadOffsetX = 1;
168 quadOffsetY = 1;
169 break;
170 case Qgis::LabelQuadrantPosition::Below:
171 quadOffsetX = 0.5;
172 quadOffsetY = 1;
173 break;
174 case Qgis::LabelQuadrantPosition::BelowRight:
175 quadOffsetX = 0;
176 quadOffsetY = 1.0;
177 break;
178 case Qgis::LabelQuadrantPosition::Over:
179 break;
180 }
181
182 return QPointF( quadOffsetX, quadOffsetY );
183}
184
185/*
186 * This is not a generic function encoder, just enough to encode the label case control functions
187 */
188void appendSimpleFunction( QDomDocument &doc, QDomElement &parent, const QString &name, const QString &attribute )
189{
190 QDomElement function = doc.createElement( QStringLiteral( "ogc:Function" ) );
191 function.setAttribute( QStringLiteral( "name" ), name );
192 parent.appendChild( function );
193 QDomElement property = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
194 property.appendChild( doc.createTextNode( attribute ) );
195 function.appendChild( property );
196}
197
198std::unique_ptr<QgsMarkerSymbolLayer> backgroundToMarkerLayer( const QgsTextBackgroundSettings &settings )
199{
200 std::unique_ptr<QgsMarkerSymbolLayer> layer;
201 switch ( settings.type() )
202 {
204 {
206 svg->setStrokeWidth( settings.strokeWidth() );
207 svg->setStrokeWidthUnit( settings.strokeWidthUnit() );
208 layer.reset( svg );
209 break;
210 }
212 {
213 // just grab the first layer and hope for the best
214 if ( settings.markerSymbol() && settings.markerSymbol()->symbolLayerCount() > 0 )
215 {
216 layer.reset( static_cast< QgsMarkerSymbolLayer * >( settings.markerSymbol()->symbolLayer( 0 )->clone() ) );
217 break;
218 }
219 FALLTHROUGH // not set, just go with the default
220 }
225 {
227 // default value
229 switch ( settings.type() )
230 {
234 break;
238 break;
241 break;
242 }
243
244 marker->setShape( shape );
245 marker->setStrokeWidth( settings.strokeWidth() );
246 marker->setStrokeWidthUnit( settings.strokeWidthUnit() );
247 layer.reset( marker );
248 }
249 }
250 layer->setEnabled( true );
251 // a marker does not have a size x and y, just a size (and it should be at least one)
252 const QSizeF size = settings.size();
253 layer->setSize( std::max( 1., std::max( size.width(), size.height() ) ) );
254 layer->setSizeUnit( settings.sizeUnit() );
255 // fill and stroke
256 QColor fillColor = settings.fillColor();
257 QColor strokeColor = settings.strokeColor();
258 if ( settings.opacity() < 1 )
259 {
260 const int alpha = std::round( settings.opacity() * 255 );
261 fillColor.setAlpha( alpha );
262 strokeColor.setAlpha( alpha );
263 }
264 layer->setFillColor( fillColor );
265 layer->setStrokeColor( strokeColor );
266 // rotation
268 {
269 layer->setAngle( settings.rotation() );
270 }
271 // offset
272 layer->setOffset( settings.offset() );
273 layer->setOffsetUnit( settings.offsetUnit() );
274
275 return layer;
276}
277
278void QgsAbstractVectorLayerLabeling::writeTextSymbolizer( QDomNode &parent, QgsPalLayerSettings &settings, const QVariantMap &props ) const
279{
280 QDomDocument doc = parent.ownerDocument();
281
282 // text symbolizer
283 QDomElement textSymbolizerElement = doc.createElement( QStringLiteral( "se:TextSymbolizer" ) );
284 parent.appendChild( textSymbolizerElement );
285
286 // label
287 QgsTextFormat format = settings.format();
288 const QFont font = format.font();
289 QDomElement labelElement = doc.createElement( QStringLiteral( "se:Label" ) );
290 textSymbolizerElement.appendChild( labelElement );
292 {
293 labelElement.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( settings.getLabelExpression()->dump() ) ) );
294 labelElement.appendChild( doc.createTextNode( "Placeholder" ) );
295 }
296 else
297 {
298 Qgis::Capitalization capitalization = format.capitalization();
299 if ( capitalization == Qgis::Capitalization::MixedCase && font.capitalization() != QFont::MixedCase )
300 capitalization = static_cast< Qgis::Capitalization >( font.capitalization() );
301 if ( capitalization == Qgis::Capitalization::AllUppercase )
302 {
303 appendSimpleFunction( doc, labelElement, QStringLiteral( "strToUpperCase" ), settings.fieldName );
304 }
305 else if ( capitalization == Qgis::Capitalization::AllLowercase )
306 {
307 appendSimpleFunction( doc, labelElement, QStringLiteral( "strToLowerCase" ), settings.fieldName );
308 }
309 else if ( capitalization == Qgis::Capitalization::ForceFirstLetterToCapital )
310 {
311 appendSimpleFunction( doc, labelElement, QStringLiteral( "strCapitalize" ), settings.fieldName );
312 }
313 else
314 {
315 QDomElement propertyNameElement = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
316 propertyNameElement.appendChild( doc.createTextNode( settings.fieldName ) );
317 labelElement.appendChild( propertyNameElement );
318 }
319 }
320
321 // font
322 QDomElement fontElement = doc.createElement( QStringLiteral( "se:Font" ) );
323 textSymbolizerElement.appendChild( fontElement );
324 fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-family" ), font.family() ) );
325 const double fontSize = QgsSymbolLayerUtils::rescaleUom( format.size(), format.sizeUnit(), props );
326 fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-size" ), QString::number( fontSize ) ) );
327 if ( format.font().italic() )
328 {
329 fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-style" ), QStringLiteral( "italic" ) ) );
330 }
331 if ( format.font().bold() )
332 {
333 fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-weight" ), QStringLiteral( "bold" ) ) );
334 }
335
336 // label placement
337 QDomElement labelPlacement = doc.createElement( QStringLiteral( "se:LabelPlacement" ) );
338 textSymbolizerElement.appendChild( labelPlacement );
339 double maxDisplacement = 0;
340 double repeatDistance = 0;
341 switch ( settings.placement )
342 {
344 {
345 QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
346 labelPlacement.appendChild( pointPlacement );
347 // anchor point
348 const QPointF anchor = quadOffsetToSldAnchor( settings.quadOffset );
349 QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, anchor );
350 // displacement
351 if ( settings.xOffset > 0 || settings.yOffset > 0 )
352 {
353 const Qgis::RenderUnit offsetUnit = settings.offsetUnits;
354 const double dx = QgsSymbolLayerUtils::rescaleUom( settings.xOffset, offsetUnit, props );
355 const double dy = QgsSymbolLayerUtils::rescaleUom( settings.yOffset, offsetUnit, props );
356 QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( dx, dy ) );
357 }
358 // rotation
359 if ( settings.angleOffset != 0 )
360 {
361 QDomElement rotation = doc.createElement( "se:Rotation" );
362 pointPlacement.appendChild( rotation );
363 rotation.appendChild( doc.createTextNode( QString::number( settings.angleOffset ) ) );
364 }
365 }
366 break;
369 {
370 QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
371 labelPlacement.appendChild( pointPlacement );
372
373 // SLD cannot do either, but let's do a best effort setting the distance using
374 // anchor point and displacement
375 QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0, 0.5 ) );
376 const Qgis::RenderUnit distUnit = settings.distUnits;
377 const double radius = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
378 const double offset = std::sqrt( radius * radius / 2 ); // make it start top/right
379 maxDisplacement = radius + 1; // lock the distance
380 QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( offset, offset ) );
381 }
382 break;
386 {
387 // still a point placement (for "free" it's a fallback, there is no SLD equivalent)
388 QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
389 labelPlacement.appendChild( pointPlacement );
390 QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0.5, 0.5 ) );
391 const Qgis::RenderUnit distUnit = settings.distUnits;
392 const double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
393 QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( 0, dist ) );
394 break;
395 }
399 {
400 QDomElement linePlacement = doc.createElement( "se:LinePlacement" );
401 labelPlacement.appendChild( linePlacement );
402
403 // perpendicular distance if required
404 if ( settings.dist > 0 )
405 {
406 const Qgis::RenderUnit distUnit = settings.distUnits;
407 const double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
408 QDomElement perpendicular = doc.createElement( "se:PerpendicularOffset" );
409 linePlacement.appendChild( perpendicular );
410 perpendicular.appendChild( doc.createTextNode( qgsDoubleToString( dist, 2 ) ) );
411 }
412
413 // repeat distance if required
414 if ( settings.repeatDistance > 0 )
415 {
416 QDomElement repeat = doc.createElement( "se:Repeat" );
417 linePlacement.appendChild( repeat );
418 repeat.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
419 QDomElement gap = doc.createElement( "se:Gap" );
420 linePlacement.appendChild( gap );
422 gap.appendChild( doc.createTextNode( qgsDoubleToString( repeatDistance, 2 ) ) );
423 }
424
425 // always generalized
426 QDomElement generalize = doc.createElement( "se:GeneralizeLine" );
427 linePlacement.appendChild( generalize );
428 generalize.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
429 }
430 break;
431 }
432
433 // halo
434 const QgsTextBufferSettings buffer = format.buffer();
435 if ( buffer.enabled() )
436 {
437 QDomElement haloElement = doc.createElement( QStringLiteral( "se:Halo" ) );
438 textSymbolizerElement.appendChild( haloElement );
439
440 QDomElement radiusElement = doc.createElement( QStringLiteral( "se:Radius" ) );
441 haloElement.appendChild( radiusElement );
442 // the SLD uses a radius, which is actually half of the link thickness the buffer size specifies
443 const double radius = QgsSymbolLayerUtils::rescaleUom( buffer.size(), buffer.sizeUnit(), props ) / 2;
444 radiusElement.appendChild( doc.createTextNode( qgsDoubleToString( radius ) ) );
445
446 QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
447 haloElement.appendChild( fillElement );
448 fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), buffer.color().name() ) );
449 if ( buffer.opacity() != 1 )
450 {
451 fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( buffer.opacity() ) ) );
452 }
453 }
454
455 // fill
456 QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
457 textSymbolizerElement.appendChild( fillElement );
458 fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), format.color().name() ) );
459 if ( format.opacity() != 1 )
460 {
461 fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( format.opacity() ) ) );
462 }
463
464 // background graphic (not supported by SE 1.1, but supported by the GeoTools ecosystem as an extension)
465 const QgsTextBackgroundSettings background = format.background();
466 if ( background.enabled() )
467 {
468 std::unique_ptr<QgsMarkerSymbolLayer> layer = backgroundToMarkerLayer( background );
469 layer->writeSldMarker( doc, textSymbolizerElement, props );
470 }
471
472 // priority and zIndex, the default values are 0 and 5 in qgis (and between 0 and 10),
473 // in the GeoTools ecosystem there is a single priority value set at 1000 by default
474 if ( settings.priority != 5 || settings.zIndex > 0 )
475 {
476 QDomElement priorityElement = doc.createElement( QStringLiteral( "se:Priority" ) );
477 textSymbolizerElement.appendChild( priorityElement );
478 int priority = 500 + 1000 * settings.zIndex + ( settings.priority - 5 ) * 100;
479 if ( settings.priority == 0 && settings.zIndex > 0 )
480 {
481 // small adjustment to make sure labels in z index n+1 are all above level n despite the priority value
482 priority += 1;
483 }
484 priorityElement.appendChild( doc.createTextNode( QString::number( priority ) ) );
485 }
486
487 // vendor options for text appearance
488 if ( font.underline() )
489 {
490 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "underlineText" ), QStringLiteral( "true" ) );
491 textSymbolizerElement.appendChild( vo );
492 }
493 if ( font.strikeOut() )
494 {
495 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "strikethroughText" ), QStringLiteral( "true" ) );
496 textSymbolizerElement.appendChild( vo );
497 }
498 // vendor options for text positioning
499 if ( maxDisplacement > 0 )
500 {
501 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxDisplacement" ), qgsDoubleToString( maxDisplacement, 2 ) );
502 textSymbolizerElement.appendChild( vo );
503 }
504
505 switch ( settings.placement )
506 {
509 {
510 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "followLine" ), QStringLiteral( "true" ) );
511 textSymbolizerElement.appendChild( vo );
513 {
514 // SLD has no notion for this, the GeoTools ecosystem can only do a single angle
515 const double angle = std::min( std::fabs( settings.maxCurvedCharAngleIn ), std::fabs( settings.maxCurvedCharAngleOut ) );
516 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxAngleDelta" ), qgsDoubleToString( angle ) );
517 textSymbolizerElement.appendChild( vo );
518 }
519 break;
520 }
521
529 break;
530 }
531
532 if ( repeatDistance > 0 )
533 {
534 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "repeat" ), qgsDoubleToString( repeatDistance, 2 ) );
535 textSymbolizerElement.appendChild( vo );
536 }
537 // miscellaneous options
539 {
541 break;
544 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "conflictResolution" ), QStringLiteral( "false" ) );
545 textSymbolizerElement.appendChild( vo );
546 break;
547 }
548 if ( settings.upsidedownLabels == Qgis::UpsideDownLabelHandling::AlwaysAllowUpsideDown )
549 {
550 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "forceLeftToRight" ), QStringLiteral( "false" ) );
551 textSymbolizerElement.appendChild( vo );
552 }
554 {
555 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "group" ), QStringLiteral( "yes" ) );
556 textSymbolizerElement.appendChild( vo );
558 {
559 const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "labelAllGroup" ), QStringLiteral( "true" ) );
560 textSymbolizerElement.appendChild( vo );
561 }
562 }
563 // background symbol resize handling
564 if ( background.enabled() )
565 {
566 // enable resizing if needed
567 switch ( background.sizeType() )
568 {
570 {
571 QString resizeType;
573 {
574 resizeType = QStringLiteral( "stretch" );
575 }
576 else
577 {
578 resizeType = QStringLiteral( "proportional" );
579 }
580 const QDomElement voResize = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-resize" ), resizeType );
581 textSymbolizerElement.appendChild( voResize );
582
583 // now hadle margin
584 const QSizeF size = background.size();
585 if ( size.width() > 0 || size.height() > 0 )
586 {
587 double x = QgsSymbolLayerUtils::rescaleUom( size.width(), background.sizeUnit(), props );
588 double y = QgsSymbolLayerUtils::rescaleUom( size.height(), background.sizeUnit(), props );
589 // in case of ellipse qgis pads the size generously to make sure the text is inside the ellipse
590 // the following seems to do the trick and keep visual output similar
591 if ( background.type() == QgsTextBackgroundSettings::ShapeEllipse )
592 {
593 x += fontSize / 2;
594 y += fontSize;
595 }
596 const QString resizeSpec = QString( "%1 %2" ).arg( qgsDoubleToString( x, 2 ), qgsDoubleToString( y, 2 ) );
597 const QDomElement voMargin = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-margin" ), resizeSpec );
598 textSymbolizerElement.appendChild( voMargin );
599 }
600 break;
601 }
604 // nothing to do here
605 break;
606 }
607 }
608}
609
610
611void QgsVectorLayerSimpleLabeling::toSld( QDomNode &parent, const QVariantMap &props ) const
612{
613
614 if ( mSettings->drawLabels )
615 {
616 QDomDocument doc = parent.ownerDocument();
617
618 QDomElement ruleElement = doc.createElement( QStringLiteral( "se:Rule" ) );
619 parent.appendChild( ruleElement );
620
621 // scale dependencies
622 if ( mSettings->scaleVisibility )
623 {
624 QVariantMap scaleProps = QVariantMap();
625 // tricky here, the max scale is expressed as its denominator, but it's still the max scale
626 // in other words, the smallest scale denominator....
627 scaleProps.insert( "scaleMinDenom", qgsDoubleToString( mSettings->maximumScale ) );
628 scaleProps.insert( "scaleMaxDenom", qgsDoubleToString( mSettings->minimumScale ) );
629 QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElement, scaleProps );
630 }
631
632 writeTextSymbolizer( ruleElement, *mSettings, props );
633 }
634
635}
636
638{
639 QgsTextFormat format { mSettings->format() };
640 format.multiplyOpacity( opacityFactor );
641 mSettings->setFormat( format );
642}
643
644void QgsVectorLayerSimpleLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
645{
646 Q_UNUSED( providerId )
647
648 if ( mSettings.get() == settings )
649 return;
650
651 mSettings.reset( settings );
652}
@ FromSymbolBounds
Offset distance applies from rendered symbol bounds.
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
@ Curved
Arranges candidates following the curvature of a line feature. Applies to line layers only.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ Free
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...
@ OrderedPositionsAroundPoint
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
@ PerimeterCurved
Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
@ OutsidePolygons
Candidates are placed outside of polygon boundaries. Applies to polygon layers only....
MarkerShape
Marker shapes.
Definition: qgis.h:2067
Capitalization
String capitalization options.
Definition: qgis.h:2323
@ MixedCase
Mixed case, ie no change.
@ AllLowercase
Convert all characters to lowercase.
@ ForceFirstLetterToCapital
Convert just the first letter of each word to uppercase, leave the rest untouched.
@ AllUppercase
Convert all characters to uppercase.
LabelQuadrantPosition
Label quadrant positions.
Definition: qgis.h:842
RenderUnit
Rendering size units.
Definition: qgis.h:3441
@ AllowOverlapAtNoCost
Labels may freely overlap other labels, at no cost.
@ AllowOverlapIfRequired
Avoids overlapping labels when possible, but permit overlaps if labels for features cannot otherwise ...
@ PreventOverlap
Do not allow labels to overlap other labels.
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the labeling...
virtual void writeTextSymbolizer(QDomNode &parent, QgsPalLayerSettings &settings, const QVariantMap &props) const
Writes a TextSymbolizer element contents based on the provided labeling settings.
static QgsAbstractVectorLayerLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Try to create instance of an implementation based on the XML data.
virtual QgsPalLayerSettings settings(const QString &providerId=QString()) const =0
Gets associated label settings.
static QgsPalLayerSettings defaultSettingsForLayer(const QgsVectorLayer *layer)
Returns the default layer settings to use for the specified vector layer.
virtual QString type() const =0
Unique type string of the labeling configuration implementation.
QString dump() const
Returns an expression string, constructed from the internal abstract syntax tree.
bool mergeLines() const
Returns true if connected line features with identical label text should be merged prior to generatin...
Qgis::LabelOverlapHandling overlapHandling() const
Returns the technique used to handle overlapping labels.
QgsProject * project() const
Returns the parent project if this map layer is added to a project.
Abstract base class for marker symbol layers.
Contains settings for how a map layer will be labeled.
double yOffset
Vertical offset of label.
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
double maxCurvedCharAngleIn
Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
Qgis::LabelOffsetType offsetType
Offset type for layer (only applies in certain placement modes)
double xOffset
Horizontal offset of label.
Qgis::LabelPlacement placement
Label placement mode.
QgsExpression * getLabelExpression()
Returns the QgsExpression for this label settings.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
Qgis::LabelQuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
double repeatDistance
Distance for repeating labels for a single feature.
int priority
Label priority.
bool labelPerPart
true if every part of a multi-part feature should be labeled.
double angleOffset
Label rotation, in degrees clockwise.
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0)
Qgis::RenderUnit offsetUnits
Units for offsets of label.
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
double dist
Distance from feature to the label.
Qgis::RenderUnit distUnits
Units the distance from feature to the label.
Qgis::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
Qgis::UpsideDownLabelHandling upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
QString fieldName
Name of field (or an expression) to use for label text.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
The class is used as a container of context for various read/write operations on other objects.
static QgsRuleBasedLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Create the instance from a DOM element with saved configuration.
void setShape(Qgis::MarkerShape shape)
Sets the rendered marker shape.
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
void setStrokeWidthUnit(Qgis::RenderUnit u)
Sets the unit for the width of the marker's stroke.
void setStrokeWidth(double w)
Sets the width of the marker's stroke.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A label settings entity for QgsStyle databases.
Definition: qgsstyle.h:1434
static QgsTextFormat defaultTextFormatForProject(QgsProject *project, QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling)
Returns the default text format to use for new text based objects for the specified project,...
Definition: qgsstyle.cpp:1223
void setStrokeWidthUnit(Qgis::RenderUnit unit)
Sets the units for the stroke width.
static void createAnchorPointElement(QDomDocument &doc, QDomElement &element, QPointF anchor)
Creates a SE 1.1 anchor point element as a child of the specified element.
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QVariantMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QDomElement createSvgParameterElement(QDomDocument &doc, const QString &name, const QString &value)
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:759
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:216
Container for settings relating to a text background object.
RotationType rotationType() const
Returns the method used for rotating the background shape.
QString svgFile() const
Returns the absolute path to the background SVG file, if set.
QSizeF size() const
Returns the size of the background shape.
@ SizePercent
Shape size is determined by percent of text size.
@ SizeBuffer
Shape size is determined by adding a buffer margin around text.
bool enabled() const
Returns whether the background is enabled.
double opacity() const
Returns the background shape's opacity.
double rotation() const
Returns the rotation for the background shape, in degrees clockwise.
QColor fillColor() const
Returns the color used for filing the background shape.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
Qgis::RenderUnit strokeWidthUnit() const
Returns the units used for the shape's stroke width.
ShapeType type() const
Returns the type of background shape (e.g., square, ellipse, SVG).
double strokeWidth() const
Returns the width of the shape's stroke (stroke).
@ ShapeSquare
Square - buffered sizes only.
Qgis::RenderUnit offsetUnit() const
Returns the units used for the shape's offset.
QColor strokeColor() const
Returns the color used for outlining the background shape.
Qgis::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
@ RotationFixed
Shape rotation is a fixed angle.
QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol to be rendered in the background.
QPointF offset() const
Returns the offset used for drawing the background shape.
Container for settings relating to a text buffer.
Qgis::RenderUnit sizeUnit() const
Returns the units for the buffer size.
double size() const
Returns the size of the buffer.
bool enabled() const
Returns whether the buffer is enabled.
double opacity() const
Returns the buffer opacity.
QColor color() const
Returns the color of the buffer.
Container for all settings relating to text rendering.
Definition: qgstextformat.h:42
Qgis::Capitalization capitalization() const
Returns the text capitalization style.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
Qgis::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
double opacity() const
Returns the text's opacity.
double size() const
Returns the size for rendered text.
QColor color() const
Returns the color that text will be rendered in.
QFont font() const
Returns the font used for rendering text.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
Basic implementation of the labeling interface.
QString type() const override
Unique type string of the labeling configuration implementation.
void multiplyOpacity(double opacityFactor) override
Multiply opacity by opacityFactor.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the labeling...
QgsPalLayerSettings settings(const QString &providerId=QString()) const override
Gets associated label settings.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const override
Returns labeling configuration as XML element.
bool requiresAdvancedEffects() const override
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
QgsVectorLayerSimpleLabeling(const QgsPalLayerSettings &settings)
Constructs simple labeling configuration with given initial settings.
void setSettings(QgsPalLayerSettings *settings, const QString &providerId=QString()) override
Set pal settings (takes ownership).
QgsVectorLayerLabelProvider * provider(QgsVectorLayer *layer) const override
static QgsVectorLayerSimpleLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Create the instance from a DOM element with saved configuration.
QgsAbstractVectorLayerLabeling * clone() const override
Returns a new copy of the object.
void toSld(QDomNode &parent, const QVariantMap &props) const override
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
QString displayField() const
This is a shorthand for accessing the displayExpression if it is a simple field.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
#define FALLTHROUGH
Definition: qgis.h:4599
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:3927
std::unique_ptr< QgsMarkerSymbolLayer > backgroundToMarkerLayer(const QgsTextBackgroundSettings &settings)
void appendSimpleFunction(QDomDocument &doc, QDomElement &parent, const QString &name, const QString &attribute)
QPointF quadOffsetToSldAnchor(Qgis::LabelQuadrantPosition quadrantPosition)