QGIS API Documentation  3.25.0-Master (349eb7cb1e)
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 #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 {
52  settings.fieldName = layer->displayField();
54 
55  switch ( layer->geometryType() )
56  {
60  break;
63  break;
66  break;
67 
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 
96 QDomElement 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  {
147  quadOffsetX = 1;
148  quadOffsetY = 0;
149  break;
151  quadOffsetX = 0.5;
152  quadOffsetY = 0;
153  break;
155  quadOffsetX = 0;
156  quadOffsetY = 0;
157  break;
159  quadOffsetX = 1;
160  quadOffsetY = 0.5;
161  break;
163  quadOffsetX = 0;
164  quadOffsetY = 0.5;
165  break;
167  quadOffsetX = 1;
168  quadOffsetY = 1;
169  break;
171  quadOffsetX = 0.5;
172  quadOffsetY = 1;
173  break;
175  quadOffsetX = 0;
176  quadOffsetY = 1.0;
177  break;
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  */
188 void 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 
198 std::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 
278 void 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 );
291  if ( settings.isExpression )
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 QgsUnitTypes::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 ) );
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 ) );
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  {
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  }
505  {
506  const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "followLine" ), QStringLiteral( "true" ) );
507  textSymbolizerElement.appendChild( vo );
509  {
510  // SLD has no notion for this, the GeoTools ecosystem can only do a single angle
511  const double angle = std::min( std::fabs( settings.maxCurvedCharAngleIn ), std::fabs( settings.maxCurvedCharAngleOut ) );
512  const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxAngleDelta" ), qgsDoubleToString( angle ) );
513  textSymbolizerElement.appendChild( vo );
514  }
515  }
516  if ( repeatDistance > 0 )
517  {
518  const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "repeat" ), qgsDoubleToString( repeatDistance, 2 ) );
519  textSymbolizerElement.appendChild( vo );
520  }
521  // miscellaneous options
522  if ( settings.displayAll )
523  {
524  const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "conflictResolution" ), QStringLiteral( "false" ) );
525  textSymbolizerElement.appendChild( vo );
526  }
528  {
529  const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "forceLeftToRight" ), QStringLiteral( "false" ) );
530  textSymbolizerElement.appendChild( vo );
531  }
532  if ( settings.lineSettings().mergeLines() )
533  {
534  const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "group" ), QStringLiteral( "yes" ) );
535  textSymbolizerElement.appendChild( vo );
536  if ( settings.labelPerPart )
537  {
538  const QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "labelAllGroup" ), QStringLiteral( "true" ) );
539  textSymbolizerElement.appendChild( vo );
540  }
541  }
542  // background symbol resize handling
543  if ( background.enabled() )
544  {
545  // enable resizing if needed
546  switch ( background.sizeType() )
547  {
549  {
550  QString resizeType;
552  {
553  resizeType = QStringLiteral( "stretch" );
554  }
555  else
556  {
557  resizeType = QStringLiteral( "proportional" );
558  }
559  const QDomElement voResize = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-resize" ), resizeType );
560  textSymbolizerElement.appendChild( voResize );
561 
562  // now hadle margin
563  const QSizeF size = background.size();
564  if ( size.width() > 0 || size.height() > 0 )
565  {
566  double x = QgsSymbolLayerUtils::rescaleUom( size.width(), background.sizeUnit(), props );
567  double y = QgsSymbolLayerUtils::rescaleUom( size.height(), background.sizeUnit(), props );
568  // in case of ellipse qgis pads the size generously to make sure the text is inside the ellipse
569  // the following seems to do the trick and keep visual output similar
570  if ( background.type() == QgsTextBackgroundSettings::ShapeEllipse )
571  {
572  x += fontSize / 2;
573  y += fontSize;
574  }
575  const QString resizeSpec = QString( "%1 %2" ).arg( qgsDoubleToString( x, 2 ), qgsDoubleToString( y, 2 ) );
576  const QDomElement voMargin = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-margin" ), resizeSpec );
577  textSymbolizerElement.appendChild( voMargin );
578  }
579  break;
580  }
583  // nothing to do here
584  break;
585  }
586  }
587 }
588 
589 
590 void QgsVectorLayerSimpleLabeling::toSld( QDomNode &parent, const QVariantMap &props ) const
591 {
592 
593  if ( mSettings->drawLabels )
594  {
595  QDomDocument doc = parent.ownerDocument();
596 
597  QDomElement ruleElement = doc.createElement( QStringLiteral( "se:Rule" ) );
598  parent.appendChild( ruleElement );
599 
600  // scale dependencies
601  if ( mSettings->scaleVisibility )
602  {
603  QVariantMap scaleProps = QVariantMap();
604  // tricky here, the max scale is expressed as its denominator, but it's still the max scale
605  // in other words, the smallest scale denominator....
606  scaleProps.insert( "scaleMinDenom", qgsDoubleToString( mSettings->maximumScale ) );
607  scaleProps.insert( "scaleMaxDenom", qgsDoubleToString( mSettings->minimumScale ) );
608  QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElement, scaleProps );
609  }
610 
611  writeTextSymbolizer( ruleElement, *mSettings, props );
612  }
613 
614 
615 }
616 
617 void QgsVectorLayerSimpleLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
618 {
619  Q_UNUSED( providerId )
620 
621  if ( mSettings.get() == settings )
622  return;
623 
624  mSettings.reset( settings );
625 }
MarkerShape
Marker shapes.
Definition: qgis.h:1206
Capitalization
String capitalization options.
Definition: qgis.h:1428
@ 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.
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...
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.
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...
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.
OffsetType offsetType
Offset type for layer (only applies in certain placement modes)
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...
@ FromSymbolBounds
Offset distance applies from rendered symbol bounds.
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(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(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.
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:1435
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:1217
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:423
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:215
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.
Qgis::Capitalization capitalization() const
Returns the text capitalization style.
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.
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:168
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.
Q_INVOKABLE QgsWkbTypes::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:2657
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:2014
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)