31 void QgsCallout::initPropertyDefinitions()
33 const QString origin = QStringLiteral(
"callouts" );
53 props.insert( QStringLiteral(
"enabled" ), mEnabled ?
"1" :
"0" );
54 props.insert( QStringLiteral(
"anchorPoint" ),
encodeAnchorPoint( mAnchorPoint ) );
61 mEnabled = props.value( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
62 mAnchorPoint =
decodeAnchorPoint( props.value( QStringLiteral(
"anchorPoint" ), QString(
"" ) ).toString() );
68 if ( element.isNull() )
75 QDomElement calloutElement = doc.createElement( QStringLiteral(
"callout" ) );
76 calloutElement.setAttribute( QStringLiteral(
"type" ),
type() );
77 calloutElement.appendChild( calloutPropsElement );
79 element.appendChild( calloutElement );
114 #if 0 // for debugging 115 QPainter *painter = context.
painter();
117 painter->setRenderHint( QPainter::Antialiasing,
false );
118 painter->translate( rect.center() );
119 painter->rotate( -angle );
121 painter->setBrush( QColor( 255, 0, 0, 100 ) );
122 painter->setPen( QColor( 255, 0, 0, 150 ) );
124 painter->drawRect( rect.width() * -0.5, rect.height() * -0.5, rect.width(), rect.height() );
127 painter->setBrush( QColor( 0, 255, 0, 100 ) );
128 painter->setPen( QColor( 0, 255, 0, 150 ) );
133 draw( context, rect, angle, anchor, calloutContext );
143 static std::once_flag initialized;
144 std::call_once( initialized, [ = ]( )
146 initPropertyDefinitions();
148 return sPropertyDefinitions;
155 QString cleaned = name.toLower().trimmed();
157 if ( cleaned == QLatin1String(
"pole_of_inaccessibility" ) )
159 else if ( cleaned == QLatin1String(
"point_on_exterior" ) )
161 else if ( cleaned == QLatin1String(
"point_on_surface" ) )
163 else if ( cleaned == QLatin1String(
"centroid" ) )
176 return QStringLiteral(
"pole_of_inaccessibility" );
178 return QStringLiteral(
"point_on_exterior" );
180 return QStringLiteral(
"point_on_surface" );
182 return QStringLiteral(
"centroid" );
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 )
218 std::unique_ptr< QgsSimpleLineCallout > callout = qgis::make_unique< QgsSimpleLineCallout >();
220 return callout.release();
225 return QStringLiteral(
"simple" );
241 props[ QStringLiteral(
"minLength" ) ] = mMinCalloutLength;
245 props[ QStringLiteral(
"offsetFromAnchor" ) ] = mOffsetFromAnchorDistance;
248 props[ QStringLiteral(
"offsetFromLabel" ) ] = mOffsetFromLabelDistance;
252 props[ QStringLiteral(
"drawToAllParts" ) ] = mDrawCalloutToAllParts;
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 ) );
267 mLineSymbol = std::move( lineSymbol );
269 mMinCalloutLength = props.value( QStringLiteral(
"minLength" ), 0 ).toDouble();
273 mOffsetFromAnchorDistance = props.value( QStringLiteral(
"offsetFromAnchor" ), 0 ).toDouble();
276 mOffsetFromLabelDistance = props.value( QStringLiteral(
"offsetFromLabel" ), 0 ).toDouble();
280 mDrawCalloutToAllParts = props.value( QStringLiteral(
"drawToAllParts" ),
false ).toBool();
287 mLineSymbol->startRender( context );
294 mLineSymbol->stopRender( context );
301 fields.unite( mLineSymbol->usedAttributes( context ) );
307 return mLineSymbol.get();
312 mLineSymbol.reset( symbol );
318 auto drawCalloutLine = [
this, &context, &label](
const QgsGeometry & partAnchor )
328 switch ( partAnchor.type() )
345 line = label.
shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) );
348 line = label.
shortestLine( partAnchor.pointOnSurface() );
367 double minLength = mMinCalloutLength;
373 double minLengthPixels = context.
convertToPainterUnits( minLength, mMinCalloutLengthUnit, mMinCalloutLengthScale );
374 if ( minLengthPixels > 0 && line.
length() < minLengthPixels )
383 const double offsetFromAnchorPixels = context.
convertToPainterUnits( offsetFromAnchor, mOffsetFromAnchorUnit, mOffsetFromAnchorScale );
391 const double offsetFromLabelPixels = context.
convertToPainterUnits( offsetFromLabel, mOffsetFromLabelUnit, mOffsetFromLabelScale );
392 if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
394 if (
QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.
get() ) )
396 line =
QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
400 mLineSymbol->renderPolyline( line.
asQPolygonF(),
nullptr, context );
403 bool toAllParts = mDrawCalloutToAllParts;
411 drawCalloutLine( anchor );
416 drawCalloutLine( part );
439 std::unique_ptr< QgsManhattanLineCallout > callout = qgis::make_unique< QgsManhattanLineCallout >();
441 return callout.release();
446 return QStringLiteral(
"manhattan" );
457 auto drawCalloutLine = [
this, &context, &label](
const QgsGeometry & partAnchor )
467 switch ( partAnchor.type() )
484 line = label.
shortestLine( partAnchor.poleOfInaccessibility( std::max( partAnchor.boundingBox().width(), partAnchor.boundingBox().height() ) / 20.0 ) );
487 line = label.
shortestLine( partAnchor.pointOnSurface() );
512 if ( minLengthPixels > 0 && line.
length() < minLengthPixels )
534 if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 )
536 if ( QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.get() ) )
538 line =
QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) );
553 drawCalloutLine( anchor );
558 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...
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...
void startRender(QgsRenderContext &context) override
Prepares the callout for rendering on the specified render context.
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)
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. ...
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.
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.
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.
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.
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.
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.
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in callouts.
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.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
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.
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...
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.
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.
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.
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.
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.
double minimumLength() const
Returns the minimum length of callout lines.
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 ...
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.
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...
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