Skip to content

Commit

Permalink
[wms] Allow for WMTS layers to take DPI into account and scale up on …
Browse files Browse the repository at this point in the history
…high DPI screens (#51018)
  • Loading branch information
nirvn committed Nov 29, 2022
1 parent 44361ba commit ec689c5
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 9 deletions.
7 changes: 7 additions & 0 deletions python/core/auto_additions/qgis.py
Expand Up @@ -1821,6 +1821,13 @@
Qgis.DpiMode.__doc__ = 'DpiMode enum\n\n.. versionadded:: 3.26\n\n' + '* ``All``: ' + Qgis.DpiMode.All.__doc__ + '\n' + '* ``Off``: ' + Qgis.DpiMode.Off.__doc__ + '\n' + '* ``QGIS``: ' + Qgis.DpiMode.QGIS.__doc__ + '\n' + '* ``UMN``: ' + Qgis.DpiMode.UMN.__doc__ + '\n' + '* ``GeoServer``: ' + Qgis.DpiMode.GeoServer.__doc__
# --
Qgis.DpiMode.baseClass = Qgis
# monkey patching scoped based enum
Qgis.TilePixelRatio.Undefined.__doc__ = "Undefined (not scale)"
Qgis.TilePixelRatio.StandardDpi.__doc__ = "Standard (96 DPI)"
Qgis.TilePixelRatio.HighDpi.__doc__ = "High (192 DPI)"
Qgis.TilePixelRatio.__doc__ = 'DpiMode enum\n\n.. versionadded:: 3.30\n\n' + '* ``Undefined``: ' + Qgis.TilePixelRatio.Undefined.__doc__ + '\n' + '* ``StandardDpi``: ' + Qgis.TilePixelRatio.StandardDpi.__doc__ + '\n' + '* ``HighDpi``: ' + Qgis.TilePixelRatio.HighDpi.__doc__
# --
Qgis.TilePixelRatio.baseClass = Qgis
QgsStringUtils.Capitalization = Qgis.Capitalization
# monkey patching scoped based enum
QgsStringUtils.MixedCase = Qgis.Capitalization.MixedCase
Expand Down
6 changes: 6 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -1163,6 +1163,12 @@ The development version
GeoServer,
};

enum class TilePixelRatio
{
Undefined,
StandardDpi,
HighDpi,
};


enum class Capitalization
Expand Down
11 changes: 11 additions & 0 deletions src/core/qgis.h
Expand Up @@ -1955,6 +1955,17 @@ class CORE_EXPORT Qgis
};
Q_ENUM( DpiMode )

/**
* DpiMode enum
* \since QGIS 3.30
*/
enum class TilePixelRatio
{
Undefined = 0, //!< Undefined (not scale)
StandardDpi = 1, //!< Standard (96 DPI)
HighDpi = 2, //!< High (192 DPI)
};
Q_ENUM( TilePixelRatio )

// NOTE -- the hardcoded numbers here must match QFont::Capitalization!

