1 /***************************************************************************
2   qgsvectortileloader.h
3   --------------------------------------
4   Date                 : March 2020
5   Copyright            : (C) 2020 by Martin Dobias
6   Email                : wonder dot sk at gmail dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #ifndef QGSVECTORTILELOADER_H
17 #define QGSVECTORTILELOADER_H
18 
19 #define SIP_NO_FILE
20 
21 class QByteArray;
22 
23 #include "qgsvectortilerenderer.h"
24 
25 /**
26  * \ingroup core
27  * \brief Keeps track of raw tile data that need to be decoded
28  *
29  * \since QGIS 3.14
30  */
31 class QgsVectorTileRawData
32 {
33   public:
34     //! Constructs a raw tile object
35     QgsVectorTileRawData( QgsTileXYZ tileID = QgsTileXYZ(), const QByteArray &raw = QByteArray() )
id(tileID)36       : id( tileID ), data( raw ) {}
37 
38     //! Tile position in tile matrix set
39     QgsTileXYZ id;
40     //! Raw tile data
41     QByteArray data;
42 };
43 
44 
45 class QNetworkReply;
46 class QEventLoop;
47 
48 class QgsMbTiles;
49 
50 class QgsTileDownloadManagerReply;
51 
52 /**
53  * \ingroup core
54  * \brief The loader class takes care of loading raw vector tile data from a tile source.
55  *
56  * \since QGIS 3.14
57  */
58 class QgsVectorTileLoader : public QObject
59 {
60     Q_OBJECT
61   public:
62 
63     //! Returns raw tile data for the specified range of tiles. Blocks the caller until all tiles are fetched.
64     static QList<QgsVectorTileRawData> blockingFetchTileRawData( const QString &sourceType,
65         const QString &sourcePath,
66         const QgsTileMatrix &tileMatrix,
67         const QPointF &viewCenter,
68         const QgsTileRange &range,
69         const QString &authid,
70         const QString &referer );
71 
72     //! Returns raw tile data for a single tile, doing a HTTP request. Block the caller until tile data are downloaded.
73     static QByteArray loadFromNetwork( const QgsTileXYZ &id,
74                                        const QgsTileMatrix &tileMatrix,
75                                        const QString &requestUrl,
76                                        const QString &authid,
77                                        const QString &referer );
78     //! Returns raw tile data for a single tile loaded from MBTiles file
79     static QByteArray loadFromMBTiles( const QgsTileXYZ &id, QgsMbTiles &mbTileReader );
80 
81     //
82     // non-static stuff
83     //
84 
85     //! Constructs tile loader for doing asynchronous requests and starts network requests
86     QgsVectorTileLoader( const QString &uri, const QgsTileMatrix &tileMatrix, const QgsTileRange &range, const QPointF &viewCenter,
87                          const QString &authid, const QString &referer, QgsFeedback *feedback );
88     ~QgsVectorTileLoader();
89 
90     //! Blocks the caller until all asynchronous requests are finished (with a success or a failure)
91     void downloadBlocking();
92 
93   private:
94     void loadFromNetworkAsync( const QgsTileXYZ &id, const QgsTileMatrix &tileMatrix, const QString &requestUrl );
95 
96   private slots:
97     void tileReplyFinished();
98     void canceled();
99 
100   signals:
101     //! Emitted when a tile request has finished. If a tile request has failed, the returned raw tile byte array is empty.
102     void tileRequestFinished( const QgsVectorTileRawData &rawTile );
103 
104   private:
105     //! Event loop used for blocking download
106     std::unique_ptr<QEventLoop> mEventLoop;
107     //! Feedback object that allows cancellation of pending requests
108     QgsFeedback *mFeedback;
109 
110     QString mAuthCfg;
111     QString mReferer;
112 
113     //! Running tile requests
114     QList<QgsTileDownloadManagerReply *> mReplies;
115 
116 };
117 
118 #endif // QGSVECTORTILELOADER_H
119