18#include "moc_qgsannotationlayer.cpp" 
   35class QgsAnnotationLayerSpatialIndex : 
public RTree<QString, float, 2, float>
 
   39    void insert( 
const QString &uuid, 
const QgsRectangle &bounds )
 
   41      std::array< float, 4 > scaledBounds = scaleBounds( bounds );
 
   44        scaledBounds[0], scaledBounds[ 1]
 
   48        scaledBounds[2], scaledBounds[ 3]
 
   62    void remove( 
const QString &uuid, 
const QgsRectangle &bounds )
 
   64      std::array< float, 4 > scaledBounds = scaleBounds( bounds );
 
   67        scaledBounds[0], scaledBounds[ 1]
 
   71        scaledBounds[2], scaledBounds[ 3]
 
   84    bool intersects( 
const QgsRectangle &bounds, 
const std::function< 
bool( 
const QString &uuid )> &callback )
 const 
   86      std::array< float, 4 > scaledBounds = scaleBounds( bounds );
 
   89        scaledBounds[0], scaledBounds[ 1]
 
   93        scaledBounds[2], scaledBounds[ 3]
 
  102    std::array<float, 4> scaleBounds( 
const QgsRectangle &bounds )
 const 
  106        static_cast< float >( bounds.
xMinimum() ),
 
  107        static_cast< float >( bounds.
yMinimum() ),
 
  108        static_cast< float >( bounds.
xMaximum() ),
 
  109        static_cast< float >( bounds.
yMaximum() )
 
  117  , mTransformContext( options.transformContext )
 
  118  , mSpatialIndex( std::make_unique< QgsAnnotationLayerSpatialIndex >() )
 
  128  mPaintEffect->setEnabled( 
false );
 
 
  134  qDeleteAll( mItems );
 
 
  155  const QString uuid = QUuid::createUuid().toString();
 
  156  mItems.insert( uuid, 
item );
 
  158    mNonIndexedItems.insert( uuid );
 
 
  171  std::unique_ptr< QgsAnnotationItem> prevItem( mItems.take( 
id ) );
 
  175    auto it = mNonIndexedItems.find( 
id );
 
  176    if ( it == mNonIndexedItems.end() )
 
  178      mSpatialIndex->remove( 
id, prevItem->boundingBox() );
 
  182      mNonIndexedItems.erase( it );
 
  186  mItems.insert( 
id, 
item );
 
  188    mNonIndexedItems.insert( 
id );
 
 
  199  if ( !mItems.contains( 
id ) )
 
  202  std::unique_ptr< QgsAnnotationItem> 
