summaryrefslogtreecommitdiff
path: root/src/plugins/geoservices/osm/qgeotileproviderosm.cpp
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2016-08-01 19:44:41 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2016-11-08 15:19:24 +0000
commit4f192687cc07dbe5de1dbed3187d90045ed38703 (patch)
tree157d0d481f7d51215f0e197dfa3160017e820f32 /src/plugins/geoservices/osm/qgeotileproviderosm.cpp
parent219e7b84ac048ff585c36f47a1c783af9ae4e4bc (diff)
downloadqtlocation-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.cpp59
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 &copyright)
m_copyRightStyle = copyright;
}
+void TileProvider::setTimestamp(const QDateTime &timestamp)
+{
+ 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
-
-
-
-