QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 
33 
46 class CORE_EXPORT QgsTileDownloadManagerReply : public QObject
47 {
48  Q_OBJECT
49  public:
51 
53  bool hasFinished() const { return mHasFinished; }
55  QByteArray data() const { return mData; }
57  QNetworkReply::NetworkError error() const { return mError; }
59  QString errorString() const { return mErrorString; }
60 
62  QNetworkRequest request() const { return mRequest; }
63 
64  signals:
66  void finished();
67 
68  private slots:
69  void requestFinished( QByteArray data, QNetworkReply::NetworkError error, const QString &errorString );
70 
71  private:
72  QgsTileDownloadManagerReply( QgsTileDownloadManager *manager, const QNetworkRequest &request );
73 
74  friend class QgsTileDownloadManager; // allows creation of new instances from the manager
75 
76  private:
78  QgsTileDownloadManager *mManager = nullptr;
79  QNetworkRequest mRequest;
80  bool mHasFinished = false;
81  QByteArray mData;
82  QNetworkReply::NetworkError mError = QNetworkReply::NoError;
83  QString mErrorString;
84 };
85 
86 
88 
94 class QgsTileDownloadManagerReplyWorkerObject : public QObject
95 {
96  Q_OBJECT
97  public:
98  QgsTileDownloadManagerReplyWorkerObject( QgsTileDownloadManager *manager, const QNetworkRequest &request )
99  : mManager( manager ), mRequest( request ) {}
100 
101  public slots:
102  void replyFinished();
103 
104  signals:
105  void finished( QByteArray data, QNetworkReply::NetworkError error, const QString &errorString );
106 
107  private:
109  QgsTileDownloadManager *mManager = nullptr;
110  QNetworkRequest mRequest;
111 };
112 
113 
119 class QgsTileDownloadManagerWorker : public QObject
120 {
121  Q_OBJECT
122 
123  public:
125  QgsTileDownloadManagerWorker( QgsTileDownloadManager *manager, QObject *parent = nullptr );
126 
127  void startIdleTimer();
128 
129  public slots:
130  void queueUpdated();
131  void idleTimerTimeout();
132 
133  signals:
134  void requestFinished( QString url, QByteArray data );
135 
136  private:
137  void quitThread();
138 
139  private:
141  QgsTileDownloadManager *mManager = nullptr;
143  QTimer mIdleTimer;
144 };
145 
147 
148 
149 
185 class CORE_EXPORT QgsTileDownloadManager
186 {
187 
189  class QueueEntry
190  {
191  public:
192  bool isValid() const { return !request.url().isEmpty(); }
193 
195  QNetworkRequest request;
197  QgsTileDownloadManagerReplyWorkerObject *objWorker = nullptr;
199  QNetworkReply *networkReply = nullptr;
200  };
201 
202  public:
203 
209  class Stats
210  {
211  public:
213  int requestsTotal = 0;
215  int requestsMerged = 0;
217  int requestsEarlyDeleted = 0;
218 
220  int networkRequestsStarted = 0;
222  int networkRequestsOk = 0;
224  int networkRequestsFailed = 0;
225  };
226 
229 
234  QgsTileDownloadManagerReply *get( const QNetworkRequest &request );
235 
237  bool hasPendingRequests() const;
238 
243  bool waitForPendingRequests( int msec = -1 );
244 
246  void shutdown();
247 
252  bool hasWorkerThreadRunning() const;
253 
258  void setIdleThreadTimeout( int timeoutMs ) { mIdleThreadTimeoutMs = timeoutMs; }
259 
261  Stats statistics() { return mStats; }
262 
264  void resetStatistics();
265 
266  friend class QgsTileDownloadManagerWorker;
268  friend class QgsTileDownloadManagerReplyWorkerObject;
269 
270  private:
271 
272  // these can be only used with mutex locked!
273  QueueEntry findEntryForRequest( const QNetworkRequest &request );
274  void addEntry( const QueueEntry &entry );
275  void updateEntry( const QueueEntry &entry );
276  void removeEntry( const QNetworkRequest &request );
277 
278  void signalQueueModified();
279 
280  private:
281 
282  QList<QueueEntry> mQueue;
283  bool mShuttingDown = false;
284 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
285  mutable QMutex mMutex;
286 #else
287  mutable QRecursiveMutex mMutex;
288 #endif
289  QThread *mWorkerThread = nullptr;
290  QgsTileDownloadManagerWorker *mWorker = nullptr;
291  Stats mStats;
292 
293  int mIdleThreadTimeoutMs = 10000;
294 };
295 
296 #endif // QGSTILEDOWNLOADMANAGER_H
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.
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)
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.
void setIdleThreadTimeout(int timeoutMs)
Sets after how many milliseconds the idle worker therad should terminate.
Stats statistics()
Returns basic statistics of the queries handled by this class.