Skip to content
Permalink
Browse files

WMS Tile retry feature

  • Loading branch information
luipir committed Aug 22, 2013
1 parent 36812e1 commit a563f2a650b13db9a1d7d58983ac2a2f5b87f1bb
Showing with 107 additions and 36 deletions.
  1. +6 −0 src/app/qgsoptions.cpp
  2. +51 −13 src/providers/wms/qgswmsprovider.cpp
  3. +9 −0 src/providers/wms/qgswmsprovider.h
  4. +41 −23 src/ui/qgsoptionsbase.ui
@@ -250,6 +250,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
// WMS/WMS-C tile expiry time
mDefaultTileExpirySpinBox->setValue( settings.value( "/qgis/defaultTileExpiry", "24" ).toInt() );

// WMS/WMS-C default max retry in case of tile request errors
mDefaultTileMaxRetrySpinBox->setValue( settings.value( "/qgis/defaultTileMaxRetry", "3" ).toInt() );

//Web proxy settings
grpProxy->setChecked( settings.value( "proxy/proxyEnabled", "0" ).toBool() );
leProxyHost->setText( settings.value( "proxy/proxyHost", "" ).toString() );
@@ -887,6 +890,9 @@ void QgsOptions::saveOptions()
// WMS/WMS-C tile expiry time
settings.setValue( "/qgis/defaultTileExpiry", mDefaultTileExpirySpinBox->value() );

// WMS/WMS-C default max retry in case of tile request errors
settings.setValue( "/qgis/defaultTileMaxRetry", mDefaultTileMaxRetrySpinBox->value() );

//Web proxy settings
settings.setValue( "proxy/proxyEnabled", grpProxy->isChecked() );
settings.setValue( "proxy/proxyHost", leProxyHost->text() );
@@ -80,7 +80,6 @@ static QString WMS_DESCRIPTION = "OGC Web Map Service version 1.3 data provider"

static QString DEFAULT_LATLON_CRS = "CRS:84";


QgsWmsProvider::QgsWmsProvider( QString const &uri )
: QgsRasterDataProvider( uri )
, mHttpUri( uri )
@@ -844,6 +843,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, i
}

int i = 0;
int retry = 0;
for ( int row = row0; row <= row1; row++ )
{
for ( int col = col0; col <= col1; col++ )
@@ -865,6 +865,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, i
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 1 ), i );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 2 ),
QRectF( tm->topLeft.x() + col * twMap, tm->topLeft.y() - ( row + 1 ) * thMap, twMap, thMap ) );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 3 ), retry );

QgsDebugMsg( QString( "gettile: %1" ).arg( turl ) );
QNetworkReply *reply = QgsNetworkAccessManager::instance()->get( request );
@@ -901,6 +902,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, i
url.removeQueryItem( "TILECOL" );

int i = 0;
int retry = 0;
for ( int row = row0; row <= row1; row++ )
{
for ( int col = col0; col <= col1; col++ )
@@ -918,6 +920,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, i
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 1 ), i );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 2 ),
QRectF( tm->topLeft.x() + col * twMap, tm->topLeft.y() - ( row + 1 ) * thMap, twMap, thMap ) );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 3 ), retry );

QgsDebugMsg( QString( "gettile: %1" ).arg( turl ) );
QNetworkReply *reply = QgsNetworkAccessManager::instance()->get( request );
@@ -941,6 +944,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, i
}

int i = 0;
int retry = 0;
for ( int row = row0; row <= row1; row++ )
{
for ( int col = col0; col <= col1; col++ )
@@ -958,6 +962,7 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, i
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 1 ), i );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 2 ),
QRectF( tm->topLeft.x() + col * twMap, tm->topLeft.y() - ( row + 1 ) * thMap, twMap, thMap ) );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 3 ), retry );

QgsDebugMsg( QString( "gettile: %1" ).arg( turl ) );
QNetworkReply *reply = QgsNetworkAccessManager::instance()->get( request );
@@ -1034,6 +1039,41 @@ void QgsWmsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
//delete image;
}

void QgsWmsProvider::repeatTileRequest( QNetworkRequest const &oldRequest )
{
QNetworkRequest request( oldRequest );

QString url = request.url().toString();
int tileReqNo = request.attribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 0 ) ).toInt();
int tileNo = request.attribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 1 ) ).toInt();
int retry = request.attribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 3 ) ).toInt();
retry++;

QSettings s;
int maxRetry = s.value( "/qgis/defaultTileMaxRetry", "3" ).toInt();
if ( retry > maxRetry )
{
if ( mErrors < 100 )
{
QgsMessageLog::logMessage( tr( "Tile request max retry error. Failed %1 requests for tile %2 of tileRequest %3 (url: %4)" )
.arg( maxRetry ).arg( tileNo ).arg( tileReqNo ).arg( url ), tr( "WMS" ) );
}
else if ( mErrors == 100 )
{
QgsMessageLog::logMessage( tr( "Not logging more than 100 request errors." ), tr( "WMS" ) );
}
return;
}

setAuthorization( request );
QgsDebugMsg( QString( "repeat tileRequest %1 %2(retry %3) for url: %4" ).arg( tileReqNo ).arg( tileNo ).arg( retry ).arg( url ) );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 3 ), retry );

QNetworkReply *reply = QgsNetworkAccessManager::instance()->get( request );
mTileReplies << reply;
connect( reply, SIGNAL( finished() ), this, SLOT( tileReplyFinished() ) );
}

