34#include "moc_qgsannotation.cpp"
36using namespace Qt::StringLiterals;
43 props.insert( u
"color"_s, u
"white"_s );
44 props.insert( u
"style"_s, u
"solid"_s );
45 props.insert( u
"style_border"_s, u
"solid"_s );
46 props.insert( u
"color_border"_s, u
"black"_s );
47 props.insert( u
"width_border"_s, u
"0.3"_s );
48 props.insert( u
"joinstyle"_s, u
"miter"_s );
65 if ( mHasFixedMapPosition == fixed )
68 mHasFixedMapPosition = fixed;
74 mMapPosition = position;
80 mMapPositionCrs = crs;
86 mRelativePosition = position;
98 return mOffsetFromReferencePoint / 3.7795275;
103 mOffsetFromReferencePoint = offset;
117 return mFrameSize / 3.7795275;
130 mContentsMargins = margins;
136 mFillSymbol.reset( symbol );
142 return mFillSymbol.get();
147 QPainter *painter = context.
painter();
156 drawFrame( context );
157 if ( mHasFixedMapPosition )
159 drawMarkerSymbol( context );
161 if ( mHasFixedMapPosition )
187 mMarkerSymbol.reset( symbol );
230 return QSizeF( 0, 0 );
240 const QRectF frameRect(
241 mHasFixedMapPosition ? scaleSize( mOffsetFromReferencePoint.x() ) : 0,
242 mHasFixedMapPosition ? scaleSize( mOffsetFromReferencePoint.y() ) : 0,
243 scaleSize( mFrameSize.width() ),
244 scaleSize( mFrameSize.height() )
246 const QgsPointXY origin = mHasFixedMapPosition ? QgsPointXY( 0, 0 ) : QgsPointXY( frameRect.center().x(), frameRect.center().y() );
250 mFillSymbol->startRender( context );
251 const QVector<QPolygonF> rings;
252 mFillSymbol->renderPolygon( poly, &rings,
nullptr, context );
253 mFillSymbol->stopRender( context );
265 mMarkerSymbol->startRender( context );
266 mMarkerSymbol->renderPoint( QPointF( 0, 0 ),
nullptr, context );
267 mMarkerSymbol->stopRender( context );
273 if ( itemElem.isNull() )
277 QDomElement annotationElem = doc.createElement( u
"AnnotationItem"_s );
278 annotationElem.setAttribute( u
"mapPositionFixed"_s, mHasFixedMapPosition );
279 annotationElem.setAttribute( u
"mapPosX"_s,
qgsDoubleToString( mMapPosition.x() ) );
280 annotationElem.setAttribute( u
"mapPosY"_s,
qgsDoubleToString( mMapPosition.y() ) );
281 if ( mMapPositionCrs.isValid() )
282 mMapPositionCrs.writeXml( annotationElem, doc );
283 annotationElem.setAttribute( u
"offsetXMM"_s,
qgsDoubleToString( mOffsetFromReferencePoint.x() ) );
284 annotationElem.setAttribute( u
"offsetYMM"_s,
qgsDoubleToString( mOffsetFromReferencePoint.y() ) );
285 annotationElem.setAttribute( u
"frameWidthMM"_s,
qgsDoubleToString( mFrameSize.width() ) );
286 annotationElem.setAttribute( u
"frameHeightMM"_s,
qgsDoubleToString( mFrameSize.height() ) );
287 annotationElem.setAttribute( u
"canvasPosX"_s,
qgsDoubleToString( mRelativePosition.x() ) );
288 annotationElem.setAttribute( u
"canvasPosY"_s,
qgsDoubleToString( mRelativePosition.y() ) );
289 annotationElem.setAttribute( u
"contentsMargin"_s, mContentsMargins.toString() );
290 annotationElem.setAttribute( u
"visible"_s,
isVisible() );
293 annotationElem.setAttribute( u
"mapLayer"_s, mMapLayer->id() );
298 if ( !symbolElem.isNull() )
300 annotationElem.appendChild( symbolElem );
305 QDomElement fillElem = doc.createElement( u
"fillSymbol"_s );
307 if ( !symbolElem.isNull() )
309 fillElem.appendChild( symbolElem );
310 annotationElem.appendChild( fillElem );
313 itemElem.appendChild( annotationElem );
318 if ( annotationElem.isNull() )
323 pos.setX( annotationElem.attribute( u
"canvasPosX"_s, u
"0"_s ).toDouble() );
324 pos.setY( annotationElem.attribute( u
"canvasPosY"_s, u
"0"_s ).toDouble() );
325 if ( pos.x() >= 1 || pos.x() < 0 || pos.y() < 0 || pos.y() >= 1 )
326 mRelativePosition = QPointF();
328 mRelativePosition = pos;
330 mapPos.
setX( annotationElem.attribute( u
"mapPosX"_s, u
"0"_s ).toDouble() );
331 mapPos.
setY( annotationElem.attribute( u
"mapPosY"_s, u
"0"_s ).toDouble() );
332 mMapPosition = mapPos;
334 if ( !mMapPositionCrs.readXml( annotationElem ) )
341 if ( annotationElem.hasAttribute( u
"frameWidthMM"_s ) )
342 mFrameSize.setWidth( annotationElem.attribute( u
"frameWidthMM"_s, u
"5"_s ).toDouble() );
344 mFrameSize.setWidth( dpiScale * annotationElem.attribute( u
"frameWidth"_s, u
"50"_s ).toDouble() );
345 if ( annotationElem.hasAttribute( u
"frameHeightMM"_s ) )
346 mFrameSize.setHeight( annotationElem.attribute( u
"frameHeightMM"_s, u
"3"_s ).toDouble() );
348 mFrameSize.setHeight( dpiScale * annotationElem.attribute( u
"frameHeight"_s, u
"50"_s ).toDouble() );
350 if ( annotationElem.hasAttribute( u
"offsetXMM"_s ) )
351 mOffsetFromReferencePoint.setX( annotationElem.attribute( u
"offsetXMM"_s, u
"0"_s ).toDouble() );
353 mOffsetFromReferencePoint.setX( dpiScale * annotationElem.attribute( u
"offsetX"_s, u
"0"_s ).toDouble() );
354 if ( annotationElem.hasAttribute( u
"offsetYMM"_s ) )
355 mOffsetFromReferencePoint.setY( annotationElem.attribute( u
"offsetYMM"_s, u
"0"_s ).toDouble() );
357 mOffsetFromReferencePoint.setY( dpiScale * annotationElem.attribute( u
"offsetY"_s, u
"0"_s ).toDouble() );
359 mHasFixedMapPosition = annotationElem.attribute( u
"mapPositionFixed"_s, u
"1"_s ).toInt();
360 mVisible = annotationElem.attribute( u
"visible"_s, u
"1"_s ).toInt();
361 if ( annotationElem.hasAttribute( u
"mapLayer"_s ) )
368 const QDomElement symbolElem = annotationElem.firstChildElement( u
"symbol"_s );
369 if ( !symbolElem.isNull() )
374 mMarkerSymbol = std::move( symbol );
379 mFillSymbol.reset(
nullptr );
380 const QDomElement fillElem = annotationElem.firstChildElement( u
"fillSymbol"_s );
381 if ( !fillElem.isNull() )
383 const QDomElement symbolElem = fillElem.firstChildElement( u
"symbol"_s );
384 if ( !symbolElem.isNull() )
389 mFillSymbol = std::move( symbol );
396 frameColor.setNamedColor( annotationElem.attribute( u
"frameColor"_s, u
"#000000"_s ) );
397 frameColor.setAlpha( annotationElem.attribute( u
"frameColorAlpha"_s, u
"255"_s ).toInt() );
398 QColor frameBackgroundColor;
399 frameBackgroundColor.setNamedColor( annotationElem.attribute( u
"frameBackgroundColor"_s ) );
400 frameBackgroundColor.setAlpha( annotationElem.attribute( u
"frameBackgroundColorAlpha"_s, u
"255"_s ).toInt() );
401 double frameBorderWidth = annotationElem.attribute( u
"frameBorderWidth"_s, u
"0.5"_s ).toDouble();
403 frameBorderWidth = frameBorderWidth * 25.4 / 96.0;
405 props.insert( u
"color"_s, frameBackgroundColor.name() );
406 props.insert( u
"style"_s, u
"solid"_s );
407 props.insert( u
"style_border"_s, u
"solid"_s );
408 props.insert( u
"color_border"_s, frameColor.name() );
409 props.insert( u
"width_border"_s, QString::number( frameBorderWidth ) );
410 props.insert( u
"joinstyle"_s, u
"miter"_s );
419 target->mVisible = mVisible;
420 target->mHasFixedMapPosition = mHasFixedMapPosition;
421 target->mMapPosition = mMapPosition;
422 target->mMapPositionCrs = mMapPositionCrs;
423 target->mRelativePosition = mRelativePosition;
424 target->mOffsetFromReferencePoint = mOffsetFromReferencePoint;
425 target->mFrameSize = mFrameSize;
426 target->mMarkerSymbol.reset( mMarkerSymbol ? mMarkerSymbol->clone() :
nullptr );
427 target->mContentsMargins = mContentsMargins;
428 target->mFillSymbol.reset( mFillSymbol ? mFillSymbol->clone() :
nullptr );
429 target->mSegmentPointWidthMm = mSegmentPointWidthMm;
430 target->mMapLayer = mMapLayer;
431 target->mFeature = mFeature;
@ Millimeters
Millimeters.
void appearanceChanged()
Emitted whenever the annotation's appearance changes.
Q_DECL_DEPRECATED void setFrameSize(QSizeF size)
Sets the size (in pixels) of the annotation's frame (the main area in which the annotation's content ...
void setFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used for rendering the annotation frame.
Q_DECL_DEPRECATED void setFrameOffsetFromReferencePoint(QPointF offset)
Sets the annotation's frame's offset (in pixels) from the mapPosition() reference point.
void setRelativePosition(QPointF position)
Sets the relative position of the annotation, if it is not attached to a fixed map position.
virtual void renderAnnotation(QgsRenderContext &context, QSizeF size) const =0
Renders the annotation's contents to a target /a context at the specified /a size.
void setMapPosition(const QgsPointXY &position)
Sets the map position of the annotation, if it is attached to a fixed map position.
void moved()
Emitted when the annotation's position has changed and items need to be moved to reflect this.
Q_DECL_DEPRECATED QPointF frameOffsetFromReferencePoint() const
Returns the annotation's frame's offset (in pixels) from the mapPosition() reference point.
void _writeXml(QDomElement &itemElem, QDomDocument &doc, const QgsReadWriteContext &context) const
Writes common annotation properties to a DOM element.
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified style entity visitor, causing it to visit all style entities associated within ...
void setContentsMargin(const QgsMargins &margins)
Sets the margins (in millimeters) between the outside of the frame and the annotation content.
void setFrameSizeMm(QSizeF size)
Sets the size (in millimeters) of the annotation's frame (the main area in which the annotation's con...
virtual void setAssociatedFeature(const QgsFeature &feature)
Sets the feature associated with the annotation.
void setFrameOffsetFromReferencePointMm(QPointF offset)
Sets the annotation's frame's offset (in millimeters) from the mapPosition() reference point.
void setMapPositionCrs(const QgsCoordinateReferenceSystem &crs)
Sets the CRS of the map position.
~QgsAnnotation() override
void _readXml(const QDomElement &annotationElem, const QgsReadWriteContext &context)
Reads common annotation properties from a DOM element.
void copyCommonProperties(QgsAnnotation *target) const
Copies common annotation properties to the targe annotation.
void render(QgsRenderContext &context) const
Renders the annotation to a target render context.
virtual QSizeF minimumFrameSize() const
Returns the minimum frame size for the annotation.
bool isVisible() const
Returns true if the annotation is visible and should be rendered.
void setHasFixedMapPosition(bool fixed)
Sets whether the annotation is attached to a fixed map position, or uses a position relative to the c...
QgsAnnotation(QObject *parent=nullptr)
Constructor for QgsAnnotation.
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the symbol that is drawn at the annotation's map position.
QgsFillSymbol * fillSymbol() const
Returns the symbol that is used for rendering the annotation frame.
void setVisible(bool visible)
Sets whether the annotation is visible and should be rendered.
void mapLayerChanged()
Emitted when the map layer associated with the annotation changes.
void setMapLayer(QgsMapLayer *layer)
Sets the map layer associated with the annotation.
Represents a coordinate reference system (CRS).
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isCanceled() const
Tells whether the operation has been canceled already.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static std::unique_ptr< QgsFillSymbol > createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Base class for all map layer types.
Defines the four margins of a rectangle.
static QgsMargins fromString(const QString &string)
Returns a QgsMargins object decoded from a string, or a null QgsMargins if the string could not be in...
A marker symbol type, for rendering Point and MultiPoint geometries.
static int qtDefaultDpiX()
Returns the default Qt horizontal DPI.
void setY(double y)
Sets the y value of the point.
void setX(double x)
Sets the x value of the point.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
A container for the context for various read/write operations on objects.
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly during rendering to check if rendering shou...
Scoped object for saving and restoring a QPainter object's state.
static QPolygonF createBalloon(const QgsPointXY &origin, const QRectF &rect, double wedgeWidth)
Generates a "balloon"/"talking bubble" style shape (as a QPolygonF).
An interface for classes which can visit style entity (e.g.
@ Annotation
An individual annotation.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Contains information relating to a node (i.e.
Contains information relating to the style entity currently being visited.