QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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 "qgis_core.h"
24
25#include <QMutex>
26#include <QNetworkAccessManager>
27#include <QNetworkReply>
28#include <QThread>
29#include <QTimer>
30
33
46class CORE_EXPORT QgsTileDownloadManagerReply : public QObject
47{
48 Q_OBJECT
49 public:
50 ~QgsTileDownloadManagerReply() override;
51
53 bool hasFinished() const { return mHasFinished; }
55 QByteArray data() const { return mData; }
57 QUrl url() const { return mUrl; }
59 QVariant attribute( QNetworkRequest::Attribute code );
61 QVariant header( QNetworkRequest::KnownHeaders header );
63 const QList<QNetworkReply::RawHeaderPair> rawHeaderPairs() const { return mRawHeaderPairs; }
65 QNetworkReply::NetworkError error() const { return mError; }
67 QString errorString() const { return mErrorString; }
69 QNetworkRequest request() const { return mRequest; }
70
71 signals:
73 void finished();
74
75 private slots:
76 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 );
77 void cachedRangeRequestFinished();
78
79 private:
80 QgsTileDownloadManagerReply( QgsTileDownloadManager *manager, const QNetworkRequest &request );
81
82 friend class QgsTileDownloadManager; // allows creation of new instances from the manager
83
84 private:
86 QgsTileDownloadManager *mManager = nullptr;
87 QNetworkRequest mRequest;
88 bool mHasFinished = false;
89 QByteArray mData;
90 QNetworkReply::NetworkError mError = QNetworkReply::NoError;
91 QString mErrorString;
92 QUrl mUrl;
93 QMap<QNetworkRequest::Attribute, QVariant> mAttributes;
94 QMap<QNetworkRequest::KnownHeaders, QVariant> mHeaders;
95 QList<QNetworkReply::RawHeaderPair> mRawHeaderPairs;
96};
97
98
100
106class QgsTileDownloadManagerReplyWorkerObject : public QObject
107{
108 Q_OBJECT
109 public:
110 QgsTileDownloadManagerReplyWorkerObject( QgsTileDownloadManager *manager, const QNetworkRequest &request )
111 : mManager( manager ), mRequest( request ) {}
112
113 public slots:
114 void replyFinished();
115
116 signals:
117 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 );
118
119 private:
121 QgsTileDownloadManager *mManager = nullptr;
122 QNetworkRequest mRequest;
123};
124
125
131class QgsTileDownloadManagerWorker : public QObject
132{
133 Q_OBJECT
134
135 public:
137 QgsTileDownloadManagerWorker( QgsTileDownloadManager *manager, QObject *parent = nullptr );
138
139 void startIdleTimer();
140
141 public slots:
142 void queueUpdated();
143 void idleTimerTimeout();
144
145 signals:
146 void requestFinished( QString url, QByteArray data );
147
148 private:
149 void quitThread();
150
151 private:
153 QgsTileDownloadManager *mManager = nullptr;
155 QTimer mIdleTimer;
156};
157
159
160
161
201class CORE_EXPORT QgsTileDownloadManager
202{
203
205 class QueueEntry
206 {
207 public:
208 bool isValid() const { return !request.url().isEmpty(); }
209
211 QNetworkRequest request;
213 QgsTileDownloadManagerReplyWorkerObject *objWorker = nullptr;
215 QNetworkReply *networkReply = nullptr;
216 };
217
218 public:
219
225 class Stats
226 {
227 public:
234
241 };
242
245
250 QgsTileDownloadManagerReply *get( const QNetworkRequest &request );
251
253 bool hasPendingRequests() const;
254
259 bool waitForPendingRequests( int msec = -1 ) const;
260
262 void shutdown();
263
268 bool hasWorkerThreadRunning() const;
269
274 void setIdleThreadTimeout( int timeoutMs ) { mIdleThreadTimeoutMs = timeoutMs; }
275
277 Stats statistics() const { return mStats; }
278
280 void resetStatistics();
281
285
286 private:
287
288 // these can be only used with mutex locked!
289 QueueEntry findEntryForRequest( const QNetworkRequest &request );
290 void addEntry( const QueueEntry &entry );
291 void updateEntry( const QueueEntry &entry );
292 void removeEntry( const QNetworkRequest &request );
293 void processStagedEntryRemovals();
294
295 void signalQueueModified();
296
297 bool isRangeRequest( const QNetworkRequest &request );
298 bool isCachedRangeRequest( const QNetworkRequest &request );
299
300 private:
301
302 std::vector<QueueEntry> mQueue;
303
304 bool mStageQueueRemovals = false;
305 std::vector< QNetworkRequest > mStagedQueueRemovals;
306
307 bool mShuttingDown = false;
308 mutable QRecursiveMutex mMutex;
309
310 QThread *mWorkerThread = nullptr;
311 QgsTileDownloadManagerWorker *mWorker = nullptr;
312 Stats mStats;
313
314 int mIdleThreadTimeoutMs = 10000;
315
316 std::unique_ptr<QgsRangeRequestCache> mRangesCache;
317};
318
319#endif // QGSTILEDOWNLOADMANAGER_H
A custom cache for handling the storage and retrieval of HTTP range requests on disk.
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.
int networkRequestsStarted
How many actual network requests were started.
int requestsMerged
How many requests were same as some other pending request and got "merged".
int networkRequestsOk
How many network requests have been successful.
int networkRequestsFailed
How many network requests have failed.
int requestsEarlyDeleted
How many requests were deleted early by the client (i.e. lost interest).
int requestsTotal
How many requests were done through the download manager.
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.
bool hasWorkerThreadRunning() const
Returns whether the worker thread is running currently (it may be stopped if there were no requests r...
friend class QgsTileDownloadManagerReplyWorkerObject
bool waitForPendingRequests(int msec=-1) const
Blocks the current thread until the queue is empty.
QgsTileDownloadManagerReply * get(const QNetworkRequest &request)
Starts a request.
void setIdleThreadTimeout(int timeoutMs)
Sets after how many milliseconds the idle worker therad should terminate.
bool hasPendingRequests() const
Returns whether there are any pending requests in the queue.
void shutdown()
Asks the worker thread to stop and blocks until it is not stopped.