void QgsWmsProvider::tileReplyFinished()
{
QNetworkReply *reply = qobject_cast<QNetworkReply*>( sender() );
@@ -1080,18 +1120,19 @@ void QgsWmsProvider::tileReplyFinished()
int tileReqNo = reply->request().attribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 0 ) ).toInt();
int tileNo = reply->request().attribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 1 ) ).toInt();
QRectF r = reply->request().attribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 2 ) ).toRectF();
int retry = reply->request().attribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 3 ) ).toInt();

#if QT_VERSION >= 0x40500
QgsDebugMsg( QString( "tile reply %1 (%2) tile:%3 rect:%4,%5 %6,%7) fromcache:%8 error:%9 url:%10" )
.arg( tileReqNo ).arg( mTileReqNo ).arg( tileNo )
QgsDebugMsg( QString( "tile reply %1 (%2) tile:%3(retry %4) rect:%5,%6 %7,%8) fromcache:%9 error:%10 url:%11" )
.arg( tileReqNo ).arg( mTileReqNo ).arg( tileNo ).arg( retry )
.arg( r.left(), 0, 'f' ).arg( r.bottom(), 0, 'f' ).arg( r.right(), 0, 'f' ).arg( r.top(), 0, 'f' )
.arg( fromCache )
.arg( reply->errorString() )
.arg( reply->url().toString() )
);
#else
QgsDebugMsg( QString( "tile reply %1 (%2) tile:%3 rect:%4,%5 %6,%7) error:%8 url:%9" )
.arg( tileReqNo ).arg( mTileReqNo ).arg( tileNo )
QgsDebugMsg( QString( "tile reply %1 (%2) tile:%3(retry %4) rect:%5,%6 %7,%8) error:%9 url:%10" )
.arg( tileReqNo ).arg( mTileReqNo ).arg( tileNo ).arg( retry )
.arg( r.left(), 0, 'f' ).arg( r.bottom(), 0, 'f' ).arg( r.right(), 0, 'f' ).arg( r.top(), 0, 'f' )
.arg( reply->errorString() )
.arg( reply->url().toString() )
@@ -1110,6 +1151,7 @@ void QgsWmsProvider::tileReplyFinished()
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 0 ), tileReqNo );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 1 ), tileNo );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 2 ), r );
request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 3 ), retry );

mTileReplies.removeOne( reply );
reply->deleteLater();
@@ -1205,6 +1247,8 @@ void QgsWmsProvider::tileReplyFinished()
{
QgsMessageLog::logMessage( tr( "Returned image is flawed [Content-Type:%1; URL: %2]" )
.arg( contentType ).arg( reply->url().toString() ), tr( "WMS" ) );

repeatTileRequest( reply->request() );
}
}
else
@@ -1224,14 +1268,8 @@ void QgsWmsProvider::tileReplyFinished()
else
{
mErrors++;
if ( mErrors < 100 )
{
QgsMessageLog::logMessage( tr( "Tile request failed [error:%1 url:%2]" ).arg( reply->errorString() ).arg( reply->url().toString() ), tr( "WMS" ) );
}
else if ( mErrors == 100 )
{
QgsMessageLog::logMessage( tr( "Not logging more than 100 request errors." ), tr( "WMS" ) );
}

repeatTileRequest( reply->request() );

mTileReplies.removeOne( reply );
reply->deleteLater();
@@ -743,6 +743,15 @@ class QgsWmsProvider : public QgsRasterDataProvider
// case insensitive attribute value lookup
static QString nodeAttribute( const QDomElement &e, QString name, QString defValue = QString::null );

/**
* \brief Relaunch tile request cloning previous request parameters and managing max repeat
*
* \param oldRequest request to clone to generate new tile request
*
* request is not launched if max retry is reached. Message is logged.
*/
void repeatTileRequest( QNetworkRequest const &oldRequest );

/**
* \brief Retrieve and parse the (cached) Capabilities document from the server
*
@@ -236,7 +236,7 @@
<item>
<widget class="QStackedWidget" name="mOptionsStackedWidget">
<property name="currentIndex">
<number>0</number>
<number>10</number>
</property>
<widget class="QWidget" name="mOptionsPage_01">
<layout class="QVBoxLayout" name="verticalLayout_3">
@@ -266,8 +266,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>523</height>
<width>656</width>
<height>676</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_28">
@@ -912,8 +912,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>670</width>
<height>750</height>
<width>656</width>
<height>803</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_22">
@@ -1248,8 +1248,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>523</height>
<width>674</width>
<height>496</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_27">
@@ -1577,8 +1577,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>670</width>
<height>611</height>
<width>656</width>
<height>757</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_29">
@@ -2092,8 +2092,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>523</height>
<width>674</width>
<height>496</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_25">
@@ -2395,8 +2395,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>670</width>
<height>619</height>
<width>656</width>
<height>768</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_30">
@@ -2802,8 +2802,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>670</width>
<height>551</height>
<width>656</width>
<height>687</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_31">
@@ -3303,8 +3303,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>523</height>
<width>674</width>
<height>496</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
@@ -3443,8 +3443,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>523</height>
<width>674</width>
<height>496</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_15">
@@ -3624,8 +3624,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>523</height>
<width>674</width>
<height>496</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
@@ -3724,8 +3724,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>670</width>
<height>528</height>
<width>656</width>
<height>704</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_33">
@@ -3785,6 +3785,24 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_33">
<item>
<widget class="QLabel" name="label_57">
<property name="text">
<string>Max retry in case of tile request errors</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="mDefaultTileMaxRetrySpinBox">
<property name="maximum">
<number>100000000</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>

0 comments on commit a563f2a

Please sign in to comment.
You can’t perform that action at this time.