Expand Down
9 changes: 9 additions & 0 deletions src/core/qgsowsconnection.cpp
Expand Up @@ -132,6 +132,11 @@ QgsDataSourceUri &QgsOwsConnection::addWmsWcsConnectionSettings( QgsDataSourceUr
{
uri.setParam( QStringLiteral( "dpiMode" ), dpiMode );
}
const QString tilePixelRatio = settings.value( settingsKey + QStringLiteral( "/tilePixelRatio" ), "0" ).toString();
if ( tilePixelRatio != QStringLiteral( "0" ) )
{
uri.setParam( QStringLiteral( "tilePixelRatio" ), tilePixelRatio );
}

return uri;
}
Expand Down Expand Up @@ -164,6 +169,10 @@ QgsDataSourceUri &QgsOwsConnection::addWmsWcsConnectionSettings( QgsDataSourceUr
{
uri.setParam( QStringLiteral( "dpiMode" ), QString::number( static_cast<int>( settingsConnectionDpiMode.value( {service.toLower(), connName} ) ) ) );
}
if ( settingsConnectionTilePixelRatio.exists( {service.toLower(), connName} ) )
{
uri.setParam( QStringLiteral( "tilePixelRatio" ), QString::number( static_cast<int>( settingsConnectionTilePixelRatio.value( {service.toLower(), connName} ) ) ) );
}

return uri;
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/qgsowsconnection.h
Expand Up @@ -50,6 +50,7 @@ class CORE_EXPORT QgsOwsConnection : public QObject
static const inline QgsSettingsEntryBool settingsConnectionSmoothPixmapTransform = QgsSettingsEntryBool( QStringLiteral( "connections-%1/%2/smoothPixmapTransform" ), QgsSettings::Prefix::QGIS, false ) SIP_SKIP;
static const inline QgsSettingsEntryBool settingsConnectionReportedLayerExtents = QgsSettingsEntryBool( QStringLiteral( "connections-%1/%2/reportedLayerExtents" ), QgsSettings::Prefix::QGIS, false ) SIP_SKIP;
static const inline QgsSettingsEntryEnumFlag<Qgis::DpiMode> settingsConnectionDpiMode = QgsSettingsEntryEnumFlag<Qgis::DpiMode>( QStringLiteral( "connections-%1/%2/dpiMode" ), QgsSettings::Prefix::QGIS, Qgis::DpiMode::All, QString(), Qgis::SettingsOption::SaveEnumFlagAsInt ) SIP_SKIP;
static const inline QgsSettingsEntryEnumFlag<Qgis::TilePixelRatio> settingsConnectionTilePixelRatio = QgsSettingsEntryEnumFlag<Qgis::TilePixelRatio>( QStringLiteral( "connections-%1/%2/tilePixelRatio" ), QgsSettings::Prefix::QGIS, Qgis::TilePixelRatio::Undefined, QString(), Qgis::SettingsOption::SaveEnumFlagAsInt ) SIP_SKIP;
static const inline QgsSettingsEntryString settingsConnectionMaxNumFeatures = QgsSettingsEntryString( QStringLiteral( "connections-%1/%2/maxnumfeatures" ), QgsSettings::Prefix::QGIS ) SIP_SKIP;
static const inline QgsSettingsEntryString settingsConnectionPagesize = QgsSettingsEntryString( QStringLiteral( "connections-%1/%2/pagesize" ), QgsSettings::Prefix::QGIS ) SIP_SKIP;
static const inline QgsSettingsEntryBool settingsConnectionPagingEnabled = QgsSettingsEntryBool( QStringLiteral( "connections-%1/%2/pagingenabled" ), QgsSettings::Prefix::QGIS, true ) SIP_SKIP;
Expand All @@ -61,7 +62,7 @@ class CORE_EXPORT QgsOwsConnection : public QObject
static const inline QgsSettingsEntryString settingsConnectionPassword = QgsSettingsEntryString( QStringLiteral( "%1/%2/password" ), QgsSettings::Prefix::QGIS ) SIP_SKIP;
static const inline QgsSettingsEntryString settingsConnectionAuthCfg = QgsSettingsEntryString( QStringLiteral( "%1/%2/authcfg" ), QgsSettings::Prefix::QGIS ) SIP_SKIP;

static const inline QgsSettingsEntryGroup settingsServiceConnectionDetailsGroup = QgsSettingsEntryGroup( {&settingsConnectionUrl, &settingsConnectionReferer, &settingsConnectionVersion, &settingsConnectionIgnoreGetMapURI, &settingsConnectionIgnoreGetFeatureInfoURI, &settingsConnectionSmoothPixmapTransform, &settingsConnectionReportedLayerExtents, &settingsConnectionDpiMode, &settingsConnectionMaxNumFeatures, &settingsConnectionPagesize, &settingsConnectionPagingEnabled, &settingsConnectionPreferCoordinatesForWfsT11, &settingsConnectionIgnoreAxisOrientation, &settingsConnectionInvertAxisOrientation} );
static const inline QgsSettingsEntryGroup settingsServiceConnectionDetailsGroup = QgsSettingsEntryGroup( {&settingsConnectionUrl, &settingsConnectionReferer, &settingsConnectionVersion, &settingsConnectionIgnoreGetMapURI, &settingsConnectionIgnoreGetFeatureInfoURI, &settingsConnectionSmoothPixmapTransform, &settingsConnectionReportedLayerExtents, &settingsConnectionDpiMode, &settingsConnectionTilePixelRatio, &settingsConnectionMaxNumFeatures, &settingsConnectionPagesize, &settingsConnectionPagingEnabled, &settingsConnectionPreferCoordinatesForWfsT11, &settingsConnectionIgnoreAxisOrientation, &settingsConnectionInvertAxisOrientation} );
static const inline QgsSettingsEntryGroup settingsServiceConnectionCredentialsGroup = QgsSettingsEntryGroup( {&settingsConnectionUsername, &settingsConnectionPassword, &settingsConnectionAuthCfg} );

/**
Expand Down
16 changes: 14 additions & 2 deletions src/gui/qgsnewhttpconnection.cpp
Expand Up @@ -65,13 +65,17 @@ QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes typ
txtName->setValidator( new QRegularExpressionValidator( QRegularExpression( "[^\\/]+" ), txtName ) );

cmbDpiMode->clear();

cmbDpiMode->addItem( tr( "all" ), static_cast<int>( Qgis::DpiMode::All ) );
cmbDpiMode->addItem( tr( "off" ), static_cast<int>( Qgis::DpiMode::Off ) );
cmbDpiMode->addItem( tr( "QGIS" ), static_cast<int>( Qgis::DpiMode::QGIS ) );
cmbDpiMode->addItem( tr( "UMN" ), static_cast<int>( Qgis::DpiMode::UMN ) );
cmbDpiMode->addItem( tr( "GeoServer" ), static_cast<int>( Qgis::DpiMode::GeoServer ) );

cmbTilePixelRatio->clear();
cmbTilePixelRatio->addItem( tr( "Undefined (not scaled)" ), static_cast<int>( Qgis::TilePixelRatio::Undefined ) );
cmbTilePixelRatio->addItem( tr( "Standard (96 DPI)" ), static_cast<int>( Qgis::TilePixelRatio::StandardDpi ) );
cmbTilePixelRatio->addItem( tr( "High (192 DPI)" ), static_cast<int>( Qgis::TilePixelRatio::HighDpi ) );

cmbVersion->clear();
cmbVersion->addItem( tr( "Maximum" ) );
cmbVersion->addItem( tr( "1.0" ) );
Expand Down Expand Up @@ -135,6 +139,10 @@ QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes typ
mGroupBox->layout()->removeWidget( cmbDpiMode );
lblDpiMode->setVisible( false );
mGroupBox->layout()->removeWidget( lblDpiMode );
cmbTilePixelRatio->setVisible( false );
mGroupBox->layout()->removeWidget( cmbTilePixelRatio );
lblTilePixelRatio->setVisible( false );
mGroupBox->layout()->removeWidget( lblTilePixelRatio );
}
}

Expand Down Expand Up @@ -286,7 +294,7 @@ QString QgsNewHttpConnection::wmsSettingsKey( const QString &base, const QString

void QgsNewHttpConnection::updateServiceSpecificSettings()
{
QStringList detailsParameters = {mServiceName.toLower(), mOriginalConnName};
QStringList detailsParameters = { mServiceName.toLower(), mOriginalConnName };

cbxIgnoreGetMapURI->setChecked( QgsOwsConnection::settingsConnectionIgnoreGetMapURI.value( detailsParameters ) );
cbxWmsIgnoreReportedLayerExtents->setChecked( QgsOwsConnection::settingsConnectionReportedLayerExtents.value( detailsParameters ) );
Expand All @@ -301,6 +309,8 @@ void QgsNewHttpConnection::updateServiceSpecificSettings()

Qgis::DpiMode dpiMode = QgsOwsConnection::settingsConnectionDpiMode.value( detailsParameters );
cmbDpiMode->setCurrentIndex( cmbDpiMode->findData( static_cast<int>( dpiMode ) ) );
Qgis::TilePixelRatio tilePixelRatio = QgsOwsConnection::settingsConnectionTilePixelRatio.value( detailsParameters );
cmbTilePixelRatio->setCurrentIndex( cmbTilePixelRatio->findData( static_cast<int>( tilePixelRatio ) ) );

const QString version = QgsOwsConnection::settingsConnectionVersion.value( detailsParameters );
int versionIdx = WFS_VERSION_MAX; // AUTO
Expand Down Expand Up @@ -395,6 +405,8 @@ void QgsNewHttpConnection::accept()

Qgis::DpiMode dpiMode = cmbDpiMode->currentData().value<Qgis::DpiMode>();
QgsOwsConnection::settingsConnectionDpiMode.setValue( dpiMode, detailsParameters );
Qgis::TilePixelRatio tilePixelRatio = cmbTilePixelRatio->currentData().value<Qgis::TilePixelRatio>();
QgsOwsConnection::settingsConnectionTilePixelRatio.setValue( tilePixelRatio, detailsParameters );

mHttpHeaders->updateSettings( settings, QStringLiteral( "qgis/connections-%1/%2" ).arg( mServiceName.toLower(), newConnectionName ) );
}
Expand Down
2 changes: 2 additions & 0 deletions src/providers/wms/qgswmscapabilities.cpp
Expand Up @@ -21,6 +21,7 @@
#include <QNetworkCacheMetaData>
#include <QRegularExpression>

#include "qgis.h"
#include "qgssettings.h"
#include "qgscoordinatetransform.h"
#include "qgsdatasourceuri.h"
Expand Down Expand Up @@ -226,6 +227,7 @@ bool QgsWmsSettings::parseUri( const QString &uriString )
// tileMatrixSet may be empty if URI was converted from < 1.9 project file URI
// in that case it means that the source is WMS-C
mTileMatrixSetId = uri.param( QStringLiteral( "tileMatrixSet" ) );
mTilePixelRatio = uri.hasParam( QStringLiteral( "tilePixelRatio" ) ) ? static_cast< Qgis::TilePixelRatio >( uri.param( QStringLiteral( "tilePixelRatio" ) ).toInt() ) : Qgis::TilePixelRatio::Undefined;
}

if ( uri.hasParam( QStringLiteral( "tileDimensions" ) ) )
Expand Down
2 changes: 2 additions & 0 deletions src/providers/wms/qgswmscapabilities.h
Expand Up @@ -845,6 +845,8 @@ class QgsWmsSettings
//! name of the chosen tile matrix set
QString mTileMatrixSetId;

Qgis::TilePixelRatio mTilePixelRatio = Qgis::TilePixelRatio::Undefined;

/**
* Maximum width and height of getmap requests
*/
Expand Down
18 changes: 18 additions & 0 deletions src/providers/wms/qgswmsprovider.cpp
Expand Up @@ -224,6 +224,22 @@ QgsWmsProvider::QgsWmsProvider( QString const &uri, const ProviderOptions &optio
temporalCapabilities()->setFlags( mTileLayer->temporalCapabilityFlags );
temporalCapabilities()->setIntervalHandlingMethod( Qgis::TemporalIntervalMatchMethod::FindClosestMatchToStartOfRange );
}

if ( !mSettings.mXyz )
{
switch ( mSettings.mTilePixelRatio )
{
case Qgis::TilePixelRatio::Undefined:
mTileLayer->dpi = -1;
break;
case Qgis::TilePixelRatio::StandardDpi:
mTileLayer->dpi = 96;
break;
case Qgis::TilePixelRatio::HighDpi:
mTileLayer->dpi = 192;
break;
}
}
}

