Skip to content
Permalink
Browse files
[api] Add framework for collecting rendered item details during map
renderer operations

This follow a similar pattern as how labeling results could be collected
after a map render job, but generalises the API so that it can be
used for storing details of rendered items of any type.

It's currently used for storing details of rendered annotation items,
so that map tools can retrieve details of annotation items visible
in the canvas in an optimised way.
  • Loading branch information
nyalldawson committed Aug 31, 2021
1 parent b09994a commit 660433d9a961480d8a8d502e264c93f2a5c88b6d
@@ -0,0 +1,57 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/annotations/qgsrenderedannotationitemdetails.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsRenderedAnnotationItemDetails : QgsRenderedItemDetails
{
%Docstring(signature="appended")
Contains information about a rendered annotation item.

.. versionadded:: 3.22
%End

%TypeHeaderCode
#include "qgsrenderedannotationitemdetails.h"
%End
public:

QgsRenderedAnnotationItemDetails( const QString &layerId, const QString &itemId );
%Docstring
Constructor for QgsRenderedAnnotationItemDetails.
%End

SIP_PYOBJECT __repr__();
%MethodCode
QString str = QStringLiteral( "<QgsRenderedAnnotationItemDetails: %1 - %2>" ).arg( sipCpp->layerId(), sipCpp->itemId() );
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
%End

virtual QgsRenderedAnnotationItemDetails *clone() const /Factory/;


QString layerId() const;
%Docstring
Returns the layer ID of the associated map layer.
%End

QString itemId() const;
%Docstring
Returns the item ID of the associated annotation item.
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/annotations/qgsrenderedannotationitemdetails.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -49,6 +49,8 @@ The following subclasses are available:

QgsMapRendererJob( const QgsMapSettings &settings );

~QgsMapRendererJob();

void start();
%Docstring
Start the rendering job and immediately return.
@@ -95,6 +97,15 @@ Gets pointer to internal labeling engine (in order to get access to the results)
This should not be used if cached labeling was redrawn - see :py:func:`~QgsMapRendererJob.usedCachedLabels`.

.. seealso:: :py:func:`usedCachedLabels`
%End

QgsRenderedItemResults *takeRenderedItemResults() /Transfer/;
%Docstring
Takes the rendered item results from the map render job and returns them.

Ownership is transferred to the caller.

.. versionadded:: 3.22
%End

void setFeatureFilterProvider( const QgsFeatureFilterProvider *f );
@@ -194,6 +205,7 @@ emitted when asynchronous rendering is finished (or canceled).





};

@@ -0,0 +1,53 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/maprenderer/qgsrendereditemresults.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/






class QgsRenderedItemResults
{
%Docstring(signature="appended")
Stores collated details of rendered items during a map rendering operation.

.. versionadded:: 3.22
%End

%TypeHeaderCode
#include "qgsrendereditemresults.h"
%End
public:
QgsRenderedItemResults();
~QgsRenderedItemResults();


QList< QgsRenderedItemDetails * > renderedItems() const;
%Docstring
Returns a list of all rendered items.
%End

QList<const QgsRenderedAnnotationItemDetails *> renderedAnnotationItemsInBounds( const QgsRectangle &bounds ) const;
%Docstring
Returns a list with details of the rendered annotation items within the specified ``bounds``.

.. versionadded:: 3.22
%End


private:
QgsRenderedItemResults( const QgsRenderedItemResults & );
};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/maprenderer/qgsrendereditemresults.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -110,11 +110,35 @@ least partially) some data
%End


QList< QgsRenderedItemDetails * > takeRenderedItemDetails() /TransferBack/;
%Docstring
Takes the list of rendered item details from the renderer.

Ownership of items is transferred to the caller.

.. seealso:: :py:func:`appendRenderedItemDetails`

.. versionadded:: 3.22
%End

protected:




void appendRenderedItemDetails( QgsRenderedItemDetails *details /Transfer/ );
%Docstring
Appends the ``details`` of a rendered item to the renderer.

Rendered item details can be retrieved by calling :py:func:`~QgsMapLayerRenderer.takeRenderedItemDetails`.

Ownership of ``details`` is transferred to the renderer.

.. seealso:: :py:func:`takeRenderedItemDetails`

.. versionadded:: 3.22
%End

};

