31 void QgsCallout::initPropertyDefinitions()
33 const QString origin = QStringLiteral(
"callouts" );
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 )
60 props.insert( QStringLiteral(
"enabled" ), mEnabled ?
"1" :
"0" );
61 props.insert( QStringLiteral(
"anchorPoint" ),
encodeAnchorPoint( mAnchorPoint ) );
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() );
77 if ( element.isNull() )
84 QDomElement calloutElement = doc.createElement( QStringLiteral(
"callout" ) );
85 calloutElement.setAttribute( QStringLiteral(
"type" ),
type() );
86 calloutElement.appendChild( calloutPropsElement );
88 element.appendChild( calloutElement );
123 #if 0 // for debugging 124 QPainter *painter = context.
painter();
126 painter->setRenderHint( QPainter::Antialiasing,
false );
127 painter->translate( rect.center() );
128 painter->rotate( -angle );
130 painter->setBrush( QColor( 255, 0, 0, 100 ) );
131 painter->setPen( QColor( 255, 0, 0, 150 ) );
133 painter->drawRect( rect.width() * -0.5, rect.height() * -0.5, rect.width(), rect.height() );
136 painter->setBrush( QColor( 0, 255, 0, 100 ) );
137 painter->setPen( QColor( 0, 255, 0, 150 ) );
142 draw( context, rect, angle, anchor, calloutContext );
152 static std::once_flag initialized;
153 std::call_once( initialized, [ = ]( )
155 initPropertyDefinitions();
157 return sPropertyDefinitions;
164 QString cleaned = name.toLower().trimmed();
166 if ( cleaned == QLatin1String(
"pole_of_inaccessibility" ) )
168 else if ( cleaned == QLatin1String(
"point_on_exterior" ) )
170 else if ( cleaned == QLatin1String(
"point_on_surface" ) )
172 else if ( cleaned == QLatin1String(
"centroid" ) )
185 return QStringLiteral(
"pole_of_inaccessibility" );
187 return QStringLiteral(
"point_on_exterior" );
189 return QStringLiteral(
"point_on_surface" );
191 return QStringLiteral(
"centroid" );
201 return QStringLiteral(
"point_on_exterior" );
203 return QStringLiteral(
"centroid" );
205 return QStringLiteral(
"tl" );
207 return QStringLiteral(
"t" );
209 return QStringLiteral(
"tr" );
211 return QStringLiteral(
"l" );
213 return QStringLiteral(
"r" );
215 return QStringLiteral(
"bl" );
217 return QStringLiteral(
"b" );
219 return QStringLiteral(
"br" );
229 QString cleaned = name.toLower().trimmed();
231 if ( cleaned == QLatin1String(
"point_on_exterior" ) )
233 else if ( cleaned == QLatin1String(
"centroid" ) )
235 else if ( cleaned == QLatin1String(
"tl" ) )
237 else if ( cleaned == QLatin1String(
"t" ) )
239 else if ( cleaned == QLatin1String(
"tr" ) )
241 else if ( cleaned == QLatin1String(
"l" ) )
243 else if ( cleaned == QLatin1String(
"r" ) )
245 else if ( cleaned == QLatin1String(
"bl" ) )
247 else if ( cleaned == QLatin1String(
"b" ) )
249 else if ( cleaned == QLatin1String(
"br" ) )
303 label.
rotate( angle, rect.topLeft() );
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 )
338 std::unique_ptr< QgsSimpleLineCallout > callout = qgis::make_unique< QgsSimpleLineCallout >();
340 return callout.release();
345 return QStringLiteral(
"simple" );
361 props[ QStringLiteral(
"minLength" ) ] = mMinCalloutLength;
365 props[ QStringLiteral(
"offsetFromAnchor" ) ] = mOffsetFromAnchorDistance;
368 props[ QStringLiteral(
"offsetFromLabel" ) ] = mOffsetFromLabelDistance;
372 props[ QStringLiteral(
"drawToAllParts" ) ] = mDrawCalloutToAllParts;
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 ) );
387 mLineSymbol = std::move( lineSymbol );
389 mMinCalloutLength = props.value( QStringLiteral(
"minLength" ), 0 ).toDouble();
393 mOffsetFromAnchorDistance = props.value( QStringLiteral(
"offsetFromAnchor" ), 0 ).toDouble();
396 mOffsetFromLabelDistance = props.value( QStringLiteral(
"offsetFromLabel" ), 0 ).toDouble();
400 mDrawCalloutToAllParts = props.value( QStringLiteral(
"drawToAllParts" ),
false ).toBool();
407 mLineSymbol->startRender( context );
414 mLineSymbol->stopRender( context );
421 fields.unite( mLineSymbol->usedAttributes( context ) );
427 return mLineSymbol.get();
432 mLineSymbol.reset( symbol );
446 auto drawCalloutLine = [
this, &context, &label](
const QgsGeometry & partAnchor )
456 switch ( partAnchor.type() )
473 line = label.
shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) );
476 line = label.
shortestLine( partAnchor.pointOnSurface() );
495 double minLength = mMinCalloutLength;
501 double minLengthPixels = context.
convertToPainterUnits( minLength, mMinCalloutLengthUnit, mMinCalloutLengthScale );
502 if ( minLengthPixels > 0 && line.
length() < minLengthPixels )
511 const double offsetFromAnchorPixels = context.
convertToPainterUnits( offsetFromAnchor, mOffsetFromAnchorUnit, mOffsetFromAnchorScale );
519 const double offsetFromLabelPixels = context.
convertToPainterUnits( offsetFromLabel, mOffsetFromLabelUnit, mOffsetFromLabelScale );
520 if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
522 if (
QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.
get() ) )
524 line =
QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
528 mLineSymbol->renderPolyline( line.
asQPolygonF(),
nullptr, context );
531 bool toAllParts = mDrawCalloutToAllParts;
539 drawCalloutLine( anchor );
544 drawCalloutLine( part );
567 std::unique_ptr< QgsManhattanLineCallout > callout = qgis::make_unique< QgsManhattanLineCallout >();
569 return callout.release();
574 return QStringLiteral(
"manhattan" );
593 auto drawCalloutLine = [
this, &context, &label](
const QgsGeometry & partAnchor )
603 switch ( partAnchor.type() )
620 line = label.
shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) );
623 line = label.
shortestLine( partAnchor.pointOnSurface() );
648 if ( minLengthPixels > 0 && line.
length() < minLengthPixels )
670 if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
672 if ( QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.get() ) )
674 line =
QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
689 drawCalloutLine( anchor );
694 drawCalloutLine( part );
QgsUnitTypes::RenderUnit minimumLengthUnit() const
Returns the units for the minimum length of callout lines.
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...
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.
static QgsCallout * create(const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext())
Creates a new QgsManhattanLineCallout, using the settings serialized in the properties map (correspon...
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
virtual void restoreProperties(const QDomElement &element, const QgsReadWriteContext &context)
Restores the callout's properties from a DOM element.
Abstract base class for callout renderers.
const QgsMapUnitScale & offsetFromAnchorMapUnitScale() const
Returns the map unit scale for the offset from anchor.
static QgsGeometry fromPolyline(const QgsPolyline &polyline)
Creates a new LineString geometry from a list of QgsPoint points.
Minimum length of callouts.
virtual void stopRender(QgsRenderContext &context)
Finalises the callout after a set of rendering operations on the specified render context...
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.
Distance to offset lines from anchor points.
QgsUnitTypes::RenderUnit offsetFromAnchorUnit() const
Returns the units for the offset from anchor point.
Contains additional contextual information about the context in which a callout is being rendered...
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
QgsManhattanLineCallout()
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...
The point on the label's boundary closest to the feature.
void startRender(QgsRenderContext &context) override
Prepares the callout for rendering on the specified render context.
A class to represent a 2D point.
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)
OperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
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...
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. ...
LabelAnchorPoint
Label's anchor point position.
QString type() const override
Returns a unique string representing the callout type.
The surface's centroid is used as anchor for polygon geometries.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
A geometry is the spatial representation of a feature.
QgsCallout()
Constructor for QgsCallout.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
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...
Feature's anchor point position.
static QString encodeLabelAnchorPoint(LabelAnchorPoint anchor)
Encodes a label anchor point to its string representation.
virtual DrawOrder drawOrder() const
Returns the desired drawing order (stacking) to use while rendering this callout. ...
Positive double value (including 0)
const QgsMapUnitScale & minimumLengthMapUnitScale() const
Returns the map unit scale for the minimum callout length.
The surface's pole of inaccessibility used as anchor for polygon geometries.
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)
A line symbol type, for rendering LineString and MultiLineString geometries.
Bottom middle of the label's boundary.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
Bottom left corner of the label's boundary.
QPolygonF asQPolygonF() const SIP_HOLDGIL
Returns contents of the geometry as a QPolygonF.
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.
Middle right of the label's boundary.
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.
void stopRender(QgsRenderContext &context) override
Finalises the callout after a set of rendering operations on the specified render context...
virtual QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns the set of attributes referenced by the callout.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
QgsLineSymbol * lineSymbol()
Returns the line symbol used to render the callout line.
Middle left of the label's boundary.
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in callouts.
Label's anchor point position.
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
bool drawCalloutToAllParts() const
Returns true if callout lines should be drawn to all feature parts.
QList< QgsSymbolLayer * > QgsSymbolLayerList
virtual bool saveProperties(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context) const
Saves the current state of the callout to a DOM element.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
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...
Render callouts below all labels.
virtual void startRender(QgsRenderContext &context)
Prepares the callout for rendering on the specified render context.
Draws straight (right angled) lines as callouts.
QString type() const override
Returns a unique string representing the callout type.
Point geometry type, with support for z-dimension and m-values.
Top left corner of the label's boundary.
double length() const
Returns the planar, 2-dimensional length of geometry.
Distance to offset lines from label area.
Definition for a property.
A simple direct line callout style.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the callout line.
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's outline closest to the label is used as anchor for polygon geometries...
QgsExpressionContext & expressionContext()
Gets the expression context.
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.
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...
double offsetFromAnchor() const
Returns the offset distance from the anchor point at which to start the line.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the callout's property collection, used for data defined overrides.
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.
QPainter * painter()
Returns the destination QPainter for the render operation.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
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.
Property requires a string value.
QVariantMap properties(const QgsReadWriteContext &context) const override
Returns the properties describing the callout encoded in a string format.
Bottom right corner of the label's boundary.
Line string geometry type, with support for z-dimension and m-values.
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.
LabelAnchorPoint labelAnchorPoint() const
Returns the label's anchor point position.
double minimumLength() const
Returns the minimum length of callout lines.
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.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
AnchorPoint
Feature's anchor point position.
QSet< QString > referencedFields(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the callout.
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 ...
Top right corner of the label's boundary.
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 ...
AnchorPoint anchorPoint() const
Returns the feature's anchor point position.
static QString encodeAnchorPoint(AnchorPoint anchor)
Encodes an anchor point to its string representation.
DrawOrder
Options for draw order (stacking) of callouts.
virtual QVariantMap properties(const QgsReadWriteContext &context) const
Returns the properties describing the callout encoded in a string format.
A point guaranteed to be on the surface is used as anchor for polygon geometries. ...
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.
Top middle of the label's boundary.
void setEnabled(bool enabled)
Sets whether the callout is enabled.
static QgsCallout * create(const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext())
Creates a new QgsSimpleLineCallout, using the settings serialized in the properties map (correspondin...
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...
QgsSimpleLineCallout * clone() const override
Duplicates a callout by creating a deep copy of the callout.
record about vertex coordinates and index of anchor to which it is snapped