if ( profile )
Expand Down Expand Up @@ -811,7 +827,9 @@ QImage *QgsWmsProvider::draw( const QgsRectangle &viewExtent, int pixelWidth, in

// if we know both source and output DPI, let's scale the tiles
if ( mDpi != -1 && mTileLayer->dpi != -1 )
{
vres *= static_cast<double>( mDpi ) / mTileLayer->dpi;
}

// find nearest resolution
tm = mTileMatrixSet->findNearestResolution( vres );
Expand Down
25 changes: 19 additions & 6 deletions src/ui/qgsnewhttpconnectionbase.ui
Expand Up @@ -140,35 +140,35 @@
<string>WMS/WMTS Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="0" colspan="2">
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="cbxWmsIgnoreAxisOrientation">
<property name="text">
<string>Ignore axis orientation (WMS 1.3/WMTS)</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="cbxIgnoreGetFeatureInfoURI">
<property name="text">
<string>Ignore GetFeatureInfo URI reported in capabilities</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="cbxIgnoreGetMapURI">
<property name="text">
<string>Ignore GetMap/GetTile/GetLegendGraphic URI reported in capabilities</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<item row="10" column="0" colspan="2">
<widget class="QCheckBox" name="cbxSmoothPixmapTransform">
<property name="text">
<string>Smooth pixmap transform</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="cbxWmsInvertAxisOrientation">
<property name="text">
<string>Invert axis orientation</string>
Expand All @@ -181,13 +181,26 @@
<item row="0" column="0">
<widget class="QLabel" name="lblDpiMode">
<property name="text">
<string>DPI-&amp;Mode</string>
<string>WMS DPI-&amp;Mode</string>
</property>
<property name="buddy">
<cstring>cmbDpiMode</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cmbTilePixelRatio"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblTilePixelRatio">
<property name="text">
<string>WMTS server-side tile pixel ratio</string>
</property>
<property name="buddy">
<cstring>cmbTilePixelRatio</cstring>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="cbxWmsIgnoreReportedLayerExtents">
<property name="text">
Expand Down

0 comments on commit ec689c5

Please sign in to comment.