32 : mEventLoop( new QEventLoop )
33 , mFeedback( feedback )
39 connect( feedback, &
QgsFeedback::canceled,
this, &QgsVectorTileLoader::canceled, Qt::QueuedConnection );
52 loadFromNetworkAsync(
id, tileMatrix, uri );
60 if ( !mReplies.isEmpty() )
72 QgsDebugMsgLevel( QStringLiteral(
"downloadBlocking - not staring event loop - canceled" ), 2 );
76 QgsDebugMsgLevel( QStringLiteral(
"Starting event loop with %1 requests" ).arg( mReplies.count() ), 2 );
78 mEventLoop->exec( QEventLoop::ExcludeUserInputEvents );
82 Q_ASSERT( mReplies.isEmpty() );
85 void QgsVectorTileLoader::loadFromNetworkAsync(
const QgsTileXYZ &
id,
const QgsTileMatrix &tileMatrix,
const QString &requestUrl )
88 QNetworkRequest request( url );
92 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 1 ),
id.column() );
93 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 2 ),
id.row() );
94 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 3 ),
id.zoomLevel() );
96 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
97 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
111 void QgsVectorTileLoader::tileReplyFinished()
115 int reqX = reply->
request().attribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 1 ) ).toInt();
116 int reqY = reply->
request().attribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 2 ) ).toInt();
117 int reqZ = reply->
request().attribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 3 ) ).toInt();
120 if ( reply->
error() == QNetworkReply::NoError )
124 QgsDebugMsgLevel( QStringLiteral(
"Tile download successful: " ) + tileID.toString(), 2 );
125 QByteArray rawData = reply->
data();
126 mReplies.removeOne( reply );
127 reply->deleteLater();
133 if ( reply->
error() == QNetworkReply::ContentAccessDenied )
135 if ( reply->
data().isEmpty() )
136 mError = tr(
"Access denied" );
138 mError = tr(
"Access denied: %1" ).arg( QString( reply->
data() ) );
142 mReplies.removeOne( reply );
143 reply->deleteLater();
148 if ( mReplies.isEmpty() )
151 QMetaObject::invokeMethod( mEventLoop.get(),
"quit", Qt::QueuedConnection );
155 void QgsVectorTileLoader::canceled()
157 QgsDebugMsgLevel( QStringLiteral(
"Canceling %1 pending requests" ).arg( mReplies.count() ), 2 );
158 qDeleteAll( mReplies );
175 QList<QgsVectorTileRawData> rawTiles;
178 bool isUrl = ( sourceType == QLatin1String(
"xyz" ) );
181 bool res = mbReader.
open();
192 if ( tiles.size() < 10000 )
195 rawTiles.reserve( tiles.size() );
196 for (
QgsTileXYZ id : std::as_const( tiles ) )
201 QByteArray rawData = isUrl ?
loadFromNetwork(
id, tileMatrix, sourcePath, authid, headers, feedback ) :
loadFromMBTiles(
id, mbReader, feedback );
202 if ( !rawData.isEmpty() )
214 nr.setUrl( QUrl( url ) );
224 QgsDebugMsg( QStringLiteral(
"Request failed: " ) + url );
236 int rowTMS = pow( 2,
id.zoomLevel() ) -
id.row() - 1;
237 QByteArray gzippedTileData = mbTileReader.
tileData(
id.zoomLevel(),
id.column(), rowTMS );
238 if ( gzippedTileData.isEmpty() )
249 QgsDebugMsg( QStringLiteral(
"Failed to decompress tile " ) +
id.toString() );
253 QgsDebugMsgLevel( QStringLiteral(
"Tile blob size %1 -> uncompressed size %2" ).arg( gzippedTileData.size() ).arg( data.size() ), 2 );
static QgsTileDownloadManager * tileDownloadManager()
Returns the application's tile download manager, used for download of map tiles when rendering.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
ErrorCode get(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr)
Performs a "get" operation on the specified request.
void setAuthCfg(const QString &authCfg)
Sets the authentication config id which should be used during the request.
@ NoError
No error was encountered.
QgsNetworkReplyContent reply() const
Returns the content of the network reply, after a get() or post() request has been made.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
void canceled()
Internal routines can connect to this signal if they use event loop.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Utility class for reading and writing MBTiles files (which are SQLite3 databases).
bool open()
Tries to open the file, returns true on success.
QByteArray tileData(int z, int x, int y)
Returns raw tile data for given tile.
static bool decodeGzip(const QByteArray &bytesIn, QByteArray &bytesOut)
Decodes gzip byte stream, returns true on success. Useful for reading vector tiles.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
QByteArray content() const
Returns the reply content.
Reply object for tile download manager requests returned from calls to QgsTileDownloadManager::get().
QString errorString() const
Returns error string (only valid when already finished)
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)
QgsTileDownloadManagerReply * get(const QNetworkRequest &request)
Starts a request.
Defines a matrix of tiles for a single zoom level: it is defined by its size (width *.
int zoomLevel() const
Returns the zoom level of the tile matrix.
Range of tiles in a tile matrix to be rendered.
Stores coordinates of a tile in a tile matrix set.
void tileRequestFinished(const QgsVectorTileRawData &rawTile)
Emitted when a tile request has finished. If a tile request has failed, the returned raw tile byte ar...
static QList< QgsVectorTileRawData > blockingFetchTileRawData(const QString &sourceType, const QString &sourcePath, const QgsTileMatrix &tileMatrix, const QPointF &viewCenter, const QgsTileRange &range, const QString &authid, const QgsHttpHeaders &headers, QgsFeedback *feedback=nullptr)
Returns raw tile data for the specified range of tiles. Blocks the caller until all tiles are fetched...
QString error() const
Returns a eventual error that occurred during loading, void if no error.
static QByteArray loadFromNetwork(const QgsTileXYZ &id, const QgsTileMatrix &tileMatrix, const QString &requestUrl, const QString &authid, const QgsHttpHeaders &headers, QgsFeedback *feedback=nullptr)
Returns raw tile data for a single tile, doing a HTTP request. Block the caller until tile data are d...
static QByteArray loadFromMBTiles(const QgsTileXYZ &id, QgsMbTiles &mbTileReader, QgsFeedback *feedback=nullptr)
Returns raw tile data for a single tile loaded from MBTiles file.
void downloadBlocking()
Blocks the caller until all asynchronous requests are finished (with a success or a failure)
QgsVectorTileLoader(const QString &uri, const QgsTileMatrix &tileMatrix, const QgsTileRange &range, const QPointF &viewCenter, const QString &authid, const QgsHttpHeaders &headers, QgsFeedback *feedback)
Constructs tile loader for doing asynchronous requests and starts network requests.
Keeps track of raw tile data that need to be decoded.
static QString formatXYZUrlTemplate(const QString &url, QgsTileXYZ tile, const QgsTileMatrix &tileMatrix)
Returns formatted tile URL string replacing {x}, {y}, {z} placeholders (or {-y} instead of {y} for TM...
static QVector< QgsTileXYZ > tilesInRange(QgsTileRange range, int zoomLevel)
Returns a list of tiles in the given tile range.
static void sortTilesByDistanceFromCenter(QVector< QgsTileXYZ > &tiles, QPointF center)
Orders tile requests according to the distance from view center (given in tile matrix coords)
#define QgsDebugMsgLevel(str, level)
#define QgsSetRequestInitiatorClass(request, _class)
#define QgsSetRequestInitiatorId(request, str)