27#include "moc_qgsvectortileloader.cpp"
30 : mEventLoop( new QEventLoop )
31 , mFeedback( feedback )
35 connect( feedback, &
QgsFeedback::canceled,
this, &QgsVectorTileLoader::canceled, Qt::QueuedConnection );
44 QVector<QgsTileXYZ> tiles = tileMatrixSet.
tilesInRange( range, zoomLevel );
48 loadFromNetworkAsync(
id, tileMatrixSet, provider, usage );
56 if ( !mReplies.isEmpty() )
66 if ( mFeedback && mFeedback->isCanceled() )
68 QgsDebugMsgLevel( QStringLiteral(
"downloadBlocking - not staring event loop - canceled" ), 2 );
72 int repliesCount = std::accumulate( mReplies.constBegin(), mReplies.constEnd(), 0, [](
int count, QList<QgsTileDownloadManagerReply *> replies ) {return count + replies.count();} );
73 Q_UNUSED( repliesCount )
74 QgsDebugMsgLevel( QStringLiteral(
"Starting event loop with %1 requests" ).arg( repliesCount ), 2 );
76 mEventLoop->exec( QEventLoop::ExcludeUserInputEvents );
80 Q_ASSERT( mReplies.isEmpty() );
85 const QList<QNetworkRequest> requests = provider->
tileRequests( tileMatrixSet,
id, usage );
87 for (
const QNetworkRequest &request : requests )
91 mReplies[id].append( reply );
95void QgsVectorTileLoader::tileReplyFinished()
97 QgsTileDownloadManagerReply *reply = qobject_cast<QgsTileDownloadManagerReply *>( sender() );
104 QgsTileXYZ tileID( reqX, reqY, reqZ );
106 if ( reply->
error() == QNetworkReply::NoError )
110 QgsDebugMsgLevel( QStringLiteral(
"Tile download successful: " ) + tileID.toString(), 2 );
111 QByteArray rawData = reply->
data();
112 mReplies[tileID].removeOne( reply );
113 mPendingRawData[tileID][sourceId] = rawData;
114 reply->deleteLater();
116 if ( mReplies[tileID].count() == 0 )
118 mReplies.remove( tileID );
119 emit
tileRequestFinished( QgsVectorTileRawData( tileID, mPendingRawData.take( tileID ) ) );
124 if ( reply->
error() == QNetworkReply::ContentAccessDenied )
126 if ( reply->
data().isEmpty() )
127 mError = tr(
"Access denied" );
129 mError = tr(
"Access denied: %1" ).arg( QString( reply->
data() ) );
133 mReplies[tileID].removeOne( reply );
134 reply->deleteLater();
136 if ( mReplies[tileID].count() == 0 )
138 mReplies.remove( tileID );
143 if ( mReplies.isEmpty() )
146 QMetaObject::invokeMethod( mEventLoop.get(),
"quit", Qt::QueuedConnection );
150void QgsVectorTileLoader::canceled()
152 int repliesCount = std::accumulate( mReplies.constBegin(), mReplies.constEnd(), 0, [](
int count, QList<QgsTileDownloadManagerReply *> replies ) {return count + replies.count();} );
153 Q_UNUSED( repliesCount )
154 QgsDebugMsgLevel( QStringLiteral(
"Canceling %1 pending requests" ).arg( repliesCount ), 2 );
155 QHash<QgsTileXYZ, QList<QgsTileDownloadManagerReply *>>::iterator it = mReplies.begin();
156 for ( ; it != mReplies.end(); ++it )
157 qDeleteAll( it.value() );
177 QVector<QgsTileXYZ> tiles = tileMatrixSet.
tilesInRange( range, zoomLevel );
180 if ( tiles.size() < 10000 )
183 return provider->
readTiles( tileMatrixSet, tiles, feedback, usage );
RendererUsage
Usage of the renderer.
static QgsTileDownloadManager * tileDownloadManager()
Returns the application's tile download manager, used for download of map tiles when rendering.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
void canceled()
Internal routines can connect to this signal if they use event loop.
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 set of tile matrices for multiple zoom levels.
QVector< QgsTileXYZ > tilesInRange(QgsTileRange range, int zoomLevel) const
Returns a list of tiles in the given tile range.
A range of tiles in a tile matrix.
Stores coordinates of a tile in a tile matrix set.
Base class for vector tile layer data providers.
virtual QList< QgsVectorTileRawData > readTiles(const QgsTileMatrixSet &tileMatrixSet, const QVector< QgsTileXYZ > &tiles, QgsFeedback *feedback=nullptr, Qgis::RendererUsage usage=Qgis::RendererUsage::Unknown) const =0
Returns raw tile data for a range of tiles.
static int DATA_ZOOM
Role to set zoom attribute in the request so it can be retrieved later.
static int DATA_ROW
Role to set row attribute in the request so it can be retrieved later.
virtual QList< QNetworkRequest > tileRequests(const QgsTileMatrixSet &tileMatrixSet, const QgsTileXYZ &id, Qgis::RendererUsage usage) const
Returns a network request for a tile.
static int DATA_SOURCE_ID
Role to set source ID attribute in the request so it can be retrieved later.
static int DATA_COLUMN
Role to set column attribute in the request so it can be retrieved later.
void tileRequestFinished(const QgsVectorTileRawData &rawTile)
Emitted when a tile request has finished. If a tile request has failed, the returned raw tile byte ar...
QString error() const
Returns a eventual error that occurred during loading, void if no error.
~QgsVectorTileLoader() override
void downloadBlocking()
Blocks the caller until all asynchronous requests are finished (with a success or a failure).
static QList< QgsVectorTileRawData > blockingFetchTileRawData(const QgsVectorTileDataProvider *provider, const QgsTileMatrixSet &tileMatrixSet, const QPointF &viewCenter, const QgsTileRange &range, int zoomLevel, QgsFeedback *feedback=nullptr, Qgis::RendererUsage usage=Qgis::RendererUsage::Unknown)
Returns raw tile data for the specified range of tiles. Blocks the caller until all tiles are fetched...
QgsVectorTileLoader(const QgsVectorTileDataProvider *provider, const QgsTileMatrixSet &tileMatrixSet, const QgsTileRange &range, int zoomLevel, const QPointF &viewCenter, QgsFeedback *feedback, Qgis::RendererUsage usage)
Constructs tile loader for doing asynchronous requests and starts network requests.
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 QgsDebugError(str)