27 : mEventLoop( new QEventLoop )
28 , mFeedback( feedback )
32 connect( feedback, &
QgsFeedback::canceled,
this, &QgsVectorTileLoader::canceled, Qt::QueuedConnection );
43 for (
QgsTileXYZ id : qgis::as_const( tiles ) )
45 loadFromNetworkAsync(
id, tileMatrix, uri );
53 if ( !mReplies.isEmpty() )
65 QgsDebugMsgLevel( QStringLiteral(
"downloadBlocking - not staring event loop - canceled" ), 2 );
69 QgsDebugMsgLevel( QStringLiteral(
"Starting event loop with %1 requests" ).arg( mReplies.count() ), 2 );
71 mEventLoop->exec( QEventLoop::ExcludeUserInputEvents );
75 Q_ASSERT( mReplies.isEmpty() );
78 void QgsVectorTileLoader::loadFromNetworkAsync(
const QgsTileXYZ &
id,
const QgsTileMatrix &tileMatrix,
const QString &requestUrl )
81 QNetworkRequest request( url );
85 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 1 ),
id.column() );
86 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 2 ),
id.row() );
87 request.setAttribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 3 ),
id.zoomLevel() );
89 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
90 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
93 connect( reply, &QNetworkReply::finished,
this, &QgsVectorTileLoader::tileReplyFinished );
98 void QgsVectorTileLoader::tileReplyFinished()
100 QNetworkReply *reply = qobject_cast<QNetworkReply *>( sender() );
102 int reqX = reply->request().attribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 1 ) ).toInt();
103 int reqY = reply->request().attribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 2 ) ).toInt();
104 int reqZ = reply->request().attribute(
static_cast<QNetworkRequest::Attribute
>( QNetworkRequest::User + 3 ) ).toInt();
107 if ( reply->error() == QNetworkReply::NoError )
111 QgsDebugMsgLevel( QStringLiteral(
"Tile download successful: " ) + tileID.toString(), 2 );
112 QByteArray rawData = reply->readAll();
113 mReplies.removeOne( reply );
114 reply->deleteLater();
120 QgsDebugMsg( QStringLiteral(
"Tile download failed! " ) + reply->errorString() );
121 mReplies.removeOne( reply );
122 reply->deleteLater();
127 if ( mReplies.isEmpty() )
130 QMetaObject::invokeMethod( mEventLoop.get(),
"quit", Qt::QueuedConnection );
134 void QgsVectorTileLoader::canceled()
136 QgsDebugMsgLevel( QStringLiteral(
"Canceling %1 pending requests" ).arg( mReplies.count() ), 2 );
137 const QList<QNetworkReply *> replies = mReplies;
138 for ( QNetworkReply *reply : replies )
148 QList<QgsVectorTileRawData> rawTiles;
151 bool isUrl = ( sourceType == QStringLiteral(
"xyz" ) );
154 bool res = mbReader.
open();
160 for (
QgsTileXYZ id : qgis::as_const( tiles ) )
163 if ( !rawData.isEmpty() )
175 nr.setUrl( QUrl( url ) );
181 QgsDebugMsg( QStringLiteral(
"Request failed: " ) + url );
193 int rowTMS = pow( 2,
id.zoomLevel() ) -
id.row() - 1;
194 QByteArray gzippedTileData = mbTileReader.
tileData(
id.zoomLevel(),
id.column(), rowTMS );
195 if ( gzippedTileData.isEmpty() )
197 QgsDebugMsg( QStringLiteral(
"Failed to get tile " ) +
id.toString() );
204 QgsDebugMsg( QStringLiteral(
"Failed to decompress tile " ) +
id.toString() );
208 QgsDebugMsgLevel( QStringLiteral(
"Tile blob size %1 -> uncompressed size %2" ).arg( gzippedTileData.size() ).arg( data.size() ), 2 );