diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2016-08-01 19:44:41 +0200 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2016-11-08 15:19:24 +0000 |
commit | 4f192687cc07dbe5de1dbed3187d90045ed38703 (patch) | |
tree | 157d0d481f7d51215f0e197dfa3160017e820f32 /src/plugins/geoservices/osm/qgeotileproviderosm.cpp | |
parent | 219e7b84ac048ff585c36f47a1c783af9ae4e4bc (diff) | |
download | qtlocation-4f192687cc07dbe5de1dbed3187d90045ed38703.tar.gz |
Evict obsolete provider data on init()
During initialization, this patch makes sure that the cached
tiles belong to the provider currently in use by using the file
lastModified() value and comparing it against the (optional)
Timestamp in the provider records.
If this value is not present in the provider record, or if it
is older than the newest modified file, the data is untouched.
This operation is performed separately for each map id.
This method isn't perfect in all use cases, though.
E.g., if we are forced to shut down one of the provider
and run on the hardcoded fallback, which has an older TS.
These are however rare edge cases that most likely won't
happen in practice (in the case above we could put the
content of the hardcoded provider in the remote json
files too)
Change-Id: Ie29cf05c1fbc835ce4e3363fc0caa38a97800214
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/plugins/geoservices/osm/qgeotileproviderosm.cpp')
-rw-r--r-- | src/plugins/geoservices/osm/qgeotileproviderosm.cpp | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/src/plugins/geoservices/osm/qgeotileproviderosm.cpp b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp index 0d99c828..1989c44f 100644 --- a/src/plugins/geoservices/osm/qgeotileproviderosm.cpp +++ b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp @@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE static const int maxValidZoom = 30; +static const QDateTime defaultTs = QDateTime::fromString(QStringLiteral("2016-06-01T00:00:00"), Qt::ISODate); QGeoTileProviderOsm::QGeoTileProviderOsm(QNetworkAccessManager *nm, const QGeoMapType &mapType, @@ -120,6 +121,13 @@ bool QGeoTileProviderOsm::isHighDpi() const return m_provider->isHighDpi(); } +const QDateTime QGeoTileProviderOsm::timestamp() const +{ + if (!m_provider) + return QDateTime(); + return m_provider->timestamp(); +} + const QGeoMapType &QGeoTileProviderOsm::mapType() const { return m_mapType; @@ -190,8 +198,10 @@ void QGeoTileProviderOsm::onResolutionError(TileProvider *provider) m_provider = p; if (!p->isValid()) { m_status = Idle; -// m_status = Resolving; -// p->resolveProvider(); +#if 0 // leaving triggering the retry to the tile fetcher, instead of constantly spinning it in here. + m_status = Resolving; + p->resolveProvider(); +#endif emit resolutionRequired(); } break; @@ -204,7 +214,9 @@ void QGeoTileProviderOsm::onResolutionError(TileProvider *provider) emit resolutionFinished(this); } else { // still not resolved. But network error is recoverable. m_status = Idle; - //m_provider->resolveProvider(); +#if 0 // leaving triggering the retry to the tile fetcher + m_provider->resolveProvider(); +#endif } } @@ -226,7 +238,7 @@ void QGeoTileProviderOsm::addProvider(TileProvider *provider) /* - QGeoTileProviderOsm::TileProvder + Class TileProvder */ static void sort2(int &a, int &b) @@ -238,13 +250,13 @@ static void sort2(int &a, int &b) } } -TileProvider::TileProvider() : m_status(Invalid), m_nm(nullptr), m_highDpi(false) +TileProvider::TileProvider() : m_status(Invalid), m_nm(nullptr), m_timestamp(defaultTs), m_highDpi(false) { } TileProvider::TileProvider(const QUrl &urlRedirector, bool highDpi) -: m_status(Idle), m_urlRedirector(urlRedirector), m_nm(nullptr), m_highDpi(highDpi) +: m_status(Idle), m_urlRedirector(urlRedirector), m_nm(nullptr), m_timestamp(defaultTs), m_highDpi(highDpi) { if (!m_urlRedirector.isValid()) m_status = Invalid; @@ -259,7 +271,7 @@ TileProvider::TileProvider(const QString &urlTemplate, int maximumZoomLevel) : m_status(Invalid), m_nm(nullptr), m_urlTemplate(urlTemplate), m_format(format), m_copyRightMap(copyRightMap), m_copyRightData(copyRightData), - m_minimumZoomLevel(minimumZoomLevel), m_maximumZoomLevel(maximumZoomLevel), m_highDpi(highDpi) + m_minimumZoomLevel(minimumZoomLevel), m_maximumZoomLevel(maximumZoomLevel), m_timestamp(defaultTs), m_highDpi(highDpi) { setupProvider(); } @@ -352,6 +364,7 @@ void TileProvider::onNetworkReplyFinished() * "StyleCopyRight" : "<copyright>", (optional) * "MinimumZoomLevel" : <minimumZoomLevel>, (optional) * "MaximumZoomLevel" : <maximumZoomLevel>, (optional) + * "Timestamp" : <timestamp>, (optional) * } * * Enabled is optional, and allows to temporarily disable a tile provider if it becomes @@ -361,27 +374,31 @@ void TileProvider::onNetworkReplyFinished() * requests to the providers, if they do not support the specific ZL. Default is 0 and 20, * respectively. * - * <server address template> is required, and is the tile url template, with %x, %y and %z as + * UrlTemplate is required, and is the tile url template, with %x, %y and %z as * placeholders for the actual parameters. * Example: * http://localhost:8080/maps/%z/%x/%y.png * - * <image format> is required, and is the format of the tile. + * ImageFormat is required, and is the format of the tile. * Examples: * "png", "jpg" * - * <MapCopyRight> is required and is the string that will be displayed in the "Map (c)" part + * MapCopyRight is required and is the string that will be displayed in the "Map (c)" part * of the on-screen copyright notice. Can be an empty string. * Example: * "<a href='http://www.mapquest.com/'>MapQuest</a>" * - * <DataCopyRight> is required and is the string that will be displayed in the "Data (c)" part + * DataCopyRight is required and is the string that will be displayed in the "Data (c)" part * of the on-screen copyright notice. Can be an empty string. * Example: * "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors" * - * <StyleCopyRight> is optional and is the string that will be displayed in the optional "Style (c)" part + * StyleCopyRight is optional and is the string that will be displayed in the optional "Style (c)" part * of the on-screen copyright notice. + * + * Timestamp is optional, and if set will cause QtLocation to clear the content of the cache older + * than this timestamp. The purpose is to prevent mixing tiles from different providers in the cache + * upon provider change. The value must be a string in ISO 8601 format (see Qt::ISODate) */ QJsonParseError error; @@ -435,6 +452,10 @@ void TileProvider::onNetworkReplyFinished() if (maxZoom.isDouble()) m_maximumZoomLevel = qBound(0, int(maxZoom.toDouble()), maxValidZoom); + const QJsonValue ts = json.value(QLatin1String("Timestamp")); + if (ts.isString()) + m_timestamp = QDateTime::fromString(ts.toString(), Qt::ISODate); + setupProvider(); if (isValid()) { QObject::disconnect(errorEmitterConnection); @@ -553,6 +574,11 @@ int TileProvider::maximumZoomLevel() const return m_maximumZoomLevel; } +const QDateTime &TileProvider::timestamp() const +{ + return m_timestamp; +} + bool TileProvider::isHighDpi() const { return m_highDpi; @@ -563,6 +589,11 @@ void TileProvider::setStyleCopyRight(const QString ©right) m_copyRightStyle = copyright; } +void TileProvider::setTimestamp(const QDateTime ×tamp) +{ + m_timestamp = timestamp; +} + QUrl TileProvider::tileAddress(int x, int y, int z) const { if (z < m_minimumZoomLevel || z > m_maximumZoomLevel) @@ -591,7 +622,3 @@ TileProvider::Status TileProvider::status() const QT_END_NAMESPACE - - - - |