item( mItems.take( 
id ) );
 
  204  auto it = mNonIndexedItems.find( 
id );
 
  205  if ( it == mNonIndexedItems.end() )
 
  211    mNonIndexedItems.erase( it );
 
 
  225  qDeleteAll( mItems );
 
  227  mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
 
  228  mNonIndexedItems.clear();
 
 
  237  return mItems.empty();
 
 
  244  return mItems.value( 
id );
 
 
  253  mSpatialIndex->intersects( bounds, [&res, feedback]( 
const QString & uuid )->
bool 
  265  QStringList res = queryIndex( bounds, feedback );
 
  267  for ( 
const QString &uuid : mNonIndexedItems )
 
  269    if ( mItems.value( uuid )->boundingBox( context ).intersects( bounds ) )
 
 
  291    auto it = mNonIndexedItems.find( operation->
itemId() );
 
  292    if ( it == mNonIndexedItems.end() )
 
  294      mSpatialIndex->remove( operation->
itemId(), targetItem->boundingBox() );
 
  296    res = targetItem->applyEditV2( operation, context );
 
  304          mSpatialIndex->insert( operation->
itemId(), targetItem->boundingBox() );
 
  309        delete mItems.take( operation->
itemId() );
 
  310        mNonIndexedItems.remove( operation->
itemId() );
 
 
  334  auto layer = std::make_unique< QgsAnnotationLayer >( 
name(), options );
 
  337  for ( 
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
 
  339    layer->mItems.insert( it.key(), ( *it )->clone() );
 
  341      layer->mNonIndexedItems.insert( it.key() );
 
  343      layer->mSpatialIndex->insert( it.key(), ( *it )->boundingBox() );
 
  347    layer->setPaintEffect( mPaintEffect->clone() );
 
  349  layer->mLinkedLayer = mLinkedLayer;
 
  351  return layer.release();
 
 
  366  for ( 
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
 
  370      rect = it.value()->boundingBox();
 
 
  385    mDataProvider->setTransformContext( context );
 
  387  mTransformContext = context;
 
 
  401  readItems( layerNode, errorMsg, context );
 
  405    const QString layerId = layerNode.toElement().attribute( QStringLiteral( 
"linkedLayer" ) );
 
  406    const QString layerName = layerNode.toElement().attribute( QStringLiteral( 
"linkedLayerName" ) );
 
  407    const QString layerSource = layerNode.toElement().attribute( QStringLiteral( 
"linkedLayerSource" ) );
 
  408    const QString layerProvider = layerNode.toElement().attribute( QStringLiteral( 
"linkedLayerProvider" ) );
 
  409    mLinkedLayer = 
QgsMapLayerRef( layerId, layerName, layerSource, layerProvider );
 
 
  422  QDomElement mapLayerNode = layer_node.toElement();
 
  424  if ( mapLayerNode.isNull() )
 
  434    mapLayerNode.setAttribute( QStringLiteral( 
"linkedLayer" ), mLinkedLayer.
layerId );
 
  435    mapLayerNode.setAttribute( QStringLiteral( 
"linkedLayerName" ), mLinkedLayer.
name );
 
  436    mapLayerNode.setAttribute( QStringLiteral( 
"linkedLayerSource" ), mLinkedLayer.
source );
 
  437    mapLayerNode.setAttribute( QStringLiteral( 
"linkedLayerProvider" ), mLinkedLayer.
provider );
 
  441  writeItems( layer_node, doc, errorMsg, context );
 
 
  451  QDomElement layerElement = node.toElement();
 
  457    QDomElement layerOpacityElem  = doc.createElement( QStringLiteral( 
"layerOpacity" ) );
 
  458    const QDomText layerOpacityText = doc.createTextNode( QString::number( 
opacity() ) );
 
  459    layerOpacityElem.appendChild( layerOpacityText );
 
  460    node.appendChild( layerOpacityElem );
 
  466    QDomElement blendModeElem  = doc.createElement( QStringLiteral( 
"blendMode" ) );
 
  468    blendModeElem.appendChild( blendModeText );
 
  469    node.appendChild( blendModeElem );
 
  471    QDomElement paintEffectElem  = doc.createElement( QStringLiteral( 
"paintEffect" ) );
 
  473      mPaintEffect->saveProperties( doc, paintEffectElem );
 
  474    node.appendChild( paintEffectElem );
 
 
  484  const QDomElement layerElement = node.toElement();
 
  489    const QDomNode layerOpacityNode = node.namedItem( QStringLiteral( 
"layerOpacity" ) );
 
  490    if ( !layerOpacityNode.isNull() )
 
  492      const QDomElement e = layerOpacityNode.toElement();
 
  500    const QDomNode blendModeNode = node.namedItem( QStringLiteral( 
"blendMode" ) );
 
  501    if ( !blendModeNode.isNull() )
 
  503      const QDomElement e = blendModeNode.toElement();
 
  508    const QDomNode paintEffectNode = node.namedItem( QStringLiteral( 
"paintEffect" ) );
 
  509    if ( !paintEffectNode.isNull() )
 
  511      const QDomElement effectElem = paintEffectNode.firstChildElement( QStringLiteral( 
"effect" ) );
 
  512      if ( !effectElem.isNull() )
 
 
  526  QDomElement itemsElement = doc.createElement( QStringLiteral( 
"items" ) );
 
  528  for ( 
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
 
  530    QDomElement itemElement = doc.createElement( QStringLiteral( 
"item" ) );
 
  531    itemElement.setAttribute( QStringLiteral( 
"type" ), ( *it )->type() );
 
  532    itemElement.setAttribute( QStringLiteral( 
"id" ), it.key() );
 
  533    ( *it )->writeXml( itemElement, doc, context );
 
  534    itemsElement.appendChild( itemElement );
 
  536  node.appendChild( itemsElement );
 
  545  qDeleteAll( mItems );
 
  547  mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
 
  548  mNonIndexedItems.clear();
 
  550  const QDomNodeList itemsElements = node.toElement().elementsByTagName( QStringLiteral( 
"items" ) );
 
  551  if ( itemsElements.size() == 0 )
 
  554  const QDomNodeList 
items = itemsElements.at( 0 ).childNodes();
 
  555  for ( 
int i = 0; i < 
items.size(); ++i )
 
  557    const QDomElement itemElement = 
items.at( i ).toElement();
 
  558    const QString 
id = itemElement.attribute( QStringLiteral( 
"id" ) );
 
  559    const QString 
type = itemElement.attribute( QStringLiteral( 
"type" ) );
 
  565        mNonIndexedItems.insert( 
id );
 
  568      mItems.insert( 
id, 
item.release() );
 
  579  writeItems( node, doc, errorMessage, context, categories );
 
  581  return writeSymbology( node, doc, errorMessage, context, categories );
 
 
  588  readItems( node, errorMessage, context, categories );
 
  590  return readSymbology( node, errorMessage, context, categories );
 
 
  612  return mDataProvider.get();
 
 
  619  return mDataProvider.get();
 
 
  626  QString 
metadata = QStringLiteral( 
"<html>\n<body>\n<h1>" ) + tr( 
"General" ) + QStringLiteral( 
"</h1>\n<hr>\n" ) + QStringLiteral( 
"<table class=\"list-view\">\n" );
 
  628  metadata += QStringLiteral( 
"<tr><td class=\"highlight\">" ) + tr( 
"Name" ) + QStringLiteral( 
"</td><td>" ) + 
name() + QStringLiteral( 
"</td></tr>\n" );
 
  631  metadata += QStringLiteral( 
"<tr><td class=\"highlight\">" ) + tr( 
"Extent" ) + QStringLiteral( 
"</td><td>" ) + 
extent().
toString() + QStringLiteral( 
"</td></tr>\n" );
 
  634  QLocale locale = QLocale();
 
  635  locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
 
  636  const int itemCount = mItems.size();
 
  637  metadata += QStringLiteral( 
"<tr><td class=\"highlight\">" )
 
  638              + tr( 
"Item count" ) + QStringLiteral( 
"</td><td>" )
 
  639              + locale.toString( 
static_cast<qlonglong
>( itemCount ) )
 
  640              + QStringLiteral( 
"</td></tr>\n" );
 
  641  metadata += QLatin1String( 
"</table>\n<br><br>" );
 
  647  metadata += QStringLiteral( 
"<h1>" ) + tr( 
"Items" ) + QStringLiteral( 
"</h1>\n<hr>\n" );
 
  649  metadata += QLatin1String( 
"<table width=\"100%\" class=\"tabular-view\">\n" );
 
  650  metadata += QLatin1String( 
"<tr><th>" ) + tr( 
"Type" ) + QLatin1String( 
"</th><th>" ) + tr( 
"Count" ) + QLatin1String( 
"</th></tr>\n" );
 
  652  QMap< QString, int > itemCounts;
 
  653  for ( 
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
 
  655    itemCounts[ it.value()->type() ]++;
 
  660  for ( 
auto it = itemTypes.begin(); it != itemTypes.end(); ++it )
 
  664      rowClass = QStringLiteral( 
"class=\"odd-row\"" );
 
  665    metadata += QLatin1String( 
"<tr " ) + rowClass + QLatin1String( 
"><td>" ) + it.value() + QLatin1String( 
"</td><td>" ) + locale.toString( 
static_cast<qlonglong
>( itemCounts.value( it.key() ) ) ) + QLatin1String( 
"</td></tr>\n" );
 
  669  metadata += QLatin1String( 
"</table>\n<br><br>" );
 
  671  metadata += QLatin1String( 
"\n</body>\n</html>\n" );
 
 
  684  return mPaintEffect.get();
 
 
  691  mPaintEffect.reset( effect );
 
 
  698  return mLinkedLayer.
get();
 
 
  714QgsAnnotationLayerDataProvider::QgsAnnotationLayerDataProvider(
 
  715  const ProviderOptions &options,
 
  727QString QgsAnnotationLayerDataProvider::name()
 const 
  731  return QStringLiteral( 
"annotation" );
 
  734QString QgsAnnotationLayerDataProvider::description()
 const 
  741QgsRectangle QgsAnnotationLayerDataProvider::extent()
 const 
  748bool QgsAnnotationLayerDataProvider::isValid()
 const 
Provides global constants and enumerations for use throughout the application.
 
@ UsersCannotToggleEditing
Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply ...
 
@ ScaleDependentBoundingBox
Item's bounding box will vary depending on map scale.
 
AnnotationItemEditOperationResult
Results from an edit operation on an annotation item.
 
@ Invalid
Operation has invalid parameters for the item, no change occurred.
 
@ Success
Item was modified successfully.
 
@ ItemCleared
The operation results in the item being cleared, and the item should be removed from the layer as a r...
 
BlendMode
Blending modes defining the available composition modes that can be used when painting.
 
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
 
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
 
QFlags< MapLayerProperty > MapLayerProperties
Map layer properties.
 
Abstract base class for annotation item edit operations.
 
QString itemId() const
Returns the associated item ID.
 
Encapsulates the context for an annotation item edit operation.
 
QMap< QString, QString > itemTypes() const
Returns a map of available item types to translated name.
 
Abstract base class for annotation items which are drawn with QgsAnnotationLayers.
 
virtual QgsRectangle boundingBox() const =0
Returns the bounding box of the item's geographic location, in the parent layer's coordinate referenc...
 
virtual bool readXml(const QDomElement &element, const QgsReadWriteContext &context)=0
Reads the item's state from the given DOM element.
 
virtual Qgis::AnnotationItemFlags flags() const
Returns item flags.
 
Represents a map layer containing a set of georeferenced annotations, e.g.
 
QgsRectangle extent() const override
Returns the extent of the layer.
 
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &, StyleCategories categories=AllStyleCategories) const override
Write the style for the layer into the document provided.
 
void resolveReferences(QgsProject *project) override
Resolve references to other layers (kept as layer IDs after reading XML) into layer objects.
 
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.
 
bool readStyle(const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories) override
Read the style for the current layer from the DOM node supplied.
 
void clear()
Removes all items from the layer.
 
QgsDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
 
QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) override
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
 
bool isEditable() const override
Returns true if the layer can be edited.
 
bool removeItem(const QString &id)
Removes (and deletes) the item with matching id.
 
QStringList itemsInBounds(const QgsRectangle &bounds, QgsRenderContext &context, QgsFeedback *feedback=nullptr) const
Returns a list of the IDs of all annotation items within the specified bounds (in layer CRS),...
 
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
 
Q_DECL_DEPRECATED Qgis::AnnotationItemEditOperationResult applyEdit(QgsAbstractAnnotationItemEditOperation *operation)
Applies an edit operation to the layer.
 
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
 
void setLinkedVisibilityLayer(QgsMapLayer *layer)
Sets a linked layer, where the items in this annotation layer will only be visible when the linked la...
 
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
 
void replaceItem(const QString &id, QgsAnnotationItem *item)
Replaces the existing item with matching id with a new item.
 
Qgis::AnnotationItemEditOperationResult applyEditV2(QgsAbstractAnnotationItemEditOperation *operation, const QgsAnnotationItemEditContext &context)
Applies an edit operation to the layer.
 
QgsAnnotationLayer * clone() const override
Returns a new instance equivalent to this one except for the id which is still unique.
 
friend class QgsAnnotationLayerRenderer
 
bool supportsEditing() const override
Returns whether the layer supports editing or not.
 
void reset()
Resets the annotation layer to a default state, and clears all items from it.
 
QString addItem(QgsAnnotationItem *item)
Adds an item to the layer.
 
QgsMapLayer * linkedVisibilityLayer()
Returns a linked layer, where the items in this annotation layer will only be visible when the linked...
 
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
 
Qgis::MapLayerProperties properties() const override
Returns the map layer properties of this layer.
 
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
 
QgsAnnotationItem * item(const QString &id) const
Returns the item with the specified id, or nullptr if no matching item was found.
 
~QgsAnnotationLayer() override
 
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.
 
bool readXml(const QDomNode &layerNode, QgsReadWriteContext &context) override
Called by readLayerXML(), used by children to read state specific to them from project files.
 
QgsAnnotationLayer(const QString &name, const QgsAnnotationLayer::LayerOptions &options)
Constructor for a new QgsAnnotationLayer with the specified layer name.
 
QMap< QString, QgsAnnotationItem * > items() const
Returns a map of items contained in the layer, by unique item ID.
 
bool writeStyle(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, StyleCategories categories) const override
Write just the symbology information for the layer into the document.
 
static QgsAnnotationItemRegistry * annotationItemRegistry()
Returns the application's annotation item registry, used for annotation item types.
 
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects.
 
Represents a coordinate reference system (CRS).
 
Contains information about the context in which a coordinate transform is executed.
 
Abstract base class for spatial data provider implementations.
 
Base class for feedback objects to be used for cancellation of something running in a worker thread.
 
bool isCanceled() const
Tells whether the operation has been canceled already.
 
static QString typeToString(Qgis::LayerType type)
Converts a map layer type to a string value.
 
Base class for utility classes that encapsulate information necessary for rendering of map layers.
 
Base class for all map layer types.
 
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
 
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
 
QString crsHtmlMetadata() const
Returns a HTML fragment containing the layer's CRS metadata, for use in the htmlMetadata() method.
 
QgsLayerMetadata metadata
 
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
 
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
 
QFlags< StyleCategory > StyleCategories
 
QUndoStack * undoStackStyles()
Returns pointer to layer's style undo stack.
 
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
 
virtual QgsMapLayer * clone() const =0
Returns a new instance equivalent to this one except for the id which is still unique.
 
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
 
void readCommonStyle(const QDomElement &layerElement, const QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories)
Read style data common to all layer types.
 
QgsMapLayer::ReadFlags mReadFlags
Read flags. It's up to the subclass to respect these when restoring state from XML.
 
QgsProject * project() const
Returns the parent project if this map layer is added to a project.
 
bool mValid
Indicates if the layer is valid and can be drawn.
 
@ Rendering
Rendering: scale visibility, simplify method, opacity.
 
void writeCommonStyle(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories) const
Write style data common to all layer types.
 
void invalidateWgs84Extent()
Invalidates the WGS84 extent.
 
bool mShouldValidateCrs
true if the layer's CRS should be validated and invalid CRSes are not permitted.
 
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
 
static QgsPaintEffect * defaultStack()
Returns a new effect stack consisting of a sensible selection of default effects.
 
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
 
Base class for visual effects which can be applied to QPicture drawings.
 
static Qgis::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a Qgis::BlendMode corresponding to a QPainter::CompositionMode.
 
static QPainter::CompositionMode getCompositionMode(Qgis::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a Qgis::BlendMode.
 
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
 
A container for the context for various read/write operations on objects.
 
A rectangle specified with double values.
 
Q_INVOKABLE QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
 
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
 
Contains information about the context of a rendering operation.
 
#define QgsDebugMsgLevel(str, level)
 
_LayerRef< QgsMapLayer > QgsMapLayerRef
 
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
 
Setting options for loading annotation layers.
 
QgsCoordinateTransformContext transformContext
Coordinate transform context.
 
Setting options for creating vector data providers.
 
QgsCoordinateTransformContext transformContext
Coordinate transform context.
 
QString source
Weak reference to layer public source.
 
QString name
Weak reference to layer name.
 
TYPE * get() const
Returns a pointer to the layer, or nullptr if the reference has not yet been matched to a layer.
 
QString provider
Weak reference to layer provider.
 
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.
 
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
 
QString layerId
Original layer ID.