34class QgsAnnotationLayerSpatialIndex :
public RTree<QString, float, 2, float>
38 void insert(
const QString &uuid,
const QgsRectangle &bounds )
40 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
43 scaledBounds[0], scaledBounds[ 1]
46 scaledBounds[2], scaledBounds[3]
57 void remove(
const QString &uuid,
const QgsRectangle &bounds )
59 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
62 scaledBounds[0], scaledBounds[ 1]
65 scaledBounds[2], scaledBounds[3]
75 bool intersects(
const QgsRectangle &bounds,
const std::function<
bool(
const QString &uuid )> &callback )
const
77 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
80 scaledBounds[0], scaledBounds[ 1]
83 scaledBounds[2], scaledBounds[3]
90 std::array<float, 4> scaleBounds(
const QgsRectangle &bounds )
const
94 static_cast< float >( bounds.
xMinimum() ),
95 static_cast< float >( bounds.
yMinimum() ),
96 static_cast< float >( bounds.
xMaximum() ),
97 static_cast< float >( bounds.
yMaximum() )
105 , mTransformContext( options.transformContext )
106 , mSpatialIndex( std::make_unique< QgsAnnotationLayerSpatialIndex >() )
113 mDataProvider =
new QgsAnnotationLayerDataProvider( providerOptions, QgsDataProvider::ReadFlags() );
116 mPaintEffect->setEnabled(
false );
122 qDeleteAll( mItems );
123 delete mDataProvider;
143 const QString uuid = QUuid::createUuid().toString();
144 mItems.insert( uuid,
item );
146 mNonIndexedItems.insert( uuid );
159 std::unique_ptr< QgsAnnotationItem> prevItem( mItems.take(
id ) );
163 auto it = mNonIndexedItems.find(
id );
164 if ( it == mNonIndexedItems.end() )
166 mSpatialIndex->remove(
id, prevItem->boundingBox() );
170 mNonIndexedItems.erase( it );
174 mItems.insert(
id,
item );
176 mNonIndexedItems.insert(
id );
187 if ( !mItems.contains(
id ) )
190 std::unique_ptr< QgsAnnotationItem>
item( mItems.take(
id ) );
192 auto it = mNonIndexedItems.find(
id );
193 if ( it == mNonIndexedItems.end() )
199 mNonIndexedItems.erase( it );
213 qDeleteAll( mItems );
215 mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
216 mNonIndexedItems.clear();
225 return mItems.empty();
232 return mItems.value(
id );
241 mSpatialIndex->intersects( bounds, [&res, feedback](
const QString & uuid )->
bool
253 QStringList res = queryIndex( bounds, feedback );
255 for (
const QString &uuid : mNonIndexedItems )
257 if ( mItems.value( uuid )->boundingBox( context ).intersects( bounds ) )
272 auto it = mNonIndexedItems.find( operation->
itemId() );
273 if ( it == mNonIndexedItems.end() )
275 mSpatialIndex->remove( operation->
itemId(), targetItem->boundingBox() );
277 res = targetItem->applyEdit( operation );
285 mSpatialIndex->insert( operation->
itemId(), targetItem->boundingBox() );
290 delete mItems.take( operation->
itemId() );
291 mNonIndexedItems.remove( operation->
itemId() );
315 std::unique_ptr< QgsAnnotationLayer > layer = std::make_unique< QgsAnnotationLayer >(
name(), options );
318 for (
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
320 layer->mItems.insert( it.key(), ( *it )->clone() );
322 layer->mNonIndexedItems.insert( it.key() );
324 layer->mSpatialIndex->insert( it.key(), ( *it )->boundingBox() );
328 layer->setPaintEffect( mPaintEffect->clone() );
330 return layer.release();
345 for (
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
349 rect = it.value()->boundingBox();
366 mTransformContext = context;
380 readItems( layerNode, errorMsg, context );
393 QDomElement mapLayerNode = layer_node.toElement();
395 if ( mapLayerNode.isNull() )
404 writeItems( layer_node, doc, errorMsg, context );
414 QDomElement layerElement = node.toElement();
420 QDomElement layerOpacityElem = doc.createElement( QStringLiteral(
"layerOpacity" ) );
421 const QDomText layerOpacityText = doc.createTextNode( QString::number(
opacity() ) );
422 layerOpacityElem.appendChild( layerOpacityText );
423 node.appendChild( layerOpacityElem );
429 QDomElement blendModeElem = doc.createElement( QStringLiteral(
"blendMode" ) );
431 blendModeElem.appendChild( blendModeText );
432 node.appendChild( blendModeElem );
434 QDomElement paintEffectElem = doc.createElement( QStringLiteral(
"paintEffect" ) );
436 mPaintEffect->saveProperties( doc, paintEffectElem );
437 node.appendChild( paintEffectElem );
447 const QDomElement layerElement = node.toElement();
452 const QDomNode layerOpacityNode = node.namedItem( QStringLiteral(
"layerOpacity" ) );
453 if ( !layerOpacityNode.isNull() )
455 const QDomElement e = layerOpacityNode.toElement();
463 const QDomNode blendModeNode = node.namedItem( QStringLiteral(
"blendMode" ) );
464 if ( !blendModeNode.isNull() )
466 const QDomElement e = blendModeNode.toElement();
471 const QDomNode paintEffectNode = node.namedItem( QStringLiteral(
"paintEffect" ) );
472 if ( !paintEffectNode.isNull() )
474 const QDomElement effectElem = paintEffectNode.firstChildElement( QStringLiteral(
"effect" ) );
475 if ( !effectElem.isNull() )
485bool QgsAnnotationLayer::writeItems( QDomNode &node, QDomDocument &doc, QString &,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories )
const
489 QDomElement itemsElement = doc.createElement( QStringLiteral(
"items" ) );
491 for (
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
493 QDomElement itemElement = doc.createElement( QStringLiteral(
"item" ) );
494 itemElement.setAttribute( QStringLiteral(
"type" ), ( *it )->type() );
495 itemElement.setAttribute( QStringLiteral(
"id" ), it.key() );
496 ( *it )->writeXml( itemElement, doc, context );
497 itemsElement.appendChild( itemElement );
499 node.appendChild( itemsElement );
504bool QgsAnnotationLayer::readItems(
const QDomNode &node, QString &,
QgsReadWriteContext &context, QgsMapLayer::StyleCategories )
508 qDeleteAll( mItems );
510 mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
511 mNonIndexedItems.clear();
513 const QDomNodeList itemsElements = node.toElement().elementsByTagName( QStringLiteral(
"items" ) );
514 if ( itemsElements.size() == 0 )
517 const QDomNodeList
items = itemsElements.at( 0 ).childNodes();
518 for (
int i = 0; i <
items.size(); ++i )
520 const QDomElement itemElement =
items.at( i ).toElement();
521 const QString
id = itemElement.attribute( QStringLiteral(
"id" ) );
522 const QString
type = itemElement.attribute( QStringLiteral(
"type" ) );
528 mNonIndexedItems.insert(
id );
531 mItems.insert(
id,
item.release() );
542 writeItems( node, doc, errorMessage, context, categories );
544 return writeSymbology( node, doc, errorMessage, context, categories );
551 readItems( node, errorMessage, context, categories );
553 return readSymbology( node, errorMessage, context, categories );
575 return mDataProvider;
582 return mDataProvider;
589 QString
metadata = QStringLiteral(
"<html>\n<body>\n<h1>" ) + tr(
"General" ) + QStringLiteral(
"</h1>\n<hr>\n" ) + QStringLiteral(
"<table class=\"list-view\">\n" );
591 metadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Name" ) + QStringLiteral(
"</td><td>" ) +
name() + QStringLiteral(
"</td></tr>\n" );
594 metadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Extent" ) + QStringLiteral(
"</td><td>" ) +
extent().
toString() + QStringLiteral(
"</td></tr>\n" );
597 QLocale locale = QLocale();
598 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
599 const int itemCount = mItems.size();
600 metadata += QStringLiteral(
"<tr><td class=\"highlight\">" )
601 + tr(
"Item count" ) + QStringLiteral(
"</td><td>" )
602 + locale.toString(
static_cast<qlonglong
>( itemCount ) )
603 + QStringLiteral(
"</td></tr>\n" );
604 metadata += QLatin1String(
"</table>\n<br><br>" );
610 metadata += QStringLiteral(
"<h1>" ) + tr(
"Items" ) + QStringLiteral(
"</h1>\n<hr>\n" );
612 metadata += QLatin1String(
"<table width=\"100%\" class=\"tabular-view\">\n" );
613 metadata += QLatin1String(
"<tr><th>" ) + tr(
"Type" ) + QLatin1String(
"</th><th>" ) + tr(
"Count" ) + QLatin1String(
"</th></tr>\n" );
615 QMap< QString, int > itemCounts;
616 for (
auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
618 itemCounts[ it.value()->type() ]++;
623 for (
auto it = itemTypes.begin(); it != itemTypes.end(); ++it )
627 rowClass = QStringLiteral(
"class=\"odd-row\"" );
628 metadata += QLatin1String(
"<tr " ) + rowClass + QLatin1String(
"><td>" ) + it.value() + QLatin1String(
"</td><td>" ) + locale.toString(
static_cast<qlonglong
>( itemCounts.value( it.key() ) ) ) + QLatin1String(
"</td></tr>\n" );
632 metadata += QLatin1String(
"</table>\n<br><br>" );
634 metadata += QLatin1String(
"\n</body>\n</html>\n" );
642 return mPaintEffect.get();
649 mPaintEffect.reset( effect );
657QgsAnnotationLayerDataProvider::QgsAnnotationLayerDataProvider(
658 const ProviderOptions &options,
659 QgsDataProvider::ReadFlags flags )
670QString QgsAnnotationLayerDataProvider::name()
const
674 return QStringLiteral(
"annotation" );
677QString QgsAnnotationLayerDataProvider::description()
const
684QgsRectangle QgsAnnotationLayerDataProvider::extent()
const
691bool QgsAnnotationLayerDataProvider::isValid()
const
The Qgis class provides global constants 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.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
Abstract base class for annotation item edit operations.
QString itemId() const
Returns the associated item ID.
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.
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.
QgsAnnotationItem * item(const QString &id)
Returns the item with the specified id, or nullptr if no matching item was found.
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.
Qgis::AnnotationItemEditOperationResult applyEdit(QgsAbstractAnnotationItemEditOperation *operation)
Applies an edit operation to the layer.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
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.
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.
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.
~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.
This class 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.
virtual void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
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....
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.
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.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
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)
#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.