QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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 }
44 
45 
47 {
48 }
49 
50 QVariantMap QgsCallout::properties( const QgsReadWriteContext & ) const
51 {
52  QVariantMap props;
53  props.insert( QStringLiteral( "enabled" ), mEnabled ? "1" : "0" );
54  props.insert( QStringLiteral( "anchorPoint" ), encodeAnchorPoint( mAnchorPoint ) );
55  props.insert( QStringLiteral( "ddProperties" ), mDataDefinedProperties.toVariant( propertyDefinitions() ) );
56  return props;
57 }
58 
59 void QgsCallout::readProperties( const QVariantMap &props, const QgsReadWriteContext & )
60 {
61  mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
62  mAnchorPoint = decodeAnchorPoint( props.value( QStringLiteral( "anchorPoint" ), QString( "" ) ).toString() );
63  mDataDefinedProperties.loadVariant( props.value( QStringLiteral( "ddProperties" ) ), propertyDefinitions() );
64 }
65 
66 bool QgsCallout::saveProperties( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context ) const
67 {
68  if ( element.isNull() )
69  {
70  return false;
71  }
72 
73  QDomElement calloutPropsElement = QgsXmlUtils::writeVariant( properties( context ), doc );
74 
75  QDomElement calloutElement = doc.createElement( QStringLiteral( "callout" ) );
76  calloutElement.setAttribute( QStringLiteral( "type" ), type() );
77  calloutElement.appendChild( calloutPropsElement );
78 
79  element.appendChild( calloutElement );
80  return true;
81 }
82 
83 void QgsCallout::restoreProperties( const QDomElement &element, const QgsReadWriteContext &context )
84 {
85  const QVariantMap props = QgsXmlUtils::readVariant( element.firstChildElement() ).toMap();
86  readProperties( props, context );
87 }
88 
90 {
91 
92 }
94 {
95 
96 }
97 
98 QSet<QString> QgsCallout::referencedFields( const QgsRenderContext &context ) const
99 {
100  mDataDefinedProperties.prepare( context.expressionContext() );
101  return mDataDefinedProperties.referencedFields( context.expressionContext() );
102 }
103 
105 {
106  return OrderBelowAllLabels;
107 }
108 
109 void QgsCallout::render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext )
110 {
111  if ( !mEnabled )
112  return;
113 
114 #if 0 // for debugging
115  QPainter *painter = context.painter();
116  painter->save();
117  painter->setRenderHint( QPainter::Antialiasing, false );
118  painter->translate( rect.center() );
119  painter->rotate( -angle );
120 
121  painter->setBrush( QColor( 255, 0, 0, 100 ) );
122  painter->setPen( QColor( 255, 0, 0, 150 ) );
123 
124  painter->drawRect( rect.width() * -0.5, rect.height() * -0.5, rect.width(), rect.height() );
125  painter->restore();
126 
127  painter->setBrush( QColor( 0, 255, 0, 100 ) );
128  painter->setPen( QColor( 0, 255, 0, 150 ) );
129 
130  painter->drawRect( anchor.boundingBox( ).buffered( 30 ).toRectF() );
131 #endif
132 
133  draw( context, rect, angle, anchor, calloutContext );
134 }
135 
137 {
138  mEnabled = enabled;
139 }
140 
142 {
143  static std::once_flag initialized;
144  std::call_once( initialized, [ = ]( )
145  {
146  initPropertyDefinitions();
147  } );
148  return sPropertyDefinitions;
149 }
150 
152 {
153  if ( ok )
154  *ok = true;
155  QString cleaned = name.toLower().trimmed();
156 
157  if ( cleaned == QLatin1String( "pole_of_inaccessibility" ) )
158  return PoleOfInaccessibility;
159  else if ( cleaned == QLatin1String( "point_on_exterior" ) )
160  return PointOnExterior;
161  else if ( cleaned == QLatin1String( "point_on_surface" ) )
162  return PointOnSurface;
163  else if ( cleaned == QLatin1String( "centroid" ) )
164  return Centroid;
165 
166  if ( ok )
167  *ok = false;
168  return PoleOfInaccessibility;
169 }
170 
172 {
173  switch ( anchor )
174  {
176  return QStringLiteral( "pole_of_inaccessibility" );
177  case PointOnExterior:
178  return QStringLiteral( "point_on_exterior" );
179  case PointOnSurface:
180  return QStringLiteral( "point_on_surface" );
181  case Centroid:
182  return QStringLiteral( "centroid" );
183  }
184  return QString();
185 }
186 
187 //
188 // QgsSimpleLineCallout
189 //
190 
192 {
193  mLineSymbol = qgis::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << new QgsSimpleLineSymbolLayer( QColor( 60, 60, 60 ), .3 ) );
194 
195 }
196 
198 
200  : QgsCallout( other )
201  , mLineSymbol( other.mLineSymbol ? other.mLineSymbol->clone() : nullptr )
202  , mMinCalloutLength( other.mMinCalloutLength )
203  , mMinCalloutLengthUnit( other.mMinCalloutLengthUnit )
204  , mMinCalloutLengthScale( other.mMinCalloutLengthScale )
205  , mOffsetFromAnchorDistance( other.mOffsetFromAnchorDistance )
206  , mOffsetFromAnchorUnit( other.mOffsetFromAnchorUnit )
207  , mOffsetFromAnchorScale( other.mOffsetFromAnchorScale )
208  , mOffsetFromLabelDistance( other.mOffsetFromLabelDistance )
209  , mOffsetFromLabelUnit( other.mOffsetFromLabelUnit )
210  , mOffsetFromLabelScale( other.mOffsetFromLabelScale )
211  , mDrawCalloutToAllParts( other.mDrawCalloutToAllParts )
212 {
213 
214 }
215 
217 {
218  std::unique_ptr< QgsSimpleLineCallout > callout = qgis::make_unique< QgsSimpleLineCallout >();
219  callout->readProperties( properties, context );
220  return callout.release();
221 }
222 
224 {
225  return QStringLiteral( "simple" );
226 }
227 
229 {
230  return new QgsSimpleLineCallout( *this );
231 }
232 
233 QVariantMap QgsSimpleLineCallout::properties( const QgsReadWriteContext &context ) const
234 {
235  QVariantMap props = QgsCallout::properties( context );
236 
237  if ( mLineSymbol )
238  {
239  props[ QStringLiteral( "lineSymbol" ) ] = QgsSymbolLayerUtils::symbolProperties( mLineSymbol.get() );
240  }
241  props[ QStringLiteral( "minLength" ) ] = mMinCalloutLength;
242  props[ QStringLiteral( "minLengthUnit" ) ] = QgsUnitTypes::encodeUnit( mMinCalloutLengthUnit );
243  props[ QStringLiteral( "minLengthMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mMinCalloutLengthScale );
244 
245  props[ QStringLiteral( "offsetFromAnchor" ) ] = mOffsetFromAnchorDistance;
246  props[ QStringLiteral( "offsetFromAnchorUnit" ) ] = QgsUnitTypes::encodeUnit( mOffsetFromAnchorUnit );
247  props[ QStringLiteral( "offsetFromAnchorMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetFromAnchorScale );
248  props[ QStringLiteral( "offsetFromLabel" ) ] = mOffsetFromLabelDistance;
249  props[ QStringLiteral( "offsetFromLabelUnit" ) ] = QgsUnitTypes::encodeUnit( mOffsetFromLabelUnit );
250  props[ QStringLiteral( "offsetFromLabelMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetFromLabelScale );
251 
252  props[ QStringLiteral( "drawToAllParts" ) ] = mDrawCalloutToAllParts;
253 
254  return props;
255 }
256 
257 void QgsSimpleLineCallout::readProperties( const QVariantMap &props, const QgsReadWriteContext &context )
258 {
259  QgsCallout::readProperties( props, context );
260 
261  const QString lineSymbolDef = props.value( QStringLiteral( "lineSymbol" ) ).toString();
262  QDomDocument doc( QStringLiteral( "symbol" ) );
263  doc.setContent( lineSymbolDef );
264  QDomElement symbolElem = doc.firstChildElement( QStringLiteral( "symbol" ) );
265  std::unique_ptr< QgsLineSymbol > lineSymbol( QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( symbolElem, context ) );
266  if ( lineSymbol )
267  mLineSymbol = std::move( lineSymbol );
268 
269  mMinCalloutLength = props.value( QStringLiteral( "minLength" ), 0 ).toDouble();
270  mMinCalloutLengthUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "minLengthUnit" ) ).toString() );
271  mMinCalloutLengthScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "minLengthMapUnitScale" ) ).toString() );
272 
273  mOffsetFromAnchorDistance = props.value( QStringLiteral( "offsetFromAnchor" ), 0 ).toDouble();
274  mOffsetFromAnchorUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "offsetFromAnchorUnit" ) ).toString() );
275  mOffsetFromAnchorScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "offsetFromAnchorMapUnitScale" ) ).toString() );
276  mOffsetFromLabelDistance = props.value( QStringLiteral( "offsetFromLabel" ), 0 ).toDouble();
277  mOffsetFromLabelUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "offsetFromLabelUnit" ) ).toString() );
278  mOffsetFromLabelScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "offsetFromLabelMapUnitScale" ) ).toString() );
279 
280  mDrawCalloutToAllParts = props.value( QStringLiteral( "drawToAllParts" ), false ).toBool();
281 }
282 
284 {
285  QgsCallout::startRender( context );
286  if ( mLineSymbol )
287  mLineSymbol->startRender( context );
288 }
289 
291 {
292  QgsCallout::stopRender( context );
293  if ( mLineSymbol )
294  mLineSymbol->stopRender( context );
295 }
296 
297 QSet<QString> QgsSimpleLineCallout::referencedFields( const QgsRenderContext &context ) const
298 {
299  QSet<QString> fields = QgsCallout::referencedFields( context );
300  if ( mLineSymbol )
301  fields.unite( mLineSymbol->usedAttributes( context ) );
302  return fields;
303 }
304 
306 {
307  return mLineSymbol.get();
308 }
309 
311 {
312  mLineSymbol.reset( symbol );
313 }
314 
315 void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const double, const QgsGeometry &anchor, QgsCalloutContext &calloutContext )
316 {
317  QgsGeometry label( QgsGeometry::fromRect( rect ) );
318  auto drawCalloutLine = [this, &context, &label]( const QgsGeometry & partAnchor )
319  {
320  QgsGeometry line;
321  AnchorPoint anchor = anchorPoint();
323  {
324  QString encodedAnchor = encodeAnchorPoint( anchor );
325  context.expressionContext().setOriginalValueVariable( encodedAnchor );
326  anchor = decodeAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::AnchorPointPosition, context.expressionContext(), encodedAnchor ) );
327  }
328  switch ( partAnchor.type() )
329  {
331  line = label.shortestLine( partAnchor );
332  break;
333 
335  line = label.shortestLine( partAnchor );
336  break;
337 
339  if ( label.intersects( partAnchor ) )
340  return;
341 
342  switch ( anchor )
343  {
345  line = label.shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) ); // really rough (but quick) pole of inaccessibility
346  break;
348  line = label.shortestLine( partAnchor.pointOnSurface() );
349  break;
351  line = label.shortestLine( partAnchor );
352  break;
354  line = label.shortestLine( partAnchor.centroid() );
355  break;
356  }
357  break;
358 
361  return; // shouldn't even get here..
362  }
363 
364  if ( qgsDoubleNear( line.length(), 0 ) )
365  return;
366 
367  double minLength = mMinCalloutLength;
369  {
370  context.expressionContext().setOriginalValueVariable( minLength );
372  }
373  double minLengthPixels = context.convertToPainterUnits( minLength, mMinCalloutLengthUnit, mMinCalloutLengthScale );
374  if ( minLengthPixels > 0 && line.length() < minLengthPixels )
375  return; // too small!
376 
377  double offsetFromAnchor = mOffsetFromAnchorDistance;
379  {
380  context.expressionContext().setOriginalValueVariable( offsetFromAnchor );
382  }
383  const double offsetFromAnchorPixels = context.convertToPainterUnits( offsetFromAnchor, mOffsetFromAnchorUnit, mOffsetFromAnchorScale );
384 
385  double offsetFromLabel = mOffsetFromLabelDistance;
387  {
388  context.expressionContext().setOriginalValueVariable( offsetFromLabel );
390  }
391  const double offsetFromLabelPixels = context.convertToPainterUnits( offsetFromLabel, mOffsetFromLabelUnit, mOffsetFromLabelScale );
392  if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
393  {
394  if ( QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.get() ) )
395  {
396  line = QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
397  }
398  }
399 
400  mLineSymbol->renderPolyline( line.asQPolygonF(), nullptr, context );
401  };
402 
403  bool toAllParts = mDrawCalloutToAllParts;
405  {
406  context.expressionContext().setOriginalValueVariable( toAllParts );
408  }
409 
410  if ( calloutContext.allFeaturePartsLabeled || !toAllParts )
411  drawCalloutLine( anchor );
412  else
413  {
414  const QVector< QgsGeometry > parts = anchor.asGeometryCollection();
415  for ( const QgsGeometry &part : parts )
416  drawCalloutLine( part );
417  }
418 }
419 
420 
421 
422 //
423 // QgsManhattanLineCallout
424 //
425 
427 {
428 }
429 
431  : QgsSimpleLineCallout( other )
432 {
433 
434 }
435 
436 
438 {
439  std::unique_ptr< QgsManhattanLineCallout > callout = qgis::make_unique< QgsManhattanLineCallout >();
440  callout->readProperties( properties, context );
441  return callout.release();
442 }
443 
445 {
446  return QStringLiteral( "manhattan" );
447 }
448 
450 {
451  return new QgsManhattanLineCallout( *this );
452 }
453 
454 void QgsManhattanLineCallout::draw( QgsRenderContext &context, QRectF rect, const double, const QgsGeometry &anchor, QgsCalloutContext &calloutContext )
455 {
456  QgsGeometry label( QgsGeometry::fromRect( rect ) );
457  auto drawCalloutLine = [this, &context, &label]( const QgsGeometry & partAnchor )
458  {
459  QgsGeometry line;
460  AnchorPoint anchor = anchorPoint();
462  {
463  QString encodedAnchor = encodeAnchorPoint( anchor );
464  context.expressionContext().setOriginalValueVariable( encodedAnchor );
465  anchor = decodeAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::AnchorPointPosition, context.expressionContext(), encodedAnchor ) );
466  }
467  switch ( partAnchor.type() )
468  {
470  line = label.shortestLine( partAnchor );
471  break;
472 
474  line = label.shortestLine( partAnchor );
475  break;
476 
478  if ( label.intersects( partAnchor ) )
479  return;
480 
481  switch ( anchor )
482  {
484  line = label.shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) ); // really rough (but quick) pole of inaccessibility
485  break;
487  line = label.shortestLine( partAnchor.pointOnSurface() );
488  break;
490  line = label.shortestLine( partAnchor );
491  break;
493  line = label.shortestLine( partAnchor.centroid() );
494  break;
495  }
496  break;
497 
500  return; // shouldn't even get here..
501  }
502 
503  if ( qgsDoubleNear( line.length(), 0 ) )
504  return;
505 
506  double minLength = minimumLength();
508  {
510  }
511  double minLengthPixels = context.convertToPainterUnits( minLength, minimumLengthUnit(), minimumLengthMapUnitScale() );
512  if ( minLengthPixels > 0 && line.length() < minLengthPixels )
513  return; // too small!
514 
515  const QgsPoint start = qgsgeometry_cast< const QgsLineString * >( line.constGet() )->startPoint();
516  const QgsPoint end = qgsgeometry_cast< const QgsLineString * >( line.constGet() )->endPoint();
517  QgsPoint mid1 = QgsPoint( start.x(), end.y() );
518 
519  line = QgsGeometry::fromPolyline( QgsPolyline() << start << mid1 << end );
520  double offsetFromAnchorDist = offsetFromAnchor();
522  {
523  offsetFromAnchorDist = dataDefinedProperties().valueAsDouble( QgsCallout::OffsetFromAnchor, context.expressionContext(), offsetFromAnchorDist );
524  }
525  const double offsetFromAnchorPixels = context.convertToPainterUnits( offsetFromAnchorDist, offsetFromAnchorUnit(), offsetFromAnchorMapUnitScale() );
526 
527  double offsetFromLabelDist = offsetFromLabel();
529  {
530  offsetFromLabelDist = dataDefinedProperties().valueAsDouble( QgsCallout::OffsetFromLabel, context.expressionContext(), offsetFromLabelDist );
531  }
532  const double offsetFromLabelPixels = context.convertToPainterUnits( offsetFromLabelDist, offsetFromAnchorUnit(), offsetFromAnchorMapUnitScale() );
533 
534  if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
535  {
536  if ( QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.get() ) )
537  {
538  line = QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
539  }
540  }
541 
542  lineSymbol()->renderPolyline( line.asQPolygonF(), nullptr, context );
543  };
544 
545  bool toAllParts = drawCalloutToAllParts();
547  {
548  context.expressionContext().setOriginalValueVariable( toAllParts );
550  }
551 
552  if ( calloutContext.allFeaturePartsLabeled || !toAllParts )
553  drawCalloutLine( anchor );
554  else
555  {
556  const QVector< QgsGeometry > parts = anchor.asGeometryCollection();
557  for ( const QgsGeometry &part : parts )
558  drawCalloutLine( part );
559  }
560 }
QgsUnitTypes::RenderUnit minimumLengthUnit() const
Returns the units for the minimum length of callout lines.
Definition: qgscallout.h:413
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:454
The class is used as a container of context for various read/write operations on other objects...
double offsetFromLabel() const
Returns the offset distance from label area at which to end the line.
Definition: qgscallout.h:481
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:437
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:70
virtual void restoreProperties(const QDomElement &element, const QgsReadWriteContext &context)
Restores the callout&#39;s properties from a DOM element.
Definition: qgscallout.cpp:83
double y
Definition: qgspoint.h:42
Abstract base class for callout renderers.
Definition: qgscallout.h:46
const QgsMapUnitScale & offsetFromAnchorMapUnitScale() const
Returns the map unit scale for the offset from anchor.
Definition: qgscallout.h:474
static QgsGeometry fromPolyline(const QgsPolyline &polyline)
Creates a new LineString geometry from a list of QgsPoint points.
Minimum length of callouts.
Definition: qgscallout.h:71
virtual void stopRender(QgsRenderContext &context)
Finalises the callout after a set of rendering operations on the specified render context...
Definition: qgscallout.cpp:93
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...
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:109
Distance to offset lines from anchor points.
Definition: qgscallout.h:72
QgsUnitTypes::RenderUnit offsetFromAnchorUnit() const
Returns the units for the offset from anchor point.
Definition: qgscallout.h:458
Contains additional contextual information about the context in which a callout is being rendered...
Definition: qgscallout.h:195
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...
void startRender(QgsRenderContext &context) override
Prepares the callout for rendering on the specified render context.
Definition: qgscallout.cpp:283
A simple line symbol layer, which renders lines using a line in a variety of styles (e...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:280
virtual QgsCallout * clone() const =0
Duplicates a callout by creating a deep copy of the callout.
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:315
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:1883
QString type() const override
Returns a unique string representing the callout type.
Definition: qgscallout.cpp:223
The surface&#39;s centroid is used as anchor for polygon geometries.
Definition: qgscallout.h:91
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:122
QgsCallout()
Constructor for QgsCallout.
Definition: qgscallout.cpp:46
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:151
Feature&#39;s anchor point position.
Definition: qgscallout.h:75
virtual DrawOrder drawOrder() const
Returns the desired drawing order (stacking) to use while rendering this callout. ...
Definition: qgscallout.cpp:104
Positive double value (including 0)
Definition: qgsproperty.h:58
const QgsMapUnitScale & minimumLengthMapUnitScale() const
Returns the map unit scale for the minimum callout length.
Definition: qgscallout.h:429
The surface&#39;s pole of inaccessibility used as anchor for polygon geometries.
Definition: qgscallout.h:88
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
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1060
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsManhattanLineCallout * clone() const override
Duplicates a callout by creating a deep copy of the callout.
Definition: qgscallout.cpp:449
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const override
Prepares the collection against a specified expression context.
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:304
void stopRender(QgsRenderContext &context) override
Finalises the callout after a set of rendering operations on the specified render context...
Definition: qgscallout.cpp:290
virtual QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns the set of attributes referenced by the callout.
Definition: qgscallout.cpp:98
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
QgsLineSymbol * lineSymbol()
Returns the line symbol used to render the callout line.
Definition: qgscallout.cpp:305
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in callouts.
Definition: qgscallout.cpp:141
bool loadVariant(const QVariant &configuration, const QgsPropertiesDefinition &definitions) override
Loads this property collection from a QVariantMap, wrapped in a QVariant.
~QgsSimpleLineCallout() override
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
bool allFeaturePartsLabeled
true if all parts of associated feature were labeled
Definition: qgscallout.h:198
bool drawCalloutToAllParts() const
Returns true if callout lines should be drawn to all feature parts.
Definition: qgscallout.h:525
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:51
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:66
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
Render callouts below all labels.
Definition: qgscallout.h:81
virtual void startRender(QgsRenderContext &context)
Prepares the callout for rendering on the specified render context.
Definition: qgscallout.cpp:89
Draws straight (right angled) lines as callouts.
Definition: qgscallout.h:567
QString type() const override
Returns a unique string representing the callout type.
Definition: qgscallout.cpp:444
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
double length() const
Returns the planar, 2-dimensional length of geometry.
Distance to offset lines from label area.
Definition: qgscallout.h:73
Definition for a property.
Definition: qgsproperty.h:46
A simple direct line callout style.
Definition: qgscallout.h:339
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the callout line.
Definition: qgscallout.cpp:310
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
A point on the surface&#39;s outline closest to the label is used as anchor for polygon geometries...
Definition: qgscallout.h:89
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsExpressionContext & expressionContext()
Gets the expression context.
QPolygonF asQPolygonF() const
Returns contents of the geometry as a QPolygonF.
virtual QString type() const =0
Returns a unique string representing the callout type.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
Whether callout lines should be drawn to all feature parts.
Definition: qgscallout.h:74
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...
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext()) const override
Returns the set of any fields referenced by the active properties from the collection.
double offsetFromAnchor() const
Returns the offset distance from the anchor point at which to start the line.
Definition: qgscallout.h:437
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the callout&#39;s property collection, used for data defined overrides.
Definition: qgscallout.h:240
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
bool enabled() const
Returns true if the the callout is enabled.
Definition: qgscallout.h:228
QPainter * painter()
Returns the destination QPainter for the render operation.
QVariant toVariant(const QgsPropertiesDefinition &definitions) const override
Saves this property collection to a QVariantMap, wrapped in a QVariant.
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:457
Property requires a string value.
Definition: qgsproperty.h:91
QVariantMap properties(const QgsReadWriteContext &context) const override
Returns the properties describing the callout encoded in a string format.
Definition: qgscallout.cpp:233
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
double minimumLength() const
Returns the minimum length of callout lines.
Definition: qgscallout.h:392
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
AnchorPoint
Feature&#39;s anchor point position.
Definition: qgscallout.h:86
QSet< QString > referencedFields(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the callout.
Definition: qgscallout.cpp:297
void readProperties(const QVariantMap &props, const QgsReadWriteContext &context) override
Reads a string map of an callout&#39;s properties and restores the callout to the state described by the ...
Definition: qgscallout.cpp:257
virtual void readProperties(const QVariantMap &props, const QgsReadWriteContext &context)
Reads a string map of an callout&#39;s properties and restores the callout to the state described by the ...
Definition: qgscallout.cpp:59
AnchorPoint anchorPoint() const
Returns the feature&#39;s anchor point position.
Definition: qgscallout.h:270
static QString encodeAnchorPoint(AnchorPoint anchor)
Encodes an anchor point to its string representation.
Definition: qgscallout.cpp:171
DrawOrder
Options for draw order (stacking) of callouts.
Definition: qgscallout.h:79
virtual QVariantMap properties(const QgsReadWriteContext &context) const
Returns the properties describing the callout encoded in a string format.
Definition: qgscallout.cpp:50
A point guaranteed to be on the surface is used as anchor for polygon geometries. ...
Definition: qgscallout.h:90
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
void setEnabled(bool enabled)
Sets whether the callout is enabled.
Definition: qgscallout.cpp:136
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:216
QgsSimpleLineCallout * clone() const override
Duplicates a callout by creating a deep copy of the callout.
Definition: qgscallout.cpp:228
double x
Definition: qgspoint.h:41
record about vertex coordinates and index of anchor to which it is snapped