QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsannotation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsannotation.cpp
3  -----------------
4  begin : January 2017
5  copyright : (C) 2017 by 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 "qgsannotation.h"
19 #include "qgssymbollayerutils.h"
20 #include "qgsmaplayer.h"
21 #include "qgsproject.h"
22 #include "qgsstyleentityvisitor.h"
23 #include "qgsshapegenerator.h"
24 #include "qgssymbol.h"
25 #include "qgsmarkersymbol.h"
26 #include "qgsfillsymbol.h"
27 
28 #include <QPen>
29 #include <QPainter>
30 
31 Q_GUI_EXPORT extern int qt_defaultDpiX();
32 
33 QgsAnnotation::QgsAnnotation( QObject *parent )
34  : QObject( parent )
35  , mMarkerSymbol( new QgsMarkerSymbol() )
36 {
37  QVariantMap props;
38  props.insert( QStringLiteral( "color" ), QStringLiteral( "white" ) );
39  props.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
40  props.insert( QStringLiteral( "style_border" ), QStringLiteral( "solid" ) );
41  props.insert( QStringLiteral( "color_border" ), QStringLiteral( "black" ) );
42  props.insert( QStringLiteral( "width_border" ), QStringLiteral( "0.3" ) );
43  props.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
44  mFillSymbol.reset( QgsFillSymbol::createSimple( props ) );
45 }
46 
48 
49 void QgsAnnotation::setVisible( bool visible )
50 {
51  if ( mVisible == visible )
52  return;
53 
54  mVisible = visible;
55  emit appearanceChanged();
56 }
57 
59 {
60  if ( mHasFixedMapPosition == fixed )
61  return;
62 
63  mHasFixedMapPosition = fixed;
64  emit moved();
65 }
66 
68 {
69  mMapPosition = position;
70  emit moved();
71 }
72 
74 {
75  mMapPositionCrs = crs;
76  emit moved();
77 }
78 
79 void QgsAnnotation::setRelativePosition( QPointF position )
80 {
81  mRelativePosition = position;
82  emit moved();
83 }
84 
86 {
87  // convert from offset in pixels at 96 dpi to mm
88  setFrameOffsetFromReferencePointMm( offset / 3.7795275 );
89 }
90 
92 {
93  return mOffsetFromReferencePoint / 3.7795275;
94 }
95 
97 {
98  mOffsetFromReferencePoint = offset;
99 
100  emit moved();
101  emit appearanceChanged();
102 }
103 
104 void QgsAnnotation::setFrameSize( QSizeF size )
105 {
106  // convert from size in pixels at 96 dpi to mm
107  setFrameSizeMm( size / 3.7795275 );
108 }
109 
111 {
112  return mFrameSize / 3.7795275;
113 }
114 
115 void QgsAnnotation::setFrameSizeMm( QSizeF size )
116 {
117  const QSizeF frameSize = minimumFrameSize().expandedTo( size ); //don't allow frame sizes below minimum
118  mFrameSize = frameSize;
119  emit moved();
120  emit appearanceChanged();
121 }
122 
124 {
125  mContentsMargins = margins;
126  emit appearanceChanged();
127 }
128 
130 {
131  mFillSymbol.reset( symbol );
132  emit appearanceChanged();
133 }
134 
136 {
137  return mFillSymbol.get();
138 }
139 
141 {
142  QPainter *painter = context.painter();
143  if ( !painter || ( context.feedback() && context.feedback()->isCanceled() ) )
144  {
145  return;
146  }
147 
148  const QgsScopedQPainterState painterState( context.painter() );
149  context.setPainterFlagsUsingContext();
150 
151  drawFrame( context );
152  if ( mHasFixedMapPosition )
153  {
154  drawMarkerSymbol( context );
155  }
156  if ( mHasFixedMapPosition )
157  {
158  painter->translate( context.convertToPainterUnits( mOffsetFromReferencePoint.x(), Qgis::RenderUnit::Millimeters ) + context.convertToPainterUnits( mContentsMargins.left(), Qgis::RenderUnit::Millimeters ),
159  context.convertToPainterUnits( mOffsetFromReferencePoint.y(), Qgis::RenderUnit::Millimeters ) + context.convertToPainterUnits( mContentsMargins.top(), Qgis::RenderUnit::Millimeters ) );
160  }
161  else
162  {
163  painter->translate( context.convertToPainterUnits( mContentsMargins.left(), Qgis::RenderUnit::Millimeters ),
164  context.convertToPainterUnits( mContentsMargins.top(), Qgis::RenderUnit::Millimeters ) );
165  }
166  const QSizeF size( context.convertToPainterUnits( mFrameSize.width(), Qgis::RenderUnit::Millimeters ) - context.convertToPainterUnits( mContentsMargins.left() + mContentsMargins.right(), Qgis::RenderUnit::Millimeters ),
167  context.convertToPainterUnits( mFrameSize.height(), Qgis::RenderUnit::Millimeters ) - context.convertToPainterUnits( mContentsMargins.top() + mContentsMargins.bottom(), Qgis::RenderUnit::Millimeters ) );
168 
169  // scale back from painter dpi to 96 dpi --
170 // double dotsPerMM = context.painter()->device()->logicalDpiX() / ( 25.4 * 3.78 );
171 // context.painter()->scale( dotsPerMM, dotsPerMM );
172 
173  renderAnnotation( context, size );
174 }
175 
177 {
178  mMarkerSymbol.reset( symbol );
179  emit appearanceChanged();
180 }
181 
183 {
184  mMapLayer = layer;
185  emit mapLayerChanged();
186 }
187 
189 {
190  mFeature = feature;
191 }
192 
194 {
195  // NOTE: if visitEnter returns false it means "don't visit the annotation", not "abort all further visitations"
196  if ( !visitor->visitEnter( QgsStyleEntityVisitorInterface::Node( QgsStyleEntityVisitorInterface::NodeType::Annotation, QStringLiteral( "annotation" ), tr( "Annotation" ) ) ) )
197  return true;
198 
199  if ( mMarkerSymbol )
200  {
201  QgsStyleSymbolEntity entity( mMarkerSymbol.get() );
202  if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, QStringLiteral( "marker" ), QObject::tr( "Marker" ) ) ) )
203  return false;
204  }
205 
206  if ( mFillSymbol )
207  {
208  QgsStyleSymbolEntity entity( mFillSymbol.get() );
209  if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, QStringLiteral( "fill" ), QObject::tr( "Fill" ) ) ) )
210  return false;
211  }
212 
213  if ( !visitor->visitExit( QgsStyleEntityVisitorInterface::Node( QgsStyleEntityVisitorInterface::NodeType::Annotation, QStringLiteral( "annotation" ), tr( "Annotation" ) ) ) )
214  return false;
215 
216  return true;
217 }
218 
220 {
221  return QSizeF( 0, 0 );
222 }
223 
224 void QgsAnnotation::drawFrame( QgsRenderContext &context ) const
225 {
226  if ( !mFillSymbol )
227  return;
228 
229  auto scaleSize = [&context]( double size )->double
230  {
232  };
233 
234  const QRectF frameRect( mHasFixedMapPosition ? scaleSize( mOffsetFromReferencePoint.x() ) : 0,
235  mHasFixedMapPosition ? scaleSize( mOffsetFromReferencePoint.y() ) : 0,
236  scaleSize( mFrameSize.width() ),
237  scaleSize( mFrameSize.height() ) );
238  const QgsPointXY origin = mHasFixedMapPosition ? QgsPointXY( 0, 0 ) : QgsPointXY( frameRect.center().x(), frameRect.center().y() );
239 
240  const QPolygonF poly = QgsShapeGenerator::createBalloon( origin, frameRect, context.convertToPainterUnits( mSegmentPointWidthMm, Qgis::RenderUnit::Millimeters ) );
241 
242  mFillSymbol->startRender( context );
243  const QVector<QPolygonF> rings; //empty list
244  mFillSymbol->renderPolygon( poly, &rings, nullptr, context );
245  mFillSymbol->stopRender( context );
246 }
247 
248 void QgsAnnotation::drawMarkerSymbol( QgsRenderContext &context ) const
249 {
250  if ( !context.painter() )
251  {
252  return;
253  }
254 
255  if ( mMarkerSymbol )
256  {
257  mMarkerSymbol->startRender( context );
258  mMarkerSymbol->renderPoint( QPointF( 0, 0 ), nullptr, context );
259  mMarkerSymbol->stopRender( context );
260  }
261 }
262 
263 void QgsAnnotation::_writeXml( QDomElement &itemElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
264 {
265  if ( itemElem.isNull() )
266  {
267  return;
268  }
269  QDomElement annotationElem = doc.createElement( QStringLiteral( "AnnotationItem" ) );
270  annotationElem.setAttribute( QStringLiteral( "mapPositionFixed" ), mHasFixedMapPosition );
271  annotationElem.setAttribute( QStringLiteral( "mapPosX" ), qgsDoubleToString( mMapPosition.x() ) );
272  annotationElem.setAttribute( QStringLiteral( "mapPosY" ), qgsDoubleToString( mMapPosition.y() ) );
273  if ( mMapPositionCrs.isValid() )
274  mMapPositionCrs.writeXml( annotationElem, doc );
275  annotationElem.setAttribute( QStringLiteral( "offsetXMM" ), qgsDoubleToString( mOffsetFromReferencePoint.x() ) );
276  annotationElem.setAttribute( QStringLiteral( "offsetYMM" ), qgsDoubleToString( mOffsetFromReferencePoint.y() ) );
277  annotationElem.setAttribute( QStringLiteral( "frameWidthMM" ), qgsDoubleToString( mFrameSize.width() ) );
278  annotationElem.setAttribute( QStringLiteral( "frameHeightMM" ), qgsDoubleToString( mFrameSize.height() ) );
279  annotationElem.setAttribute( QStringLiteral( "canvasPosX" ), qgsDoubleToString( mRelativePosition.x() ) );
280  annotationElem.setAttribute( QStringLiteral( "canvasPosY" ), qgsDoubleToString( mRelativePosition.y() ) );
281  annotationElem.setAttribute( QStringLiteral( "contentsMargin" ), mContentsMargins.toString() );
282  annotationElem.setAttribute( QStringLiteral( "visible" ), isVisible() );
283  if ( mMapLayer )
284  {
285  annotationElem.setAttribute( QStringLiteral( "mapLayer" ), mMapLayer->id() );
286  }
287  if ( mMarkerSymbol )
288  {
289  const QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "marker symbol" ), mMarkerSymbol.get(), doc, context );
290  if ( !symbolElem.isNull() )
291  {
292  annotationElem.appendChild( symbolElem );
293  }
294  }
295  if ( mFillSymbol )
296  {
297  QDomElement fillElem = doc.createElement( QStringLiteral( "fillSymbol" ) );
298  const QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "fill symbol" ), mFillSymbol.get(), doc, context );
299  if ( !symbolElem.isNull() )
300  {
301  fillElem.appendChild( symbolElem );
302  annotationElem.appendChild( fillElem );
303  }
304  }
305  itemElem.appendChild( annotationElem );
306 }
307 
308 void QgsAnnotation::_readXml( const QDomElement &annotationElem, const QgsReadWriteContext &context )
309 {
310  if ( annotationElem.isNull() )
311  {
312  return;
313  }
314  QPointF pos;
315  pos.setX( annotationElem.attribute( QStringLiteral( "canvasPosX" ), QStringLiteral( "0" ) ).toDouble() );
316  pos.setY( annotationElem.attribute( QStringLiteral( "canvasPosY" ), QStringLiteral( "0" ) ).toDouble() );
317  if ( pos.x() >= 1 || pos.x() < 0 || pos.y() < 0 || pos.y() >= 1 )
318  mRelativePosition = QPointF();
319  else
320  mRelativePosition = pos;
321  QgsPointXY mapPos;
322  mapPos.setX( annotationElem.attribute( QStringLiteral( "mapPosX" ), QStringLiteral( "0" ) ).toDouble() );
323  mapPos.setY( annotationElem.attribute( QStringLiteral( "mapPosY" ), QStringLiteral( "0" ) ).toDouble() );
324  mMapPosition = mapPos;
325 
326  if ( !mMapPositionCrs.readXml( annotationElem ) )
327  {
328  mMapPositionCrs = QgsCoordinateReferenceSystem();
329  }
330 
331  mContentsMargins = QgsMargins::fromString( annotationElem.attribute( QStringLiteral( "contentsMargin" ) ) );
332  const double dpiScale = 25.4 / qt_defaultDpiX();
333  if ( annotationElem.hasAttribute( QStringLiteral( "frameWidthMM" ) ) )
334  mFrameSize.setWidth( annotationElem.attribute( QStringLiteral( "frameWidthMM" ), QStringLiteral( "5" ) ).toDouble() );
335  else
336  mFrameSize.setWidth( dpiScale * annotationElem.attribute( QStringLiteral( "frameWidth" ), QStringLiteral( "50" ) ).toDouble() );
337  if ( annotationElem.hasAttribute( QStringLiteral( "frameHeightMM" ) ) )
338  mFrameSize.setHeight( annotationElem.attribute( QStringLiteral( "frameHeightMM" ), QStringLiteral( "3" ) ).toDouble() );
339  else
340  mFrameSize.setHeight( dpiScale * annotationElem.attribute( QStringLiteral( "frameHeight" ), QStringLiteral( "50" ) ).toDouble() );
341 
342  if ( annotationElem.hasAttribute( QStringLiteral( "offsetXMM" ) ) )
343  mOffsetFromReferencePoint.setX( annotationElem.attribute( QStringLiteral( "offsetXMM" ), QStringLiteral( "0" ) ).toDouble() );
344  else
345  mOffsetFromReferencePoint.setX( dpiScale * annotationElem.attribute( QStringLiteral( "offsetX" ), QStringLiteral( "0" ) ).toDouble() );
346  if ( annotationElem.hasAttribute( QStringLiteral( "offsetYMM" ) ) )
347  mOffsetFromReferencePoint.setY( annotationElem.attribute( QStringLiteral( "offsetYMM" ), QStringLiteral( "0" ) ).toDouble() );
348  else
349  mOffsetFromReferencePoint.setY( dpiScale * annotationElem.attribute( QStringLiteral( "offsetY" ), QStringLiteral( "0" ) ).toDouble() );
350 
351  mHasFixedMapPosition = annotationElem.attribute( QStringLiteral( "mapPositionFixed" ), QStringLiteral( "1" ) ).toInt();
352  mVisible = annotationElem.attribute( QStringLiteral( "visible" ), QStringLiteral( "1" ) ).toInt();
353  if ( annotationElem.hasAttribute( QStringLiteral( "mapLayer" ) ) )
354  {
355  mMapLayer = QgsProject::instance()->mapLayer( annotationElem.attribute( QStringLiteral( "mapLayer" ) ) );
356  }
357 
358  //marker symbol
359  {
360  const QDomElement symbolElem = annotationElem.firstChildElement( QStringLiteral( "symbol" ) );
361  if ( !symbolElem.isNull() )
362  {
363  QgsMarkerSymbol *symbol = QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context );
364  if ( symbol )
365  {
366  mMarkerSymbol.reset( symbol );
367  }
368  }
369  }
370 
371  mFillSymbol.reset( nullptr );
372  const QDomElement fillElem = annotationElem.firstChildElement( QStringLiteral( "fillSymbol" ) );
373  if ( !fillElem.isNull() )
374  {
375  const QDomElement symbolElem = fillElem.firstChildElement( QStringLiteral( "symbol" ) );
376  if ( !symbolElem.isNull() )
377  {
378  QgsFillSymbol *symbol = QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElem, context );
379  if ( symbol )
380  {
381  mFillSymbol.reset( symbol );
382  }
383  }
384  }
385  if ( !mFillSymbol )
386  {
387  QColor frameColor;
388  frameColor.setNamedColor( annotationElem.attribute( QStringLiteral( "frameColor" ), QStringLiteral( "#000000" ) ) );
389  frameColor.setAlpha( annotationElem.attribute( QStringLiteral( "frameColorAlpha" ), QStringLiteral( "255" ) ).toInt() );
390  QColor frameBackgroundColor;
391  frameBackgroundColor.setNamedColor( annotationElem.attribute( QStringLiteral( "frameBackgroundColor" ) ) );
392  frameBackgroundColor.setAlpha( annotationElem.attribute( QStringLiteral( "frameBackgroundColorAlpha" ), QStringLiteral( "255" ) ).toInt() );
393  double frameBorderWidth = annotationElem.attribute( QStringLiteral( "frameBorderWidth" ), QStringLiteral( "0.5" ) ).toDouble();
394  // need to roughly convert border width from pixels to mm - just assume 96 dpi
395  frameBorderWidth = frameBorderWidth * 25.4 / 96.0;
396  QVariantMap props;
397  props.insert( QStringLiteral( "color" ), frameBackgroundColor.name() );
398  props.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
399  props.insert( QStringLiteral( "style_border" ), QStringLiteral( "solid" ) );
400  props.insert( QStringLiteral( "color_border" ), frameColor.name() );
401  props.insert( QStringLiteral( "width_border" ), QString::number( frameBorderWidth ) );
402  props.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
403  mFillSymbol.reset( QgsFillSymbol::createSimple( props ) );
404  }
405 
406  emit mapLayerChanged();
407 }
408 
410 {
411  target->mVisible = mVisible;
412  target->mHasFixedMapPosition = mHasFixedMapPosition;
413  target->mMapPosition = mMapPosition;
414  target->mMapPositionCrs = mMapPositionCrs;
415  target->mRelativePosition = mRelativePosition;
416  target->mOffsetFromReferencePoint = mOffsetFromReferencePoint;
417  target->mFrameSize = mFrameSize;
418  target->mMarkerSymbol.reset( mMarkerSymbol ? mMarkerSymbol->clone() : nullptr );
419  target->mContentsMargins = mContentsMargins;
420  target->mFillSymbol.reset( mFillSymbol ? mFillSymbol->clone() : nullptr );
421  target->mSegmentPointWidthMm = mSegmentPointWidthMm;
422  target->mMapLayer = mMapLayer;
423  target->mFeature = mFeature;
424 }
425 
@ Millimeters
Millimeters.
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:53
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.
Definition: qgsannotation.h:94
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.
QSizeF frameSize
Definition: qgsannotation.h:73
void mapLayerChanged()
Emitted when the map layer associated with the annotation changes.
void setMapLayer(QgsMapLayer *layer)
Sets the map layer associated with the annotation.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Base class for all map layer types.
Definition: qgsmaplayer.h:75
The QgsMargins class defines the four margins of a rectangle.
Definition: qgsmargins.h:37
double top() const
Returns the top margin.
Definition: qgsmargins.h:77
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...
Definition: qgsmargins.cpp:27
double right() const
Returns the right margin.
Definition: qgsmargins.h:83
double bottom() const
Returns the bottom margin.
Definition: qgsmargins.h:89
QString toString() const
Returns the margins encoded to a string.
Definition: qgsmargins.cpp:18
double left() const
Returns the left margin.
Definition: qgsmargins.h:71
A marker symbol type, for rendering Point and MultiPoint geometries.
A class to represent a 2D point.
Definition: qgspointxy.h:60
void setY(double y)
Sets the y value of the point.
Definition: qgspointxy.h:130
double y
Definition: qgspointxy.h:64
Q_GADGET double x
Definition: qgspointxy.h:63
void setX(double x)
Sets the x value of the point.
Definition: qgspointxy.h:120
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:481
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
The class is used as a container of context for various read/write operations on other 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.
Definition: qgsstyle.h:1372
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.
Definition: qgis.h:5089
Q_GUI_EXPORT int qt_defaultDpiX()
const QgsCoordinateReferenceSystem & crs
Contains information relating to a node (i.e.
Contains information relating to the style entity currently being visited.