QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsannotationlayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsannotationlayer.cpp
3  ------------------
4  copyright : (C) 2019 by Sandro Mani
5  email : smani at sourcepole dot ch
6  ***************************************************************************/
7 
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgsannotationlayer.h"
19 #include "qgsannotationitem.h"
21 #include "qgsapplication.h"
22 #include "qgslogger.h"
23 #include <QUuid>
24 
25 QgsAnnotationLayer::QgsAnnotationLayer( const QString &name, const LayerOptions &options )
27  , mTransformContext( options.transformContext )
28 {
29  mShouldValidateCrs = false;
30  mValid = true;
31 }
32 
34 {
35  emit willBeDeleted();
36  qDeleteAll( mItems );
37 }
38 
40 {
41  mOpacity = 1.0;
44  clear();
45 }
46 
48 {
49  const QString uuid = QUuid::createUuid().toString();
50  mItems.insert( uuid, item );
51 
53 
54  return uuid;
55 }
56 
57 bool QgsAnnotationLayer::removeItem( const QString &id )
58 {
59  if ( !mItems.contains( id ) )
60  return false;
61 
62  delete mItems.take( id );
63 
65 
66  return true;
67 }
68 
70 {
71  qDeleteAll( mItems );
72  mItems.clear();
73 
75 }
76 
78 {
79  return mItems.empty();
80 }
81 
82 void QgsAnnotationLayer::setOpacity( double opacity )
83 {
84  mOpacity = opacity;
86 }
87 
89 {
90  QgsAnnotationLayer::LayerOptions options( mTransformContext );
91  std::unique_ptr< QgsAnnotationLayer > layer = qgis::make_unique< QgsAnnotationLayer >( name(), options );
92  QgsMapLayer::clone( layer.get() );
93 
94  layer->setOpacity( opacity() );
95 
96  for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
97  {
98  layer->mItems.insert( it.key(), ( *it )->clone() );
99  }
100 
101  return layer.release();
102 }
103 
105 {
106  return new QgsAnnotationLayerRenderer( this, rendererContext );
107 }
108 
110 {
111  QgsRectangle rect;
112  for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
113  {
114  if ( rect.isNull() )
115  {
116  rect = it.value()->boundingBox();
117  }
118  else
119  {
120  rect.combineExtentWith( it.value()->boundingBox() );
121  }
122  }
123  return rect;
124 }
125 
127 {
128  mTransformContext = context;
129 }
130 
131 bool QgsAnnotationLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext &context )
132 {
134  {
135  return false;
136  }
137 
138  qDeleteAll( mItems );
139  mItems.clear();
140 
141  QDomNodeList itemsElements = layerNode.toElement().elementsByTagName( QStringLiteral( "items" ) );
142  if ( itemsElements.size() == 0 )
143  return false;
144 
145  QDomNodeList items = itemsElements.at( 0 ).childNodes();
146  for ( int i = 0; i < items.size(); ++i )
147  {
148  QDomElement itemElement = items.at( i ).toElement();
149  const QString id = itemElement.attribute( QStringLiteral( "id" ) );
150  const QString type = itemElement.attribute( QStringLiteral( "type" ) );
151  std::unique_ptr< QgsAnnotationItem > item( QgsApplication::annotationItemRegistry()->createItem( type ) );
152  if ( item )
153  {
154  item->readXml( itemElement, context );
155  mItems.insert( id, item.release() );
156  }
157  }
158 
159  QString errorMsg;
160  readSymbology( layerNode, errorMsg, context );
161 
162  triggerRepaint();
163 
164  return mValid;
165 }
166 
167 bool QgsAnnotationLayer::writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const
168 {
169  // first get the layer element so that we can append the type attribute
170  QDomElement mapLayerNode = layer_node.toElement();
171 
172  if ( mapLayerNode.isNull() )
173  {
174  QgsDebugMsgLevel( QStringLiteral( "can't find maplayer node" ), 2 );
175  return false;
176  }
177 
178  mapLayerNode.setAttribute( QStringLiteral( "type" ), QStringLiteral( "annotation" ) );
179 
180  QDomElement itemsElement = doc.createElement( "items" );
181  for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
182  {
183  QDomElement itemElement = doc.createElement( "item" );
184  itemElement.setAttribute( QStringLiteral( "type" ), ( *it )->type() );
185  itemElement.setAttribute( QStringLiteral( "id" ), it.key() );
186  ( *it )->writeXml( itemElement, doc, context );
187  itemsElement.appendChild( itemElement );
188  }
189  mapLayerNode.appendChild( itemsElement );
190 
191  // renderer specific settings
192  QString errorMsg;
193  return writeSymbology( layer_node, doc, errorMsg, context );
194 }
195 
196 bool QgsAnnotationLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &, const QgsReadWriteContext &, QgsMapLayer::StyleCategories categories ) const
197 {
198  // add the layer opacity
199  if ( categories.testFlag( Rendering ) )
200  {
201  QDomElement layerOpacityElem = doc.createElement( QStringLiteral( "layerOpacity" ) );
202  QDomText layerOpacityText = doc.createTextNode( QString::number( opacity() ) );
203  layerOpacityElem.appendChild( layerOpacityText );
204  node.appendChild( layerOpacityElem );
205  }
206  return true;
207 }
208 
209 bool QgsAnnotationLayer::readSymbology( const QDomNode &node, QString &, QgsReadWriteContext &, QgsMapLayer::StyleCategories categories )
210 {
211  if ( categories.testFlag( Rendering ) )
212  {
213  QDomNode layerOpacityNode = node.namedItem( QStringLiteral( "layerOpacity" ) );
214  if ( !layerOpacityNode.isNull() )
215  {
216  QDomElement e = layerOpacityNode.toElement();
217  setOpacity( e.text().toDouble() );
218  }
219  }
220  return true;
221 }
QgsMapLayer::willBeDeleted
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
QgsAnnotationLayer::clone
QgsAnnotationLayer * clone() const override
Returns a new instance equivalent to this one except for the id which is still unique.
Definition: qgsannotationlayer.cpp:88
QgsCoordinateTransformContext
Contains information about the context in which a coordinate transform is executed.
Definition: qgscoordinatetransformcontext.h:58
QgsRectangle::combineExtentWith
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:359
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsMapLayerType::VectorLayer
@ VectorLayer
QgsAnnotationLayer::writeXml
bool writeXml(QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context) const override
Called by writeLayerXML(), used by children to write state specific to them to project files.
Definition: qgsannotationlayer.cpp:167
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsMapLayer::clone
virtual QgsMapLayer * clone() const =0
Returns a new instance equivalent to this one except for the id which is still unique.
QgsMapLayer::mReadFlags
QgsMapLayer::ReadFlags mReadFlags
Read flags. It's up to the subclass to respect these when restoring state from XML.
Definition: qgsmaplayer.h:1589
QgsAnnotationLayer::createMapRenderer
QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) override
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
Definition: qgsannotationlayer.cpp:104
QgsMapLayerType
QgsMapLayerType
Types of layers that can be added to a map.
Definition: qgsmaplayer.h:68
QgsAnnotationLayer::clear
void clear()
Removes all items from the layer.
Definition: qgsannotationlayer.cpp:69
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
qgsannotationlayerrenderer.h
QgsAnnotationLayerRenderer
Implementation of threaded rendering for annotation layers.
Definition: qgsannotationlayerrenderer.h:37
QgsAnnotationLayer::LayerOptions
Setting options for loading annotation layers.
Definition: qgsannotationlayer.h:50
QgsMapLayer::setCrs
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Definition: qgsmaplayer.cpp:771
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsAnnotationLayer::opacity
double opacity() const
Returns the opacity for the annotation layer, where opacity is a value between 0 (totally transparent...
Definition: qgsannotationlayer.h:124
QgsMapLayer::mShouldValidateCrs
bool mShouldValidateCrs
true if the layer's CRS should be validated and invalid CRSes are not permitted.
Definition: qgsmaplayer.h:1596
QgsAnnotationLayer::readSymbology
bool readSymbology(const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories) override
Read the symbology for the current layer from the DOM node supplied.
Definition: qgsannotationlayer.cpp:209
QgsMapLayer::Rendering
@ Rendering
Rendering: scale visibility, simplify method, opacity.
Definition: qgsmaplayer.h:172
QgsMapLayerRenderer
Base class for utility classes that encapsulate information necessary for rendering of map layers.
Definition: qgsmaplayerrenderer.h:51
qgsapplication.h
QgsMapLayer::triggerRepaint
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
Definition: qgsmaplayer.cpp:1826
QgsMapLayer::FlagDontResolveLayers
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
Definition: qgsmaplayer.h:556
QgsMapLayer::mValid
bool mValid
Indicates if the layer is valid and can be drawn.
Definition: qgsmaplayer.h:1535
QgsAnnotationLayer::isEmpty
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
Definition: qgsannotationlayer.cpp:77
QgsAnnotationLayer::addItem
QString addItem(QgsAnnotationItem *item)
Adds an item to the layer.
Definition: qgsannotationlayer.cpp:47
QgsAnnotationLayer::removeItem
bool removeItem(const QString &id)
Removes (and deletes) the item with matching id.
Definition: qgsannotationlayer.cpp:57
QgsAnnotationLayer::writeSymbology
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &, StyleCategories categories=AllStyleCategories) const override
Write the style for the layer into the docment provided.
Definition: qgsannotationlayer.cpp:196
qgsannotationlayer.h
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:206
QgsAnnotationLayer::readXml
bool readXml(const QDomNode &layerNode, QgsReadWriteContext &context) override
Called by readLayerXML(), used by children to read state specific to them from project files.
Definition: qgsannotationlayer.cpp:131
QgsAnnotationLayer::~QgsAnnotationLayer
~QgsAnnotationLayer() override
Definition: qgsannotationlayer.cpp:33
QgsAnnotationLayer::items
QMap< QString, QgsAnnotationItem * > items() const
Returns a map of items contained in the layer, by unique item ID.
Definition: qgsannotationlayer.h:110
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsAnnotationLayer::setOpacity
void setOpacity(double opacity)
Sets the opacity for the annotation layer, where opacity is a value between 0 (totally transparent) a...
Definition: qgsannotationlayer.cpp:82
QgsAnnotationLayer
Represents a map layer containing a set of georeferenced annotations, e.g.
Definition: qgsannotationlayer.h:40
QgsAnnotationLayer::reset
void reset()
Resets the annotation layer to a default state, and clears all items from it.
Definition: qgsannotationlayer.cpp:39
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:86
QgsAnnotationLayer::extent
QgsRectangle extent() const override
Returns the extent of the layer.
Definition: qgsannotationlayer.cpp:109
qgsannotationitemregistry.h
qgsannotationitem.h
qgslogger.h
QgsAnnotationLayer::setTransformContext
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
Definition: qgsannotationlayer.cpp:126
QgsAnnotationLayer::QgsAnnotationLayer
QgsAnnotationLayer(const QString &name, const QgsAnnotationLayer::LayerOptions &options)
Constructor for a new QgsAnnotationLayer with the specified layer name.
Definition: qgsannotationlayer.cpp:25
QgsRectangle::isNull
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:447
QgsAnnotationItem
Abstract base class for annotation items which are drawn with QgsAnnotationLayers.
Definition: qgsannotationitem.h:39
QgsApplication::annotationItemRegistry
static QgsAnnotationItemRegistry * annotationItemRegistry()
Returns the application's annotation item registry, used for annotation item types.
Definition: qgsapplication.cpp:2218
QgsMapLayer::type
QgsMapLayerType type
Definition: qgsmaplayer.h:90