30 : mEventLoop( new QEventLoop )
31 , mFeedback( feedback )
37 connect( feedback, &
QgsFeedback::canceled,
this, &QgsVectorTileLoader::canceled, Qt::QueuedConnection );
48 for (
QgsTileXYZ id : qgis::as_const( tiles ) )
50 loadFromNetworkAsync(
id, tileMatrix, uri );
58 if ( !mReplies.isEmpty() )
70 QgsDebugMsgLevel( QStringLiteral(
"downloadBlocking - not staring event loop - canceled" ), 2 );
74 QgsDebugMsgLevel( QStringLiteral(
"Starting event loop with %1 requests" ).arg( mReplies.count() ), 2 );
76 mEventLoop->exec( QEventLoop::ExcludeUserInputEvents );
80 Q_ASSERT( mReplies.isEmpty() );
83 void QgsVectorTileLoader::loadFromNetworkAsync(
const QgsTileXYZ &
id,
const QgsTileMatrix &tileMatrix,
const QString &requestUrl )
86 QNetworkRequest request( url );
90 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 1 ),
id.column() );
91 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 2 ),
id.row() );
92 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 3 ),
id.zoomLevel() );
94 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
95 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
97 if ( !mReferer.isEmpty() )
98 request.setRawHeader(
"Referer", mReferer.toUtf8() );
106 connect( reply, &QNetworkReply::finished,
this, &QgsVectorTileLoader::tileReplyFinished );
111 void QgsVectorTileLoader::tileReplyFinished()
113 QNetworkReply *reply = qobject_cast<QNetworkReply *>( sender() );
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->readAll();
126 mReplies.removeOne( reply );
127 reply->deleteLater();
133 QgsDebugMsg( QStringLiteral(
"Tile download failed! " ) + reply->errorString() );
134 mReplies.removeOne( reply );
135 reply->deleteLater();
140 if ( mReplies.isEmpty() )
143 QMetaObject::invokeMethod( mEventLoop.get(),
"quit", Qt::QueuedConnection );
147 void QgsVectorTileLoader::canceled()
149 QgsDebugMsgLevel( QStringLiteral(
"Canceling %1 pending requests" ).arg( mReplies.count() ), 2 );
150 const QList<QNetworkReply *> replies = mReplies;
151 for ( QNetworkReply *reply : replies )
161 QList<QgsVectorTileRawData> rawTiles;
164 bool isUrl = ( sourceType == QLatin1String(
"xyz" ) );
167 bool res = mbReader.
open();
174 for (
QgsTileXYZ id : qgis::as_const( tiles ) )
177 if ( !rawData.isEmpty() )
189 nr.setUrl( QUrl( url ) );
191 if ( !referer.isEmpty() )
192 nr.setRawHeader(
"Referer", referer.toUtf8() );
200 QgsDebugMsg( QStringLiteral(
"Request failed: " ) + url );
212 int rowTMS = pow( 2,
id.zoomLevel() ) -
id.row() - 1;
213 QByteArray gzippedTileData = mbTileReader.
tileData(
id.zoomLevel(),
id.column(), rowTMS );
214 if ( gzippedTileData.isEmpty() )
216 QgsDebugMsg( QStringLiteral(
"Failed to get tile " ) +
id.toString() );
223 QgsDebugMsg( QStringLiteral(
"Failed to decompress tile " ) +
id.toString() );
227 QgsDebugMsgLevel( QStringLiteral(
"Tile blob size %1 -> uncompressed size %2" ).arg( gzippedTileData.size() ).arg( data.size() ), 2 );