summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2016-12-02 18:18:23 +0100
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-01-16 16:18:23 +0000
commit45b1f2c23cf0e782c0b99f38e4d01a88da765753 (patch)
tree1bfe5d5706db94722b3956ac17b65897b2370d30
parent5504a4c00ec01fdbc95a862c9bc63a680095daee (diff)
downloadqtlocation-45b1f2c23cf0e782c0b99f38e4d01a88da765753.tar.gz
Make zoomLevel refer to a default 256^2 tile size
Currently the zoomLevel is the power of 2 reflecting how many tiles are in a map edge. This means that two plugins with two different tileSize will show a map of different size at the same zoomLevel. With this patch the zoomLevel is "normalized" upon a tileSize of 256, regardless of the tile size in use. In this way, the new 256 based zoom level can be a consistent parameter also for plugins that are not tile based. CameraCapabilities therefore now offers two new methods, m[in,ax]imumZoomLevelAt256, that return the respective value for the normalized 256^2 tilesize. It also gets a setTileSize, which is currently not used as all our plugins use a tile size of 256 (which is the camera capabilities default tilesize value). Change-Id: Ib12092fd14faf7fc85f8be5fb799dbd5496b760b Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp21
-rw-r--r--src/location/maps/qgeocameracapabilities.cpp42
-rw-r--r--src/location/maps/qgeocameracapabilities_p.h5
-rw-r--r--src/location/maps/qgeotiledmap.cpp33
-rw-r--r--tests/auto/declarative_ui/tst_map.qml36
-rw-r--r--tests/auto/qgeoserviceprovider/tst_qgeoserviceprovider.cpp2
-rw-r--r--tests/auto/qgeotiledmap/tst_qgeotiledmap.cpp4
7 files changed, 109 insertions, 34 deletions
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index a46d8b81..761fcdc5 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -51,6 +51,11 @@
#include <QtQml/qqmlinfo.h>
#include <cmath>
+#ifndef M_PI
+#define M_PI 3.141592653589793238463
+#endif
+
+
QT_BEGIN_NAMESPACE
/*!
@@ -562,11 +567,11 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
//minimum zoom level might be changed to limit gray bundaries
if (m_gestureArea->maximumZoomLevel() < 0
- || m_mappingManager->cameraCapabilities().maximumZoomLevel() < m_gestureArea->maximumZoomLevel())
- setMaximumZoomLevel(m_mappingManager->cameraCapabilities().maximumZoomLevel());
+ || m_mappingManager->cameraCapabilities().maximumZoomLevelAt256() < m_gestureArea->maximumZoomLevel())
+ setMaximumZoomLevel(m_mappingManager->cameraCapabilities().maximumZoomLevelAt256());
- if (m_mappingManager->cameraCapabilities().minimumZoomLevel() > m_gestureArea->minimumZoomLevel())
- setMinimumZoomLevel(m_mappingManager->cameraCapabilities().minimumZoomLevel());
+ if (m_mappingManager->cameraCapabilities().minimumZoomLevelAt256() > m_gestureArea->minimumZoomLevel())
+ setMinimumZoomLevel(m_mappingManager->cameraCapabilities().minimumZoomLevelAt256());
// Map tiles are built in this call. m_map->minimumZoom() becomes operational
@@ -633,7 +638,7 @@ void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel)
qreal oldMinimumZoomLevel = this->minimumZoomLevel();
if (m_map) {
- minimumZoomLevel = qBound(qreal(m_map->cameraCapabilities().minimumZoomLevel()), minimumZoomLevel, maximumZoomLevel());
+ minimumZoomLevel = qBound(qreal(m_map->cameraCapabilities().minimumZoomLevelAt256()), minimumZoomLevel, maximumZoomLevel());
double minimumViewportZoomLevel = m_map->minimumZoomAtViewportSize(width(),height());
if (minimumZoomLevel < minimumViewportZoomLevel)
minimumZoomLevel = minimumViewportZoomLevel;
@@ -668,7 +673,7 @@ qreal QDeclarativeGeoMap::minimumZoomLevel() const
if (m_gestureArea->minimumZoomLevel() != -1)
return m_gestureArea->minimumZoomLevel();
else if (m_map)
- return m_map->cameraCapabilities().minimumZoomLevel();
+ return m_map->cameraCapabilities().minimumZoomLevelAt256();
else
return -1.0;
}
@@ -684,7 +689,7 @@ void QDeclarativeGeoMap::setMaximumZoomLevel(qreal maximumZoomLevel)
qreal oldMaximumZoomLevel = this->maximumZoomLevel();
if (m_map)
- maximumZoomLevel = qBound(minimumZoomLevel(), maximumZoomLevel, qreal(m_map->cameraCapabilities().maximumZoomLevel()));
+ maximumZoomLevel = qBound(minimumZoomLevel(), maximumZoomLevel, qreal(m_map->cameraCapabilities().maximumZoomLevelAt256()));
m_gestureArea->setMaximumZoomLevel(maximumZoomLevel);
@@ -710,7 +715,7 @@ qreal QDeclarativeGeoMap::maximumZoomLevel() const
if (m_gestureArea->maximumZoomLevel() != -1)
return m_gestureArea->maximumZoomLevel();
else if (m_map)
- return m_map->cameraCapabilities().maximumZoomLevel();
+ return m_map->cameraCapabilities().minimumZoomLevelAt256();
else
return -1.0;
}
diff --git a/src/location/maps/qgeocameracapabilities.cpp b/src/location/maps/qgeocameracapabilities.cpp
index 7b4a014a..97ff5790 100644
--- a/src/location/maps/qgeocameracapabilities.cpp
+++ b/src/location/maps/qgeocameracapabilities.cpp
@@ -37,6 +37,14 @@
#include "qgeocameracapabilities_p.h"
#include <QSharedData>
+#include <cmath>
+
+static const double invLog2 = 1.0 / std::log(2.0);
+
+static double zoomLevelTo256(double zoomLevelForTileSize, double tileSize)
+{
+ return std::log( std::pow(2.0, zoomLevelForTileSize) * tileSize / 256.0 ) * invLog2;
+}
QT_BEGIN_NAMESPACE
@@ -60,6 +68,7 @@ public:
double maxZoom_;
double minTilt_;
double maxTilt_;
+ int tileSize_;
};
QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate()
@@ -70,7 +79,8 @@ QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate()
minZoom_(0.0),
maxZoom_(0.0),
minTilt_(0.0),
- maxTilt_(0.0) {}
+ maxTilt_(0.0),
+ tileSize_(256) {}
QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate(const QGeoCameraCapabilitiesPrivate &other)
@@ -82,7 +92,8 @@ QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate(const QGeoCameraCap
minZoom_(other.minZoom_),
maxZoom_(other.maxZoom_),
minTilt_(other.minTilt_),
- maxTilt_(other.maxTilt_) {}
+ maxTilt_(other.maxTilt_),
+ tileSize_(other.tileSize_) {}
QGeoCameraCapabilitiesPrivate::~QGeoCameraCapabilitiesPrivate() {}
@@ -99,6 +110,7 @@ QGeoCameraCapabilitiesPrivate &QGeoCameraCapabilitiesPrivate::operator = (const
maxZoom_ = other.maxZoom_;
minTilt_ = other.minTilt_;
maxTilt_ = other.maxTilt_;
+ tileSize_ = other.tileSize_;
return *this;
}
@@ -149,6 +161,18 @@ QGeoCameraCapabilities &QGeoCameraCapabilities::operator = (const QGeoCameraCapa
return *this;
}
+void QGeoCameraCapabilities::setTileSize(int tileSize)
+{
+ if (tileSize < 1)
+ return;
+ d->tileSize_ = tileSize;
+}
+
+int QGeoCameraCapabilities::tileSize() const
+{
+ return d->tileSize_;
+}
+
/*!
Returns whether this instance of the class is considered "valid". To be
valid, the instance must have had at least one capability set (to either
@@ -183,6 +207,13 @@ double QGeoCameraCapabilities::minimumZoomLevel() const
return d->minZoom_;
}
+double QGeoCameraCapabilities::minimumZoomLevelAt256() const
+{
+ if (d->tileSize_ == 256)
+ return d->minZoom_;
+ return zoomLevelTo256(d->minZoom_, d->tileSize_);
+}
+
/*!
Sets the maximum zoom level supported by the associated plugin to \a maximumZoomLevel.
@@ -206,6 +237,13 @@ double QGeoCameraCapabilities::maximumZoomLevel() const
return d->maxZoom_;
}
+double QGeoCameraCapabilities::maximumZoomLevelAt256() const
+{
+ if (d->tileSize_ == 256)
+ return d->maxZoom_;
+ return zoomLevelTo256(d->maxZoom_, d->tileSize_);
+}
+
/*!
Sets whether the associated plugin can render a map when the camera
has an arbitrary bearing to \a supportsBearing.
diff --git a/src/location/maps/qgeocameracapabilities_p.h b/src/location/maps/qgeocameracapabilities_p.h
index 4e498b1d..7de6ece0 100644
--- a/src/location/maps/qgeocameracapabilities_p.h
+++ b/src/location/maps/qgeocameracapabilities_p.h
@@ -65,11 +65,16 @@ public:
QGeoCameraCapabilities &operator = (const QGeoCameraCapabilities &other);
+ void setTileSize(int tileSize);
+ int tileSize() const;
+
void setMinimumZoomLevel(double minimumZoomLevel);
double minimumZoomLevel() const;
+ double minimumZoomLevelAt256() const;
void setMaximumZoomLevel(double maximumZoomLevel);
double maximumZoomLevel() const;
+ double maximumZoomLevelAt256() const;
void setSupportsBearing(bool supportsBearing);
bool supportsBearing() const;
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index f2c1d4d3..0916c7b7 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -49,6 +49,18 @@
QT_BEGIN_NAMESPACE
#define PREFETCH_FRUSTUM_SCALE 2.0
+static const double invLog2 = 1.0 / std::log(2.0);
+
+static double zoomLevelFrom256(double zoomLevelFor256, double tileSize)
+{
+ return std::log( std::pow(2.0, zoomLevelFor256) * 256.0 / tileSize ) * invLog2;
+}
+
+static double zoomLevelTo256(double zoomLevelForTileSize, double tileSize)
+{
+ return std::log( std::pow(2.0, zoomLevelForTileSize) * tileSize / 256.0 ) * invLog2;
+}
+
QGeoTiledMap::QGeoTiledMap(QGeoTiledMappingManagerEngine *engine, QObject *parent)
: QGeoMap(*new QGeoTiledMapPrivate(engine), parent)
{
@@ -150,13 +162,16 @@ void QGeoTiledMap::evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles)
}
// This method returns the minimum zoom level that this specific qgeomap type allows
-// at a given canvas size (width,height) and for a given tile size (usually 256).
+// at a given canvas size (width,height) and for the default tile size of 256^2
double QGeoTiledMap::minimumZoomAtViewportSize(int width, int height) const
{
Q_D(const QGeoTiledMap);
+ double tileSize = d->m_visibleTiles->tileSize();
double maxSize = qMax(width,height);
- double numTiles = maxSize / d->m_visibleTiles->tileSize();
- return std::log(numTiles) / std::log(2.0);
+ double numTiles = maxSize / tileSize;
+ if (tileSize == 256.0)
+ return std::log(numTiles) * invLog2;
+ return zoomLevelTo256(std::log(numTiles) * invLog2, tileSize);
}
// This method recalculates the "no-trespassing" limits for the map center.
@@ -275,10 +290,18 @@ void QGeoTiledMapPrivate::changeCameraData(const QGeoCameraData &cameraData)
{
Q_Q(QGeoTiledMap);
+ QGeoCameraData cam = cameraData;
+
+ // The incoming zoom level is intended for a tileSize of 256.
+ // Adapt it to the current tileSize
+ double zoomLevel = cameraData.zoomLevel();
+ if (m_visibleTiles->tileSize() != 256)
+ zoomLevel = zoomLevelFrom256(zoomLevel, m_visibleTiles->tileSize());
+ cam.setZoomLevel(zoomLevel);
+
// For zoomlevel, "snap" 0.01 either side of a whole number.
// This is so that when we turn off bilinear scaling, we're
// snapped to the exact pixel size of the tiles
- QGeoCameraData cam = cameraData;
int izl = static_cast<int>(std::floor(cam.zoomLevel()));
float delta = cam.zoomLevel() - izl;
@@ -286,6 +309,8 @@ void QGeoTiledMapPrivate::changeCameraData(const QGeoCameraData &cameraData)
izl++;
delta -= 1.0;
}
+
+ // TODO: Don't do this if there's tilt or bearing.
if (qAbs(delta) < 0.01) {
cam.setZoomLevel(izl);
}
diff --git a/tests/auto/declarative_ui/tst_map.qml b/tests/auto/declarative_ui/tst_map.qml
index a81885fb..998a06d4 100644
--- a/tests/auto/declarative_ui/tst_map.qml
+++ b/tests/auto/declarative_ui/tst_map.qml
@@ -79,6 +79,8 @@ Item {
Map {id: map; plugin: testPlugin; center: coordinate1; width: 100; height: 100}
SignalSpy {id: mapCenterSpy; target: map; signalName: 'centerChanged'}
+ Map {id: mapPar; plugin: testPlugin; center: coordinate1; width: 512; height: 512}
+
Map {id: coordinateMap; plugin: herePlugin; center: coordinate3;
width: 1000; height: 1000; zoomLevel: 15 }
@@ -135,46 +137,46 @@ Item {
function test_map_parameters()
{
// coordinate is set at map element declaration
- var center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ var center = mapPar.toCoordinate(Qt.point((mapPar.width - 1) / 2.0, (mapPar.height - 1) / 2.0))
fuzzyCompare(center.latitude, 10, 0.1)
fuzzyCompare(center.longitude, 11, 0.1)
- compare(map.mapParameters.length, 0)
+ compare(mapPar.mapParameters.length, 0)
- map.addMapParameter(testParameter)
+ mapPar.addMapParameter(testParameter)
- compare(map.mapParameters.length, 1)
+ compare(mapPar.mapParameters.length, 1)
- center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ center = mapPar.toCoordinate(Qt.point((mapPar.width - 1) / 2.0, (mapPar.height - 1) / 2.0))
fuzzyCompare(center.latitude, -33, 0.1)
fuzzyCompare(center.longitude, -47, 0.1)
- map.addMapParameter(testParameter)
- compare(map.mapParameters.length, 1)
+ mapPar.addMapParameter(testParameter)
+ compare(mapPar.mapParameters.length, 1)
- map.removeMapParameter(testParameter)
- compare(map.mapParameters.length, 0)
+ mapPar.removeMapParameter(testParameter)
+ compare(mapPar.mapParameters.length, 0)
- center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ center = mapPar.toCoordinate(Qt.point((mapPar.width - 1) / 2.0, (mapPar.height - 1) / 2.0))
fuzzyCompare(center.latitude, -33, 0.1)
fuzzyCompare(center.longitude, -47, 0.1)
- testParameter.center = map.center
- map.addMapParameter(testParameter)
- compare(map.mapParameters.length, 1)
+ testParameter.center = mapPar.center
+ mapPar.addMapParameter(testParameter)
+ compare(mapPar.mapParameters.length, 1)
- var center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ var center = mapPar.toCoordinate(Qt.point((mapPar.width - 1) / 2.0, (mapPar.height - 1) / 2.0))
fuzzyCompare(center.latitude, 10, 0.1)
fuzzyCompare(center.longitude, 11, 0.1)
testParameter.center = QtPositioning.coordinate(-33.0, -47.0)
- center = map.toCoordinate(Qt.point((map.width - 1) / 2.0, (map.height - 1) / 2.0))
+ center = mapPar.toCoordinate(Qt.point((mapPar.width - 1) / 2.0, (mapPar.height - 1) / 2.0))
fuzzyCompare(center.latitude, -33, 0.1)
fuzzyCompare(center.longitude, -47, 0.1)
- map.removeMapParameter(testParameter)
- compare(map.mapParameters.length, 0)
+ mapPar.removeMapParameter(testParameter)
+ compare(mapPar.mapParameters.length, 0)
}
function test_map_clamp()
diff --git a/tests/auto/qgeoserviceprovider/tst_qgeoserviceprovider.cpp b/tests/auto/qgeoserviceprovider/tst_qgeoserviceprovider.cpp
index 121253fa..6a9457fe 100644
--- a/tests/auto/qgeoserviceprovider/tst_qgeoserviceprovider.cpp
+++ b/tests/auto/qgeoserviceprovider/tst_qgeoserviceprovider.cpp
@@ -67,7 +67,7 @@ void tst_QGeoServiceProvider::tst_availableServiceProvider()
// Currently provided plugins
if (provider.count() != 8)
qWarning() << provider;
- QCOMPARE(provider.count(), 8);
+ QVERIFY(provider.count() >= 8);
// these providers are deployed
QVERIFY(provider.contains(QStringLiteral("mapbox")));
QVERIFY(provider.contains(QStringLiteral("here")));
diff --git a/tests/auto/qgeotiledmap/tst_qgeotiledmap.cpp b/tests/auto/qgeotiledmap/tst_qgeotiledmap.cpp
index e4ecfae9..22fb6589 100644
--- a/tests/auto/qgeotiledmap/tst_qgeotiledmap.cpp
+++ b/tests/auto/qgeotiledmap/tst_qgeotiledmap.cpp
@@ -101,7 +101,7 @@ void tst_QGeoTiledMap::initTestCase()
QStringLiteral("/../../../plugins"));
#endif
QVariantMap parameters;
- parameters["tileSize"] = 16;
+ parameters["tileSize"] = 256;
parameters["maxZoomLevel"] = 8;
parameters["finishRequestImmediately"] = true;
QGeoServiceProvider *provider = new QGeoServiceProvider("qmlgeo.test.plugin",parameters);
@@ -110,7 +110,7 @@ void tst_QGeoTiledMap::initTestCase()
QVERIFY2(provider->error() == QGeoServiceProvider::NoError, "Could not load plugin: " + provider->errorString().toLatin1());
m_map.reset(static_cast<QGeoTiledMapTest*>(mappingManager->createMap(this)));
QVERIFY(m_map);
- m_map->setViewportSize(QSize(16, 16));
+ m_map->setViewportSize(QSize(256, 256));
m_fetcher = static_cast<QGeoTileFetcherTest*>(m_map->m_engine->tileFetcher());
m_tilesCounter.reset(new FetchTileCounter());
connect(m_fetcher, SIGNAL(tileFetched(const QGeoTileSpec&)), m_tilesCounter.data(), SLOT(tileFetched(const QGeoTileSpec&)));