Skip to content

Commit

Permalink
[xyz] Optional scaling of XYZ tile layers
Browse files Browse the repository at this point in the history
This adds "Resolution" configuration flag for XYZ tile layers.
It supports several options:
- unknown (default) - everything works as before
- standard resolution - applies scaling
- high resolution - applies scaling, assumes high-res tiles

If tiles are made for standard resolution (e.g. 96 DPI) then on high res displays (e.g. 192 DPI)
labels and other map features may appear very small if the resolution is not set. When
configured as "standard resolution", map tiles will be picked according to this resolution and
thus on high res displays the tiles will get scaled up. Similarly for print output, tiles will
be scaled up so the printouts will have matching tile resolutions.

The "high resolution" option is for tiles 512x512 aimed towards high-resolution displays.
  • Loading branch information
wonder-sk committed Mar 1, 2019
1 parent 334ae0c commit 7d83263
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 49 deletions.
1 change: 1 addition & 0 deletions src/providers/wms/qgswmscapabilities.h
Expand Up @@ -423,6 +423,7 @@ struct QgsWmtsTileLayer
QStringList formats;
QStringList infoFormats;
QString defaultStyle;
int dpi = -1; //!< DPI of the tile layer (-1 for unknown DPI)
//! available dimensions (optional, for multi-dimensional data)
QHash<QString, QgsWmtsDimension> dimensions;
QHash<QString, QgsWmtsStyle> styles;
Expand Down
22 changes: 21 additions & 1 deletion src/providers/wms/qgswmsprovider.cpp
Expand Up @@ -655,6 +655,10 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, in
Q_ASSERT( mTileMatrixSet );
Q_ASSERT( !mTileMatrixSet->tileMatrices.isEmpty() );

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

// find nearest resolution
tm = mTileMatrixSet->findNearestResolution( vres );
Q_ASSERT( tm );
Expand Down Expand Up @@ -1219,6 +1223,22 @@ void QgsWmsProvider::setupXyzCapabilities( const QString &uri )
tl.tileMode = XYZ;
tl.identifier = QStringLiteral( "xyz" ); // as set in parseUri
tl.boundingBoxes << bbox;

double tilePixelRatio = 0.; // unknown
if ( parsedUri.hasParam( QStringLiteral( "tilePixelRatio" ) ) )
tilePixelRatio = parsedUri.param( QStringLiteral( "tilePixelRatio" ) ).toDouble();

if ( tilePixelRatio != 0 )
{
// known tile pixel ratio - will be doing auto-scaling of tiles based on output DPI
tl.dpi = 96 * tilePixelRatio; // TODO: is 96 correct base DPI ?
}
else
{
// unknown tile pixel ratio - no scaling of tiles based on output DPI
tilePixelRatio = 1;
}

mCaps.mTileLayersSupported.append( tl );

QgsWmtsTileMatrixSet tms;
Expand All @@ -1239,7 +1259,7 @@ void QgsWmsProvider::setupXyzCapabilities( const QString &uri )
QgsWmtsTileMatrix tm;
tm.identifier = QString::number( zoom );
tm.topLeft = topLeft;
tm.tileWidth = tm.tileHeight = 256;
tm.tileWidth = tm.tileHeight = 256 * tilePixelRatio;
tm.matrixWidth = tm.matrixHeight = 1 << zoom;
tm.tres = xspan / ( tm.tileWidth * tm.matrixWidth );
tm.scaleDenom = 0.0;
Expand Down
4 changes: 4 additions & 0 deletions src/providers/wms/qgsxyzconnection.cpp
Expand Up @@ -36,6 +36,8 @@ QString QgsXyzConnection::encodedUri() const
uri.setParam( QStringLiteral( "password" ), password );
if ( ! referer.isEmpty() )
uri.setParam( QStringLiteral( "referer" ), referer );
if ( tilePixelRatio != 0 )
uri.setParam( QStringLiteral( "tilePixelRatio" ), QString::number( tilePixelRatio ) );
return uri.encodedUri();
}

