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 );
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" ) )
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 >();
339 callout->readProperties(
properties, context );
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 ) );
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 )
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 >();
568 callout->readProperties(
properties, context );
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 )
651 const QgsPoint start = qgsgeometry_cast< const QgsLineString * >( line.
constGet() )->startPoint();
652 const QgsPoint end = qgsgeometry_cast< const QgsLineString * >( line.
constGet() )->endPoint();
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 );
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 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.
Abstract base class for callout renderers.
static QString encodeAnchorPoint(AnchorPoint anchor)
Encodes an anchor point to its string representation.
void render(QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext)
Renders the callout onto the specified render context.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context) const
Saves the current state of the callout to a DOM element.
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.
virtual void stopRender(QgsRenderContext &context)
Finalises the callout after a set of rendering operations on the specified render context.
void setEnabled(bool enabled)
Sets whether the callout is enabled.
virtual QString type() const =0
Returns a unique string representing the callout type.
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in callouts.
AnchorPoint anchorPoint() const
Returns the feature's anchor point position.
LabelAnchorPoint labelAnchorPoint() const
Returns the label's anchor point position.
AnchorPoint
Feature's anchor point position.
@ PointOnExterior
A point on the surface's outline closest to the label is used as anchor for polygon geometries.
@ Centroid
The surface's centroid is used as anchor for polygon geometries.
@ PointOnSurface
A point guaranteed to be on the surface is used as anchor for polygon geometries.
@ PoleOfInaccessibility
The surface's pole of inaccessibility used as anchor for polygon geometries.
virtual void restoreProperties(const QDomElement &element, const QgsReadWriteContext &context)
Restores the callout's properties from a DOM element.
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.
static QString encodeLabelAnchorPoint(LabelAnchorPoint anchor)
Encodes a label anchor point to its string representation.
virtual void startRender(QgsRenderContext &context)
Prepares the callout for rendering on the specified render context.
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...
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the callout's property collection, used for data defined overrides.
QgsCallout()
Constructor for QgsCallout.
DrawOrder
Options for draw order (stacking) of callouts.
@ OrderBelowAllLabels
Render callouts below all labels.
virtual DrawOrder drawOrder() const
Returns the desired drawing order (stacking) to use while rendering this callout.
LabelAnchorPoint
Label's anchor point position.
@ LabelPointOnExterior
The point on the label's boundary closest to the feature.
@ LabelBottomLeft
Bottom left corner of the label's boundary.
@ LabelBottomMiddle
Bottom middle of the label's boundary.
@ LabelMiddleLeft
Middle left of the label's boundary.
@ LabelBottomRight
Bottom right corner of the label's boundary.
@ LabelMiddleRight
Middle right of the label's boundary.
@ LabelTopMiddle
Top middle of the label's boundary.
@ LabelTopLeft
Top left corner of the label's boundary.
@ LabelCentroid
The labe's centroid.
@ LabelTopRight
Top right corner of the label's boundary.
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.
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 ...
virtual QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns the set of attributes referenced by the callout.
@ AnchorPointPosition
Feature's anchor point position.
@ LabelAnchorPointPosition
Label's anchor point position.
@ DrawCalloutToAllParts
Whether callout lines should be drawn to all feature parts.
@ OffsetFromAnchor
Distance to offset lines from anchor points.
@ OffsetFromLabel
Distance to offset lines from label area.
@ MinimumCalloutLength
Minimum length of callouts.
virtual QVariantMap properties(const QgsReadWriteContext &context) const
Returns the properties describing the callout encoded in a string format.
bool enabled() const
Returns true if the the callout is enabled.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
double length() const
Returns the planar, 2-dimensional length of geometry.
OperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
static QgsGeometry fromPolyline(const QgsPolyline &polyline)
Creates a new LineString geometry from a list of QgsPoint points.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
QPolygonF asQPolygonF() const SIP_HOLDGIL
Returns contents of the geometry as a QPolygonF.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Line string geometry type, with support for z-dimension and m-values.
A line symbol type, for rendering LineString and MultiLineString geometries.
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.
Draws straight (right angled) lines as callouts.
QgsManhattanLineCallout()
QString type() const override
Returns a unique string representing the callout type.
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.
static QgsCallout * create(const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext())
Creates a new QgsManhattanLineCallout, using the settings serialized in the properties map (correspon...
QgsManhattanLineCallout * clone() const override
Duplicates a callout by creating a deep copy of the callout.
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
bool loadVariant(const QVariant &configuration, const QgsPropertiesDefinition &definitions) override
Loads this property collection from a QVariantMap, wrapped in a QVariant.
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.
QVariant toVariant(const QgsPropertiesDefinition &definitions) const override
Saves this property collection to a QVariantMap, wrapped in a QVariant.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const override
Prepares the collection against a specified expression context.
Definition for a property.
@ DoublePositive
Positive double value (including 0)
@ DataTypeString
Property requires a string value.
The class is used as a container of context for various read/write operations on other objects.
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
A simple direct line callout style.
void startRender(QgsRenderContext &context) override
Prepares the callout for rendering on the specified render context.
double minimumLength() const
Returns the minimum length of callout lines.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the callout line.
void stopRender(QgsRenderContext &context) override
Finalises the callout after a set of rendering operations on the specified render context.
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.
QSet< QString > referencedFields(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the callout.
double offsetFromLabel() const
Returns the offset distance from label area at which to end the line.
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 ...
QString type() const override
Returns a unique string representing the callout type.
QgsUnitTypes::RenderUnit minimumLengthUnit() const
Returns the units for the minimum length of callout lines.
double offsetFromAnchor() const
Returns the offset distance from the anchor point at which to start the line.
~QgsSimpleLineCallout() override
const QgsMapUnitScale & offsetFromAnchorMapUnitScale() const
Returns the map unit scale for the offset from anchor.
bool drawCalloutToAllParts() const
Returns true if callout lines should be drawn to all feature parts.
static QgsCallout * create(const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext())
Creates a new QgsSimpleLineCallout, using the settings serialized in the properties map (correspondin...
const QgsMapUnitScale & minimumLengthMapUnitScale() const
Returns the map unit scale for the minimum callout length.
QVariantMap properties(const QgsReadWriteContext &context) const override
Returns the properties describing the callout encoded in a string format.
QgsSimpleLineCallout * clone() const override
Duplicates a callout by creating a deep copy of the callout.
QgsLineSymbol * lineSymbol()
Returns the line symbol used to render the callout line.
QgsUnitTypes::RenderUnit offsetFromAnchorUnit() const
Returns the units for the offset from anchor point.
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
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)
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
QList< QgsSymbolLayer * > QgsSymbolLayerList
record about vertex coordinates and index of anchor to which it is snapped
Contains additional contextual information about the context in which a callout is being rendered.
bool allFeaturePartsLabeled
true if all parts of associated feature were labeled