QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgstiledownloadmanager.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgstiledownloadmanager.h
3  ------------------------
4  begin : January 2021
5  copyright : (C) 2021 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef QGSTILEDOWNLOADMANAGER_H
19 #define QGSTILEDOWNLOADMANAGER_H
20 
21 #define SIP_NO_FILE
22 
23 #include <QTimer>
24 #include <QThread>
25 #include <QMutex>
26 
27 #include <QNetworkAccessManager>
28 #include <QNetworkReply>
29 
30 #include "qgis_core.h"
31 
34 
47 class CORE_EXPORT QgsTileDownloadManagerReply : public QObject
48 {
49  Q_OBJECT
50  public:
52 
54  bool hasFinished() const { return mHasFinished; }
56  QByteArray data() const { return mData; }
58  QUrl url() const { return mUrl; }
60  QVariant attribute( QNetworkRequest::Attribute code );
62  QVariant header( QNetworkRequest::KnownHeaders header );
64  const QList<QNetworkReply::RawHeaderPair> rawHeaderPairs() const { return mRawHeaderPairs; }
66  QNetworkReply::NetworkError error() const { return mError; }
68  QString errorString() const { return mErrorString; }
70  QNetworkRequest request() const { return mRequest; }
71 
72  signals:
74  void finished();
75 
76  private slots:
77  void requestFinished( QByteArray data, QUrl url, const QMap<QNetworkRequest::Attribute, QVariant> &attributes, const QMap<QNetworkRequest::KnownHeaders, QVariant> &headers, const QList<QNetworkReply::RawHeaderPair> rawHeaderPairs, QNetworkReply::NetworkError error, const QString &errorString );
78  void cachedRangeRequestFinished();
79 
80  private:
81  QgsTileDownloadManagerReply( QgsTileDownloadManager *manager, const QNetworkRequest &request );
82 
83  friend class QgsTileDownloadManager; // allows creation of new instances from the manager
84 
85  private:
87  QgsTileDownloadManager *mManager = nullptr;
88  QNetworkRequest mRequest;
89  bool mHasFinished = false;
90  QByteArray mData;
91  QNetworkReply::NetworkError mError = QNetworkReply::NoError;
92  QString mErrorString;
93  QUrl mUrl;
94  QMap<QNetworkRequest::Attribute, QVariant> mAttributes;
95  QMap<QNetworkRequest::KnownHeaders, QVariant> mHeaders;
96  QList<QNetworkReply::RawHeaderPair> mRawHeaderPairs;
97 };
98 
99 
101 
107 class QgsTileDownloadManagerReplyWorkerObject : public QObject
108 {
109  Q_OBJECT
110  public:
111  QgsTileDownloadManagerReplyWorkerObject( QgsTileDownloadManager *manager, const QNetworkRequest &request )
112  : mManager( manager ), mRequest( request ) {}
113 
114  public slots:
115  void replyFinished();
116 
117  signals:
118  void finished( QByteArray data, QUrl url, const QMap<QNetworkRequest::Attribute, QVariant> &attributes, const QMap<QNetworkRequest::KnownHeaders, QVariant> &headers, const QList<QNetworkReply::RawHeaderPair> rawHeaderPairs, QNetworkReply::NetworkError error, const QString &errorString );
119 
120  private:
122  QgsTileDownloadManager *mManager = nullptr;
123  QNetworkRequest mRequest;
124 };
125 
126 
132 class QgsTileDownloadManagerWorker : public QObject
133 {
134  Q_OBJECT
135 
136  public:
138  QgsTileDownloadManagerWorker( QgsTileDownloadManager *manager, QObject *parent = nullptr );
139 
140  void startIdleTimer();
141 
142  public slots:
143  void queueUpdated();
144  void idleTimerTimeout();
145 
146  signals:
147  void requestFinished( QString url, QByteArray data );
148 
149  private:
150  void quitThread();
151 
152  private:
154  QgsTileDownloadManager *mManager = nullptr;
156  QTimer mIdleTimer;
157 };
158 
160 
161 
162 
202 class CORE_EXPORT QgsTileDownloadManager
203 {
204 
206  class QueueEntry
207  {
208  public:
209  bool isValid() const { return !request.url().isEmpty(); }
210 
212  QNetworkRequest request;
214  QgsTileDownloadManagerReplyWorkerObject *objWorker = nullptr;
216  QNetworkReply *networkReply = nullptr;
217  };
218 
219  public:
220 
226  class Stats
227  {
228  public:
230  int requestsTotal = 0;
232  int requestsMerged = 0;
234  int requestsEarlyDeleted = 0;
235 
237  int networkRequestsStarted = 0;
239  int networkRequestsOk = 0;
241  int networkRequestsFailed = 0;
242  };
243 
246 
251  QgsTileDownloadManagerReply *get( const QNetworkRequest &request );
252 
254  bool hasPendingRequests() const;
255 
260  bool waitForPendingRequests( int msec = -1 ) const;
261 
263  void shutdown();
264 
269  bool hasWorkerThreadRunning() const;
270 
275  void setIdleThreadTimeout( int timeoutMs ) { mIdleThreadTimeoutMs = timeoutMs; }
276 
278  Stats statistics() const { return mStats; }
279 
281  void resetStatistics();
282 
283  friend class QgsTileDownloadManagerWorker;
285  friend class QgsTileDownloadManagerReplyWorkerObject;
286 
287  private:
288 
289  // these can be only used with mutex locked!
290  QueueEntry findEntryForRequest( const QNetworkRequest &request );
291  void addEntry( const QueueEntry &entry );
292  void updateEntry( const QueueEntry &entry );
293  void removeEntry( const QNetworkRequest &request );
294  void processStagedEntryRemovals();
295 
296  void signalQueueModified();
297 
298  bool isRangeRequest( const QNetworkRequest &request );
299  bool isCachedRangeRequest( const QNetworkRequest &request );
300 
301  private:
302 
303  std::vector<QueueEntry> mQueue;
304 
305  bool mStageQueueRemovals = false;
306  std::vector< QNetworkRequest > mStagedQueueRemovals;
307 
308  bool mShuttingDown = false;
309 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
310  mutable QMutex mMutex;
311 #else
312  mutable QRecursiveMutex mMutex;
313 #endif
314  QThread *mWorkerThread = nullptr;
315  QgsTileDownloadManagerWorker *mWorker = nullptr;
316  Stats mStats;
317 
318  int mIdleThreadTimeoutMs = 10000;
319 
320  std::unique_ptr<QgsRangeRequestCache> mRangesCache;
321 };
322 
323 #endif // QGSTILEDOWNLOADMANAGER_H
QgsTileDownloadManager
Tile download manager handles downloads of map tiles for the purpose of map rendering....
Definition: qgstiledownloadmanager.h:202
QgsTileDownloadManagerReply::rawHeaderPairs
const QList< QNetworkReply::RawHeaderPair > rawHeaderPairs() const
Returns a list of raw header pairs.
Definition: qgstiledownloadmanager.h:64
QgsTileDownloadManager::statistics
Stats statistics() const
Returns basic statistics of the queries handled by this class.
Definition: qgstiledownloadmanager.h:278
QgsTileDownloadManagerReply::errorString
QString errorString() const
Returns error string (only valid when already finished)
Definition: qgstiledownloadmanager.h:68
QgsTileDownloadManagerReply::request
QNetworkRequest request() const
Returns the original request for this reply object.
Definition: qgstiledownloadmanager.h:70
QgsTileDownloadManagerReply::data
QByteArray data() const
Returns binary data returned in the reply (only valid when already finished)
Definition: qgstiledownloadmanager.h:56
QgsTileDownloadManager::setIdleThreadTimeout
void setIdleThreadTimeout(int timeoutMs)
Sets after how many milliseconds the idle worker therad should terminate.
Definition: qgstiledownloadmanager.h:275
QgsRangeRequestCache
A custom cache for handling the storage and retrieval of HTTP range requests on disk.
Definition: qgsrangerequestcache.h:43
QgsTileDownloadManagerReply::hasFinished
bool hasFinished() const
Returns whether the reply has already finished (with success/failure)
Definition: qgstiledownloadmanager.h:54
QgsTileDownloadManager::Stats
Encapsulates any statistics we would like to keep about requests.
Definition: qgstiledownloadmanager.h:226
QgsTileDownloadManagerReply::error
QNetworkReply::NetworkError error() const
Returns error code (only valid when already finished)
Definition: qgstiledownloadmanager.h:66
QgsTileDownloadManagerReply
Reply object for tile download manager requests returned from calls to QgsTileDownloadManager::get().
Definition: qgstiledownloadmanager.h:47
QgsTileDownloadManagerReply::url
QUrl url() const
Returns the reply URL.
Definition: qgstiledownloadmanager.h:58