QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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
22#include "qgis_core.h"
23
24#include <QMutex>
25#include <QNetworkAccessManager>
26#include <QNetworkReply>
27#include <QThread>
28#include <QTimer>
29
30#define SIP_NO_FILE
31
34
47class CORE_EXPORT QgsTileDownloadManagerReply : public QObject
48{
49 Q_OBJECT
50 public:
51 ~QgsTileDownloadManagerReply() override;
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(
78 QByteArray data,
79 QUrl url,
80 const QMap<QNetworkRequest::Attribute, QVariant> &attributes,
81 const QMap<QNetworkRequest::KnownHeaders, QVariant> &headers,
82 const QList<QNetworkReply::RawHeaderPair> rawHeaderPairs,
83 QNetworkReply::NetworkError error,
84 const QString &errorString
85 );
86 void cachedRangeRequestFinished();
87
88 private:
89 QgsTileDownloadManagerReply( QgsTileDownloadManager *manager, const QNetworkRequest &request );
90
91 friend class QgsTileDownloadManager; // allows creation of new instances from the manager
92
93 private:
95 QgsTileDownloadManager *mManager = nullptr;
96 QNetworkRequest mRequest;
97 bool mHasFinished = false;
98 QByteArray mData;
99 QNetworkReply::NetworkError mError = QNetworkReply::NoError;
100 QString mErrorString;
101 QUrl mUrl;
102 QMap<QNetworkRequest::Attribute, QVariant> mAttributes;
103 QMap<QNetworkRequest::KnownHeaders, QVariant> mHeaders;
104 QList<QNetworkReply::RawHeaderPair> mRawHeaderPairs;
105};
106
107
109
115class QgsTileDownloadManagerReplyWorkerObject : public QObject
116{
117 Q_OBJECT
118 public:
119 QgsTileDownloadManagerReplyWorkerObject( QgsTileDownloadManager *manager, const QNetworkRequest &request )
120 : mManager( manager )
121 , mRequest( request )
122 {}
123
124 public slots:
125 void replyFinished();
126
127 signals:
128 void finished(
129 QByteArray data,
130 QUrl url,
131 const QMap<QNetworkRequest::Attribute, QVariant> &attributes,
132 const QMap<QNetworkRequest::KnownHeaders, QVariant> &headers,
133 const QList<QNetworkReply::RawHeaderPair> rawHeaderPairs,
134 QNetworkReply::NetworkError error,
135 const QString &errorString
136 );
137
138 private:
140 QgsTileDownloadManager *mManager = nullptr;
141 QNetworkRequest mRequest;
142};
143
144
150class QgsTileDownloadManagerWorker : public QObject
151{
152 Q_OBJECT
153
154 public:
156 QgsTileDownloadManagerWorker( QgsTileDownloadManager *manager, QObject *parent = nullptr );
157
158 void startIdleTimer();
159
160 public slots:
161 void queueUpdated();
162 void idleTimerTimeout();
163
164 signals:
165 void requestFinished( QString url, QByteArray data );
166
167 private:
168 void quitThread();
169
170 private:
172 QgsTileDownloadManager *mManager = nullptr;
174 QTimer mIdleTimer;
175};
176
178
179
219class CORE_EXPORT QgsTileDownloadManager
220{
222 class QueueEntry
223 {
224 public:
225 bool isValid() const { return !request.url().isEmpty(); }
226
228 QNetworkRequest request;
230 QgsTileDownloadManagerReplyWorkerObject *objWorker = nullptr;
232 QNetworkReply *networkReply = nullptr;
233 };
234
235 public:
241 class Stats
242 {
243 public:
250
257 };
258
261
266 QgsTileDownloadManagerReply *get( const QNetworkRequest &request );
267
269 bool hasPendingRequests() const;
270
275 bool waitForPendingRequests( int msec = -1 ) const;
276
278 void shutdown();
279
284 bool hasWorkerThreadRunning() const;
285
290 void setIdleThreadTimeout( int timeoutMs ) { mIdleThreadTimeoutMs = timeoutMs; }
291
293 Stats statistics() const { return mStats; }
294
296 void resetStatistics();
297
301
302 private:
303 // these can be only used with mutex locked!
304 QueueEntry findEntryForRequest( const QNetworkRequest &request );
305 void addEntry( const QueueEntry &entry );
306 void updateEntry( const QueueEntry &entry );
307 void removeEntry( const QNetworkRequest &request );
308 void processStagedEntryRemovals();
309
310 void signalQueueModified();
311
312 bool isRangeRequest( const QNetworkRequest &request );
313 bool isCachedRangeRequest( const QNetworkRequest &request );
314
315 private:
316 std::vector<QueueEntry> mQueue;
317
318 bool mStageQueueRemovals = false;
319 std::vector< QNetworkRequest > mStagedQueueRemovals;
320
321 bool mShuttingDown = false;
322 mutable QRecursiveMutex mMutex;
323
324 QThread *mWorkerThread = nullptr;
325 QgsTileDownloadManagerWorker *mWorker = nullptr;
326 Stats mStats;
327
328 int mIdleThreadTimeoutMs = 10000;
329
330 std::unique_ptr<QgsRangeRequestCache> mRangesCache;
331};
332
333#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.