Skip to content

Commit

Permalink
Cleaner handling of raster provider native resolutions
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 6, 2019
1 parent 55311c2 commit 8b16e05
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 19 deletions.
10 changes: 10 additions & 0 deletions python/core/auto_generated/raster/qgsrasterdataprovider.sip.in
Expand Up @@ -466,6 +466,16 @@ Step height for raster iterations.
.. seealso:: :py:func:`stepWidth`

.. versionadded:: 3.0
%End

virtual QList< double > nativeResolutions() const;
%Docstring
Returns a list of native resolutions if available, i.e. map units per pixel at which the raster source
was originally created.

Resolutions are calculated in the provider's crs().

.. versionadded:: 3.8.0
%End

signals:
Expand Down
5 changes: 5 additions & 0 deletions src/core/raster/qgsrasterdataprovider.cpp
Expand Up @@ -502,6 +502,11 @@ QgsRasterInterface::Capability QgsRasterDataProvider::identifyFormatToCapability
}
}

QList<double> QgsRasterDataProvider::nativeResolutions() const
{
return QList< double >();
}

bool QgsRasterDataProvider::userNoDataValuesContains( int bandNo, double value ) const
{
QgsRasterRangeList rangeList = mUserNoDataValue.value( bandNo - 1 );
Expand Down
10 changes: 10 additions & 0 deletions src/core/raster/qgsrasterdataprovider.h
Expand Up @@ -527,6 +527,16 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
*/
virtual int stepHeight() const { return QgsRasterIterator::DEFAULT_MAXIMUM_TILE_HEIGHT; }

/**
* Returns a list of native resolutions if available, i.e. map units per pixel at which the raster source
* was originally created.
*
* Resolutions are calculated in the provider's crs().
*
* \since QGIS 3.8.0
*/
virtual QList< double > nativeResolutions() const;

signals:

/**
Expand Down
7 changes: 5 additions & 2 deletions src/providers/arcgisrest/qgsamsprovider.cpp
Expand Up @@ -246,7 +246,6 @@ QgsAmsProvider::QgsAmsProvider( const QString &uri, const ProviderOptions &optio
mResolutions << lodEntryMap[QStringLiteral( "resolution" )].toDouble();
}
std::sort( mResolutions.begin(), mResolutions.end() );
setProperty( "resolutions", mResolutions );
}
}

Expand Down Expand Up @@ -275,7 +274,6 @@ QgsAmsProvider::QgsAmsProvider( const QgsAmsProvider &other, const QgsDataProvid

// is this needed?
mTimestamp = QDateTime::currentDateTime();
setProperty( "resolutions", mResolutions );
}

QgsRasterDataProvider::ProviderCapabilities QgsAmsProvider::providerCapabilities() const
Expand Down Expand Up @@ -779,6 +777,11 @@ QgsRasterIdentifyResult QgsAmsProvider::identify( const QgsPointXY &point, QgsRa
return QgsRasterIdentifyResult( format, entries );
}

QList<double> QgsAmsProvider::nativeResolutions() const
{
return mResolutions;
}

bool QgsAmsProvider::readBlock( int /*bandNo*/, const QgsRectangle &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback )
{
// TODO: optimize to avoid writing to QImage
Expand Down
3 changes: 2 additions & 1 deletion src/providers/arcgisrest/qgsamsprovider.h
Expand Up @@ -92,6 +92,7 @@ class QgsAmsProvider : public QgsRasterDataProvider
QImage getLegendGraphic( double scale = 0, bool forceRefresh = false, const QgsRectangle *visibleExtent = nullptr ) override;
QgsImageFetcher *getLegendGraphicFetcher( const QgsMapSettings *mapSettings ) override;
QgsRasterIdentifyResult identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &extent = QgsRectangle(), int width = 0, int height = 0, int dpi = 96 ) override;
QList< double > nativeResolutions() const override;

//! Helper struct for tile requests
struct TileRequest
Expand Down Expand Up @@ -139,7 +140,7 @@ class QgsAmsProvider : public QgsRasterDataProvider
int mTileReqNo = 0;
bool mTiled = false;
QgsLayerMetadata mLayerMetadata;
QVariantList mResolutions;
QList< double > mResolutions;
};

//! Handler for tiled MapServer requests, the data are written to the given image
Expand Down
13 changes: 7 additions & 6 deletions src/providers/wms/qgstilescalewidget.cpp
Expand Up @@ -50,16 +50,15 @@ void QgsTileScaleWidget::layerChanged( QgsMapLayer *layer )
if ( !rl || !rl->dataProvider() )
return;

const QVariant res = rl->dataProvider()->property( "resolutions" );
if ( res.toList().isEmpty() )
const QList< double > resolutions = rl->dataProvider()->nativeResolutions();
if ( resolutions.isEmpty() )
return;

mResolutions.clear();
const auto constToList = res.toList();
for ( const QVariant &r : constToList )
for ( const double res : resolutions )
{
QgsDebugMsg( QStringLiteral( "found resolution: %1" ).arg( r.toDouble() ) );
mResolutions << r.toDouble();
QgsDebugMsg( QStringLiteral( "found resolution: %1" ).arg( res ) );
mResolutions << res;
}

