QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgscallout.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscallout.cpp
3  ----------------
4  begin : July 2019
5  copyright : (C) 2019 Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgscallout.h"
19 #include "qgsrendercontext.h"
20 #include "qgssymbol.h"
21 #include "qgslinesymbollayer.h"
22 #include "qgssymbollayerutils.h"
23 #include "qgsxmlutils.h"
24 #include "qgslinestring.h"
25 #include "qgslogger.h"
26 #include <QPainter>
27 #include <mutex>
28 
29 QgsPropertiesDefinition QgsCallout::sPropertyDefinitions;
30 
31 void QgsCallout::initPropertyDefinitions()
32 {
33  const QString origin = QStringLiteral( "callouts" );
34 
35  sPropertyDefinitions = QgsPropertiesDefinition
36  {
37  { QgsCallout::MinimumCalloutLength, QgsPropertyDefinition( "MinimumCalloutLength", QObject::tr( "Minimum callout length" ), QgsPropertyDefinition::DoublePositive, origin ) },
38  { QgsCallout::OffsetFromAnchor, QgsPropertyDefinition( "OffsetFromAnchor", QObject::tr( "Offset from feature" ), QgsPropertyDefinition::DoublePositive, origin ) },
39  { QgsCallout::OffsetFromLabel, QgsPropertyDefinition( "OffsetFromLabel", QObject::tr( "Offset from label" ), QgsPropertyDefinition::DoublePositive, origin ) },
40  { QgsCallout::DrawCalloutToAllParts, QgsPropertyDefinition( "DrawCalloutToAllParts", QObject::tr( "Draw lines to all feature parts" ), QgsPropertyDefinition::Boolean, origin ) },
41  { QgsCallout::AnchorPointPosition, QgsPropertyDefinition( "AnchorPointPosition", QgsPropertyDefinition::DataTypeString, QObject::tr( "Feature's anchor point position" ), QObject::tr( "string " ) + "[<b>pole_of_inaccessibility</b>|<b>point_on_exterior</b>|<b>point_on_surface</b>|<b>centroid</b>]", origin ) },
42  {
43  QgsCallout::LabelAnchorPointPosition, QgsPropertyDefinition( "LabelAnchorPointPosition", QgsPropertyDefinition::DataTypeString, QObject::tr( "Label's anchor point position" ), QObject::tr( "string " ) + "[<b>point_on_exterior</b>|<b>centroid</b>|<b>TL</b>=Top left|<b>T</b>=Top middle|"
44  "<b>TR</b>=Top right|<br>"
45  "<b>L</b>=Left|<b>R</b>=Right|<br>"
46  "<b>BL</b>=Bottom left|<b>B</b>=Bottom middle|"
47  "<b>BR</b>=Bottom right]", origin )
48  },
49  };
50 }
51 
52 
54 {
55 }
56 
57 QVariantMap QgsCallout::properties( const QgsReadWriteContext & ) const
58 {
59  QVariantMap props;
60  props.insert( QStringLiteral( "enabled" ), mEnabled ? "1" : "0" );
61  props.insert( QStringLiteral( "anchorPoint" ), encodeAnchorPoint( mAnchorPoint ) );
62  props.insert( QStringLiteral( "labelAnchorPoint" ), encodeLabelAnchorPoint( mLabelAnchorPoint ) );
63  props.insert( QStringLiteral( "ddProperties" ), mDataDefinedProperties.toVariant( propertyDefinitions() ) );
64  return props;
65 }
66 
67 void QgsCallout::readProperties( const QVariantMap &props, const QgsReadWriteContext & )
68 {
69  mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
70  mAnchorPoint = decodeAnchorPoint( props.value( QStringLiteral( "anchorPoint" ), QString() ).toString() );
71  mLabelAnchorPoint = decodeLabelAnchorPoint( props.value( QStringLiteral( "labelAnchorPoint" ), QString() ).toString() );
72  mDataDefinedProperties.loadVariant( props.value( QStringLiteral( "ddProperties" ) ), propertyDefinitions() );
73 }
74 
75 bool QgsCallout::saveProperties( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context ) const
76 {
77  if ( element.isNull() )
78  {
79  return false;
80  }
81 
82  QDomElement calloutPropsElement = QgsXmlUtils::writeVariant( properties( context ), doc );
83 
84  QDomElement calloutElement = doc.createElement( QStringLiteral( "callout" ) );
85  calloutElement.setAttribute( QStringLiteral( "type" ), type() );
86  calloutElement.appendChild( calloutPropsElement );
87 
88  element.appendChild( calloutElement );
89  return true;
90 }
91 
92 void QgsCallout::restoreProperties( const QDomElement &element, const QgsReadWriteContext &context )
93 {
94  const QVariantMap props = QgsXmlUtils::readVariant( element.firstChildElement() ).toMap();
95  readProperties( props, context );
96 }
97 
99 {
100 
101 }
103 {
104 
105 }
106 
107 QSet<QString> QgsCallout::referencedFields( const QgsRenderContext &context ) const
108 {
109  mDataDefinedProperties.prepare( context.expressionContext() );
110  return mDataDefinedProperties.referencedFields( context.expressionContext() );
111 }
112 
114 {
115  return OrderBelowAllLabels;
116 }
117 
118 void QgsCallout::render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext )
119 {
120  if ( !mEnabled )
121  return;
122 
123 #if 0 // for debugging
124  QPainter *painter = context.painter();
125  painter->save();
126  painter->setRenderHint( QPainter::Antialiasing, false );
127  painter->translate( rect.center() );
128  painter->rotate( -angle );
129 
130  painter->setBrush( QColor( 255, 0, 0, 100 ) );
131  painter->setPen( QColor( 255, 0, 0, 150 ) );
132 
133  painter->drawRect( rect.width() * -0.5, rect.height() * -0.5, rect.width(), rect.height() );
134  painter->restore();
135 
136  painter->setBrush( QColor( 0, 255, 0, 100 ) );
137  painter->setPen( QColor( 0, 255, 0, 150 ) );
138 
139  painter->drawRect( anchor.boundingBox( ).buffered( 30 ).toRectF() );
140 #endif
141 
142  draw( context, rect, angle, anchor, calloutContext );
143 }
144 
145 void QgsCallout::setEnabled( bool enabled )
146 {
147  mEnabled = enabled;
148 }
149 
151 {
152  static std::once_flag initialized;
153  std::call_once( initialized, [ = ]( )
154  {
155  initPropertyDefinitions();
156  } );
157  return sPropertyDefinitions;
158 }
159 
161 {
162  if ( ok )
163  *ok = true;
164  QString cleaned = name.toLower().trimmed();
165 
166  if ( cleaned == QLatin1String( "pole_of_inaccessibility" ) )
167  return PoleOfInaccessibility;
168  else if ( cleaned == QLatin1String( "point_on_exterior" ) )
169  return PointOnExterior;
170  else if ( cleaned == QLatin1String( "point_on_surface" ) )
171  return PointOnSurface;
172  else if ( cleaned == QLatin1String( "centroid" ) )
173  return Centroid;
174 
175  if ( ok )
176  *ok = false;
177  return PoleOfInaccessibility;
178 }
179 
181 {
182  switch ( anchor )
183  {
185  return QStringLiteral( "pole_of_inaccessibility" );
186  case PointOnExterior:
187  return QStringLiteral( "point_on_exterior" );
188  case PointOnSurface:
189  return QStringLiteral( "point_on_surface" );
190  case Centroid:
191  return QStringLiteral( "centroid" );
192  }
193  return QString();
194 }
195 
197 {
198  switch ( anchor )
199  {
201  return QStringLiteral( "point_on_exterior" );
202  case LabelCentroid:
203  return QStringLiteral( "centroid" );
204  case LabelTopLeft:
205  return QStringLiteral( "tl" );
206  case LabelTopMiddle:
207  return QStringLiteral( "t" );
208  case LabelTopRight:
209  return QStringLiteral( "tr" );
210  case LabelMiddleLeft:
211  return QStringLiteral( "l" );
212  case LabelMiddleRight:
213  return QStringLiteral( "r" );
214  case LabelBottomLeft:
215  return QStringLiteral( "bl" );
216  case LabelBottomMiddle:
217  return QStringLiteral( "b" );
218  case LabelBottomRight:
219  return QStringLiteral( "br" );
220  }
221 
222  return QString();
223 }
224 
226 {
227  if ( ok )
228  *ok = true;
229  QString cleaned = name.toLower().trimmed();
230 
231  if ( cleaned == QLatin1String( "point_on_exterior" ) )
232  return LabelPointOnExterior;
233  else if ( cleaned == QLatin1String( "centroid" ) )
234  return LabelCentroid;
235  else if ( cleaned == QLatin1String( "tl" ) )
236  return LabelTopLeft;
237  else if ( cleaned == QLatin1String( "t" ) )
238  return LabelTopMiddle;
239  else if ( cleaned == QLatin1String( "tr" ) )
240  return LabelTopRight;
241  else if ( cleaned == QLatin1String( "l" ) )
242  return LabelMiddleLeft;
243  else if ( cleaned == QLatin1String( "r" ) )
244  return LabelMiddleRight;
245  else if ( cleaned == QLatin1String( "bl" ) )
246  return LabelBottomLeft;
247  else if ( cleaned == QLatin1String( "b" ) )
248  return LabelBottomMiddle;
249  else if ( cleaned == QLatin1String( "br" ) )
250  return LabelBottomRight;
251 
252  if ( ok )
253  *ok = false;
254  return LabelPointOnExterior;
255 }
256 
257 QgsGeometry QgsCallout::labelAnchorGeometry( QRectF rect, const double angle, LabelAnchorPoint anchor ) const
258 {
259  QgsGeometry label;
260  switch ( anchor )
261  {
263  label = QgsGeometry::fromRect( rect );
264  break;
265 
266  case LabelCentroid:
267  label = QgsGeometry::fromRect( rect ).centroid();
268  break;
269 
270  case LabelTopLeft:
271  label = QgsGeometry::fromPointXY( QgsPointXY( rect.bottomLeft() ) );
272  break;
273 
274  case LabelTopMiddle:
275  label = QgsGeometry::fromPointXY( QgsPointXY( ( rect.left() + rect.right() ) / 2.0, rect.bottom() ) );
276  break;
277 
278  case LabelTopRight:
279  label = QgsGeometry::fromPointXY( QgsPointXY( rect.bottomRight() ) );
280  break;
281 
282  case LabelMiddleLeft:
283  label = QgsGeometry::fromPointXY( QgsPointXY( rect.left(), ( rect.top() + rect.bottom() ) / 2.0 ) );
284  break;
285 
286  case LabelMiddleRight:
287  label = QgsGeometry::fromPointXY( QgsPointXY( rect.right(), ( rect.top() + rect.bottom() ) / 2.0 ) );
288  break;
289 
290  case LabelBottomLeft:
291  label = QgsGeometry::fromPointXY( QgsPointXY( rect.topLeft() ) );
292  break;
293 
294  case LabelBottomMiddle:
295  label = QgsGeometry::fromPointXY( QgsPointXY( ( rect.left() + rect.right() ) / 2.0, rect.top() ) );
296  break;
297 
298  case LabelBottomRight:
299  label = QgsGeometry::fromPointXY( QgsPointXY( rect.topRight() ) );
300  break;
301  }
302 
303  label.rotate( angle, rect.topLeft() );
304  return label;
305 }
306 
307 //
308 // QgsSimpleLineCallout
309 //
310 
312 {
313  mLineSymbol = qgis::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << new QgsSimpleLineSymbolLayer( QColor( 60, 60, 60 ), .3 ) );
314 
315 }
316 
318 
320  : QgsCallout( other )
321  , mLineSymbol( other.mLineSymbol ? other.mLineSymbol->clone() : nullptr )
322  , mMinCalloutLength( other.mMinCalloutLength )
323  , mMinCalloutLengthUnit( other.mMinCalloutLengthUnit )
324  , mMinCalloutLengthScale( other.mMinCalloutLengthScale )
325  , mOffsetFromAnchorDistance( other.mOffsetFromAnchorDistance )
326  , mOffsetFromAnchorUnit( other.mOffsetFromAnchorUnit )
327  , mOffsetFromAnchorScale( other.mOffsetFromAnchorScale )
328  , mOffsetFromLabelDistance( other.mOffsetFromLabelDistance )
329  , mOffsetFromLabelUnit( other.mOffsetFromLabelUnit )
330  , mOffsetFromLabelScale( other.mOffsetFromLabelScale )
331  , mDrawCalloutToAllParts( other.mDrawCalloutToAllParts )
332 {
333 
334 }
335 
336 QgsCallout *QgsSimpleLineCallout::create( const QVariantMap &properties, const QgsReadWriteContext &context )
337 {
338  std::unique_ptr< QgsSimpleLineCallout > callout = qgis::make_unique< QgsSimpleLineCallout >();
339  callout->readProperties( properties, context );
340  return callout.release();
341 }
342 
344 {
345  return QStringLiteral( "simple" );
346 }
347 
349 {
350  return new QgsSimpleLineCallout( *this );
351 }
352 
353 QVariantMap QgsSimpleLineCallout::properties( const QgsReadWriteContext &context ) const
354 {
355  QVariantMap props = QgsCallout::properties( context );
356 
357  if ( mLineSymbol )
358  {
359  props[ QStringLiteral( "lineSymbol" ) ] = QgsSymbolLayerUtils::symbolProperties( mLineSymbol.get() );
360  }
361  props[ QStringLiteral( "minLength" ) ] = mMinCalloutLength;
362  props[ QStringLiteral( "minLengthUnit" ) ] = QgsUnitTypes::encodeUnit( mMinCalloutLengthUnit );
363  props[ QStringLiteral( "minLengthMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mMinCalloutLengthScale );
364 
365  props[ QStringLiteral( "offsetFromAnchor" ) ] = mOffsetFromAnchorDistance;
366  props[ QStringLiteral( "offsetFromAnchorUnit" ) ] = QgsUnitTypes::encodeUnit( mOffsetFromAnchorUnit );
367  props[ QStringLiteral( "offsetFromAnchorMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetFromAnchorScale );
368  props[ QStringLiteral( "offsetFromLabel" ) ] = mOffsetFromLabelDistance;
369  props[ QStringLiteral( "offsetFromLabelUnit" ) ] = QgsUnitTypes::encodeUnit( mOffsetFromLabelUnit );
370  props[ QStringLiteral( "offsetFromLabelMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetFromLabelScale );
371 
372  props[ QStringLiteral( "drawToAllParts" ) ] = mDrawCalloutToAllParts;
373 
374  return props;
375 }
376 
377 void QgsSimpleLineCallout::readProperties( const QVariantMap &props, const QgsReadWriteContext &context )
378 {
379  QgsCallout::readProperties( props, context );
380 
381  const QString lineSymbolDef = props.value( QStringLiteral( "lineSymbol" ) ).toString();
382  QDomDocument doc( QStringLiteral( "symbol" ) );
383  doc.setContent( lineSymbolDef );
384  QDomElement symbolElem = doc.firstChildElement( QStringLiteral( "symbol" ) );
385  std::unique_ptr< QgsLineSymbol > lineSymbol( QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( symbolElem, context ) );
386  if ( lineSymbol )
387  mLineSymbol = std::move( lineSymbol );
388 
389  mMinCalloutLength = props.value( QStringLiteral( "minLength" ), 0 ).toDouble();
390  mMinCalloutLengthUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "minLengthUnit" ) ).toString() );
391  mMinCalloutLengthScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "minLengthMapUnitScale" ) ).toString() );
392 
393  mOffsetFromAnchorDistance = props.value( QStringLiteral( "offsetFromAnchor" ), 0 ).toDouble();
394  mOffsetFromAnchorUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "offsetFromAnchorUnit" ) ).toString() );
395  mOffsetFromAnchorScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "offsetFromAnchorMapUnitScale" ) ).toString() );
396  mOffsetFromLabelDistance = props.value( QStringLiteral( "offsetFromLabel" ), 0 ).toDouble();
397  mOffsetFromLabelUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "offsetFromLabelUnit" ) ).toString() );
398  mOffsetFromLabelScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "offsetFromLabelMapUnitScale" ) ).toString() );
399 
400  mDrawCalloutToAllParts = props.value( QStringLiteral( "drawToAllParts" ), false ).toBool();
401 }
402 
404 {
405  QgsCallout::startRender( context );
406  if ( mLineSymbol )
407  mLineSymbol->startRender( context );
408 }
409 
411 {
412  QgsCallout::stopRender( context );
413  if ( mLineSymbol )
414  mLineSymbol->stopRender( context );
415 }
416 
417 QSet<QString> QgsSimpleLineCallout::referencedFields( const QgsRenderContext &context ) const
418 {
419  QSet<QString> fields = QgsCallout::referencedFields( context );
420  if ( mLineSymbol )
421  fields.unite( mLineSymbol->usedAttributes( context ) );
422  return fields;
423 }
424 
426 {
427  return mLineSymbol.get();
428 }
429 
431 {
432  mLineSymbol.reset( symbol );
433 }
434 
435 void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext )
436 {
437  LabelAnchorPoint labelAnchor = labelAnchorPoint();
439  {
440  QString encodedAnchor = encodeLabelAnchorPoint( labelAnchor );
441  context.expressionContext().setOriginalValueVariable( encodedAnchor );
442  labelAnchor = decodeLabelAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::LabelAnchorPointPosition, context.expressionContext(), encodedAnchor ) );
443  }
444  QgsGeometry label = labelAnchorGeometry( rect, angle, labelAnchor );
445 
446  auto drawCalloutLine = [this, &context, &label]( const QgsGeometry & partAnchor )
447  {
448  QgsGeometry line;
449  AnchorPoint anchor = anchorPoint();
451  {
452  QString encodedAnchor = encodeAnchorPoint( anchor );
453  context.expressionContext().setOriginalValueVariable( encodedAnchor );
454  anchor = decodeAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::AnchorPointPosition, context.expressionContext(), encodedAnchor ) );
455  }
456  switch ( partAnchor.type() )
457  {
459  line = label.shortestLine( partAnchor );
460  break;
461 
463  line = label.shortestLine( partAnchor );
464  break;
465 
467  if ( label.intersects( partAnchor ) )
468  return;
469 
470  switch ( anchor )
471  {
473  line = label.shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) ); // really rough (but quick) pole of inaccessibility
474  break;
476  line = label.shortestLine( partAnchor.pointOnSurface() );
477  break;
479  line = label.shortestLine( partAnchor );
480  break;
482  line = label.shortestLine( partAnchor.centroid() );
483  break;
484  }
485  break;
486 
489  return; // shouldn't even get here..
490  }
491 
492  if ( qgsDoubleNear( line.length(), 0 ) )
493  return;
494 
495  double minLength = mMinCalloutLength;
497  {
498  context.expressionContext().setOriginalValueVariable( minLength );
500  }
501  double minLengthPixels = context.convertToPainterUnits( minLength, mMinCalloutLengthUnit, mMinCalloutLengthScale );
502  if ( minLengthPixels > 0 && line.length() < minLengthPixels )
503  return; // too small!
504 
505  double offsetFromAnchor = mOffsetFromAnchorDistance;
507  {
510  }
511  const double offsetFromAnchorPixels = context.convertToPainterUnits( offsetFromAnchor, mOffsetFromAnchorUnit, mOffsetFromAnchorScale );
512 
513  double offsetFromLabel = mOffsetFromLabelDistance;
515  {
518  }
519  const double offsetFromLabelPixels = context.convertToPainterUnits( offsetFromLabel, mOffsetFromLabelUnit, mOffsetFromLabelScale );
520  if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
521  {
522  if ( QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.get() ) )
523  {
524  line = QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
525  }
526  }
527 
528  mLineSymbol->renderPolyline( line.asQPolygonF(), nullptr, context );
529  };
530 
531  bool toAllParts = mDrawCalloutToAllParts;
533  {
534  context.expressionContext().setOriginalValueVariable( toAllParts );
536  }
537 
538  if ( calloutContext.allFeaturePartsLabeled || !toAllParts )
539  drawCalloutLine( anchor );
540  else
541  {
542  const QVector< QgsGeometry > parts = anchor.asGeometryCollection();
543  for ( const QgsGeometry &part : parts )
544  drawCalloutLine( part );
545  }
546 }
547 
548 
549 
550 //
551 // QgsManhattanLineCallout
552 //
553 
555 {
556 }
557 
559  : QgsSimpleLineCallout( other )
560 {
561 
562 }
563 
564 
565 QgsCallout *QgsManhattanLineCallout::create( const QVariantMap &properties, const QgsReadWriteContext &context )
566 {
567  std::unique_ptr< QgsManhattanLineCallout > callout = qgis::make_unique< QgsManhattanLineCallout >();
568  callout->readProperties( properties, context );
569  return callout.release();
570 }
571 
573 {
574  return QStringLiteral( "manhattan" );
575 }
576 
578 {
579  return new QgsManhattanLineCallout( *this );
580 }
581 
582 void QgsManhattanLineCallout::draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext )
583 {
584  LabelAnchorPoint labelAnchor = labelAnchorPoint();
586  {
587  QString encodedAnchor = encodeLabelAnchorPoint( labelAnchor );
588  context.expressionContext().setOriginalValueVariable( encodedAnchor );
589  labelAnchor = decodeLabelAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::LabelAnchorPointPosition, context.expressionContext(), encodedAnchor ) );
590  }
591  QgsGeometry label = labelAnchorGeometry( rect, angle, labelAnchor );
592 
593  auto drawCalloutLine = [this, &context, &label]( const QgsGeometry & partAnchor )
594  {
595  QgsGeometry line;
596  AnchorPoint anchor = anchorPoint();
598  {
599  QString encodedAnchor = encodeAnchorPoint( anchor );
600  context.expressionContext().setOriginalValueVariable( encodedAnchor );
601  anchor = decodeAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::AnchorPointPosition, context.expressionContext(), encodedAnchor ) );
602  }
603  switch ( partAnchor.type() )
604  {
606  line = label.shortestLine( partAnchor );
607  break;
608 
610  line = label.shortestLine( partAnchor );
611  break;
612 
614  if ( label.intersects( partAnchor ) )
615  return;
616 
617  switch ( anchor )
618  {
620  line = label.shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) ); // really rough (but quick) pole of inaccessibility
621  break;
623  line = label.shortestLine( partAnchor.pointOnSurface() );
624  break;
626  line = label.shortestLine( partAnchor );
627  break;
629  line = label.shortestLine( partAnchor.centroid() );
630  break;
631  }
632  break;
633 
636  return; // shouldn't even get here..
637  }
638 
639  if ( qgsDoubleNear( line.length(), 0 ) )
640  return;
641 
642  double minLength = minimumLength();
644  {
646  }
647  double minLengthPixels = context.convertToPainterUnits( minLength, minimumLengthUnit(), minimumLengthMapUnitScale() );
648  if ( minLengthPixels > 0 && line.length() < minLengthPixels )
649  return; // too small!
650 
651  const QgsPoint start = qgsgeometry_cast< const QgsLineString * >( line.constGet() )->startPoint();
652  const QgsPoint end = qgsgeometry_cast< const QgsLineString * >( line.constGet() )->endPoint();
653  QgsPoint mid1 = QgsPoint( start.x(), end.y() );
654 
655  line = QgsGeometry::fromPolyline( QgsPolyline() << start << mid1 << end );
656  double offsetFromAnchorDist = offsetFromAnchor();
658  {
659  offsetFromAnchorDist = dataDefinedProperties().valueAsDouble( QgsCallout::OffsetFromAnchor, context.expressionContext(), offsetFromAnchorDist );
660  }
661  const double offsetFromAnchorPixels = context.convertToPainterUnits( offsetFromAnchorDist, offsetFromAnchorUnit(), offsetFromAnchorMapUnitScale() );
662 
663  double offsetFromLabelDist = offsetFromLabel();
665  {
666  offsetFromLabelDist = dataDefinedProperties().valueAsDouble( QgsCallout::OffsetFromLabel, context.expressionContext(), offsetFromLabelDist );
667  }
668  const double offsetFromLabelPixels = context.convertToPainterUnits( offsetFromLabelDist, offsetFromAnchorUnit(), offsetFromAnchorMapUnitScale() );
669 
670  if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
671  {
672  if ( QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.get() ) )
673  {
674  line = QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
675  }
676  }
677 
678  lineSymbol()->renderPolyline( line.asQPolygonF(), nullptr, context );
679  };
680 
681  bool toAllParts = drawCalloutToAllParts();
683  {
684  context.expressionContext().setOriginalValueVariable( toAllParts );
686  }
687 
688  if ( calloutContext.allFeaturePartsLabeled || !toAllParts )
689  drawCalloutLine( anchor );
690  else
691  {
692  const QVector< QgsGeometry > parts = anchor.asGeometryCollection();
693  for ( const QgsGeometry &part : parts )
694  drawCalloutLine( part );
695  }
696 }
QgsCallout::LabelPointOnExterior
@ LabelPointOnExterior
The point on the label's boundary closest to the feature.
Definition: qgscallout.h:101
QgsSimpleLineCallout::lineSymbol
QgsLineSymbol * lineSymbol()
Returns the line symbol used to render the callout line.
Definition: qgscallout.cpp:425
QgsPropertyCollection::prepare
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const override
Prepares the collection against a specified expression context.
Definition: qgspropertycollection.cpp:240
QgsAbstractPropertyCollection::valueAsDouble
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
Definition: qgspropertycollection.cpp:66
QgsRenderContext::convertToPainterUnits
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
Definition: qgsrendercontext.cpp:318
QgsCallout::OffsetFromAnchor
@ OffsetFromAnchor
Distance to offset lines from anchor points.
Definition: qgscallout.h:72
QgsSimpleLineCallout::offsetFromAnchor
double offsetFromAnchor() const
Returns the offset distance from the anchor point at which to start the line.
Definition: qgscallout.h:499
QgsSimpleLineCallout::~QgsSimpleLineCallout
~QgsSimpleLineCallout() override
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:596
qgslinestring.h
QgsCallout::AnchorPoint
AnchorPoint
Feature's anchor point position.
Definition: qgscallout.h:88
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsWkbTypes::NullGeometry
@ NullGeometry
Definition: qgswkbtypes.h:146
QgsCallout
Abstract base class for callout renderers.
Definition: qgscallout.h:47
QgsSymbolLayerUtils::encodeMapUnitScale
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
Definition: qgssymbollayerutils.cpp:558
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsGeometry::fromPolyline
static QgsGeometry fromPolyline(const QgsPolyline &polyline)
Creates a new LineString geometry from a list of QgsPoint points.
Definition: qgsgeometry.cpp:184
QgsPropertyDefinition::DataTypeString
@ DataTypeString
Property requires a string value.
Definition: qgsproperty.h:93
QgsExpressionContext::setOriginalValueVariable
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
Definition: qgsexpressioncontext.cpp:566
qgssymbollayerutils.h
QgsCallout::propertyDefinitions
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in callouts.
Definition: qgscallout.cpp:150
QgsGeometry::fromPointXY
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
Definition: qgsgeometry.cpp:164
QgsGeometry::centroid
QgsGeometry centroid() const
Returns the center of mass of a geometry.
Definition: qgsgeometry.cpp:2138
QgsRectangle::toRectF
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:468
QgsPropertyCollection::loadVariant
bool loadVariant(const QVariant &configuration, const QgsPropertiesDefinition &definitions) override
Loads this property collection from a QVariantMap, wrapped in a QVariant.
Definition: qgspropertycollection.cpp:341
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
QgsGeometry::rotate
OperationResult rotate(double rotation, const QgsPointXY &center)
Rotate this geometry around the Z axis.
Definition: qgsgeometry.cpp:815
QgsCallout::anchorPoint
AnchorPoint anchorPoint() const
Returns the feature's anchor point position.
Definition: qgscallout.h:289
QgsCallout::LabelCentroid
@ LabelCentroid
The labe's centroid.
Definition: qgscallout.h:102
QgsSimpleLineCallout::setLineSymbol
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the callout line.
Definition: qgscallout.cpp:430
QgsCallout::PoleOfInaccessibility
@ PoleOfInaccessibility
The surface's pole of inaccessibility used as anchor for polygon geometries.
Definition: qgscallout.h:89
QgsSimpleLineCallout::create
static QgsCallout * create(const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext())
Creates a new QgsSimpleLineCallout, using the settings serialized in the properties map (correspondin...
Definition: qgscallout.cpp:336
QgsCallout::LabelBottomMiddle
@ LabelBottomMiddle
Bottom middle of the label's boundary.
Definition: qgscallout.h:109
QgsManhattanLineCallout::clone
QgsManhattanLineCallout * clone() const override
Duplicates a callout by creating a deep copy of the callout.
Definition: qgscallout.cpp:577
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
QgsSimpleLineCallout::clone
QgsSimpleLineCallout * clone() const override
Duplicates a callout by creating a deep copy of the callout.
Definition: qgscallout.cpp:348
QgsManhattanLineCallout::QgsManhattanLineCallout
QgsManhattanLineCallout()
Definition: qgscallout.cpp:554
QgsCallout::type
virtual QString type() const =0
Returns a unique string representing the callout type.
QgsCallout::AnchorPointPosition
@ AnchorPointPosition
Feature's anchor point position.
Definition: qgscallout.h:75
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsGeometry::asGeometryCollection
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
Definition: qgsgeometry.cpp:2517
QgsCallout::PointOnExterior
@ PointOnExterior
A point on the surface's outline closest to the label is used as anchor for polygon geometries.
Definition: qgscallout.h:90
QgsCallout::LabelMiddleRight
@ LabelMiddleRight
Middle right of the label's boundary.
Definition: qgscallout.h:107
QgsSimpleLineCallout::referencedFields
QSet< QString > referencedFields(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the callout.
Definition: qgscallout.cpp:417
QgsSymbolLayerUtils::symbolProperties
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
Definition: qgssymbollayerutils.cpp:1228
QgsCallout::LabelTopLeft
@ LabelTopLeft
Top left corner of the label's boundary.
Definition: qgscallout.h:103
QgsUnitTypes::decodeRenderUnit
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
Definition: qgsunittypes.cpp:2900
QgsSimpleLineCallout::properties
QVariantMap properties(const QgsReadWriteContext &context) const override
Returns the properties describing the callout encoded in a string format.
Definition: qgscallout.cpp:353
QgsPoint::y
double y
Definition: qgspoint.h:42
QgsSimpleLineCallout::minimumLength
double minimumLength() const
Returns the minimum length of callout lines.
Definition: qgscallout.h:454
QgsPropertiesDefinition
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
Definition: qgspropertycollection.h:29
QgsGeometry::asQPolygonF
QPolygonF asQPolygonF() const SIP_HOLDGIL
Returns contents of the geometry as a QPolygonF.
Definition: qgsgeometry.cpp:2549
AnchorPoint
record about vertex coordinates and index of anchor to which it is snapped
Definition: qgsgeometrysnappersinglesource.cpp:30
QgsCallout::restoreProperties
virtual void restoreProperties(const QDomElement &element, const QgsReadWriteContext &context)
Restores the callout's properties from a DOM element.
Definition: qgscallout.cpp:92
QgsSimpleLineCallout::offsetFromLabel
double offsetFromLabel() const
Returns the offset distance from label area at which to end the line.
Definition: qgscallout.h:543
QgsGeometry::intersects
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
Definition: qgsgeometry.cpp:1129
QgsUnitTypes::encodeUnit
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
Definition: qgsunittypes.cpp:122
QgsCallout::LabelAnchorPointPosition
@ LabelAnchorPointPosition
Label's anchor point position.
Definition: qgscallout.h:76
QgsSimpleLineCallout::readProperties
void readProperties(const QVariantMap &props, const QgsReadWriteContext &context) override
Reads a string map of an callout's properties and restores the callout to the state described by the ...
Definition: qgscallout.cpp:377
QgsXmlUtils::readVariant
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
Definition: qgsxmlutils.cpp:251
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsSimpleLineSymbolLayer
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
Definition: qgslinesymbollayer.h:40
QgsCallout::QgsCalloutContext::allFeaturePartsLabeled
bool allFeaturePartsLabeled
true if all parts of associated feature were labeled
Definition: qgscallout.h:217
QgsCallout::decodeAnchorPoint
static QgsCallout::AnchorPoint decodeAnchorPoint(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of an anchor point name to the corresponding anchor point.
Definition: qgscallout.cpp:160
QgsCallout::labelAnchorPoint
LabelAnchorPoint labelAnchorPoint() const
Returns the label's anchor point position.
Definition: qgscallout.h:322
qgsrendercontext.h
QgsLineSymbol
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1131
QgsCallout::DrawCalloutToAllParts
@ DrawCalloutToAllParts
Whether callout lines should be drawn to all feature parts.
Definition: qgscallout.h:74
QgsCallout::encodeLabelAnchorPoint
static QString encodeLabelAnchorPoint(LabelAnchorPoint anchor)
Encodes a label anchor point to its string representation.
Definition: qgscallout.cpp:196
QgsCallout::drawOrder
virtual DrawOrder drawOrder() const
Returns the desired drawing order (stacking) to use while rendering this callout.
Definition: qgscallout.cpp:113
QgsPoint::x
Q_GADGET double x
Definition: qgspoint.h:41
QgsPropertyDefinition
Definition for a property.
Definition: qgsproperty.h:48
QgsCallout::Centroid
@ Centroid
The surface's centroid is used as anchor for polygon geometries.
Definition: qgscallout.h:92
QgsGeometry::length
double length() const
Returns the planar, 2-dimensional length of geometry.
Definition: qgsgeometry.cpp:1783
QgsSimpleLineCallout::offsetFromAnchorMapUnitScale
const QgsMapUnitScale & offsetFromAnchorMapUnitScale() const
Returns the map unit scale for the offset from anchor.
Definition: qgscallout.h:536
QgsSimpleLineCallout
A simple direct line callout style.
Definition: qgscallout.h:402
QgsCallout::QgsCallout
QgsCallout()
Constructor for QgsCallout.
Definition: qgscallout.cpp:53
QgsSimpleLineCallout::draw
void draw(QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext) override
Performs the actual rendering of the callout implementation onto the specified render context.
Definition: qgscallout.cpp:435
QgsRectangle::buffered
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:304
QgsSimpleLineCallout::QgsSimpleLineCallout
QgsSimpleLineCallout()
Definition: qgscallout.cpp:311
QgsPropertyCollection::referencedFields
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext(), bool ignoreContext=false) const override
Returns the set of any fields referenced by the active properties from the collection.
Definition: qgspropertycollection.cpp:254
QgsCallout::setEnabled
void setEnabled(bool enabled)
Sets whether the callout is enabled.
Definition: qgscallout.cpp:145
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsCallout::encodeAnchorPoint
static QString encodeAnchorPoint(AnchorPoint anchor)
Encodes an anchor point to its string representation.
Definition: qgscallout.cpp:180
QgsCallout::readProperties
virtual void readProperties(const QVariantMap &props, const QgsReadWriteContext &context)
Reads a string map of an callout's properties and restores the callout to the state described by the ...
Definition: qgscallout.cpp:67
QgsCallout::decodeLabelAnchorPoint
static QgsCallout::LabelAnchorPoint decodeLabelAnchorPoint(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a label anchor point name to the corresponding anchor p...
Definition: qgscallout.cpp:225
qgsxmlutils.h
QgsPolyline
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:71
QgsCallout::DrawOrder
DrawOrder
Options for draw order (stacking) of callouts.
Definition: qgscallout.h:81
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsCallout::properties
virtual QVariantMap properties(const QgsReadWriteContext &context) const
Returns the properties describing the callout encoded in a string format.
Definition: qgscallout.cpp:57
QgsCallout::LabelBottomLeft
@ LabelBottomLeft
Bottom left corner of the label's boundary.
Definition: qgscallout.h:108
QgsSimpleLineCallout::startRender
void startRender(QgsRenderContext &context) override
Prepares the callout for rendering on the specified render context.
Definition: qgscallout.cpp:403
QgsManhattanLineCallout::type
QString type() const override
Returns a unique string representing the callout type.
Definition: qgscallout.cpp:572
QgsGeometry::get
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:133
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsManhattanLineCallout
Draws straight (right angled) lines as callouts.
Definition: qgscallout.h:630
QgsSimpleLineCallout::minimumLengthMapUnitScale
const QgsMapUnitScale & minimumLengthMapUnitScale() const
Returns the map unit scale for the minimum callout length.
Definition: qgscallout.h:491
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
qgscallout.h
qgslinesymbollayer.h
QgsSimpleLineCallout::offsetFromAnchorUnit
QgsUnitTypes::RenderUnit offsetFromAnchorUnit() const
Returns the units for the offset from anchor point.
Definition: qgscallout.h:520
QgsGeometry::shortestLine
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Definition: qgsgeometry.cpp:625
QgsPropertyDefinition::Boolean
@ Boolean
Boolean value.
Definition: qgsproperty.h:54
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsAbstractPropertyCollection::valueAsBool
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
Definition: qgspropertycollection.cpp:88
QgsSimpleLineCallout::minimumLengthUnit
QgsUnitTypes::RenderUnit minimumLengthUnit() const
Returns the units for the minimum length of callout lines.
Definition: qgscallout.h:475
QgsSymbolLayerList
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:53
QgsCallout::referencedFields
virtual QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns the set of attributes referenced by the callout.
Definition: qgscallout.cpp:107
QgsCallout::render
void render(QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext)
Renders the callout onto the specified render context.
Definition: qgscallout.cpp:118
QgsCallout::MinimumCalloutLength
@ MinimumCalloutLength
Minimum length of callouts.
Definition: qgscallout.h:71
QgsGeometry::fromRect
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
Definition: qgsgeometry.cpp:229
QgsLineSymbol::renderPolyline
void renderPolyline(const QPolygonF &points, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
Renders the symbol along the line joining points, using the given render context.
Definition: qgssymbol.cpp:2125
QgsCallout::QgsCalloutContext
Contains additional contextual information about the context in which a callout is being rendered.
Definition: qgscallout.h:215
QgsWkbTypes::UnknownGeometry
@ UnknownGeometry
Definition: qgswkbtypes.h:145
QgsCallout::LabelMiddleLeft
@ LabelMiddleLeft
Middle left of the label's boundary.
Definition: qgscallout.h:106
QgsCallout::draw
virtual void draw(QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext)=0
Performs the actual rendering of the callout implementation onto the specified render context.
QgsCallout::LabelBottomRight
@ LabelBottomRight
Bottom right corner of the label's boundary.
Definition: qgscallout.h:110
QgsCallout::labelAnchorGeometry
QgsGeometry labelAnchorGeometry(QRectF bodyBoundingBox, const double angle, LabelAnchorPoint anchor) const
Returns the anchor point geometry for a label with the given bounding box and anchor point mode.
Definition: qgscallout.cpp:257
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:996
QgsCallout::LabelTopMiddle
@ LabelTopMiddle
Top middle of the label's boundary.
Definition: qgscallout.h:104
QgsSimpleLineCallout::type
QString type() const override
Returns a unique string representing the callout type.
Definition: qgscallout.cpp:343
QgsCallout::startRender
virtual void startRender(QgsRenderContext &context)
Prepares the callout for rendering on the specified render context.
Definition: qgscallout.cpp:98
QgsCallout::stopRender
virtual void stopRender(QgsRenderContext &context)
Finalises the callout after a set of rendering operations on the specified render context.
Definition: qgscallout.cpp:102
QgsPropertyCollection::toVariant
QVariant toVariant(const QgsPropertiesDefinition &definitions) const override
Saves this property collection to a QVariantMap, wrapped in a QVariant.
Definition: qgspropertycollection.cpp:320
QgsCallout::saveProperties
virtual bool saveProperties(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context) const
Saves the current state of the callout to a DOM element.
Definition: qgscallout.cpp:75
qgslogger.h
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:179
QgsSimpleLineCallout::drawCalloutToAllParts
bool drawCalloutToAllParts() const
Returns true if callout lines should be drawn to all feature parts.
Definition: qgscallout.h:587
QgsManhattanLineCallout::create
static QgsCallout * create(const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext())
Creates a new QgsManhattanLineCallout, using the settings serialized in the properties map (correspon...
Definition: qgscallout.cpp:565
QgsSimpleLineCallout::stopRender
void stopRender(QgsRenderContext &context) override
Finalises the callout after a set of rendering operations on the specified render context.
Definition: qgscallout.cpp:410
QgsXmlUtils::writeVariant
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
Definition: qgsxmlutils.cpp:106
QgsCallout::OrderBelowAllLabels
@ OrderBelowAllLabels
Render callouts below all labels.
Definition: qgscallout.h:82
MathUtils::angle
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
QgsCallout::LabelAnchorPoint
LabelAnchorPoint
Label's anchor point position.
Definition: qgscallout.h:100
qgssymbol.h
QgsSymbolLayerUtils::decodeMapUnitScale
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
Definition: qgssymbollayerutils.cpp:568
QgsCallout::OffsetFromLabel
@ OffsetFromLabel
Distance to offset lines from label area.
Definition: qgscallout.h:73
QgsManhattanLineCallout::draw
void draw(QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext) override
Performs the actual rendering of the callout implementation onto the specified render context.
Definition: qgscallout.cpp:582
QgsCallout::dataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the callout's property collection, used for data defined overrides.
Definition: qgscallout.h:259
QgsCallout::enabled
bool enabled() const
Returns true if the the callout is enabled.
Definition: qgscallout.h:247
QgsCallout::PointOnSurface
@ PointOnSurface
A point guaranteed to be on the surface is used as anchor for polygon geometries.
Definition: qgscallout.h:91
QgsCallout::LabelTopRight
@ LabelTopRight
Top right corner of the label's boundary.
Definition: qgscallout.h:105
QgsPropertyDefinition::DoublePositive
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:59