QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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  ***************************************************************************/
15 #include "qgsvectorlayerlabeling.h"
16 
17 #include "qgspallabeling.h"
18 #include "qgsrulebasedlabeling.h"
19 #include "qgsvectorlayer.h"
20 #include "qgssymbollayerutils.h"
21 #include "qgssymbollayer.h"
22 #include "qgsmarkersymbollayer.h"
23 #include "qgis.h"
24 #include "qgsstyleentityvisitor.h"
25 
26 
28 {
29  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 {
51  return new QgsVectorLayerLabelProvider( layer, QString(), false, mSettings.get() );
52 }
53 
55  : mSettings( new QgsPalLayerSettings( settings ) )
56 {
57 
58 }
59 
61 {
62  return QStringLiteral( "simple" );
63 }
64 
66 {
67  return new QgsVectorLayerSimpleLabeling( *mSettings );
68 }
69 
70 QDomElement QgsVectorLayerSimpleLabeling::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
71 {
72  QDomElement elem = doc.createElement( QStringLiteral( "labeling" ) );
73  elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "simple" ) );
74  elem.appendChild( mSettings->writeXml( doc, context ) );
75  return elem;
76 }
77 
79 {
80  Q_UNUSED( providerId )
81  return *mSettings;
82 }
83 
85 {
86  if ( mSettings )
87  {
88  QgsStyleLabelSettingsEntity entity( *mSettings );
89  if ( !visitor->visit( &entity ) )
90  return false;
91  }
92  return true;
93 }
94 
96 {
97  return mSettings->format().containsAdvancedEffects();
98 }
99 
101 {
102  QDomElement settingsElem = element.firstChildElement( QStringLiteral( "settings" ) );
103  if ( !settingsElem.isNull() )
104  {
106  settings.readXml( settingsElem, context );
108  }
109 
111 }
112 
114 {
115  double quadOffsetX = 0.5, quadOffsetY = 0.5;
116 
117  // adjust quadrant offset of labels
118  switch ( quadrantPosition )
119  {
121  quadOffsetX = 1;
122  quadOffsetY = 0;
123  break;
125  quadOffsetX = 0.5;
126  quadOffsetY = 0;
127  break;
129  quadOffsetX = 0;
130  quadOffsetY = 0;
131  break;
133  quadOffsetX = 1;
134  quadOffsetY = 0.5;
135  break;
137  quadOffsetX = 0;
138  quadOffsetY = 0.5;
139  break;
141  quadOffsetX = 1;
142  quadOffsetY = 1;
143  break;
145  quadOffsetX = 0.5;
146  quadOffsetY = 1;
147  break;
149  quadOffsetX = 0;
150  quadOffsetY = 1.0;
151  break;
153  break;
154  }
155 
156  return QPointF( quadOffsetX, quadOffsetY );
157 }
158 
159 /*
160  * This is not a generic function encoder, just enough to encode the label case control functions
161  */
162 void appendSimpleFunction( QDomDocument &doc, QDomElement &parent, const QString &name, const QString &attribute )
163 {
164  QDomElement function = doc.createElement( QStringLiteral( "ogc:Function" ) );
165  function.setAttribute( QStringLiteral( "name" ), name );
166  parent.appendChild( function );
167  QDomElement property = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
168  property.appendChild( doc.createTextNode( attribute ) );
169  function.appendChild( property );
170 }
171 
172 std::unique_ptr<QgsMarkerSymbolLayer> backgroundToMarkerLayer( const QgsTextBackgroundSettings &settings )
173 {
174  std::unique_ptr<QgsMarkerSymbolLayer> layer;
175  switch ( settings.type() )
176  {
178  {
180  svg->setStrokeWidth( settings.strokeWidth() );
181  svg->setStrokeWidthUnit( settings.strokeWidthUnit() );
182  layer.reset( svg );
183  break;
184  }
186  {
187  // just grab the first layer and hope for the best
188  if ( settings.markerSymbol() && settings.markerSymbol()->symbolLayerCount() > 0 )
189  {
190  layer.reset( static_cast< QgsMarkerSymbolLayer * >( settings.markerSymbol()->symbolLayer( 0 )->clone() ) );
191  break;
192  }
193  FALLTHROUGH // not set, just go with the default
194  }
199  {
201  // default value
203  switch ( settings.type() )
204  {
208  break;
212  break;
215  break;
216  }
217 
218  marker->setShape( shape );
219  marker->setStrokeWidth( settings.strokeWidth() );
220  marker->setStrokeWidthUnit( settings.strokeWidthUnit() );
221  layer.reset( marker );
222  }
223  }
224  layer->setEnabled( true );
225  // a marker does not have a size x and y, just a size (and it should be at least one)
226  QSizeF size = settings.size();
227  layer->setSize( std::max( 1., std::max( size.width(), size.height() ) ) );
228  layer->setSizeUnit( settings.sizeUnit() );
229  // fill and stroke
230  QColor fillColor = settings.fillColor();
231  QColor strokeColor = settings.strokeColor();
232  if ( settings.opacity() < 1 )
233  {
234  int alpha = std::round( settings.opacity() * 255 );
235  fillColor.setAlpha( alpha );
236  strokeColor.setAlpha( alpha );
237  }
238  layer->setFillColor( fillColor );
239  layer->setStrokeColor( strokeColor );
240  // rotation
242  {
243  layer->setAngle( settings.rotation() );
244  }
245  // offset
246  layer->setOffset( settings.offset() );
247  layer->setOffsetUnit( settings.offsetUnit() );
248 
249  return layer;
250 }
251 
252 void QgsAbstractVectorLayerLabeling::writeTextSymbolizer( QDomNode &parent, QgsPalLayerSettings &settings, const QVariantMap &props ) const
253 {
254  QDomDocument doc = parent.ownerDocument();
255 
256  // text symbolizer
257  QDomElement textSymbolizerElement = doc.createElement( QStringLiteral( "se:TextSymbolizer" ) );
258  parent.appendChild( textSymbolizerElement );
259 
260  // label
261  QgsTextFormat format = settings.format();
262  QFont font = format.font();
263  QDomElement labelElement = doc.createElement( QStringLiteral( "se:Label" ) );
264  textSymbolizerElement.appendChild( labelElement );
265  if ( settings.isExpression )
266  {
267  labelElement.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( settings.getLabelExpression()->dump() ) ) );
268  labelElement.appendChild( doc.createTextNode( "Placeholder" ) );
269  }
270  else
271  {
272  QgsStringUtils::Capitalization capitalization = format.capitalization();
273  if ( capitalization == QgsStringUtils::MixedCase && font.capitalization() != QFont::MixedCase )
274  capitalization = static_cast< QgsStringUtils::Capitalization >( font.capitalization() );
275  if ( capitalization == QgsStringUtils::AllUppercase )
276  {
277  appendSimpleFunction( doc, labelElement, QStringLiteral( "strToUpperCase" ), settings.fieldName );
278  }
279  else if ( capitalization == QgsStringUtils::AllLowercase )
280  {
281  appendSimpleFunction( doc, labelElement, QStringLiteral( "strToLowerCase" ), settings.fieldName );
282  }
283  else if ( capitalization == QgsStringUtils::ForceFirstLetterToCapital )
284  {
285  appendSimpleFunction( doc, labelElement, QStringLiteral( "strCapitalize" ), settings.fieldName );
286  }
287  else
288  {
289  QDomElement propertyNameElement = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
290  propertyNameElement.appendChild( doc.createTextNode( settings.fieldName ) );
291  labelElement.appendChild( propertyNameElement );
292  }
293  }
294 
295  // font
296  QDomElement fontElement = doc.createElement( QStringLiteral( "se:Font" ) );
297  textSymbolizerElement.appendChild( fontElement );
298  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-family" ), font.family() ) );
299  double fontSize = QgsSymbolLayerUtils::rescaleUom( format.size(), format.sizeUnit(), props );
300  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-size" ), QString::number( fontSize ) ) );
301  if ( format.font().italic() )
302  {
303  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-style" ), QStringLiteral( "italic" ) ) );
304  }
305  if ( format.font().bold() )
306  {
307  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-weight" ), QStringLiteral( "bold" ) ) );
308  }
309 
310  // label placement
311  QDomElement labelPlacement = doc.createElement( QStringLiteral( "se:LabelPlacement" ) );
312  textSymbolizerElement.appendChild( labelPlacement );
313  double maxDisplacement = 0;
314  double repeatDistance = 0;
315  switch ( settings.placement )
316  {
318  {
319  QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
320  labelPlacement.appendChild( pointPlacement );
321  // anchor point
322  QPointF anchor = quadOffsetToSldAnchor( settings.quadOffset );
323  QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, anchor );
324  // displacement
325  if ( settings.xOffset > 0 || settings.yOffset > 0 )
326  {
328  double dx = QgsSymbolLayerUtils::rescaleUom( settings.xOffset, offsetUnit, props );
329  double dy = QgsSymbolLayerUtils::rescaleUom( settings.yOffset, offsetUnit, props );
330  QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( dx, dy ) );
331  }
332  // rotation
333  if ( settings.angleOffset != 0 )
334  {
335  QDomElement rotation = doc.createElement( "se:Rotation" );
336  pointPlacement.appendChild( rotation );
337  rotation.appendChild( doc.createTextNode( QString::number( settings.angleOffset ) ) );
338  }
339  }
340  break;
343  {
344  QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
345  labelPlacement.appendChild( pointPlacement );
346 
347  // SLD cannot do either, but let's do a best effort setting the distance using
348  // anchor point and displacement
349  QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0, 0.5 ) );
351  double radius = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
352  double offset = std::sqrt( radius * radius / 2 ); // make it start top/right
353  maxDisplacement = radius + 1; // lock the distance
354  QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( offset, offset ) );
355  }
356  break;
360  {
361  // still a point placement (for "free" it's a fallback, there is no SLD equivalent)
362  QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
363  labelPlacement.appendChild( pointPlacement );
364  QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0.5, 0.5 ) );
366  double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
367  QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( 0, dist ) );
368  break;
369  }
373  {
374  QDomElement linePlacement = doc.createElement( "se:LinePlacement" );
375  labelPlacement.appendChild( linePlacement );
376 
377  // perpendicular distance if required
378  if ( settings.dist > 0 )
379  {
381  double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
382  QDomElement perpendicular = doc.createElement( "se:PerpendicularOffset" );
383  linePlacement.appendChild( perpendicular );
384  perpendicular.appendChild( doc.createTextNode( qgsDoubleToString( dist, 2 ) ) );
385  }
386 
387  // repeat distance if required
388  if ( settings.repeatDistance > 0 )
389  {
390  QDomElement repeat = doc.createElement( "se:Repeat" );
391  linePlacement.appendChild( repeat );
392  repeat.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
393  QDomElement gap = doc.createElement( "se:Gap" );
394  linePlacement.appendChild( gap );
396  gap.appendChild( doc.createTextNode( qgsDoubleToString( repeatDistance, 2 ) ) );
397  }
398 
399  // always generalized
400  QDomElement generalize = doc.createElement( "se:GeneralizeLine" );
401  linePlacement.appendChild( generalize );
402  generalize.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
403  }
404  break;
405  }
406 
407  // halo
408  QgsTextBufferSettings buffer = format.buffer();
409  if ( buffer.enabled() )
410  {
411  QDomElement haloElement = doc.createElement( QStringLiteral( "se:Halo" ) );
412  textSymbolizerElement.appendChild( haloElement );
413 
414  QDomElement radiusElement = doc.createElement( QStringLiteral( "se:Radius" ) );
415  haloElement.appendChild( radiusElement );
416  // the SLD uses a radius, which is actually half of the link thickness the buffer size specifies
417  double radius = QgsSymbolLayerUtils::rescaleUom( buffer.size(), buffer.sizeUnit(), props ) / 2;
418  radiusElement.appendChild( doc.createTextNode( qgsDoubleToString( radius ) ) );
419 
420  QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
421  haloElement.appendChild( fillElement );
422  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), buffer.color().name() ) );
423  if ( buffer.opacity() != 1 )
424  {
425  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( buffer.opacity() ) ) );
426  }
427  }
428 
429  // fill
430  QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
431  textSymbolizerElement.appendChild( fillElement );
432  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), format.color().name() ) );
433  if ( format.opacity() != 1 )
434  {
435  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( format.opacity() ) ) );
436  }
437 
438  // background graphic (not supported by SE 1.1, but supported by the GeoTools ecosystem as an extension)
439  QgsTextBackgroundSettings background = format.background();
440  if ( background.enabled() )
441  {
442  std::unique_ptr<QgsMarkerSymbolLayer> layer = backgroundToMarkerLayer( background );
443  layer->writeSldMarker( doc, textSymbolizerElement, props );
444  }
445 
446  // priority and zIndex, the default values are 0 and 5 in qgis (and between 0 and 10),
447  // in the GeoTools ecosystem there is a single priority value set at 1000 by default
448  if ( settings.priority != 5 || settings.zIndex > 0 )
449  {
450  QDomElement priorityElement = doc.createElement( QStringLiteral( "se:Priority" ) );
451  textSymbolizerElement.appendChild( priorityElement );
452  int priority = 500 + 1000 * settings.zIndex + ( settings.priority - 5 ) * 100;
453  if ( settings.priority == 0 && settings.zIndex > 0 )
454  {
455  // small adjustment to make sure labels in z index n+1 are all above level n despite the priority value
456  priority += 1;
457  }
458  priorityElement.appendChild( doc.createTextNode( QString::number( priority ) ) );
459  }
460 
461  // vendor options for text appearance
462  if ( font.underline() )
463  {
464  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "underlineText" ), QStringLiteral( "true" ) );
465  textSymbolizerElement.appendChild( vo );
466  }
467  if ( font.strikeOut() )
468  {
469  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "strikethroughText" ), QStringLiteral( "true" ) );
470  textSymbolizerElement.appendChild( vo );
471  }
472  // vendor options for text positioning
473  if ( maxDisplacement > 0 )
474  {
475  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxDisplacement" ), qgsDoubleToString( maxDisplacement, 2 ) );
476  textSymbolizerElement.appendChild( vo );
477  }
479  {
480  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "followLine" ), QStringLiteral( "true" ) );
481  textSymbolizerElement.appendChild( vo );
483  {
484  // SLD has no notion for this, the GeoTools ecosystem can only do a single angle
485  double angle = std::min( std::fabs( settings.maxCurvedCharAngleIn ), std::fabs( settings.maxCurvedCharAngleOut ) );
486  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxAngleDelta" ), qgsDoubleToString( angle ) );
487  textSymbolizerElement.appendChild( vo );
488  }
489  }
490  if ( repeatDistance > 0 )
491  {
492  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "repeat" ), qgsDoubleToString( repeatDistance, 2 ) );
493  textSymbolizerElement.appendChild( vo );
494  }
495  // miscellaneous options
496  if ( settings.displayAll )
497  {
498  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "conflictResolution" ), QStringLiteral( "false" ) );
499  textSymbolizerElement.appendChild( vo );
500  }
502  {
503  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "forceLeftToRight" ), QStringLiteral( "false" ) );
504  textSymbolizerElement.appendChild( vo );
505  }
506  if ( settings.lineSettings().mergeLines() )
507  {
508  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "group" ), QStringLiteral( "yes" ) );
509  textSymbolizerElement.appendChild( vo );
510  if ( settings.labelPerPart )
511  {
512  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "labelAllGroup" ), QStringLiteral( "true" ) );
513  textSymbolizerElement.appendChild( vo );
514  }
515  }
516  // background symbol resize handling
517  if ( background.enabled() )
518  {
519  // enable resizing if needed
520  switch ( background.sizeType() )
521  {
523  {
524  QString resizeType;
526  {
527  resizeType = QStringLiteral( "stretch" );
528  }
529  else
530  {
531  resizeType = QStringLiteral( "proportional" );
532  }
533  QDomElement voResize = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-resize" ), resizeType );
534  textSymbolizerElement.appendChild( voResize );
535 
536  // now hadle margin
537  QSizeF size = background.size();
538  if ( size.width() > 0 || size.height() > 0 )
539  {
540  double x = QgsSymbolLayerUtils::rescaleUom( size.width(), background.sizeUnit(), props );
541  double y = QgsSymbolLayerUtils::rescaleUom( size.height(), background.sizeUnit(), props );
542  // in case of ellipse qgis pads the size generously to make sure the text is inside the ellipse
543  // the following seems to do the trick and keep visual output similar
544  if ( background.type() == QgsTextBackgroundSettings::ShapeEllipse )
545  {
546  x += fontSize / 2;
547  y += fontSize;
548  }
549  QString resizeSpec = QString( "%1 %2" ).arg( qgsDoubleToString( x, 2 ), qgsDoubleToString( y, 2 ) );
550  QDomElement voMargin = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-margin" ), resizeSpec );
551  textSymbolizerElement.appendChild( voMargin );
552  }
553  break;
554  }
557  // nothing to do here
558  break;
559  }
560  }
561 }
562 
563 
564 void QgsVectorLayerSimpleLabeling::toSld( QDomNode &parent, const QVariantMap &props ) const
565 {
566 
567  if ( mSettings->drawLabels )
568  {
569  QDomDocument doc = parent.ownerDocument();
570 
571  QDomElement ruleElement = doc.createElement( QStringLiteral( "se:Rule" ) );
572  parent.appendChild( ruleElement );
573 
574  // scale dependencies
575  if ( mSettings->scaleVisibility )
576  {
577  QVariantMap scaleProps = QVariantMap();
578  // tricky here, the max scale is expressed as its denominator, but it's still the max scale
579  // in other words, the smallest scale denominator....
580  scaleProps.insert( "scaleMinDenom", qgsDoubleToString( mSettings->maximumScale ) );
581  scaleProps.insert( "scaleMaxDenom", qgsDoubleToString( mSettings->minimumScale ) );
582  QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElement, scaleProps );
583  }
584 
585  writeTextSymbolizer( ruleElement, *mSettings, props );
586  }
587 
588 
589 }
590 
591 void QgsVectorLayerSimpleLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
592 {
593  Q_UNUSED( providerId )
594 
595  if ( mSettings.get() == settings )
596  return;
597 
598  mSettings.reset( settings );
599 }
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.
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...
Abstract base class for marker symbol layers.
Contains settings for how a map layer will be labeled.
double yOffset
Vertical offset of label.
double maxCurvedCharAngleIn
Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
bool displayAll
If true, all features will be labelled even when overlaps occur.
double xOffset
Horizontal offset of label.
QgsExpression * getLabelExpression()
Returns the QgsExpression for this label settings.
QuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
@ ShowAll
Show upside down for all labels, including dynamic ones.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QgsUnitTypes::RenderUnit offsetUnits
Units for offsets of label.
double repeatDistance
Distance for repeating labels for a single feature.
@ PerimeterCurved
Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
@ Curved
Arranges candidates following the curvature of a line feature. Applies to line layers only.
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
@ Free
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
@ 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'...
@ OrderedPositionsAroundPoint
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
@ OutsidePolygons
Candidates are placed outside of polygon boundaries. Applies to polygon layers only....
int priority
Label priority.
bool labelPerPart
true if every part of a multi-part feature should be labeled.
QgsUnitTypes::RenderUnit distUnits
Units the distance from feature to the label.
QgsUnitTypes::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
double angleOffset
Label rotation, in degrees clockwise.
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0)
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
double dist
Distance from feature to the label.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
UpsideDownLabels 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.
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(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Sets the rendered marker shape.
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
void setStrokeWidthUnit(QgsUnitTypes::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.
Capitalization
Capitalization options.
@ MixedCase
Mixed case, ie no change.
@ AllLowercase
Convert all characters to lowercase.
@ AllUppercase
Convert all characters to uppercase.
@ ForceFirstLetterToCapital
Convert just the first letter of each word to uppercase, leave the rest untouched.
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:1294
void setStrokeWidthUnit(QgsUnitTypes::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, QgsUnitTypes::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:411
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:199
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.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the units used for the shape's stroke width.
@ 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.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shape's offset.
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...
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.
QColor strokeColor() const
Returns the color used for outlining the background shape.
QgsUnitTypes::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.
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.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
QColor color() const
Returns the color of the buffer.
Container for all settings relating to text rendering.
Definition: qgstextformat.h:41
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
double opacity() const
Returns the text's opacity.
double size() const
Returns the size for rendered text.
QgsStringUtils::Capitalization capitalization() const
Returns the text capitalization style.
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.
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:167
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.
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.
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:829
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:276
void appendSimpleFunction(QDomDocument &doc, QDomElement &parent, const QString &name, const QString &attribute)
QPointF quadOffsetToSldAnchor(QgsPalLayerSettings::QuadrantPosition quadrantPosition)
std::unique_ptr< QgsMarkerSymbolLayer > backgroundToMarkerLayer(const QgsTextBackgroundSettings &settings)