if ( mResolutions.isEmpty() )
Expand Down Expand Up @@ -89,7 +88,9 @@ void QgsTileScaleWidget::scaleChanged( double scale )

int i;
for ( i = 0; i < mResolutions.size() && mResolutions.at( i ) < mupp; i++ )
{
QgsDebugMsg( QStringLiteral( "test resolution %1: %2 d:%3" ).arg( i ).arg( mResolutions.at( i ) ).arg( mupp - mResolutions.at( i ) ) );
}

if ( i == mResolutions.size() ||
( i > 0 && mResolutions.at( i ) - mupp > mupp - mResolutions.at( i - 1 ) ) )
Expand Down
16 changes: 8 additions & 8 deletions src/providers/wms/qgswmsprovider.cpp
Expand Up @@ -447,7 +447,7 @@ bool QgsWmsProvider::setImageCrs( QString const &crs )
break;
}

QList<QVariant> resolutions;
mNativeResolutions.clear();
if ( mCaps.mTileMatrixSets.contains( mSettings.mTileMatrixSetId ) )
{
mTileMatrixSet = &mCaps.mTileMatrixSets[ mSettings.mTileMatrixSetId ];
Expand All @@ -456,7 +456,7 @@ bool QgsWmsProvider::setImageCrs( QString const &crs )
const auto constKeys = keys;
for ( double key : constKeys )
{
resolutions << key;
mNativeResolutions << key;
}
if ( !mTileMatrixSet->tileMatrices.empty() )
{
Expand All @@ -470,8 +470,6 @@ bool QgsWmsProvider::setImageCrs( QString const &crs )
mTileMatrixSet = nullptr;
}

setProperty( "resolutions", resolutions );

if ( !mTileLayer || !mTileMatrixSet )
{
appendError( ERR( tr( "Tile layer or tile matrix set not found" ) ) );
Expand Down Expand Up @@ -2300,11 +2298,8 @@ QString QgsWmsProvider::htmlMetadata()
tr( "Bottom" ),
tr( "Right" ) );

const auto constToList = property( "resolutions" ).toList();
for ( const QVariant &res : constToList )
for ( const double key : mNativeResolutions )
{
double key = res.toDouble();

QgsWmtsTileMatrix &tm = mTileMatrixSet->tileMatrices[ key ];

double tw = key * tm.tileWidth;
Expand Down Expand Up @@ -3235,6 +3230,11 @@ bool QgsWmsProvider::renderInPreview( const QgsDataProvider::PreviewContext &con
return QgsRasterDataProvider::renderInPreview( context );
}

QList<double> QgsWmsProvider::nativeResolutions() const
{
return mNativeResolutions;
}

QVector<QgsWmsSupportedFormat> QgsWmsProvider::supportedFormats()
{
QVector<QgsWmsSupportedFormat> formats;
Expand Down
3 changes: 3 additions & 0 deletions src/providers/wms/qgswmsprovider.h
Expand Up @@ -210,6 +210,7 @@ class QgsWmsProvider : public QgsRasterDataProvider
QString description() const override;
void reloadData() override;
bool renderInPreview( const QgsDataProvider::PreviewContext &context ) override;
QList< double > nativeResolutions() const override;

static QVector<QgsWmsSupportedFormat> supportedFormats();

Expand Down Expand Up @@ -462,6 +463,8 @@ class QgsWmsProvider : public QgsRasterDataProvider
//! User's settings (URI, authorization, layer, style, ...)
QgsWmsSettings mSettings;

QList< double > mNativeResolutions;

friend class TestQgsWmsProvider;

};
Expand Down
6 changes: 4 additions & 2 deletions src/server/services/wms/qgswmsgetcapabilities.cpp
Expand Up @@ -36,6 +36,7 @@
#include "qgsexception.h"
#include "qgsexpressionnodeimpl.h"
#include "qgsvectorlayer.h"
#include "qgsrasterdataprovider.h"


namespace QgsWms
Expand Down Expand Up @@ -1826,8 +1827,9 @@ namespace QgsWms
QVariant wmsPublishDataSourceUrl = currentLayer->customProperty( QStringLiteral( "WMSPublishDataSourceUrl" ), false );
if ( wmsPublishDataSourceUrl.toBool() )
{
QList< QVariant > resolutionList = provider->property( "resolutions" ).toList();
bool tiled = resolutionList.size() > 0;
bool tiled = qobject_cast< const QgsRasterDataProvider * >( provider )
? !qobject_cast< const QgsRasterDataProvider * >( provider )->nativeResolutions().isEmpty()
: false;

QDomElement dataSourceElem = doc.createElement( tiled ? QStringLiteral( "WMTSDataSource" ) : QStringLiteral( "WMSDataSource" ) );
QDomText dataSourceUri = doc.createTextNode( provider->dataSourceUri() );
Expand Down

0 comments on commit 8b16e05

Please sign in to comment.