Expand Down Expand Up @@ -78,6 +80,7 @@ QgsXyzConnection QgsXyzConnectionUtils::connection( const QString &name )
conn.username = settings.value( QStringLiteral( "username" ) ).toString();
conn.password = settings.value( QStringLiteral( "password" ) ).toString();
conn.referer = settings.value( QStringLiteral( "referer" ) ).toString();
conn.tilePixelRatio = settings.value( QStringLiteral( "tilePixelRatio" ), 0 ).toDouble();
conn.hidden = settings.value( QStringLiteral( "hidden" ) ).toBool();
return conn;
}
Expand Down Expand Up @@ -120,6 +123,7 @@ void QgsXyzConnectionUtils::addConnection( const QgsXyzConnection &conn )
settings.setValue( QStringLiteral( "username" ), conn.username );
settings.setValue( QStringLiteral( "password" ), conn.password );
settings.setValue( QStringLiteral( "referer" ), conn.referer );
settings.setValue( QStringLiteral( "tilePixelRatio" ), conn.tilePixelRatio );
if ( addHiddenProperty )
{
settings.setValue( QStringLiteral( "hidden" ), false );
Expand Down
2 changes: 2 additions & 0 deletions src/providers/wms/qgsxyzconnection.h
Expand Up @@ -32,6 +32,8 @@ struct QgsXyzConnection
QString password;
// Referer
QString referer;
// tile pixel ratio (0 = unknown (not scaled), 1.0 = 256x256, 2.0 = 512x512)
double tilePixelRatio = 0;
bool hidden = false;

QString encodedUri() const;
Expand Down
12 changes: 12 additions & 0 deletions src/providers/wms/qgsxyzconnectiondialog.cpp
Expand Up @@ -37,6 +37,12 @@ void QgsXyzConnectionDialog::setConnection( const QgsXyzConnection &conn )
mAuthSettings->setUsername( conn.username );
mAuthSettings->setPassword( conn.password );
mEditReferer->setText( conn.referer );
int index = 0; // default is "unknown"
if ( conn.tilePixelRatio == 2. )
index = 2; // high-res
else if ( conn.tilePixelRatio == 1. )
index = 1; // normal-res
mComboTileResolution->setCurrentIndex( index );
mAuthSettings->setConfigId( conn.authCfg );
}

Expand All @@ -52,6 +58,12 @@ QgsXyzConnection QgsXyzConnectionDialog::connection() const
conn.username = mAuthSettings->username();
conn.password = mAuthSettings->password();
conn.referer = mEditReferer->text();
if ( mComboTileResolution->currentIndex() == 1 )
conn.tilePixelRatio = 1.; // normal-res
else if ( mComboTileResolution->currentIndex() == 2 )
conn.tilePixelRatio = 2.; // high-res
else
conn.tilePixelRatio = 0; // unknown
conn.authCfg = mAuthSettings->configId( );
return conn;
}
122 changes: 74 additions & 48 deletions src/ui/qgsxyzconnectiondialog.ui
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>525</width>
<height>332</height>
<width>636</width>
<height>624</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -20,15 +20,18 @@
<string>Connection Details</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="9" column="0" colspan="2">
<widget class="QLabel" name="lblReferer">
<property name="text">
<string>Referer</string>
<item row="10" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="buddy">
<cstring>mEditReferer</cstring>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</widget>
</spacer>
</item>
<item row="9" column="2">
<widget class="QLineEdit" name="mEditReferer">
Expand All @@ -37,13 +40,10 @@
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QCheckBox" name="mCheckBoxZMax">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Max. Zoom Level</string>
</property>
<property name="checked">
<bool>true</bool>
<string>URL</string>
</property>
</widget>
</item>
Expand All @@ -60,43 +60,13 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="mEditUrl">
<property name="toolTip">
<string>URL of the connection, {z}, {y}, and {z} will be replaced with actual values. Use {-y} for inverted y axis.</string>
</property>
<property name="placeholderText">
<string>http://example.com/{z}/{x}/{y}.png</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="mEditName">
<property name="toolTip">
<string>Name of the new connection</string>
</property>
</widget>
</item>
<item row="10" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" rowspan="2" colspan="3">
<widget class="QGroupBox" name="mAuthGroupBox">
<property name="title">
Expand All @@ -121,10 +91,40 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<item row="0" column="2">
<widget class="QLineEdit" name="mEditName">
<property name="toolTip">
<string>Name of the new connection</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<widget class="QLabel" name="lblReferer">
<property name="text">
<string>URL</string>
<string>Referer</string>
</property>
<property name="buddy">
<cstring>mEditReferer</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="mEditUrl">
<property name="toolTip">
<string>URL of the connection, {z}, {y}, and {z} will be replaced with actual values. Use {-y} for inverted y axis.</string>
</property>
<property name="placeholderText">
<string>http://example.com/{z}/{x}/{y}.png</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QCheckBox" name="mCheckBoxZMax">
<property name="text">
<string>Max. Zoom Level</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
Expand All @@ -148,6 +148,32 @@
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Tile Resolution</string>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QComboBox" name="mComboTileResolution">
<item>
<property name="text">
<string>Unknown (not scaled)</string>
</property>
</item>
<item>
<property name="text">
<string>Standard (256x256 / 96 DPI)</string>
</property>
</item>
<item>
<property name="text">
<string>High (512x512 / 192 DPI)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down

0 comments on commit 7d83263

Please sign in to comment.