Skip to content

Commit 267f263

Browse files
committed
Move tile cache to a new file
1 parent 02a9211 commit 267f263

File tree

4 files changed

+119
-35
lines changed

4 files changed

+119
-35
lines changed

src/providers/wms/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ SET (WMS_SRCS
99
qgswmssourceselect.cpp
1010
qgswmsconnection.cpp
1111
qgswmsdataitems.cpp
12+
qgstilecache.cpp
1213
qgstilescalewidget.cpp
1314
qgswmtsdimensions.cpp
1415
qgsxyzconnection.cpp

src/providers/wms/qgstilecache.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/***************************************************************************
2+
qgstilecache.h
3+
--------------------------------------
4+
Date : September 2016
5+
Copyright : (C) 2016 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 "qgstilecache.h"
17+
18+
#include "qgsnetworkaccessmanager.h"
19+
20+
#include <QAbstractNetworkCache>
21+
#include <QImage>
22+
23+
QCache<QUrl, QImage> QgsTileCache::sTileCache( 256 );
24+
QMutex QgsTileCache::sTileCacheMutex;
25+
26+
27+
void QgsTileCache::insertTile( const QUrl& url, const QImage& image )
28+
{
29+
QMutexLocker locker( &sTileCacheMutex );
30+
sTileCache.insert( url, new QImage( image ) );
31+
}
32+
33+
bool QgsTileCache::tile( const QUrl& url, QImage& image )
34+
{
35+
QMutexLocker locker( &sTileCacheMutex );
36+
if ( QImage* i = sTileCache.object( url ) )
37+
{
38+
image = *i;
39+
return true;
40+
}
41+
else if ( QgsNetworkAccessManager::instance()->cache()->metaData( url ).isValid() )
42+
{
43+
if ( QIODevice* data = QgsNetworkAccessManager::instance()->cache()->data( url ) )
44+
{
45+
QByteArray imageData = data->readAll();
46+
delete data;
47+
48+
image = QImage::fromData( imageData );
49+
50+
// cache it as well (mutex is already locked)
51+
sTileCache.insert( url, new QImage( image ) );
52+
53+
return true;
54+
}
55+
}
56+
return false;
57+
}

src/providers/wms/qgstilecache.h

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/***************************************************************************
2+
qgstilecache.h
3+
--------------------------------------
4+
Date : September 2016
5+
Copyright : (C) 2016 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+
#ifndef QGSTILECACHE_H
17+
#define QGSTILECACHE_H
18+
19+
20+
#include <QCache>
21+
#include <QMutex>
22+
23+
class QImage;
24+
class QUrl;
25+
26+
/** A simple tile cache implementation. Tiles are cached according to their URL.
27+
* There is a small in-memory cache and a secondary caching in the local disk.
28+
* The in-memory cache is there to save CPU time otherwise wasted to read and
29+
* uncompress data saved on the disk.
30+
*
31+
* The class is thread safe (its methods can be called from any thread).
32+
*/
33+
class QgsTileCache
34+
{
35+
public:
36+
37+
//! Add a tile image with given URL to the cache
38+
static void insertTile( const QUrl& url, const QImage& image );
39+
40+
//! Try to access a tile and load it into "image" argument
41+
//! @returns true if the tile exists in the cache
42+
static bool tile( const QUrl& url, QImage& image );
43+
44+
//! how many tiles are stored in the in-memory cache
45+
static int totalCost() { return sTileCache.totalCost(); }
46+
//! how many tiles can be stored in the in-memory cache
47+
static int maxCost() { return sTileCache.maxCost(); }
48+
49+
private:
50+
//! in-memory cache
51+
static QCache<QUrl, QImage> sTileCache;
52+
//! mutex to protect the in-memory cache
53+
static QMutex sTileCacheMutex;
54+
};
55+
56+
#endif // QGSTILECACHE_H

src/providers/wms/qgswmsprovider.cpp

+5-35
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "qgsmessagelog.h"
4141
#include "qgsnetworkaccessmanager.h"
4242
#include "qgsnetworkreplyparser.h"
43+
#include "qgstilecache.h"
4344
#include "qgsgml.h"
4445
#include "qgsgmlschema.h"
4546
#include "qgswmscapabilities.h"
@@ -501,35 +502,6 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, in
501502
return draw( viewExtent, pixelWidth, pixelHeight, nullptr );
502503
}
503504

504-
#include <QCache>
505-
static QCache<QUrl, QImage> sTileCache( 256 );
506-
static QMutex sTileCacheMutex;
507-
508-
static bool _fetchCachedTileImage( const QUrl& url, QImage& localImage )
509-
{
510-
QMutexLocker locker( &sTileCacheMutex );
511-
if ( QImage* i = sTileCache.object( url ) )
512-
{
513-
localImage = *i;
514-
return true;
515-
}
516-
else if ( QgsNetworkAccessManager::instance()->cache()->metaData( url ).isValid() )
517-
{
518-
if ( QIODevice* data = QgsNetworkAccessManager::instance()->cache()->data( url ) )
519-
{
520-
QByteArray imageData = data->readAll();
521-
delete data;
522-
523-
localImage = QImage::fromData( imageData );
524-
525-
// cache it as well (mutex is already locked)
526-
sTileCache.insert( url, new QImage( localImage ) );
527-
528-
return true;
529-
}
530-
}
531-
return false;
532-
}
533505

534506
static bool _fuzzyContainsRect( const QRectF& r1, const QRectF& r2 )
535507
{
@@ -581,7 +553,7 @@ void QgsWmsProvider::fetchOtherResTiles( QgsTileMode tileMode, const QgsRectangl
581553
Q_FOREACH ( const TileRequest& r, requests )
582554
{
583555
QImage localImage;
584-
if ( !_fetchCachedTileImage( r.url, localImage ) )
556+
if ( ! QgsTileCache::tile( r.url, localImage ) )
585557
continue;
586558

587559
double cr = viewExtent.width() / imageWidth;
@@ -785,7 +757,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const & viewExtent, int pixelWidth, i
785757
Q_FOREACH ( const TileRequest& r, requests )
786758
{
787759
QImage localImage;
788-
if ( _fetchCachedTileImage( r.url, localImage ) )
760+
if ( QgsTileCache::tile( r.url, localImage ) )
789761
{
790762
double cr = viewExtent.width() / image->width();
791763

@@ -880,7 +852,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const & viewExtent, int pixelWidth, i
880852
handler.downloadBlocking();
881853
}
882854

883-
qDebug( "TILE CACHE total: %d / %d ", sTileCache.totalCost(), sTileCache.maxCost() );
855+
qDebug( "TILE CACHE total: %d / %d ", QgsTileCache::totalCost(), QgsTileCache::maxCost() );
884856

885857
#if 0
886858
const QgsWmsStatistics::Stat& stat = QgsWmsStatistics::statForUri( dataSourceUri() );
@@ -3909,9 +3881,7 @@ void QgsWmsTiledImageDownloadHandler::tileReplyFinished()
39093881
.arg( r.width() ).arg( r.height() ) );
39103882
#endif
39113883

3912-
sTileCacheMutex.lock();
3913-
sTileCache.insert( reply->url(), new QImage( myLocalImage ) );
3914-
sTileCacheMutex.unlock();
3884+
QgsTileCache::insertTile( reply->url(), myLocalImage );
39153885

39163886
if ( mFeedback )
39173887
mFeedback->onNewData();

0 commit comments

Comments
 (0)