/************************************************************************
@@ -0,0 +1,61 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsrendereditemdetails.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsRenderedItemDetails
{
%Docstring(signature="appended")
Base class for detailed information about a rendered item.

.. versionadded:: 3.22
%End

%TypeHeaderCode
#include "qgsrendereditemdetails.h"
%End
public:

%ConvertToSubClassCode
if ( dynamic_cast<QgsRenderedAnnotationItemDetails *>( sipCpp ) )
sipType = sipType_QgsRenderedAnnotationItemDetails;
else
sipType = 0;
%End

virtual ~QgsRenderedItemDetails();

virtual QgsRenderedItemDetails *clone() const = 0 /Factory/;
%Docstring
Clones the details.
%End

QgsRectangle boundingBox() const;
%Docstring
Returns the bounding box of the item (in map units).

.. seealso:: :py:func:`setBoundingBox`
%End

void setBoundingBox( const QgsRectangle &bounds );
%Docstring
Sets the bounding box of the item (in map units).

.. seealso:: :py:func:`boundingBox`
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsrendereditemdetails.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -152,6 +152,7 @@
%Include auto_generated/qgsrenderchecker.sip
%Include auto_generated/qgsrendercontext.sip
%Include auto_generated/qgsrenderedfeaturehandlerinterface.sip
%Include auto_generated/qgsrendereditemdetails.sip
%Include auto_generated/qgsrunprocess.sip
%Include auto_generated/qgsruntimeprofiler.sip
%Include auto_generated/qgsscalecalculator.sip
@@ -212,6 +213,7 @@
%Include auto_generated/annotations/qgsannotationpointtextitem.sip
%Include auto_generated/annotations/qgsannotationpolygonitem.sip
%Include auto_generated/annotations/qgshtmlannotation.sip
%Include auto_generated/annotations/qgsrenderedannotationitemdetails.sip
%Include auto_generated/annotations/qgssvgannotation.sip
%Include auto_generated/annotations/qgstextannotation.sip
%Include auto_generated/auth/qgsauthcertutils.sip
@@ -419,6 +421,7 @@
%Include auto_generated/maprenderer/qgsmaprendererparalleljob.sip
%Include auto_generated/maprenderer/qgsmaprenderersequentialjob.sip
%Include auto_generated/maprenderer/qgsmaprenderertask.sip
%Include auto_generated/maprenderer/qgsrendereditemresults.sip
%Include auto_generated/mesh/qgsmesh3daveraging.sip
%Include auto_generated/mesh/qgsmesheditor.sip
%Include auto_generated/mesh/qgsmeshdataprovider.sip
@@ -115,6 +115,17 @@ Since QGIS 3.20, if the ``allowOutdatedResults`` flag is ``False`` then outdated
as a result of an ongoing canvas render) will not be returned, and instead ``None`` will be returned.

.. versionadded:: 2.4
%End

const QgsRenderedItemResults *renderedItemResults( bool allowOutdatedResults = true ) const;
%Docstring
Gets access to the rendered item results (may be ``None``), which includes the results of rendering
annotation items in the canvas map.

If the ``allowOutdatedResults`` flag is ``False`` then outdated rendered item results (e.g.
as a result of an ongoing canvas render) will not be returned, and instead ``None`` will be returned.

.. versionadded:: 3.22
%End

void setCachingEnabled( bool enabled );
@@ -184,6 +184,7 @@ set(QGIS_CORE_SRCS
annotations/qgsannotationpointtextitem.cpp
annotations/qgsannotationpolygonitem.cpp
annotations/qgshtmlannotation.cpp
annotations/qgsrenderedannotationitemdetails.cpp
annotations/qgssvgannotation.cpp
annotations/qgstextannotation.cpp

@@ -397,6 +398,7 @@ set(QGIS_CORE_SRCS
qgsmaplayerlegend.cpp
qgsmaplayermodel.cpp
qgsmaplayerproxymodel.cpp
qgsmaplayerrenderer.cpp
qgsmaplayerstore.cpp
qgsmaplayerstyle.cpp
qgsmaplayerstylemanager.cpp
@@ -448,6 +450,7 @@ set(QGIS_CORE_SRCS
qgsremappingproxyfeaturesink.cpp
qgsrenderchecker.cpp
qgsrendercontext.cpp
qgsrendereditemdetails.cpp
qgsrunprocess.cpp
qgsruntimeprofiler.cpp
qgsscalecalculator.cpp
@@ -588,6 +591,7 @@ set(QGIS_CORE_SRCS
maprenderer/qgsmaprenderersequentialjob.cpp
maprenderer/qgsmaprendererstagedrenderjob.cpp
maprenderer/qgsmaprenderertask.cpp
maprenderer/qgsrendereditemresults.cpp

pal/costcalculator.cpp
pal/feature.cpp
@@ -1084,6 +1088,7 @@ set(QGIS_CORE_HDRS
qgsrenderchecker.h
qgsrendercontext.h
qgsrenderedfeaturehandlerinterface.h
qgsrendereditemdetails.h
qgsrunprocess.h
qgsruntimeprofiler.h
qgsscalecalculator.h
@@ -1158,6 +1163,7 @@ set(QGIS_CORE_HDRS
annotations/qgsannotationpolygonitem.h
annotations/qgsannotationregistry.h
annotations/qgshtmlannotation.h
annotations/qgsrenderedannotationitemdetails.h
annotations/qgssvgannotation.h
annotations/qgstextannotation.h

@@ -1404,6 +1410,7 @@ set(QGIS_CORE_HDRS
maprenderer/qgsmaprenderersequentialjob.h
maprenderer/qgsmaprendererstagedrenderjob.h
maprenderer/qgsmaprenderertask.h
maprenderer/qgsrendereditemresults.h

mesh/qgsmesh3daveraging.h
mesh/qgsmesheditor.h
@@ -17,6 +17,7 @@
#include "qgsannotationlayerrenderer.h"
#include "qgsannotationlayer.h"
#include "qgsfeedback.h"
#include "qgsrenderedannotationitemdetails.h"

QgsAnnotationLayerRenderer::QgsAnnotationLayerRenderer( QgsAnnotationLayer *layer, QgsRenderContext &context )
: QgsMapLayerRenderer( layer->id(), &context )
@@ -39,15 +40,18 @@ QgsAnnotationLayerRenderer::QgsAnnotationLayerRenderer( QgsAnnotationLayer *laye

mItems.reserve( items.size() );
std::transform( items.begin(), items.end(), std::back_inserter( mItems ),
[layer]( const QString & id ) -> QgsAnnotationItem* { return layer->item( id )->clone(); } );
[layer]( const QString & id ) ->std::pair< QString, std::unique_ptr< QgsAnnotationItem > >
{
return std::make_pair( id, std::unique_ptr< QgsAnnotationItem >( layer->item( id )->clone() ) );
} );

std::sort( mItems.begin(), mItems.end(), []( QgsAnnotationItem * a, QgsAnnotationItem * b ) { return a->zIndex() < b->zIndex(); } ); //clazy:exclude=detaching-member
std::sort( mItems.begin(), mItems.end(), [](
const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &a,
const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &b )
{ return a.second->zIndex() < b.second->zIndex(); } );
}

QgsAnnotationLayerRenderer::~QgsAnnotationLayerRenderer()
{
qDeleteAll( mItems );
}
QgsAnnotationLayerRenderer::~QgsAnnotationLayerRenderer() = default;

QgsFeedback *QgsAnnotationLayerRenderer::feedback() const
{
@@ -59,15 +63,22 @@ bool QgsAnnotationLayerRenderer::render()
QgsRenderContext &context = *renderContext();

bool canceled = false;
for ( QgsAnnotationItem *item : std::as_const( mItems ) )
for ( const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &item : std::as_const( mItems ) )
{
if ( mFeedback->isCanceled() )
{
canceled = true;
break;
}

item->render( context, mFeedback.get() );
const QgsRectangle bounds = item.second->boundingBox( context );
if ( bounds.intersects( context.extent() ) )
{
item.second->render( context, mFeedback.get() );
std::unique_ptr< QgsRenderedAnnotationItemDetails > details = std::make_unique< QgsRenderedAnnotationItemDetails >( mLayerID, item.first );
details->setBoundingBox( bounds );
appendRenderedItemDetails( details.release() );
}
}
return !canceled;
}

0 comments on commit 660433d

Please sign in to comment.