QGIS API Documentation 3.41.0-Master (3440c17df1d)
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 , mLayerBlendMode( layer->blendMode() )
30{
31 if ( QgsMapLayer *linkedLayer = layer->linkedVisibilityLayer() )
32 {
33 if ( !context.customProperties().value( QStringLiteral( "visible_layer_ids" ) ).toList().contains( linkedLayer->id() ) )
34 {
35 mReadyToCompose = true;
36 return;
37 }
38 }
39
40 // Clone items from layer which fall inside the rendered extent
41 // Because some items have scale dependent bounds, we have to accept some limitations here.
42 // first, we can use the layer's spatial index to very quickly retrieve items we know will fall within the visible
43 // extent. This will ONLY apply to items which have a non-scale-dependent bounding box though.
44
45 const QStringList itemsList = layer->queryIndex( context.extent() );
46 QSet< QString > items( itemsList.begin(), itemsList.end() );
47
48 // we also have NO choice but to clone ALL non-indexed items (i.e. those with a scale-dependent bounding box)
49 // since these won't be in the layer's spatial index, and it's too expensive to determine their actual bounding box
50 // upfront (we are blocking the main thread right now!)
51
52 // TODO -- come up with some brilliant way to avoid this and also index scale-dependent items ;)
53 items.unite( layer->mNonIndexedItems );
54
55 mItems.reserve( items.size() );
56 std::transform( items.begin(), items.end(), std::back_inserter( mItems ),
57 [layer]( const QString & id ) ->std::pair< QString, std::unique_ptr< QgsAnnotationItem > >
58 {
59 return std::make_pair( id, std::unique_ptr< QgsAnnotationItem >( layer->item( id )->clone() ) );
60 } );
61
62 std::sort( mItems.begin(), mItems.end(), [](
63 const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &a,
64 const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &b )
65 { return a.second->zIndex() < b.second->zIndex(); } );
66
67 if ( layer->paintEffect() && layer->paintEffect()->enabled() )
68 {
69 mPaintEffect.reset( layer->paintEffect()->clone() );
70 }
71}
72
74
76{
77 return mFeedback.get();
78}
79
81{
82 QgsRenderContext &context = *renderContext();
83
84 if ( mPaintEffect )
85 {
86 mPaintEffect->begin( context );
87 }
88
89 bool canceled = false;
90 for ( const std::pair< QString, std::unique_ptr< QgsAnnotationItem > > &item : std::as_const( mItems ) )
91 {
92 if ( mFeedback->isCanceled() )
93 {
94 canceled = true;
95 break;
96 }
97
98 if ( !item.second->enabled() )
99 continue;
100
101 std::optional< QgsScopedRenderContextReferenceScaleOverride > referenceScaleOverride;
102 if ( item.second->useSymbologyReferenceScale() && item.second->flags() & Qgis::AnnotationItemFlag::SupportsReferenceScale )
103 {
104 referenceScaleOverride.emplace( QgsScopedRenderContextReferenceScaleOverride( context, item.second->symbologyReferenceScale() ) );
105 }
106
107 const QgsRectangle bounds = item.second->boundingBox( context );
108 if ( bounds.intersects( context.extent() ) )
109 {
110 item.second->render( context, mFeedback.get() );
111 std::unique_ptr< QgsRenderedAnnotationItemDetails > details = std::make_unique< QgsRenderedAnnotationItemDetails >( mLayerID, item.first );
112 details->setBoundingBox( bounds );
113 appendRenderedItemDetails( details.release() );
114 }
115 }
116
117 if ( mPaintEffect )
118 {
119 mPaintEffect->end( context );
120 }
121
122 return !canceled;
123}
124
126{
128 return false;
129
130 if ( !qgsDoubleNear( mLayerOpacity, 1.0 ) )
131 return true;
132
133 if ( mLayerBlendMode != QPainter::CompositionMode_SourceOver )
134 return true;
135
136 return false;
137}
@ 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...
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:5958