QGIS API Documentation  3.0.2-Girona (307d082)
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 <QPen>
23 #include <QPainter>
24 
25 QgsAnnotation::QgsAnnotation( QObject *parent )
26  : QObject( parent )
27  , mMarkerSymbol( new QgsMarkerSymbol() )
28 {
29  QgsStringMap props;
30  props.insert( QStringLiteral( "color" ), QStringLiteral( "white" ) );
31  props.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
32  props.insert( QStringLiteral( "style_border" ), QStringLiteral( "solid" ) );
33  props.insert( QStringLiteral( "color_border" ), QStringLiteral( "black" ) );
34  props.insert( QStringLiteral( "width_border" ), QStringLiteral( "0.3" ) );
35  props.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
36  mFillSymbol.reset( QgsFillSymbol::createSimple( props ) );
37 }
38 
40 {
41  if ( mVisible == visible )
42  return;
43 
44  mVisible = visible;
45  emit appearanceChanged();
46 }
47 
49 {
50  if ( mHasFixedMapPosition == fixed )
51  return;
52 
53  mHasFixedMapPosition = fixed;
54  updateBalloon();
55  emit moved();
56 }
57 
59 {
60  mMapPosition = position;
61  emit moved();
62 }
63 
65 {
66  mMapPositionCrs = crs;
67  emit moved();
68 }
69 
70 void QgsAnnotation::setRelativePosition( QPointF position )
71 {
72  mRelativePosition = position;
73  emit moved();
74 }
75 
77 {
78  mOffsetFromReferencePoint = offset;
79  updateBalloon();
80  emit moved();
81  emit appearanceChanged();
82 }
83 
84 void QgsAnnotation::setFrameSize( QSizeF size )
85 {
86  QSizeF frameSize = minimumFrameSize().expandedTo( size ); //don't allow frame sizes below minimum
87  mFrameSize = frameSize;
88  updateBalloon();
89  emit moved();
90  emit appearanceChanged();
91 }
92 
94 {
95  mContentsMargins = margins;
96  emit appearanceChanged();
97 }
98 
100 {
101  mFillSymbol.reset( symbol );
102  emit appearanceChanged();
103 }
104 
106 {
107  QPainter *painter = context.painter();
108  if ( !painter )
109  {
110  return;
111  }
112 
113  painter->save();
114  drawFrame( context );
115  if ( mHasFixedMapPosition )
116  {
117  drawMarkerSymbol( context );
118  }
119  if ( mHasFixedMapPosition )
120  {
121  painter->translate( mOffsetFromReferencePoint.x() + context.convertToPainterUnits( mContentsMargins.left(), QgsUnitTypes::RenderMillimeters ),
122  mOffsetFromReferencePoint.y() + context.convertToPainterUnits( mContentsMargins.top(), QgsUnitTypes::RenderMillimeters ) );
123  }
124  else
125  {
126  painter->translate( context.convertToPainterUnits( mContentsMargins.left(), QgsUnitTypes::RenderMillimeters ),
127  context.convertToPainterUnits( mContentsMargins.top(), QgsUnitTypes::RenderMillimeters ) );
128  }
129  QSizeF size( mFrameSize.width() - context.convertToPainterUnits( mContentsMargins.left() + mContentsMargins.right(), QgsUnitTypes::RenderMillimeters ),
130  mFrameSize.height() - context.convertToPainterUnits( mContentsMargins.top() + mContentsMargins.bottom(), QgsUnitTypes::RenderMillimeters ) );
131 
132  renderAnnotation( context, size );
133  painter->restore();
134 }
135 
137 {
138  mMarkerSymbol.reset( symbol );
139  emit appearanceChanged();
140 }
141 
143 {
144  mMapLayer = layer;
145  emit mapLayerChanged();
146 }
147 
149 {
150  mFeature = feature;
151 }
152 
154 {
155  return QSizeF( 0, 0 );
156 }
157 
158 void QgsAnnotation::updateBalloon()
159 {
160  //first test if the point is in the frame. In that case we don't need a balloon.
161  if ( !mHasFixedMapPosition ||
162  ( mOffsetFromReferencePoint.x() < 0 && ( mOffsetFromReferencePoint.x() + mFrameSize.width() ) > 0
163  && mOffsetFromReferencePoint.y() < 0 && ( mOffsetFromReferencePoint.y() + mFrameSize.height() ) > 0 ) )
164  {
165  mBalloonSegment = -1;
166  return;
167  }
168 
169  //edge list
170  QList<QLineF> segmentList;
171  segmentList << segment( 0 );
172  segmentList << segment( 1 );
173  segmentList << segment( 2 );
174  segmentList << segment( 3 );
175 
176  //find closest edge / closest edge point
177  double minEdgeDist = DBL_MAX;
178  int minEdgeIndex = -1;
179  QLineF minEdge;
180  QgsPointXY minEdgePoint;
181  QgsPointXY origin( 0, 0 );
182 
183  for ( int i = 0; i < 4; ++i )
184  {
185  QLineF currentSegment = segmentList.at( i );
186  QgsPointXY currentMinDistPoint;
187  double currentMinDist = origin.sqrDistToSegment( currentSegment.x1(), currentSegment.y1(), currentSegment.x2(), currentSegment.y2(), currentMinDistPoint );
188  if ( currentMinDist < minEdgeDist )
189  {
190  minEdgeIndex = i;
191  minEdgePoint = currentMinDistPoint;
192  minEdgeDist = currentMinDist;
193  minEdge = currentSegment;
194  }
195  }
196 
197  if ( minEdgeIndex < 0 )
198  {
199  return;
200  }
201 
202  //make that configurable for the item
203  double segmentPointWidth = 10;
204 
205  mBalloonSegment = minEdgeIndex;
206  QPointF minEdgeEnd = minEdge.p2();
207  mBalloonSegmentPoint1 = QPointF( minEdgePoint.x(), minEdgePoint.y() );
208  if ( std::sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < segmentPointWidth )
209  {
210  mBalloonSegmentPoint1 = pointOnLineWithDistance( minEdge.p2(), minEdge.p1(), segmentPointWidth );
211  }
212 
213  mBalloonSegmentPoint2 = pointOnLineWithDistance( mBalloonSegmentPoint1, minEdge.p2(), 10 );
214 }
215 
216 QLineF QgsAnnotation::segment( int index ) const
217 {
218  if ( mHasFixedMapPosition )
219  {
220  switch ( index )
221  {
222  case 0:
223  return QLineF( mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y(), mOffsetFromReferencePoint.x()
224  + mFrameSize.width(), mOffsetFromReferencePoint.y() );
225  case 1:
226  return QLineF( mOffsetFromReferencePoint.x() + mFrameSize.width(), mOffsetFromReferencePoint.y(),
227  mOffsetFromReferencePoint.x() + mFrameSize.width(), mOffsetFromReferencePoint.y() + mFrameSize.height() );
228  case 2:
229  return QLineF( mOffsetFromReferencePoint.x() + mFrameSize.width(), mOffsetFromReferencePoint.y() + mFrameSize.height(),
230  mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y() + mFrameSize.height() );
231  case 3:
232  return QLineF( mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y() + mFrameSize.height(),
233  mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y() );
234  default:
235  return QLineF();
236  }
237  }
238  else
239  {
240  switch ( index )
241  {
242  case 0:
243  return QLineF( 0, 0, mFrameSize.width(), 0 );
244  case 1:
245  return QLineF( mFrameSize.width(), 0,
246  mFrameSize.width(), mFrameSize.height() );
247  case 2:
248  return QLineF( mFrameSize.width(), mFrameSize.height(),
249  0, mFrameSize.height() );
250  case 3:
251  return QLineF( 0, mFrameSize.height(),
252  0, 0 );
253  default:
254  return QLineF();
255  }
256  }
257 }
258 
259 
260 QPointF QgsAnnotation::pointOnLineWithDistance( QPointF startPoint, QPointF directionPoint, double distance ) const
261 {
262  double dx = directionPoint.x() - startPoint.x();
263  double dy = directionPoint.y() - startPoint.y();
264  double length = std::sqrt( dx * dx + dy * dy );
265  double scaleFactor = distance / length;
266  return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
267 }
268 
269 void QgsAnnotation::drawFrame( QgsRenderContext &context ) const
270 {
271  if ( !mFillSymbol )
272  return;
273 
274  context.painter()->setRenderHint( QPainter::Antialiasing, context.flags() & QgsRenderContext::Antialiasing );
275 
276  QPolygonF poly;
277  QList<QPolygonF> rings; //empty list
278  for ( int i = 0; i < 4; ++i )
279  {
280  QLineF currentSegment = segment( i );
281  poly << currentSegment.p1();
282  if ( i == mBalloonSegment && mHasFixedMapPosition )
283  {
284  poly << mBalloonSegmentPoint1;
285  poly << QPointF( 0, 0 );
286  poly << mBalloonSegmentPoint2;
287  }
288  poly << currentSegment.p2();
289  }
290  if ( poly.at( 0 ) != poly.at( poly.count() - 1 ) )
291  poly << poly.at( 0 );
292 
293  mFillSymbol->startRender( context );
294  mFillSymbol->renderPolygon( poly, &rings, nullptr, context );
295  mFillSymbol->stopRender( context );
296 }
297 
298 void QgsAnnotation::drawMarkerSymbol( QgsRenderContext &context ) const
299 {
300  if ( !context.painter() )
301  {
302  return;
303  }
304 
305  if ( mMarkerSymbol )
306  {
307  mMarkerSymbol->startRender( context );
308  mMarkerSymbol->renderPoint( QPointF( 0, 0 ), nullptr, context );
309  mMarkerSymbol->stopRender( context );
310  }
311 }
312 
313 void QgsAnnotation::_writeXml( QDomElement &itemElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
314 {
315  if ( itemElem.isNull() )
316  {
317  return;
318  }
319  QDomElement annotationElem = doc.createElement( QStringLiteral( "AnnotationItem" ) );
320  annotationElem.setAttribute( QStringLiteral( "mapPositionFixed" ), mHasFixedMapPosition );
321  annotationElem.setAttribute( QStringLiteral( "mapPosX" ), qgsDoubleToString( mMapPosition.x() ) );
322  annotationElem.setAttribute( QStringLiteral( "mapPosY" ), qgsDoubleToString( mMapPosition.y() ) );
323  if ( mMapPositionCrs.isValid() )
324  mMapPositionCrs.writeXml( annotationElem, doc );
325  annotationElem.setAttribute( QStringLiteral( "offsetX" ), qgsDoubleToString( mOffsetFromReferencePoint.x() ) );
326  annotationElem.setAttribute( QStringLiteral( "offsetY" ), qgsDoubleToString( mOffsetFromReferencePoint.y() ) );
327  annotationElem.setAttribute( QStringLiteral( "frameWidth" ), qgsDoubleToString( mFrameSize.width() ) );
328  annotationElem.setAttribute( QStringLiteral( "frameHeight" ), qgsDoubleToString( mFrameSize.height() ) );
329  annotationElem.setAttribute( QStringLiteral( "canvasPosX" ), qgsDoubleToString( mRelativePosition.x() ) );
330  annotationElem.setAttribute( QStringLiteral( "canvasPosY" ), qgsDoubleToString( mRelativePosition.y() ) );
331  annotationElem.setAttribute( QStringLiteral( "contentsMargin" ), mContentsMargins.toString() );
332  annotationElem.setAttribute( QStringLiteral( "visible" ), isVisible() );
333  if ( mMapLayer )
334  {
335  annotationElem.setAttribute( QStringLiteral( "mapLayer" ), mMapLayer->id() );
336  }
337  if ( mMarkerSymbol )
338  {
339  QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "marker symbol" ), mMarkerSymbol.get(), doc, context );
340  if ( !symbolElem.isNull() )
341  {
342  annotationElem.appendChild( symbolElem );
343  }
344  }
345  if ( mFillSymbol )
346  {
347  QDomElement fillElem = doc.createElement( QStringLiteral( "fillSymbol" ) );
348  QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "fill symbol" ), mFillSymbol.get(), doc, context );
349  if ( !symbolElem.isNull() )
350  {
351  fillElem.appendChild( symbolElem );
352  annotationElem.appendChild( fillElem );
353  }
354  }
355  itemElem.appendChild( annotationElem );
356 }
357 
358 void QgsAnnotation::_readXml( const QDomElement &annotationElem, const QgsReadWriteContext &context )
359 {
360  if ( annotationElem.isNull() )
361  {
362  return;
363  }
364  QPointF pos;
365  pos.setX( annotationElem.attribute( QStringLiteral( "canvasPosX" ), QStringLiteral( "0" ) ).toDouble() );
366  pos.setY( annotationElem.attribute( QStringLiteral( "canvasPosY" ), QStringLiteral( "0" ) ).toDouble() );
367  if ( pos.x() >= 1 || pos.x() < 0 || pos.y() < 0 || pos.y() >= 1 )
368  mRelativePosition = QPointF();
369  else
370  mRelativePosition = pos;
371  QgsPointXY mapPos;
372  mapPos.setX( annotationElem.attribute( QStringLiteral( "mapPosX" ), QStringLiteral( "0" ) ).toDouble() );
373  mapPos.setY( annotationElem.attribute( QStringLiteral( "mapPosY" ), QStringLiteral( "0" ) ).toDouble() );
374  mMapPosition = mapPos;
375 
376  if ( !mMapPositionCrs.readXml( annotationElem ) )
377  {
378  mMapPositionCrs = QgsCoordinateReferenceSystem();
379  }
380 
381  mContentsMargins = QgsMargins::fromString( annotationElem.attribute( QStringLiteral( "contentsMargin" ) ) );
382  mFrameSize.setWidth( annotationElem.attribute( QStringLiteral( "frameWidth" ), QStringLiteral( "50" ) ).toDouble() );
383  mFrameSize.setHeight( annotationElem.attribute( QStringLiteral( "frameHeight" ), QStringLiteral( "50" ) ).toDouble() );
384  mOffsetFromReferencePoint.setX( annotationElem.attribute( QStringLiteral( "offsetX" ), QStringLiteral( "0" ) ).toDouble() );
385  mOffsetFromReferencePoint.setY( annotationElem.attribute( QStringLiteral( "offsetY" ), QStringLiteral( "0" ) ).toDouble() );
386  mHasFixedMapPosition = annotationElem.attribute( QStringLiteral( "mapPositionFixed" ), QStringLiteral( "1" ) ).toInt();
387  mVisible = annotationElem.attribute( QStringLiteral( "visible" ), QStringLiteral( "1" ) ).toInt();
388  if ( annotationElem.hasAttribute( QStringLiteral( "mapLayer" ) ) )
389  {
390  mMapLayer = QgsProject::instance()->mapLayer( annotationElem.attribute( QStringLiteral( "mapLayer" ) ) );
391  }
392 
393  //marker symbol
394  QDomElement symbolElem = annotationElem.firstChildElement( QStringLiteral( "symbol" ) );
395  if ( !symbolElem.isNull() )
396  {
397  QgsMarkerSymbol *symbol = QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context );
398  if ( symbol )
399  {
400  mMarkerSymbol.reset( symbol );
401  }
402  }
403 
404  mFillSymbol.reset( nullptr );
405  QDomElement fillElem = annotationElem.firstChildElement( QStringLiteral( "fillSymbol" ) );
406  if ( !fillElem.isNull() )
407  {
408  QDomElement symbolElem = fillElem.firstChildElement( QStringLiteral( "symbol" ) );
409  if ( !symbolElem.isNull() )
410  {
411  QgsFillSymbol *symbol = QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElem, context );
412  if ( symbol )
413  {
414  mFillSymbol.reset( symbol );
415  }
416  }
417  }
418  if ( !mFillSymbol )
419  {
420  QColor frameColor;
421  frameColor.setNamedColor( annotationElem.attribute( QStringLiteral( "frameColor" ), QStringLiteral( "#000000" ) ) );
422  frameColor.setAlpha( annotationElem.attribute( QStringLiteral( "frameColorAlpha" ), QStringLiteral( "255" ) ).toInt() );
423  QColor frameBackgroundColor;
424  frameBackgroundColor.setNamedColor( annotationElem.attribute( QStringLiteral( "frameBackgroundColor" ) ) );
425  frameBackgroundColor.setAlpha( annotationElem.attribute( QStringLiteral( "frameBackgroundColorAlpha" ), QStringLiteral( "255" ) ).toInt() );
426  double frameBorderWidth = annotationElem.attribute( QStringLiteral( "frameBorderWidth" ), QStringLiteral( "0.5" ) ).toDouble();
427  // need to roughly convert border width from pixels to mm - just assume 96 dpi
428  frameBorderWidth = frameBorderWidth * 25.4 / 96.0;
429  QgsStringMap props;
430  props.insert( QStringLiteral( "color" ), frameBackgroundColor.name() );
431  props.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
432  props.insert( QStringLiteral( "style_border" ), QStringLiteral( "solid" ) );
433  props.insert( QStringLiteral( "color_border" ), frameColor.name() );
434  props.insert( QStringLiteral( "width_border" ), QString::number( frameBorderWidth ) );
435  props.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
436  mFillSymbol.reset( QgsFillSymbol::createSimple( props ) );
437  }
438 
439  updateBalloon();
440  emit mapLayerChanged();
441 }
442 
444 {
445  target->mVisible = mVisible;
446  target->mHasFixedMapPosition = mHasFixedMapPosition;
447  target->mMapPosition = mMapPosition;
448  target->mMapPositionCrs = mMapPositionCrs;
449  target->mRelativePosition = mRelativePosition;
450  target->mOffsetFromReferencePoint = mOffsetFromReferencePoint;
451  target->mFrameSize = mFrameSize;
452  target->mMarkerSymbol.reset( mMarkerSymbol ? mMarkerSymbol->clone() : nullptr );
453  target->mContentsMargins = mContentsMargins;
454  target->mFillSymbol.reset( mFillSymbol ? mFillSymbol->clone() : nullptr );
455  target->mBalloonSegment = mBalloonSegment;
456  target->mBalloonSegmentPoint1 = mBalloonSegmentPoint1;
457  target->mBalloonSegmentPoint2 = mBalloonSegmentPoint2;
458  target->mMapLayer = mMapLayer;
459  target->mFeature = mFeature;
460 }
461 
double right() const
Returns the right margin.
Definition: qgsmargins.h:84
The class is used as a container of context for various read/write operations on other objects...
void setVisible(bool visible)
Sets whether the annotation is visible and should be rendered.
Base class for all map layer types.
Definition: qgsmaplayer.h:56
bool isVisible() const
Returns true if the annotation is visible and should be rendered.
Definition: qgsannotation.h:87
void appearanceChanged()
Emitted whenever the annotation&#39;s appearance changes.
void _writeXml(QDomElement &itemElem, QDomDocument &doc, const QgsReadWriteContext &context) const
Writes common annotation properties to a DOM element.
void setMapLayer(QgsMapLayer *layer)
Sets the map layer associated with the annotation.
Use antialiasing while drawing.
void mapLayerChanged()
Emitted when the map layer associated with the annotation changes.
double y
Definition: qgspointxy.h:48
static QgsFillSymbol * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties. ...
Definition: qgssymbol.cpp:1114
A class to represent a 2D point.
Definition: qgspointxy.h:43
void setFrameOffsetFromReferencePoint(QPointF offset)
Sets the annotation&#39;s frame&#39;s offset from the mapPosition() reference point.
Flags flags() const
Return combination of flags used for rendering.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
void copyCommonProperties(QgsAnnotation *target) const
Copies common annotation properties to the targe annotation.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:479
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:47
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
Definition: qgspointxy.cpp:68
virtual void renderAnnotation(QgsRenderContext &context, QSizeF size) const =0
Renders the annotation&#39;s contents to a target /a context at the specified /a size.
double sqrDistToSegment(double x1, double y1, double x2, double y2, QgsPointXY &minDistPoint, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Returns the minimum distance between this point and a segment.
Definition: qgspointxy.cpp:136
void setContentsMargin(const QgsMargins &margins)
Sets the margins (in millimeters) between the outside of the frame and the annotation content...
double bottom() const
Returns the bottom margin.
Definition: qgsmargins.h:90
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:237
void setY(double y)
Sets the y value of the point.
Definition: qgspointxy.h:113
void render(QgsRenderContext &context) const
Renders the annotation to a target render context.
double top() const
Returns the top margin.
Definition: qgsmargins.h:78
virtual QSizeF minimumFrameSize() const
Returns the minimum frame size for the annotation.
void _readXml(const QDomElement &annotationElem, const QgsReadWriteContext &context)
Reads common annotation properties from a DOM element.
void setX(double x)
Sets the x value of the point.
Definition: qgspointxy.h:104
double x
Definition: qgspointxy.h:47
void setFrameSize(QSizeF size)
Sets the size of the annotation&#39;s frame (the main area in which the annotation&#39;s content is drawn)...
void setMapPosition(const QgsPointXY &position)
Sets the map position of the annotation, if it is attached to a fixed map position.
QSizeF frameSize() const
Returns the size of the annotation&#39;s frame (the main area in which the annotation&#39;s content is drawn)...
void moved()
Emitted when the annotation&#39;s position has changed and items need to be moved to reflect this...
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.
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).
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the symbol that is drawn at the annotation&#39;s map position.
QPainter * painter()
Returns the destination QPainter for the render operation.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:383
This class represents a coordinate reference system (CRS).
static QDomElement saveSymbol(const QString &symbolName, QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
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
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QString toString() const
Returns the margins encoded to a string.
Definition: qgsmargins.cpp:18
void setFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used for rendering the annotation frame.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
virtual void setAssociatedFeature(const QgsFeature &feature)
Sets the feature associated with the annotation.
void setMapPositionCrs(const QgsCoordinateReferenceSystem &crs)
Sets the CRS of the map position.
double left() const
Returns the left margin.
Definition: qgsmargins.h:72
The QgsMargins class defines the four margins of a rectangle.
Definition: qgsmargins.h:37
void setRelativePosition(QPointF position)
Sets the relative position of the annotation, if it is not attached to a fixed map position...
bool isValid() const
Returns whether this CRS is correctly initialized and usable.