QGIS API Documentation 3.39.0-Master (d85f3c2a281)
Loading...
Searching...
No Matches
qgsannotationlayerrenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsannotationlayerrenderer.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
18#include "qgsannotationlayer.h"
19#include "qgsfeedback.h"
21#include "qgspainteffect.h"
22#include "qgsrendercontext.h"
23#include <optional>
24
26 : QgsMapLayerRenderer( layer->id(), &context )
27 , mFeedback( std::make_unique< QgsFeedback >() )
28 , mLayerOpacity( layer->opacity() )
29{
30 if ( QgsMapLayer *linkedLayer = layer->linkedVisibilityLayer() )
31 {
32 if ( !context.customProperties().value( QStringLiteral( "visible_layer_ids" ) ).toList().contains( linkedLayer->id() ) )
33 {
34 mReadyToCompose = true;
35 return;
36 }
37 }
38
39 // Clone items from layer which fall inside the rendered extent
40 // Because some items have scale dependent bounds, we have to accept some limitations here.
41 // first, we can use the layer's spatial index to very quickly retrieve items we know will fall within the visible
42 // extent. This will ONLY apply to items which have a non-scale-dependent bounding box though.
43
44 const QStringList itemsList = layer->queryIndex( context.extent() );
45 QSet< QString > items( itemsList.begin(), itemsList.end() );
46
47 // we also have NO choice but to clone ALL non-indexed items (i.e. those with a scale-dependent bounding box)
48 // since these won't be in the layer's spatial index, and it's too expensive to determine their actual bounding box
49 // upfront (we are blocking the main thread right now!)
50
51 // TODO -- come up with some brilliant way to avoid this and also index scale-dependent items ;)
52 items.unite( layer->mNonIndexedItems );
53
54 mItems.reserve( items.size() );
55 std::transform( items.begin(), items.end(), std::back_inserter( mItems ),
56 [layer]( const QString & id ) ->std::pair< QString, std::unique_ptr< QgsAnnotationItem > >
57 {
58 return std::make_pair( id, std::unique_ptr< QgsAnnotationItem >( layer->item( id )->clone() ) );
59 } );
60
61 std::sort( mItems.begin(), mItems.end(), [](
62 const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &a,
63 const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &b )
64 { return a.second->zIndex() < b.second->zIndex(); } );
65
66 if ( layer->paintEffect() && layer->paintEffect()->enabled() )
67 {
68 mPaintEffect.reset( layer->paintEffect()->clone() );
69 }
70}
71
73
75{
76 return mFeedback.get();
77}
78
80{
81 QgsRenderContext &context = *renderContext();
82
83 if ( mPaintEffect )
84 {
85 mPaintEffect->begin( context );
86 }
87
88 bool canceled = false;
89 for ( const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &item : std::as_const( mItems ) )
90 {
91 if ( mFeedback->isCanceled() )
92 {
93 canceled = true;
94 break;
95 }
96
97 if ( !item.second->enabled() )
98 continue;
99
100 std::optional< QgsScopedRenderContextReferenceScaleOverride > referenceScaleOverride;
101 if ( item.second->useSymbologyReferenceScale() && item.second->flags() & Qgis::AnnotationItemFlag::SupportsReferenceScale )
102 {
103 referenceScaleOverride.emplace( QgsScopedRenderContextReferenceScaleOverride( context, item.second->symbologyReferenceScale() ) );
104 }
105
106 const QgsRectangle bounds = item.second->boundingBox( context );
107 if ( bounds.intersects( context.extent() ) )
108 {
109 item.second->render( context, mFeedback.get() );
110 std::unique_ptr< QgsRenderedAnnotationItemDetails > details = std::make_unique< QgsRenderedAnnotationItemDetails >( mLayerID, item.first );
111 details->setBoundingBox( bounds );
112 appendRenderedItemDetails( details.release() );
113 }
114 }
115
116 if ( mPaintEffect )
117 {
118 mPaintEffect->end( context );
119 }
120
121 return !canceled;
122}
123
@ SupportsReferenceScale
Item supports reference scale based rendering.
@ UseAdvancedEffects
Enable layer opacity and blending effects.
bool forceRasterRender() const override
Returns true if the renderer must be rendered to a raster paint device (e.g.
~QgsAnnotationLayerRenderer() override
bool render() override
Do the rendering (based on data stored in the class).
QgsFeedback * feedback() const override
Access to feedback object of the layer renderer (may be nullptr)
QgsAnnotationLayerRenderer(QgsAnnotationLayer *layer, QgsRenderContext &context)
Constructor for a QgsAnnotationLayerRenderer, for the specified layer.
Represents a map layer containing a set of georeferenced annotations, e.g.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
QgsMapLayer * linkedVisibilityLayer()
Returns a linked layer, where the items in this annotation layer will only be visible when the linked...
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
Base class for utility classes that encapsulate information necessary for rendering of map layers.
bool mReadyToCompose
The flag must be set to false in renderer's constructor if wants to use the smarter map redraws funct...
void appendRenderedItemDetails(QgsRenderedItemDetails *details)
Appends the details of a rendered item to the renderer.
QgsRenderContext * renderContext()
Returns the render context associated with the renderer.
Base class for all map layer types.
Definition qgsmaplayer.h:76
bool enabled() const
Returns whether the effect is enabled.
virtual QgsPaintEffect * clone() const =0
Duplicates an effect by creating a deep copy of the effect.
A rectangle specified with double values.
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
Contains information about the context of a rendering operation.
double symbologyReferenceScale() const
Returns the symbology reference scale.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
bool testFlag(Qgis::RenderContextFlag flag) const
Check whether a particular flag is enabled.
QVariantMap customProperties() const
Returns custom rendering properties.
Scoped object for temporary override of the symbologyReferenceScale property of a QgsRenderContext.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:5857