From ee4bbb765e9a3ccfc9f5943d253290e3fc24484c Mon Sep 17 00:00:00 2001
From: Paolo Angelelli <paolo.angelelli@theqtcompany.com>
Date: Mon, 15 Aug 2016 14:44:22 +0200
Subject: [PATCH] OSM: Honor min/max zoom level limits coming from the provider
 records

This patch prevents the tile fetcher from requesting tiles with a
z values that is outside the range defined in the provider record.
If the provider record does not specify these values, the default
values are used (0 and 20)

Change-Id: I5c3f7be8bbd2b2ce6c8c8d6d8d81431237e60f5b
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
---
 src/location/maps/qgeotilefetcher.cpp         |  7 +++--
 .../geoservices/osm/qgeotilefetcherosm.cpp    |  3 ++
 .../geoservices/osm/qgeotileproviderosm.cpp   | 28 +++++++++++++++++--
 .../geoservices/osm/qgeotileproviderosm.h     |  4 +++
 4 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/location/maps/qgeotilefetcher.cpp b/src/location/maps/qgeotilefetcher.cpp
index 0e0e81caa..955839cbb 100644
--- a/src/location/maps/qgeotilefetcher.cpp
+++ b/src/location/maps/qgeotilefetcher.cpp
@@ -109,8 +109,12 @@ void QGeoTileFetcher::requestNextTile()
         return;
 
     QGeoTileSpec ts = d->queue_.takeFirst();
+    if (d->queue_.isEmpty())
+        d->timer_.stop();
 
     QGeoTiledMapReply *reply = getTileImage(ts);
+    if (!reply)
+        return;
 
     if (reply->isFinished()) {
         handleReply(reply, ts);
@@ -123,9 +127,6 @@ void QGeoTileFetcher::requestNextTile()
 
         d->invmap_.insert(ts, reply);
     }
-
-    if (d->queue_.isEmpty())
-        d->timer_.stop();
 }
 
 void QGeoTileFetcher::finished()
diff --git a/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp b/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp
index 0d7fa58e7..c7de7cc95 100644
--- a/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp
@@ -121,6 +121,9 @@ QGeoTiledMapReply *QGeoTileFetcherOsm::getTileImage(const QGeoTileSpec &spec)
     }
     id -= 1; // TODO: make OSM map ids start from 0.
 
+    if (spec.zoom() > m_providers[id]->maximumZoomLevel() || spec.zoom() < m_providers[id]->minimumZoomLevel())
+        return Q_NULLPTR;
+
     const QUrl url = m_providers[id]->tileAddress(spec.x(), spec.y(), spec.zoom());
     QNetworkRequest request;
     request.setHeader(QNetworkRequest::UserAgentHeader, m_userAgent);
diff --git a/src/plugins/geoservices/osm/qgeotileproviderosm.cpp b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp
index afa8e45f4..684ac43c7 100644
--- a/src/plugins/geoservices/osm/qgeotileproviderosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp
@@ -99,6 +99,20 @@ QString QGeoTileProviderOsm::format() const
     return m_provider->format();
 }
 
+int QGeoTileProviderOsm::minimumZoomLevel() const
+{
+    if (m_status != Resolved || !m_provider)
+        return 0;
+    return m_provider->minimumZoomLevel();
+}
+
+int QGeoTileProviderOsm::maximumZoomLevel() const
+{
+    if (m_status != Resolved || !m_provider)
+        return 20;
+    return m_provider->maximumZoomLevel();
+}
+
 const QGeoMapType &QGeoTileProviderOsm::mapType() const
 {
     return m_mapType;
@@ -332,7 +346,7 @@ void TileProvider::onNetworkReplyFinished()
      * unavailable, without making the osm plugin fire requests to it. Default is true.
      *
      * MinimumZoomLevel and MaximumZoomLevel are also optional, and allow to prevent invalid tile
-     * requests to the providers, if they do not support the specific ZL. Default is 0 and 19,
+     * 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
@@ -401,7 +415,7 @@ void TileProvider::onNetworkReplyFinished()
         m_copyRightStyle = copyRightStyle.toString();
 
     m_minimumZoomLevel = 0;
-    m_maximumZoomLevel = 19;
+    m_maximumZoomLevel = 20;
     const QJsonValue minZoom = json.value(QLatin1String("MinimumZoomLevel"));
     if (minZoom.isDouble())
         m_minimumZoomLevel = qBound(0, int(minZoom.toDouble()), maxValidZoom);
@@ -517,6 +531,16 @@ QString TileProvider::format() const
     return m_format;
 }
 
+int TileProvider::minimumZoomLevel() const
+{
+    return m_minimumZoomLevel;
+}
+
+int TileProvider::maximumZoomLevel() const
+{
+    return m_maximumZoomLevel;
+}
+
 void TileProvider::setStyleCopyRight(const QString &copyright)
 {
     m_copyRightStyle = copyright;
diff --git a/src/plugins/geoservices/osm/qgeotileproviderosm.h b/src/plugins/geoservices/osm/qgeotileproviderosm.h
index d9f80482b..3e887965f 100644
--- a/src/plugins/geoservices/osm/qgeotileproviderosm.h
+++ b/src/plugins/geoservices/osm/qgeotileproviderosm.h
@@ -87,6 +87,8 @@ public:
     inline QString dataCopyRight() const;
     inline QString styleCopyRight() const;
     inline QString format() const;
+    inline int minimumZoomLevel() const;
+    inline int maximumZoomLevel() const;
     QUrl tileAddress(int x, int y, int z) const;
 
     // Optional properties, not needed to construct a provider
@@ -141,6 +143,8 @@ public:
     QString dataCopyRight() const;
     QString styleCopyRight() const;
     QString format() const;
+    int minimumZoomLevel() const;
+    int maximumZoomLevel() const;
     const QGeoMapType &mapType() const;
     bool isValid() const;
     bool isResolved() const;
-- 
GitLab