QGIS API Documentation  3.2.0-Bonn (bc43194)
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 
25 
27 {
28  QString type = element.attribute( QStringLiteral( "type" ) );
29  if ( type == QLatin1String( "rule-based" ) )
30  {
31  return QgsRuleBasedLabeling::create( element, context );
32  }
33  else if ( type == QLatin1String( "simple" ) )
34  {
35  return QgsVectorLayerSimpleLabeling::create( element, context );
36  }
37  else
38  {
39  return nullptr;
40  }
41 }
42 
44 {
45  return new QgsVectorLayerLabelProvider( layer, QString(), false, mSettings.get() );
46 }
47 
49  : mSettings( new QgsPalLayerSettings( settings ) )
50 {
51 
52 }
53 
55 {
56  return QStringLiteral( "simple" );
57 }
58 
60 {
61  return new QgsVectorLayerSimpleLabeling( *mSettings );
62 }
63 
64 QDomElement QgsVectorLayerSimpleLabeling::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
65 {
66  QDomElement elem = doc.createElement( QStringLiteral( "labeling" ) );
67  elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "simple" ) );
68  elem.appendChild( mSettings->writeXml( doc, context ) );
69  return elem;
70 }
71 
73 {
74  Q_UNUSED( providerId );
75  return *mSettings;
76 }
77 
79 {
80  return mSettings->format().containsAdvancedEffects();
81 }
82 
84 {
85  QDomElement settingsElem = element.firstChildElement( QStringLiteral( "settings" ) );
86  if ( !settingsElem.isNull() )
87  {
89  settings.readXml( settingsElem, context );
90  return new QgsVectorLayerSimpleLabeling( settings );
91  }
92 
94 }
95 
97 {
98  double quadOffsetX = 0.5, quadOffsetY = 0.5;
99 
100  // adjust quadrant offset of labels
101  switch ( quadrantPosition )
102  {
104  quadOffsetX = 1;
105  quadOffsetY = 0;
106  break;
108  quadOffsetX = 0.5;
109  quadOffsetY = 0;
110  break;
112  quadOffsetX = 0;
113  quadOffsetY = 0;
114  break;
116  quadOffsetX = 1;
117  quadOffsetY = 0.5;
118  break;
120  quadOffsetX = 0;
121  quadOffsetY = 0.5;
122  break;
124  quadOffsetX = 1;
125  quadOffsetY = 1;
126  break;
128  quadOffsetX = 0.5;
129  quadOffsetY = 1;
130  break;
132  quadOffsetX = 0;
133  quadOffsetY = 1.0;
134  break;
136  break;
137  }
138 
139  return QPointF( quadOffsetX, quadOffsetY );
140 }
141 
142 /*
143  * This is not a generic function encoder, just enough to encode the label case control functions
144  */
145 void appendSimpleFunction( QDomDocument &doc, QDomElement &parent, const QString &name, const QString &attribute )
146 {
147  QDomElement function = doc.createElement( QStringLiteral( "ogc:Function" ) );
148  function.setAttribute( QStringLiteral( "name" ), name );
149  parent.appendChild( function );
150  QDomElement property = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
151  property.appendChild( doc.createTextNode( attribute ) );
152  function.appendChild( property );
153 }
154 
155 std::unique_ptr<QgsMarkerSymbolLayer> backgroundToMarkerLayer( const QgsTextBackgroundSettings &settings )
156 {
157  std::unique_ptr<QgsMarkerSymbolLayer> layer;
158  switch ( settings.type() )
159  {
161  {
163  svg->setStrokeWidth( settings.strokeWidth() );
164  svg->setStrokeWidthUnit( settings.strokeWidthUnit() );
165  layer.reset( svg );
166  break;
167  }
172  {
174  // default value
176  switch ( settings.type() )
177  {
181  break;
185  break;
187  break;
188  }
189 
190  marker->setShape( shape );
191  marker->setStrokeWidth( settings.strokeWidth() );
192  marker->setStrokeWidthUnit( settings.strokeWidthUnit() );
193  layer.reset( marker );
194  }
195  }
196  layer->setEnabled( true );
197  // a marker does not have a size x and y, just a size (and it should be at least one)
198  QSizeF size = settings.size();
199  layer->setSize( std::max( 1., std::max( size.width(), size.height() ) ) );
200  layer->setSizeUnit( settings.sizeUnit() );
201  // fill and stroke
202  QColor fillColor = settings.fillColor();
203  QColor strokeColor = settings.strokeColor();
204  if ( settings.opacity() < 1 )
205  {
206  int alpha = std::round( settings.opacity() * 255 );
207  fillColor.setAlpha( alpha );
208  strokeColor.setAlpha( alpha );
209  }
210  layer->setFillColor( fillColor );
211  layer->setStrokeColor( strokeColor );
212  // rotation
214  {
215  layer->setAngle( settings.rotation() );
216  }
217  // offset
218  layer->setOffset( settings.offset() );
219  layer->setOffsetUnit( settings.offsetUnit() );
220 
221  return layer;
222 }
223 
225 {
226  QDomDocument doc = parent.ownerDocument();
227 
228  // text symbolizer
229  QDomElement textSymbolizerElement = doc.createElement( QStringLiteral( "se:TextSymbolizer" ) );
230  parent.appendChild( textSymbolizerElement );
231 
232  // label
233  QgsTextFormat format = settings.format();
234  QFont font = format.font();
235  QDomElement labelElement = doc.createElement( QStringLiteral( "se:Label" ) );
236  textSymbolizerElement.appendChild( labelElement );
237  if ( settings.isExpression )
238  {
239  labelElement.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( settings.getLabelExpression()->dump() ) ) );
240  labelElement.appendChild( doc.createTextNode( "Placeholder" ) );
241  }
242  else
243  {
244  if ( font.capitalization() == QFont::AllUppercase )
245  {
246  appendSimpleFunction( doc, labelElement, QStringLiteral( "strToUpperCase" ), settings.fieldName );
247  }
248  else if ( font.capitalization() == QFont::AllLowercase )
249  {
250  appendSimpleFunction( doc, labelElement, QStringLiteral( "strToLowerCase" ), settings.fieldName );
251  }
252  else if ( font.capitalization() == QFont::Capitalize )
253  {
254  appendSimpleFunction( doc, labelElement, QStringLiteral( "strCapitalize" ), settings.fieldName );
255  }
256  else
257  {
258  QDomElement propertyNameElement = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
259  propertyNameElement.appendChild( doc.createTextNode( settings.fieldName ) );
260  labelElement.appendChild( propertyNameElement );
261  }
262  }
263 
264  // font
265  QDomElement fontElement = doc.createElement( QStringLiteral( "se:Font" ) );
266  textSymbolizerElement.appendChild( fontElement );
267  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-family" ), font.family() ) );
268  double fontSize = QgsSymbolLayerUtils::rescaleUom( format.size(), format.sizeUnit(), props );
269  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-size" ), QString::number( fontSize ) ) );
270  if ( format.font().italic() )
271  {
272  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-style" ), QStringLiteral( "italic" ) ) );
273  }
274  if ( format.font().bold() )
275  {
276  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-weight" ), QStringLiteral( "bold" ) ) );
277  }
278 
279  // label placement
280  QDomElement labelPlacement = doc.createElement( QStringLiteral( "se:LabelPlacement" ) );
281  textSymbolizerElement.appendChild( labelPlacement );
282  double maxDisplacement = 0;
283  double repeatDistance = 0;
284  switch ( settings.placement )
285  {
287  {
288  QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
289  labelPlacement.appendChild( pointPlacement );
290  // anchor point
291  QPointF anchor = quadOffsetToSldAnchor( settings.quadOffset );
292  QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, anchor );
293  // displacement
294  if ( settings.xOffset > 0 || settings.yOffset > 0 )
295  {
296  QgsUnitTypes::RenderUnit offsetUnit = settings.offsetUnits;
297  double dx = QgsSymbolLayerUtils::rescaleUom( settings.xOffset, offsetUnit, props );
298  double dy = QgsSymbolLayerUtils::rescaleUom( settings.yOffset, offsetUnit, props );
299  QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( dx, dy ) );
300  }
301  // rotation
302  if ( settings.angleOffset != 0 )
303  {
304  QDomElement rotation = doc.createElement( "se:Rotation" );
305  pointPlacement.appendChild( rotation );
306  rotation.appendChild( doc.createTextNode( QString::number( settings.angleOffset ) ) );
307  }
308  }
309  break;
312  {
313  QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
314  labelPlacement.appendChild( pointPlacement );
315 
316  // SLD cannot do either, but let's do a best effort setting the distance using
317  // anchor point and displacement
318  QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0, 0.5 ) );
319  QgsUnitTypes::RenderUnit distUnit = settings.distUnits;
320  double radius = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
321  double offset = std::sqrt( radius * radius / 2 ); // make it start top/right
322  maxDisplacement = radius + 1; // lock the distance
323  QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( offset, offset ) );
324  }
325  break;
328  {
329  // still a point placement (for "free" it's a fallback, there is no SLD equivalent)
330  QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
331  labelPlacement.appendChild( pointPlacement );
332  QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0.5, 0.5 ) );
333  QgsUnitTypes::RenderUnit distUnit = settings.distUnits;
334  double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
335  QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( 0, dist ) );
336  break;
337  }
341  {
342  QDomElement linePlacement = doc.createElement( "se:LinePlacement" );
343  labelPlacement.appendChild( linePlacement );
344 
345  // perpendicular distance if required
346  if ( settings.dist > 0 )
347  {
348  QgsUnitTypes::RenderUnit distUnit = settings.distUnits;
349  double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
350  QDomElement perpendicular = doc.createElement( "se:PerpendicularOffset" );
351  linePlacement.appendChild( perpendicular );
352  perpendicular.appendChild( doc.createTextNode( qgsDoubleToString( dist, 2 ) ) );
353  }
354 
355  // repeat distance if required
356  if ( settings.repeatDistance > 0 )
357  {
358  QDomElement repeat = doc.createElement( "se:Repeat" );
359  linePlacement.appendChild( repeat );
360  repeat.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
361  QDomElement gap = doc.createElement( "se:Gap" );
362  linePlacement.appendChild( gap );
363  repeatDistance = QgsSymbolLayerUtils::rescaleUom( settings.repeatDistance, settings.repeatDistanceUnit, props );
364  gap.appendChild( doc.createTextNode( qgsDoubleToString( repeatDistance, 2 ) ) );
365  }
366 
367  // always generalized
368  QDomElement generalize = doc.createElement( "se:GeneralizeLine" );
369  linePlacement.appendChild( generalize );
370  generalize.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
371  }
372  break;
373  }
374 
375  // halo
376  QgsTextBufferSettings buffer = format.buffer();
377  if ( buffer.enabled() )
378  {
379  QDomElement haloElement = doc.createElement( QStringLiteral( "se:Halo" ) );
380  textSymbolizerElement.appendChild( haloElement );
381 
382  QDomElement radiusElement = doc.createElement( QStringLiteral( "se:Radius" ) );
383  haloElement.appendChild( radiusElement );
384  // the SLD uses a radius, which is actually half of the link thickness the buffer size specifies
385  double radius = QgsSymbolLayerUtils::rescaleUom( buffer.size(), buffer.sizeUnit(), props ) / 2;
386  radiusElement.appendChild( doc.createTextNode( qgsDoubleToString( radius ) ) );
387 
388  QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
389  haloElement.appendChild( fillElement );
390  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), buffer.color().name() ) );
391  if ( buffer.opacity() != 1 )
392  {
393  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( buffer.opacity() ) ) );
394  }
395  }
396 
397  // fill
398  QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
399  textSymbolizerElement.appendChild( fillElement );
400  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), format.color().name() ) );
401  if ( format.opacity() != 1 )
402  {
403  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( format.opacity() ) ) );
404  }
405 
406  // background graphic (not supported by SE 1.1, but supported by the GeoTools ecosystem as an extension)
407  QgsTextBackgroundSettings background = format.background();
408  if ( background.enabled() )
409  {
410  std::unique_ptr<QgsMarkerSymbolLayer> layer = backgroundToMarkerLayer( background );
411  layer->writeSldMarker( doc, textSymbolizerElement, props );
412  }
413 
414  // priority and zIndex, the default values are 0 and 5 in qgis (and between 0 and 10),
415  // in the GeoTools ecosystem there is a single priority value set at 1000 by default
416  if ( settings.priority != 5 || settings.zIndex > 0 )
417  {
418  QDomElement priorityElement = doc.createElement( QStringLiteral( "se:Priority" ) );
419  textSymbolizerElement.appendChild( priorityElement );
420  int priority = 500 + 1000 * settings.zIndex + ( settings.priority - 5 ) * 100;
421  if ( settings.priority == 0 && settings.zIndex > 0 )
422  {
423  // small adjustment to make sure labels in z index n+1 are all above level n despite the priority value
424  priority += 1;
425  }
426  priorityElement.appendChild( doc.createTextNode( QString::number( priority ) ) );
427  }
428 
429  // vendor options for text appearance
430  if ( font.underline() )
431  {
432  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "underlineText" ), QStringLiteral( "true" ) );
433  textSymbolizerElement.appendChild( vo );
434  }
435  if ( font.strikeOut() )
436  {
437  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "strikethroughText" ), QStringLiteral( "true" ) );
438  textSymbolizerElement.appendChild( vo );
439  }
440  // vendor options for text positioning
441  if ( maxDisplacement > 0 )
442  {
443  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxDisplacement" ), qgsDoubleToString( maxDisplacement, 2 ) );
444  textSymbolizerElement.appendChild( vo );
445  }
447  {
448  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "followLine" ), QStringLiteral( "true" ) );
449  textSymbolizerElement.appendChild( vo );
450  if ( settings.maxCurvedCharAngleIn > 0 || settings.maxCurvedCharAngleOut > 0 )
451  {
452  // SLD has no notion for this, the GeoTools ecosystem can only do a single angle
453  double angle = std::min( std::fabs( settings.maxCurvedCharAngleIn ), std::fabs( settings.maxCurvedCharAngleOut ) );
454  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxAngleDelta" ), qgsDoubleToString( angle ) );
455  textSymbolizerElement.appendChild( vo );
456  }
457  }
458  if ( repeatDistance > 0 )
459  {
460  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "repeat" ), qgsDoubleToString( repeatDistance, 2 ) );
461  textSymbolizerElement.appendChild( vo );
462  }
463  // miscellaneous options
464  if ( settings.displayAll )
465  {
466  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "conflictResolution" ), QStringLiteral( "false" ) );
467  textSymbolizerElement.appendChild( vo );
468  }
470  {
471  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "forceLeftToRight" ), QStringLiteral( "false" ) );
472  textSymbolizerElement.appendChild( vo );
473  }
474  if ( settings.mergeLines )
475  {
476  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "group" ), QStringLiteral( "yes" ) );
477  textSymbolizerElement.appendChild( vo );
478  if ( settings.labelPerPart )
479  {
480  QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "labelAllGroup" ), QStringLiteral( "true" ) );
481  textSymbolizerElement.appendChild( vo );
482  }
483  }
484  // background symbol resize handling
485  if ( background.enabled() )
486  {
487  // enable resizing if needed
488  switch ( background.sizeType() )
489  {
491  {
492  QString resizeType;
494  {
495  resizeType = QStringLiteral( "stretch" );
496  }
497  else
498  {
499  resizeType = QStringLiteral( "proportional" );
500  }
501  QDomElement voResize = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-resize" ), resizeType );
502  textSymbolizerElement.appendChild( voResize );
503 
504  // now hadle margin
505  QSizeF size = background.size();
506  if ( size.width() > 0 || size.height() > 0 )
507  {
508  double x = QgsSymbolLayerUtils::rescaleUom( size.width(), background.sizeUnit(), props );
509  double y = QgsSymbolLayerUtils::rescaleUom( size.height(), background.sizeUnit(), props );
510  // in case of ellipse qgis pads the size generously to make sure the text is inside the ellipse
511  // the following seems to do the trick and keep visual output similar
512  if ( background.type() == QgsTextBackgroundSettings::ShapeEllipse )
513  {
514  x += fontSize / 2;
515  y += fontSize;
516  }
517  QString resizeSpec = QString( "%1 %2" ).arg( qgsDoubleToString( x, 2 ), qgsDoubleToString( y, 2 ) );
518  QDomElement voMargin = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-margin" ), resizeSpec );
519  textSymbolizerElement.appendChild( voMargin );
520  }
521  break;
522  }
525  // nothing to do here
526  break;
527  }
528  }
529 }
530 
531 
532 void QgsVectorLayerSimpleLabeling::toSld( QDomNode &parent, const QgsStringMap &props ) const
533 {
534 
535  if ( mSettings->drawLabels )
536  {
537  QDomDocument doc = parent.ownerDocument();
538 
539  QDomElement ruleElement = doc.createElement( QStringLiteral( "se:Rule" ) );
540  parent.appendChild( ruleElement );
541 
542  // scale dependencies
543  if ( mSettings->scaleVisibility )
544  {
545  QgsStringMap scaleProps = QgsStringMap();
546  // tricky here, the max scale is expressed as its denominator, but it's still the max scale
547  // in other words, the smallest scale denominator....
548  scaleProps.insert( "scaleMinDenom", qgsDoubleToString( mSettings->maximumScale ) );
549  scaleProps.insert( "scaleMaxDenom", qgsDoubleToString( mSettings->minimumScale ) );
550  QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElement, scaleProps );
551  }
552 
553  writeTextSymbolizer( ruleElement, *mSettings, props );
554  }
555 
556 
557 }
558 
560 {
561  Q_UNUSED( providerId );
562 
563  if ( mSettings.get() == settings )
564  return;
565 
566  mSettings.reset( settings );
567 }
QString type() const override
Unique type string of the labeling configuration implementation.
double xOffset
Horizontal offset of label.
The class is used as a container of context for various read/write operations on other objects...
QColor strokeColor() const
Returns the color used for outlining the background shape.
Shape size is determined by adding a buffer margin around text.
void toSld(QDomNode &parent, const QgsStringMap &props) const override
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0) ...
QgsVectorLayerLabelProvider * provider(QgsVectorLayer *layer) const override
QgsUnitTypes::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
QSizeF size() const
Returns the size of the background shape.
double opacity() const
Returns the text&#39;s opacity.
QPointF offset() const
Returns the offset used for drawing the background shape.
QColor fillColor() const
Returns the color used for filing the background shape.
bool requiresAdvancedEffects() const override
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker&#39;s stroke.
double angleOffset
Label rotation, in degrees clockwise.
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke...
void readXml(QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QgsStringMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
UpsideDownLabels upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
static QDomElement createSvgParameterElement(QDomDocument &doc, const QString &name, const QString &value)
double opacity() const
Returns the background shape&#39;s opacity.
QString dump() const
Returns an expression string, constructed from the internal abstract syntax tree. ...
double strokeWidth() const
Returns the width of the shape&#39;s stroke (stroke).
double repeatDistance
Distance for repeating labels for a single feature.
QgsVectorLayerSimpleLabeling(const QgsPalLayerSettings &settings)
Constructs simple labeling configuration with given initial settings.
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
QuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
QgsUnitTypes::RenderUnit offsetUnits
Units for offsets of label.
QColor color() const
Returns the color that text will be rendered in.
double yOffset
Vertical offset of label.
void setStrokeWidth(double w)
Sets the width of the marker&#39;s stroke.
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
bool mergeLines
True if connected line features with identical label text should be merged prior to generating label ...
static QgsVectorLayerSimpleLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Create the instance from a DOM element with saved configuration.
Shape size is determined by percent of text size.
Container for settings relating to a text background object.
QgsAbstractVectorLayerLabeling * clone() const override
Returns a new copy of the object.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:501
double maxCurvedCharAngleIn
Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
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
ShapeType type() const
Returns the type of background shape (e.g., square, ellipse, SVG).
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
Arranges candidates following the curvature of a line feature. Applies to line layers only...
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QgsStringMap &props)
Rescales the given size based on the uomScale found in the props, if any is found, otherwise returns the value un-modified.
Shape rotation is a fixed angle.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
bool displayAll
If true, all features will be labelled even when overlaps occur.
std::unique_ptr< QgsMarkerSymbolLayer > backgroundToMarkerLayer(const QgsTextBackgroundSettings &settings)
virtual QgsPalLayerSettings settings(const QString &providerId=QString()) const =0
Gets associated label settings.
RotationType rotationType() const
Returns the method used for rotating the background shape.
Show upside down for all labels, including dynamic ones.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:237
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
QString svgFile() const
Returns the absolute path to the background SVG file, if set.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
double opacity() const
Returns the buffer opacity.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the units used for the shape&#39;s stroke width.
void setSettings(QgsPalLayerSettings *settings, const QString &providerId=QString()) override
Set pal settings (takes ownership).
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc...
static QgsRuleBasedLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Create the instance from a DOM element with saved configuration.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shape&#39;s offset.
double rotation() const
Returns the rotation for the background shape, in degrees clockwise.
QgsExpression * getLabelExpression()
Returns the QgsExpression for this label settings.
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point...
void setShape(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Sets the rendered marker shape.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const override
Returns labeling configuration as XML element.
QColor color() const
Returns the color of the buffer.
double size() const
Returns the size of the buffer.
static void createAnchorPointElement(QDomDocument &doc, QDomElement &element, QPointF anchor)
Creates a SE 1.1 anchor point element as a child of the specified element.
Container for settings relating to a text buffer.
double dist
Distance from feature to the label.
double size() const
Returns the size for rendered text.
bool enabled() const
Returns whether the background is enabled.
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
QPointF quadOffsetToSldAnchor(QgsPalLayerSettings::QuadrantPosition quadrantPosition)
virtual void writeTextSymbolizer(QDomNode &parent, QgsPalLayerSettings &settings, const QgsStringMap &props) const
Writes a TextSymbolizer element contents based on the provided labeling settings. ...
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
bool enabled() const
Returns whether the buffer is enabled.
Basic implementation of the labeling interface.
bool isExpression
True if this label is made from a expression string, e.g., FieldName || &#39;mm&#39;.
QgsPalLayerSettings settings(const QString &providerId=QString()) const override
Gets associated label settings.
virtual QString type() const =0
Unique type string of the labeling configuration implementation.
Container for all settings relating to text rendering.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
Represents a vector layer which manages a vector based data sets.
Square - buffered sizes only.
QFont font() const
Returns the font used for rendering text.
void appendSimpleFunction(QDomDocument &doc, QDomElement &parent, const QString &name, const QString &attribute)
int priority
Label priority.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units used for the shape&#39;s size.
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.
static QgsAbstractVectorLayerLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Try to create instance of an implementation based on the XML data.
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:100
QString fieldName
Name of field (or an expression) to use for label text.
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...