QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsmaprenderercache.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaprenderercache.cpp
3  --------------------------------------
4  Date : December 2013
5  Copyright : (C) 2013 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsmaprenderercache.h"
17 
18 #include "qgsmaplayer.h"
19 #include "qgsmaplayerlistutils.h"
20 
22 {
23  clear();
24 }
25 
27 {
28  QMutexLocker lock( &mMutex );
29  clearInternal();
30 }
31 
32 void QgsMapRendererCache::clearInternal()
33 {
34  mExtent.setMinimal();
35  mScale = 0;
36 
37  // make sure we are disconnected from all layers
38  const auto constMConnectedLayers = mConnectedLayers;
39  for ( const QgsWeakMapLayerPointer &layer : constMConnectedLayers )
40  {
41  if ( layer.data() )
42  {
43  disconnect( layer.data(), &QgsMapLayer::repaintRequested, this, &QgsMapRendererCache::layerRequestedRepaint );
44  disconnect( layer.data(), &QgsMapLayer::willBeDeleted, this, &QgsMapRendererCache::layerRequestedRepaint );
45  }
46  }
47  mCachedImages.clear();
48  mConnectedLayers.clear();
49 }
50 
51 void QgsMapRendererCache::dropUnusedConnections()
52 {
53  QSet< QgsWeakMapLayerPointer > stillDepends = dependentLayers();
54  QSet< QgsWeakMapLayerPointer > disconnects = mConnectedLayers.subtract( stillDepends );
55  const auto constDisconnects = disconnects;
56  for ( const QgsWeakMapLayerPointer &layer : constDisconnects )
57  {
58  if ( layer.data() )
59  {
60  disconnect( layer.data(), &QgsMapLayer::repaintRequested, this, &QgsMapRendererCache::layerRequestedRepaint );
61  disconnect( layer.data(), &QgsMapLayer::willBeDeleted, this, &QgsMapRendererCache::layerRequestedRepaint );
62  }
63  }
64 
65  mConnectedLayers = stillDepends;
66 }
67 
68 QSet<QgsWeakMapLayerPointer > QgsMapRendererCache::dependentLayers() const
69 {
70  QSet< QgsWeakMapLayerPointer > result;
71  QMap<QString, CacheParameters>::const_iterator it = mCachedImages.constBegin();
72  for ( ; it != mCachedImages.constEnd(); ++it )
73  {
74  const auto dependentLayers { it.value().dependentLayers };
75  for ( const QgsWeakMapLayerPointer &l : dependentLayers )
76  {
77  if ( l.data() )
78  result << l;
79  }
80  }
81  return result;
82 }
83 
84 bool QgsMapRendererCache::init( const QgsRectangle &extent, double scale )
85 {
86  QMutexLocker lock( &mMutex );
87 
88  // check whether the params are the same
89  if ( extent == mExtent &&
90  qgsDoubleNear( scale, mScale ) )
91  return true;
92 
93  clearInternal();
94 
95  // set new params
96  mExtent = extent;
97  mScale = scale;
98 
99  return false;
100 }
101 
102 void QgsMapRendererCache::setCacheImage( const QString &cacheKey, const QImage &image, const QList<QgsMapLayer *> &dependentLayers )
103 {
104  QMutexLocker lock( &mMutex );
105 
106  CacheParameters params;
107  params.cachedImage = image;
108 
109  // connect to the layer to listen to layer's repaintRequested() signals
110  const auto constDependentLayers = dependentLayers;
111  for ( QgsMapLayer *layer : constDependentLayers )
112  {
113  if ( layer )
114  {
115  params.dependentLayers << layer;
116  if ( !mConnectedLayers.contains( QgsWeakMapLayerPointer( layer ) ) )
117  {
118  connect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapRendererCache::layerRequestedRepaint );
119  connect( layer, &QgsMapLayer::willBeDeleted, this, &QgsMapRendererCache::layerRequestedRepaint );
120  mConnectedLayers << layer;
121  }
122  }
123  }
124 
125  mCachedImages[cacheKey] = params;
126 }
127 
128 bool QgsMapRendererCache::hasCacheImage( const QString &cacheKey ) const
129 {
130  return mCachedImages.contains( cacheKey );
131 }
132 
133 QImage QgsMapRendererCache::cacheImage( const QString &cacheKey ) const
134 {
135  QMutexLocker lock( &mMutex );
136  return mCachedImages.value( cacheKey ).cachedImage;
137 }
138 
139 QList< QgsMapLayer * > QgsMapRendererCache::dependentLayers( const QString &cacheKey ) const
140 {
141  if ( mCachedImages.contains( cacheKey ) )
142  {
143  return _qgis_listQPointerToRaw( mCachedImages.value( cacheKey ).dependentLayers );
144  }
145  return QList< QgsMapLayer * >();
146 }
147 
148 
149 void QgsMapRendererCache::layerRequestedRepaint()
150 {
151  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
152  invalidateCacheForLayer( layer );
153 }
154 
156 {
157  if ( !layer )
158  return;
159 
160  QMutexLocker lock( &mMutex );
161 
162  // check through all cached images to clear any which depend on this layer
163  QMap<QString, CacheParameters>::iterator it = mCachedImages.begin();
164  for ( ; it != mCachedImages.end(); )
165  {
166  if ( !it.value().dependentLayers.contains( layer ) )
167  {
168  ++it;
169  continue;
170  }
171 
172  it = mCachedImages.erase( it );
173  }
174  dropUnusedConnections();
175 }
176 
177 void QgsMapRendererCache::clearCacheImage( const QString &cacheKey )
178 {
179  QMutexLocker lock( &mMutex );
180 
181  mCachedImages.remove( cacheKey );
182  dropUnusedConnections();
183 }
184 
QgsMapLayer::willBeDeleted
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
QgsMapRendererCache::hasCacheImage
bool hasCacheImage(const QString &cacheKey) const
Returns true if the cache contains an image with the specified cacheKey.
Definition: qgsmaprenderercache.cpp:128
QgsMapRendererCache::clear
void clear()
Invalidates the cache contents, clearing all cached images.
Definition: qgsmaprenderercache.cpp:26
QgsRectangle::setMinimal
void setMinimal() SIP_HOLDGIL
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:151
QgsMapRendererCache::init
bool init(const QgsRectangle &extent, double scale)
Initialize cache: set new parameters and clears the cache if any parameters have changed since last i...
Definition: qgsmaprenderercache.cpp:84
qgsmaprenderercache.h
QgsMapRendererCache::cacheImage
QImage cacheImage(const QString &cacheKey) const
Returns the cached image for the specified cacheKey.
Definition: qgsmaprenderercache.cpp:133
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsMapRendererCache::QgsMapRendererCache
QgsMapRendererCache()
Definition: qgsmaprenderercache.cpp:21
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsMapLayer::repaintRequested
void repaintRequested(bool deferredUpdate=false)
By emitting this signal the layer tells that either appearance or content have been changed and any v...
qgsmaplayer.h
QgsMapRendererCache::dependentLayers
QList< QgsMapLayer * > dependentLayers(const QString &cacheKey) const
Returns a list of map layers on which an image in the cache depends.
Definition: qgsmaprenderercache.cpp:139
QgsWeakMapLayerPointer
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Definition: qgsmaplayer.h:1688
QgsMapRendererCache::setCacheImage
void setCacheImage(const QString &cacheKey, const QImage &image, const QList< QgsMapLayer * > &dependentLayers=QList< QgsMapLayer * >())
Set the cached image for a particular cacheKey.
Definition: qgsmaprenderercache.cpp:102
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsMapRendererCache::clearCacheImage
void clearCacheImage(const QString &cacheKey)
Removes an image from the cache with matching cacheKey.
Definition: qgsmaprenderercache.cpp:177
qgsmaplayerlistutils.h
QgsMapRendererCache::invalidateCacheForLayer
void invalidateCacheForLayer(QgsMapLayer *layer)
Invalidates cached images which relate to the specified map layer.
Definition: qgsmaprenderercache.cpp:155