QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
47class 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
107class 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
132class 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
202class 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 mutable QRecursiveMutex mMutex;
310
311 QThread *mWorkerThread = nullptr;
312 QgsTileDownloadManagerWorker *mWorker = nullptr;
313 Stats mStats;
314
315 int mIdleThreadTimeoutMs = 10000;
316
317 std::unique_ptr<QgsRangeRequestCache> mRangesCache;
318};
319
320#endif // QGSTILEDOWNLOADMANAGER_H
A custom cache for handling the storage and retrieval of HTTP range requests on disk.
Reply object for tile download manager requests returned from calls to QgsTileDownloadManager::get().
QString errorString() const
Returns error string (only valid when already finished)
bool hasFinished() const
Returns whether the reply has already finished (with success/failure)
QNetworkRequest request() const
Returns the original request for this reply object.
const QList< QNetworkReply::RawHeaderPair > rawHeaderPairs() const
Returns a list of raw header pairs.
QByteArray data() const
Returns binary data returned in the reply (only valid when already finished)
QNetworkReply::NetworkError error() const
Returns error code (only valid when already finished)
QUrl url() const
Returns the reply URL.
void finished()
Emitted when the reply has finished (either with a success or with a failure)
Encapsulates any statistics we would like to keep about requests.
Tile download manager handles downloads of map tiles for the purpose of map rendering.
Stats statistics() const
Returns basic statistics of the queries handled by this class.
void setIdleThreadTimeout(int timeoutMs)
Sets after how many milliseconds the idle worker therad should terminate.