Skip to content

Commit

Permalink
Avoid multiple redundant requests for mapserver legends
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 10, 2019
1 parent 3cad7ed commit 5c84bbc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 18 deletions.
55 changes: 38 additions & 17 deletions src/providers/arcgisrest/qgsamsprovider.cpp
Expand Up @@ -60,8 +60,10 @@ struct LessThanTileRequest
}
};

QgsAmsLegendFetcher::QgsAmsLegendFetcher( QgsAmsProvider *provider )
: QgsImageFetcher( provider ), mProvider( provider )
QgsAmsLegendFetcher::QgsAmsLegendFetcher( QgsAmsProvider *provider, const QImage &fetchedImage )
: QgsImageFetcher( provider )
, mProvider( provider )
, mLegendImage( fetchedImage )
{
mQuery = new QgsArcGisAsyncQuery( this );
connect( mQuery, &QgsArcGisAsyncQuery::finished, this, &QgsAmsLegendFetcher::handleFinished );
Expand All @@ -70,18 +72,25 @@ QgsAmsLegendFetcher::QgsAmsLegendFetcher( QgsAmsProvider *provider )

void QgsAmsLegendFetcher::start()
{
// http://resources.arcgis.com/en/help/rest/apiref/mslegend.html
// http://sampleserver5.arcgisonline.com/arcgis/rest/services/CommunityAddressing/MapServer/legend?f=pjson
QgsDataSourceUri dataSource( mProvider->dataSourceUri() );
const QString authCfg = dataSource.authConfigId();
const QString referer = dataSource.param( QStringLiteral( "referer" ) );
QgsStringMap headers;
if ( !referer.isEmpty() )
headers[ QStringLiteral( "Referer" )] = referer;

QUrl queryUrl( dataSource.param( QStringLiteral( "url" ) ) + "/legend" );
queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) );
mQuery->start( queryUrl, authCfg, &mQueryReply, false, headers );
if ( mLegendImage.isNull() )
{
// http://resources.arcgis.com/en/help/rest/apiref/mslegend.html
// http://sampleserver5.arcgisonline.com/arcgis/rest/services/CommunityAddressing/MapServer/legend?f=pjson
QgsDataSourceUri dataSource( mProvider->dataSourceUri() );
const QString authCfg = dataSource.authConfigId();
const QString referer = dataSource.param( QStringLiteral( "referer" ) );
QgsStringMap headers;
if ( !referer.isEmpty() )
headers[ QStringLiteral( "Referer" )] = referer;

QUrl queryUrl( dataSource.param( QStringLiteral( "url" ) ) + "/legend" );
queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) );
mQuery->start( queryUrl, authCfg, &mQueryReply, false, headers );
}
else
{
QTimer::singleShot( 1, this, &QgsAmsLegendFetcher::sendCachedImage );
}
}

void QgsAmsLegendFetcher::handleError( const QString &errorTitle, const QString &errorMsg )
Expand All @@ -91,6 +100,11 @@ void QgsAmsLegendFetcher::handleError( const QString &errorTitle, const QString
emit error( errorTitle + ": " + errorMsg );
}

void QgsAmsLegendFetcher::sendCachedImage()
{
emit finish( mLegendImage );
}

void QgsAmsLegendFetcher::handleFinished()
{
// Parse result
Expand Down Expand Up @@ -154,6 +168,7 @@ void QgsAmsLegendFetcher::handleFinished()
++i;
}
}
emit fetchedNew( mLegendImage );
emit finish( mLegendImage );
}

Expand All @@ -167,7 +182,7 @@ QgsAmsProvider::QgsAmsProvider( const QString &uri, const ProviderOptions &optio
if ( !referer.isEmpty() )
mRequestHeaders[ QStringLiteral( "Referer" )] = referer;

mLegendFetcher = new QgsAmsLegendFetcher( this );
mLegendFetcher = new QgsAmsLegendFetcher( this, QImage() );


const QString authcfg = dataSource.authConfigId();
Expand Down Expand Up @@ -291,7 +306,7 @@ QgsAmsProvider::QgsAmsProvider( const QgsAmsProvider &other, const QgsDataProvid
// - mCachedImage
// - mCachedImageExtent
{
mLegendFetcher = new QgsAmsLegendFetcher( this );
mLegendFetcher = new QgsAmsLegendFetcher( this, other.mLegendFetcher->getImage() );

// is this needed?
mTimestamp = QDateTime::currentDateTime();
Expand Down Expand Up @@ -747,6 +762,7 @@ QImage QgsAmsProvider::getLegendGraphic( double /*scale*/, bool forceRefresh, co
{
return mLegendFetcher->getImage();
}
mLegendFetcher->clear();
QEventLoop evLoop;
connect( mLegendFetcher, &QgsImageFetcher::finish, &evLoop, &QEventLoop::quit );
connect( mLegendFetcher, &QgsImageFetcher::error, &evLoop, &QEventLoop::quit );
Expand All @@ -766,7 +782,12 @@ QImage QgsAmsProvider::getLegendGraphic( double /*scale*/, bool forceRefresh, co

QgsImageFetcher *QgsAmsProvider::getLegendGraphicFetcher( const QgsMapSettings * /*mapSettings*/ )
{
return new QgsAmsLegendFetcher( this );
QgsAmsLegendFetcher *fetcher = new QgsAmsLegendFetcher( this, mLegendFetcher->getImage() );
connect( fetcher, &QgsAmsLegendFetcher::fetchedNew, this, [ = ]( const QImage & fetched )
{
mLegendFetcher->setImage( fetched );
} );
return fetcher;
}

QgsRasterIdentifyResult QgsAmsProvider::identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &extent, int width, int height, int dpi )
Expand Down
9 changes: 8 additions & 1 deletion src/providers/arcgisrest/qgsamsprovider.h
Expand Up @@ -32,16 +32,23 @@ class QgsAmsLegendFetcher : public QgsImageFetcher
{
Q_OBJECT
public:
QgsAmsLegendFetcher( QgsAmsProvider *provider );
QgsAmsLegendFetcher( QgsAmsProvider *provider, const QImage &fetchedImage );
void start() override;
bool haveImage() const { return mLegendImage.isNull(); }
QImage getImage() const { return mLegendImage; }
void setImage( const QImage &image ) { mLegendImage = image; }
void clear() { mLegendImage = QImage(); }
const QString &errorTitle() const { return mErrorTitle; }
const QString &errorMessage() const { return mError; }

signals:

void fetchedNew( const QImage &image );

private slots:
void handleFinished();
void handleError( const QString &errorTitle, const QString &errorMsg );
void sendCachedImage();

private:
QgsAmsProvider *mProvider = nullptr;
Expand Down

0 comments on commit 5c84bbc

Please sign in to comment.