Skip to content
Permalink
Browse files

[xyz] Optional scaling of XYZ tile layers

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 Feb 27, 2019
1 parent 334ae0c commit 7d832634de0e6b9fc12ab9a46b593da69e18bea6
@@ -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;
@@ -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 );
@@ -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;
@@ -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;
@@ -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();
}

@@ -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;
}
@@ -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 );
@@ -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;
@@ -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 );
}

@@ -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;
}
@@ -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">
@@ -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">
@@ -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>
@@ -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">
@@ -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>
@@ -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>

0 comments on commit 7d83263

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