Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add method to replace an existing item in an annotation layer
  • Loading branch information
nyalldawson committed Sep 7, 2021
1 parent d656bae commit 38b8b82
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 0 deletions.
Expand Up @@ -68,6 +68,15 @@ Adds an ``item`` to the layer.
Ownership of ``item`` is transferred to the layer.

Returns the unique ID assigned to the item.
%End

void replaceItem( const QString &id, QgsAnnotationItem *item /Transfer/ );
%Docstring
Replaces the existing item with matching ``id`` with a new ``item``.

Ownership of ``item`` is transferred to the layer.

.. versionadded:: 3.22
%End

bool removeItem( const QString &id );
Expand Down
26 changes: 26 additions & 0 deletions src/core/annotations/qgsannotationlayer.cpp
Expand Up @@ -135,6 +135,32 @@ QString QgsAnnotationLayer::addItem( QgsAnnotationItem *item )
return uuid;
}

void QgsAnnotationLayer::replaceItem( const QString &id, QgsAnnotationItem *item )
{
std::unique_ptr< QgsAnnotationItem> prevItem( mItems.take( id ) );

if ( prevItem )
{
auto it = mNonIndexedItems.find( id );
if ( it == mNonIndexedItems.end() )
{
mSpatialIndex->remove( id, prevItem->boundingBox() );
}
else
{
mNonIndexedItems.erase( it );
}
}

mItems.insert( id, item );
if ( item->flags() & Qgis::AnnotationItemFlag::ScaleDependentBoundingBox )
mNonIndexedItems.insert( id );
else
mSpatialIndex->insert( id, item->boundingBox() );

triggerRepaint();
}

bool QgsAnnotationLayer::removeItem( const QString &id )
{
if ( !mItems.contains( id ) )
Expand Down
9 changes: 9 additions & 0 deletions src/core/annotations/qgsannotationlayer.h
Expand Up @@ -97,6 +97,15 @@ class CORE_EXPORT QgsAnnotationLayer : public QgsMapLayer
*/
QString addItem( QgsAnnotationItem *item SIP_TRANSFER );

/**
* Replaces the existing item with matching \a id with a new \a item.
*
* Ownership of \a item is transferred to the layer.
*
* \since QGIS 3.22
*/
void replaceItem( const QString &id, QgsAnnotationItem *item SIP_TRANSFER );

/**
* Removes (and deletes) the item with matching \a id.
*/
Expand Down
19 changes: 19 additions & 0 deletions tests/src/python/test_qgsannotationlayer.py
Expand Up @@ -114,6 +114,25 @@ def testItems(self):
layer.clear()
self.assertEqual(len(layer.items()), 0)

def testReplaceItem(self):
layer = QgsAnnotationLayer('test', QgsAnnotationLayer.LayerOptions(QgsProject.instance().transformContext()))

polygon_item_id = layer.addItem(QgsAnnotationPolygonItem(
QgsPolygon(QgsLineString([QgsPoint(12, 13), QgsPoint(14, 13), QgsPoint(14, 15), QgsPoint(12, 13)]))))
linestring_item_id = layer.addItem(
QgsAnnotationLineItem(QgsLineString([QgsPoint(11, 13), QgsPoint(12, 13), QgsPoint(12, 15)])))
marker_item_id = layer.addItem(QgsAnnotationMarkerItem(QgsPoint(12, 13)))

self.assertEqual(layer.item(polygon_item_id).geometry().asWkt(), 'Polygon ((12 13, 14 13, 14 15, 12 13))')
self.assertEqual(layer.item(linestring_item_id).geometry().asWkt(), 'LineString (11 13, 12 13, 12 15)')
self.assertEqual(layer.item(marker_item_id).geometry().asWkt(), 'POINT(12 13)')

layer.replaceItem(linestring_item_id,
QgsAnnotationLineItem(QgsLineString([QgsPoint(21, 13), QgsPoint(22, 13), QgsPoint(22, 15)])))
self.assertEqual(layer.item(polygon_item_id).geometry().asWkt(), 'Polygon ((12 13, 14 13, 14 15, 12 13))')
self.assertEqual(layer.item(linestring_item_id).geometry().asWkt(), 'LineString (21 13, 22 13, 22 15)')
self.assertEqual(layer.item(marker_item_id).geometry().asWkt(), 'POINT(12 13)')

def testReset(self):
layer = QgsAnnotationLayer('test', QgsAnnotationLayer.LayerOptions(QgsProject.instance().transformContext()))
self.assertTrue(layer.isValid())
Expand Down

0 comments on commit 38b8b82

Please sign in to comment.