summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@theqtcompany.com>2016-02-01 10:45:24 +0100
committerPaolo Angelelli <paolo.angelelli@theqtcompany.com>2016-03-02 14:41:22 +0000
commit820f79284248e5fcc9910282055e67f07c918559 (patch)
tree8bdfb0b283f463b13453c04c5a28f6734cf568f5
parent3a079a1e6761f3a26223e360d22530f22b5aeade (diff)
downloadqtlocation-820f79284248e5fcc9910282055e67f07c918559.tar.gz
Adjustment for the minimum zoom level to prevent gray bands
This patch introduces a lower bound for the minimum zoom level of a map element so that it becomes canvas size dependent, and it will also prevent the map from being smaller than the canvas size in either dimension, avoiding gray bands. It also bounds the center of the map so that the map cannot be panned or flicked out of bounds. The documentation for QDeclarativeGeoMap::minimumZoomLevel has been modified to reflect the new behavior. A few testcases have been modified to reflect this new behavior and its implications. Change-Id: I3c8160d0295e8dda2f7001e8fec68a5200ea2172 Reviewed-by: Michal Klocek <michal.klocek@theqtcompany.com>
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp86
-rw-r--r--src/imports/location/qquickgeomapgesturearea.cpp4
-rw-r--r--src/location/maps/qgeomap.cpp9
-rw-r--r--src/location/maps/qgeomap_p.h5
-rw-r--r--src/location/maps/qgeomap_p_p.h1
-rw-r--r--src/location/maps/qgeomappingmanagerengine.cpp4
-rw-r--r--src/location/maps/qgeomappingmanagerengine_p.h2
-rw-r--r--src/location/maps/qgeotiledmap.cpp105
-rw-r--r--src/location/maps/qgeotiledmap_p.h1
-rw-r--r--src/location/maps/qgeotiledmap_p_p.h2
-rw-r--r--tests/auto/declarative_ui/tst_map.qml34
-rw-r--r--tests/auto/declarative_ui/tst_map_mouse.qml2
-rw-r--r--tests/auto/qgeomapcontroller/tst_qgeomapcontroller.cpp40
13 files changed, 213 insertions, 82 deletions
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index 8fbe6e32..591bcd7f 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -475,12 +475,30 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
m_map = m_mappingManager->createMap(this);
m_gestureArea->setMap(m_map);
- // once mappingManagerInitilized_ is set zoomLevel() returns the default initialised
- // zoom level of the map controller. Overwrite it here to whatever the user chose.
+ m_map->setActiveMapType(QGeoMapType());
+ QList<QGeoMapType> types = m_mappingManager->supportedMapTypes();
+ for (int i = 0; i < types.size(); ++i) {
+ QDeclarativeGeoMapType *type = new QDeclarativeGeoMapType(types[i], this);
+ m_supportedMapTypes.append(type);
+ }
+
+ if (!m_supportedMapTypes.isEmpty()) {
+ QDeclarativeGeoMapType *type = m_supportedMapTypes.at(0);
+ m_activeMapType = type;
+ m_map->setActiveMapType(type->mapType());
+ }
+
+ // Map tiles are built in this call. m_map->minimumZoom() becomes operational
+ // after this has been called at least once, after creation.
+ m_map->resize(width(), height());
+
+ // once mappingManagerInitilized_ is set, zoomLevel() returns the default initialised
+ // zoom level of the map (controller). Overwrite it here to whatever the user chose.
m_map->mapController()->setZoom(m_zoomLevel);
//The zoom level limits are only restricted by the plugins values, if the user has set a more
//strict zoom level limit before initialization nothing is done here.
+ //minimum zoom level might be changed to limit gray bundaries
if (m_mappingManager->cameraCapabilities().minimumZoomLevel() > m_gestureArea->minimumZoomLevel())
setMinimumZoomLevel(m_mappingManager->cameraCapabilities().minimumZoomLevel());
@@ -488,7 +506,8 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
|| m_mappingManager->cameraCapabilities().maximumZoomLevel() < m_gestureArea->maximumZoomLevel())
setMaximumZoomLevel(m_mappingManager->cameraCapabilities().maximumZoomLevel());
- m_map->setActiveMapType(QGeoMapType());
+ // Finally, set the center too
+ m_map->mapController()->setCenter(m_center);
m_copyrights = new QDeclarativeGeoMapCopyrightNotice(this);
connect(m_map, SIGNAL(copyrightsChanged(QImage)),
@@ -515,28 +534,13 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
// set visibility of copyright notice
m_copyrights->setCopyrightsVisible(m_copyrightsVisible);
- m_map->mapController()->setCenter(m_center);
-
- QList<QGeoMapType> types = m_mappingManager->supportedMapTypes();
- for (int i = 0; i < types.size(); ++i) {
- QDeclarativeGeoMapType *type = new QDeclarativeGeoMapType(types[i], this);
- m_supportedMapTypes.append(type);
- }
-
- if (!m_supportedMapTypes.isEmpty()) {
- QDeclarativeGeoMapType *type = m_supportedMapTypes.at(0);
- m_activeMapType = type;
- m_map->setActiveMapType(type->mapType());
- }
-
- // Map tiles are built in this call
- m_map->resize(width(), height());
// This prefetches a buffer around the map
m_map->prefetchData();
m_map->update();
emit minimumZoomLevelChanged();
emit maximumZoomLevelChanged();
+ emit zoomLevelChanged(m_zoomLevel);
emit supportedMapTypesChanged();
emit activeMapTypeChanged();
@@ -560,17 +564,22 @@ QDeclarativeGeoServiceProvider *QDeclarativeGeoMap::plugin() const
\internal
Sets the gesture areas minimum zoom level. If the camera capabilities
has been set this method honors the boundaries set by it.
+ The minimum zoom level will also have a lower bound dependent on the size
+ of the canvas, effectively preventing to display out of bounds areas.
*/
void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel)
{
if (m_gestureArea && minimumZoomLevel >= 0) {
qreal oldMinimumZoomLevel = this->minimumZoomLevel();
- if (m_mappingManagerInitialized
- && minimumZoomLevel < m_mappingManager->cameraCapabilities().minimumZoomLevel()) {
- minimumZoomLevel = m_mappingManager->cameraCapabilities().minimumZoomLevel();
+ if (m_mappingManagerInitialized) {
+ minimumZoomLevel = qBound(m_map->minimumZoom(),minimumZoomLevel,m_mappingManager->cameraCapabilities().maximumZoomLevel());
}
+
m_gestureArea->setMinimumZoomLevel(minimumZoomLevel);
- setZoomLevel(qBound<qreal>(minimumZoomLevel, zoomLevel(), maximumZoomLevel()));
+
+ if (zoomLevel() < minimumZoomLevel)
+ setZoomLevel(minimumZoomLevel);
+
if (oldMinimumZoomLevel != minimumZoomLevel)
emit minimumZoomLevelChanged();
}
@@ -581,7 +590,12 @@ void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel)
This property holds the minimum valid zoom level for the map.
- The minimum zoom level is defined by the \l plugin used.
+ The minimum zoom level defined by the \l plugin used is a lower bound for
+ this property. However, the returned value is also canvas-size-dependent, and
+ can be higher than the user-specified value, or than the minimum zoom level
+ defined by the plugin used, to prevent the map from being smaller than the
+ viewport in either dimension.
+
If a plugin supporting mapping is not set, -1.0 is returned.
*/
@@ -604,12 +618,15 @@ void QDeclarativeGeoMap::setMaximumZoomLevel(qreal maximumZoomLevel)
{
if (m_gestureArea && maximumZoomLevel >= 0) {
qreal oldMaximumZoomLevel = this->maximumZoomLevel();
- if (m_mappingManagerInitialized
- && maximumZoomLevel > m_mappingManager->cameraCapabilities().maximumZoomLevel()) {
- maximumZoomLevel = m_mappingManager->cameraCapabilities().maximumZoomLevel();
+ if (m_mappingManagerInitialized) {
+ maximumZoomLevel = qBound(m_map->minimumZoom(),maximumZoomLevel,m_mappingManager->cameraCapabilities().maximumZoomLevel());
}
+
m_gestureArea->setMaximumZoomLevel(maximumZoomLevel);
- setZoomLevel(qBound<qreal>(minimumZoomLevel(), zoomLevel(), maximumZoomLevel));
+
+ if (zoomLevel() > maximumZoomLevel)
+ setZoomLevel(maximumZoomLevel);
+
if (oldMaximumZoomLevel != maximumZoomLevel)
emit maximumZoomLevelChanged();
}
@@ -647,13 +664,12 @@ void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel)
if (m_zoomLevel == zoomLevel || zoomLevel < 0)
return;
- if ((zoomLevel < minimumZoomLevel()
- || (maximumZoomLevel() >= 0 && zoomLevel > maximumZoomLevel())))
- return;
-
- m_zoomLevel = zoomLevel;
- if (m_mappingManagerInitialized)
+ if (m_mappingManagerInitialized) {
+ m_zoomLevel = qBound(minimumZoomLevel(), zoomLevel, maximumZoomLevel());
m_map->mapController()->setZoom(m_zoomLevel);
+ } else {
+ m_zoomLevel = zoomLevel;
+ }
emit zoomLevelChanged(zoomLevel);
}
@@ -1207,6 +1223,8 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF
return;
m_map->resize(newGeometry.width(), newGeometry.height());
+ //Them minimum allowed zoom level to limit gray bundaries might have changed
+ setMinimumZoomLevel(m_map->minimumZoom());
QQuickItem::geometryChanged(newGeometry, oldGeometry);
/*!
diff --git a/src/imports/location/qquickgeomapgesturearea.cpp b/src/imports/location/qquickgeomapgesturearea.cpp
index 9bb8068b..938d2170 100644
--- a/src/imports/location/qquickgeomapgesturearea.cpp
+++ b/src/imports/location/qquickgeomapgesturearea.cpp
@@ -690,8 +690,8 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event)
QGeoCoordinate wheelGeoPos = m_map->itemPositionToCoordinate(QDoubleVector2D(event->posF()), false);
QPointF preZoomPoint = m_map->coordinateToItemPosition(wheelGeoPos, false).toPointF();
- m_declarativeMap->setZoomLevel(qBound(minimumZoomLevel(), m_declarativeMap->zoomLevel() + event->angleDelta().y() * qreal(0.001), maximumZoomLevel()));
-
+ double zoomLevelDelta = event->angleDelta().y() * qreal(0.001);
+ m_declarativeMap->setZoomLevel(m_declarativeMap->zoomLevel() + zoomLevelDelta);
QPointF postZoomPoint = m_map->coordinateToItemPosition(wheelGeoPos, false).toPointF();
if (preZoomPoint != postZoomPoint)
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index 37bf139a..4cc2bbfe 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -119,7 +119,13 @@ const QGeoMapType QGeoMap::activeMapType() const
return d->m_activeMapType;
}
-QGeoCameraCapabilities QGeoMap::cameraCapabilities()
+double QGeoMap::minimumZoom() const
+{
+ Q_D(const QGeoMap);
+ return d->m_minimumZoom;
+}
+
+QGeoCameraCapabilities QGeoMap::cameraCapabilities() const
{
Q_D(const QGeoMap);
if (!d->m_engine.isNull())
@@ -143,6 +149,7 @@ QGeoMapPrivate::QGeoMapPrivate(QGeoMappingManagerEngine *engine)
m_width(0),
m_height(0),
m_aspectRatio(0.0),
+ m_minimumZoom(0.0),
m_engine(engine),
m_controller(0),
m_activeMapType(QGeoMapType())
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index acc928ea..7747347f 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -83,11 +83,10 @@ public:
virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const = 0;
virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const = 0;
+ double minimumZoom() const;
virtual void prefetchData();
virtual void clearData();
-
- QGeoCameraCapabilities cameraCapabilities();
-
+ QGeoCameraCapabilities cameraCapabilities() const;
protected:
QGeoMap(QGeoMapPrivate &dd, QObject *parent = 0);
diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h
index 3b996ecc..1d1c9a13 100644
--- a/src/location/maps/qgeomap_p_p.h
+++ b/src/location/maps/qgeomap_p_p.h
@@ -77,6 +77,7 @@ protected:
int m_width;
int m_height;
double m_aspectRatio;
+ double m_minimumZoom;
QPointer<QGeoMappingManagerEngine> m_engine;
QGeoMapController *m_controller;
QGeoCameraData m_cameraData;
diff --git a/src/location/maps/qgeomappingmanagerengine.cpp b/src/location/maps/qgeomappingmanagerengine.cpp
index 70b1e836..91eecf39 100644
--- a/src/location/maps/qgeomappingmanagerengine.cpp
+++ b/src/location/maps/qgeomappingmanagerengine.cpp
@@ -149,9 +149,9 @@ void QGeoMappingManagerEngine::setSupportedMapTypes(const QList<QGeoMapType> &su
d->supportedMapTypes = supportedMapTypes;
}
-QGeoCameraCapabilities QGeoMappingManagerEngine::cameraCapabilities()
+QGeoCameraCapabilities QGeoMappingManagerEngine::cameraCapabilities() const
{
- Q_D(QGeoMappingManagerEngine);
+ Q_D(const QGeoMappingManagerEngine);
return d->capabilities_;
}
diff --git a/src/location/maps/qgeomappingmanagerengine_p.h b/src/location/maps/qgeomappingmanagerengine_p.h
index 7e866d89..4496e7bd 100644
--- a/src/location/maps/qgeomappingmanagerengine_p.h
+++ b/src/location/maps/qgeomappingmanagerengine_p.h
@@ -89,7 +89,7 @@ public:
QList<QGeoMapType> supportedMapTypes() const;
- QGeoCameraCapabilities cameraCapabilities();
+ QGeoCameraCapabilities cameraCapabilities() const;
void setLocale(const QLocale &locale);
QLocale locale() const;
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index 7ca1a5ff..6e9930f4 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -103,6 +103,19 @@ QSGNode *QGeoTiledMap::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
return d->updateSceneGraph(oldNode, window);
}
+// 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).
+double QGeoTiledMap::minimumZoomLevel(int width, int height, int tileSize) const
+{
+ double maxSize = qMax(width,height);
+ double numTiles = maxSize / tileSize;
+ double minZoom = std::log(numTiles) / std::log(2.0);
+ const QGeoCameraCapabilities capa = cameraCapabilities();
+ if (capa.isValid())
+ minZoom = qMax(minZoom, capa.minimumZoomLevel());
+ return minZoom;
+}
+
void QGeoTiledMap::prefetchData()
{
Q_D(QGeoTiledMap);
@@ -153,8 +166,9 @@ QDoubleVector2D QGeoTiledMap::coordinateToItemPosition(const QGeoCoordinate &coo
if (clipToViewport) {
int w = width();
int h = height();
-
- if ((pos.x() < 0) || (w < pos.x()) || (pos.y() < 0) || (h < pos.y()))
+ double x = pos.x();
+ double y = pos.y();
+ if ((x < 0.0) || (x > w) || (y < 0) || (y > h) || qIsNaN(x) || qIsNaN(y))
return QDoubleVector2D(qQNaN(), qQNaN());
}
@@ -170,7 +184,8 @@ QGeoTiledMapPrivate::QGeoTiledMapPrivate(QGeoTiledMappingManagerEngine *engine)
m_tileRequests(0),
m_maxZoomLevel(static_cast<int>(std::ceil(engine->cameraCapabilities().maximumZoomLevel()))),
m_minZoomLevel(static_cast<int>(std::ceil(engine->cameraCapabilities().minimumZoomLevel()))),
- m_prefetchStyle(QGeoTiledMap::PrefetchTwoNeighbourLayers)
+ m_prefetchStyle(QGeoTiledMap::PrefetchTwoNeighbourLayers),
+ m_centerLatitudinalBound(0.0)
{
int tileSize = engine->tileSize().width();
QString pluginString(engine->managerName() + QLatin1Char('_') + QString::number(engine->managerVersion()));
@@ -249,31 +264,40 @@ void QGeoTiledMapPrivate::prefetchTiles()
void QGeoTiledMapPrivate::changeCameraData(const QGeoCameraData &oldCameraData)
{
- Q_Q(QGeoTiledMap);
- double lat = oldCameraData.center().latitude();
-
- if (m_mapScene->verticalLock()) {
- QGeoCoordinate coord = q->cameraData().center();
- coord.setLatitude(lat);
- q->cameraData().setCenter(coord);
- }
-
- // For zoomlevel, "snap" 0.05 either side of a whole number.
+ // 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 = q->cameraData();
- int izl = static_cast<int>(std::floor(cam.zoomLevel()));
- float delta = cam.zoomLevel() - izl;
+ int izl = static_cast<int>(std::floor(m_cameraData.zoomLevel()));
+ float delta = m_cameraData.zoomLevel() - izl;
if (delta > 0.5) {
izl++;
delta -= 1.0;
}
- if (qAbs(delta) < 0.05) {
- cam.setZoomLevel(izl);
+ if (qAbs(delta) < 0.01) {
+ m_cameraData.setZoomLevel(izl);
+ }
+
+ double oldZoomLevel = oldCameraData.zoomLevel();
+ if (m_cameraData.zoomLevel() != oldZoomLevel) {
+ // Zoom level changed: recompute latitudinal border for the center
+ updateCenterLatitudinalBound(m_visibleTiles->tileSize(),m_cameraData.zoomLevel());
+ }
+
+ QGeoCoordinate coord = m_cameraData.center();
+ if (coord.isValid()) {
+ double lat = coord.latitude();
+ if (m_mapScene->verticalLock())
+ lat = oldCameraData.center().latitude();
+
+ // Clamp center latitude to prevent gray borders
+ lat = qBound(-m_centerLatitudinalBound, lat, m_centerLatitudinalBound);
+ coord.setLatitude(lat);
}
+ m_cameraData.setCenter(coord);
+
+ m_visibleTiles->setCameraData(m_cameraData);
+ m_mapScene->setCameraData(m_cameraData);
- m_visibleTiles->setCameraData(cam);
- m_mapScene->setCameraData(cam);
updateScene();
}
@@ -300,6 +324,27 @@ void QGeoTiledMapPrivate::updateScene()
q->update();
}
+// This method recalculates the "no-trespassing" limits for the map center.
+// This has to be done when:
+// 1) the map is resized, because the meters per pixel remain the same, but
+// the amount of pixels between the center and the borders changes
+// 2) when the zoom level changes, because the amount of pixels between the center
+// and the borders stays the same, but the meters per pixel change
+void QGeoTiledMapPrivate::updateCenterLatitudinalBound(int tileSize, double zoomLevel)
+{
+ double mapEdgeSize = std::pow(2.0,zoomLevel);
+ mapEdgeSize *= tileSize;
+
+ // At init time weird things happen
+ int clampedWindowHeight = (m_height > mapEdgeSize) ? mapEdgeSize : m_height;
+
+ // Use the window height divided by 2 as the topmost allowed center, with respect to the map size in pixels
+ double mercatorTopmost = (clampedWindowHeight * 0.5) / mapEdgeSize ;
+ QGeoCoordinate topMost = QGeoProjection::mercatorToCoord(QDoubleVector2D(0.0,mercatorTopmost));
+
+ m_centerLatitudinalBound = topMost.latitude();
+}
+
void QGeoTiledMapPrivate::changeActiveMapType(const QGeoMapType mapType)
{
m_visibleTiles->setMapType(mapType);
@@ -316,11 +361,25 @@ void QGeoTiledMapPrivate::changeTileVersion(int version)
void QGeoTiledMapPrivate::mapResized(int width, int height)
{
Q_Q(QGeoTiledMap);
+
+ m_mapScene->setScreenSize(QSize(width, height));
m_visibleTiles->setScreenSize(QSize(width, height));
m_prefetchTiles->setScreenSize(QSize(width, height));
- m_mapScene->setScreenSize(QSize(width, height));
- if (q)
- q->setCameraData(q->cameraData());
+ // Keep the following step order:
+ // 1) Update the minimum zoom level
+ m_minimumZoom = q->minimumZoomLevel(width, height, m_visibleTiles->tileSize());
+
+ // 2) clamp the current zoom level in the camera data, which will have to be
+ // propagated in the QDeclarativeGeoMap
+ QGeoCameraData camData = q->cameraData();
+ double zoomLevel = camData.zoomLevel();
+ zoomLevel = qMax(m_minimumZoom,zoomLevel); // The correct zoom level. Will be set later
+
+ // 3) Since the map size changed, recompute latitudinal bound for the center.
+ // This is re-done, despite being already in changeCameraData, because
+ // changeCameraData triggers it only on zoomLevel changed, which might not
+ // be the case.
+ updateCenterLatitudinalBound(m_visibleTiles->tileSize(), zoomLevel);
if (width > 0 && height > 0 && m_cache) {
// absolute minimum size: one tile each side of display, 32-bit colour
diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h
index 9e1d1596..051264ff 100644
--- a/src/location/maps/qgeotiledmap_p.h
+++ b/src/location/maps/qgeotiledmap_p.h
@@ -92,6 +92,7 @@ public:
protected:
QSGNode *updateSceneGraph(QSGNode *, QQuickWindow *window) Q_DECL_OVERRIDE;
virtual void evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles);
+ double minimumZoomLevel(int width, int height, int tileSize) const;
private Q_SLOTS:
void handleTileVersionChanged();
diff --git a/src/location/maps/qgeotiledmap_p_p.h b/src/location/maps/qgeotiledmap_p_p.h
index 6f8be328..05ada7b9 100644
--- a/src/location/maps/qgeotiledmap_p_p.h
+++ b/src/location/maps/qgeotiledmap_p_p.h
@@ -90,6 +90,7 @@ protected:
private:
void updateScene();
+ void updateCenterLatitudinalBound(int tileSize, double zoomLevel);
private:
QAbstractGeoTileCache *m_cache;
@@ -100,6 +101,7 @@ private:
int m_maxZoomLevel;
int m_minZoomLevel;
QGeoTiledMap::PrefetchStyle m_prefetchStyle;
+ double m_centerLatitudinalBound;
Q_DISABLE_COPY(QGeoTiledMapPrivate)
};
diff --git a/tests/auto/declarative_ui/tst_map.qml b/tests/auto/declarative_ui/tst_map.qml
index 202fc958..c6620635 100644
--- a/tests/auto/declarative_ui/tst_map.qml
+++ b/tests/auto/declarative_ui/tst_map.qml
@@ -60,16 +60,30 @@ Item {
Map { id: mapZoomOnCompleted; width: 200; height: 200;
zoomLevel: 3; center: coordinate1; plugin: testPlugin;
- Component.onCompleted: { zoomLevel = 7 } }
+ Component.onCompleted: {
+ zoomLevel = 7
+ }
+ }
+ SignalSpy {id: mapZoomSpy; target: mapZoomOnCompleted; signalName: 'zoomLevelChanged'}
+
Map { id: mapZoomDefault; width: 200; height: 200;
center: coordinate1; plugin: testPlugin; }
- Map { id: mapZoomUserInit; width: 200; height: 200;
- zoomLevel: 4; center: coordinate1; plugin: testPlugin; }
- Map {id: map; plugin: testPlugin; center: coordinate1; width: 100; height: 100}
- Map {id: coordinateMap; plugin: herePlugin; center: coordinate3; width: 1000; height: 1000; zoomLevel: 15}
+ Map { id: mapZoomUserInit; width: 210; height: 210;
+ zoomLevel: 4; center: coordinate1; plugin: testPlugin;
+ Component.onCompleted: {
+ console.log("mapZoomUserInit completed")
+ }
+ }
+
+ Map {id: map; plugin: testPlugin; center: coordinate1; width: 100; height: 100}
SignalSpy {id: mapCenterSpy; target: map; signalName: 'centerChanged'}
- SignalSpy {id: mapZoomSpy; target: mapZoomOnCompleted; signalName: 'zoomLevelChanged'}
+
+ Map {id: coordinateMap; plugin: herePlugin; center: coordinate3;
+ width: 1000; height: 1000; zoomLevel: 15 }
+
+
+
TestCase {
when: windowShown
@@ -156,7 +170,7 @@ Item {
function test_zoom()
{
- wait(100)
+ wait(1000)
compare(mapZoomOnCompleted.zoomLevel, 7)
compare(mapZoomDefault.zoomLevel, 8)
compare(mapZoomUserInit.zoomLevel, 4)
@@ -164,7 +178,6 @@ Item {
mapZoomSpy.clear()
mapZoomOnCompleted.zoomLevel = 6
tryCompare(mapZoomSpy, "count", 1)
-
}
function test_pan()
@@ -264,10 +277,13 @@ Item {
point = coordinateMap.fromCoordinate(altitudelessCoordinate)
verify (point.x > 495 && point.x < 505)
verify (point.y > 495 && point.y < 505)
- // out of map area
+ // out of map area in view
+ //var oldZoomLevel = coordinateMap.zoomLevel
+ //coordinateMap.zoomLevel = 8
point = coordinateMap.fromCoordinate(coordinate4)
verify(isNaN(point.x))
verify(isNaN(point.y))
+ //coordinateMap.zoomLevel = oldZoomLevel
// invalid coordinates
point = coordinateMap.fromCoordinate(invalidCoordinate)
verify(isNaN(point.x))
diff --git a/tests/auto/declarative_ui/tst_map_mouse.qml b/tests/auto/declarative_ui/tst_map_mouse.qml
index 92603233..99aff03d 100644
--- a/tests/auto/declarative_ui/tst_map_mouse.qml
+++ b/tests/auto/declarative_ui/tst_map_mouse.qml
@@ -288,7 +288,7 @@ Item {
clear_data()
wait(500);
// on map but without mouse area
- var startZoomLevel = 6
+ var startZoomLevel = 6.20
map.zoomLevel = startZoomLevel
mouseWheel(map, 5, 5, 15, 5, Qt.LeftButton, Qt.NoModifiers)
//see QDeclarativeGeoMapGestureArea::handleWheelEvent
diff --git a/tests/auto/qgeomapcontroller/tst_qgeomapcontroller.cpp b/tests/auto/qgeomapcontroller/tst_qgeomapcontroller.cpp
index cc1b4e4a..a5650e42 100644
--- a/tests/auto/qgeomapcontroller/tst_qgeomapcontroller.cpp
+++ b/tests/auto/qgeomapcontroller/tst_qgeomapcontroller.cpp
@@ -34,7 +34,7 @@
#include <QtLocation/private/qgeomappingmanager_p.h>
#include <QtLocation/private/qgeomapcontroller_p.h>
#include <QtLocation/private/qgeocameracapabilities_p.h>
-
+#include <cmath> /* for std::abs(double) */
QT_USE_NAMESPACE
@@ -135,18 +135,29 @@ void tst_QGeoMapController::signalsConstructedTest()
void tst_QGeoMapController::constructorTest_data()
{
QTest::addColumn<QGeoCoordinate>("center");
+ QTest::addColumn<QGeoCoordinate>("expectedCenter");
QTest::addColumn<double>("bearing");
QTest::addColumn<double>("tilt");
QTest::addColumn<double>("roll");
QTest::addColumn<double>("zoom");
- QTest::newRow("zeros") << QGeoCoordinate() << 0.0 << 0.0 << 0.0 << 0.0;
- QTest::newRow("valid") << QGeoCoordinate(10.0, 20.5, 30.8) << 0.1 << 0.2 << 0.3 << 2.0;
- QTest::newRow("negative values") << QGeoCoordinate(-50, -20, 100) << -0.1 << -0.2 << -0.3 << 1.0;
+ QTest::newRow("zeros") << QGeoCoordinate() << QGeoCoordinate() << 0.0 << 0.0 << 0.0 << 0.0;
+ QTest::newRow("valid") << QGeoCoordinate(10.0, 20.5, 30.8) << QGeoCoordinate(10.0, 20.5, 30.8) << 0.1 << 0.2 << 0.3 << 2.0;
+ QTest::newRow("negative values") << QGeoCoordinate(-50, -20, 100) << QGeoCoordinate(-50, -20, 100) << -0.1 << -0.2 << -0.3 << 1.0;
+ QTest::newRow("clamped center negative") << QGeoCoordinate(-89, -45, 0) << QGeoCoordinate(-80.8728, -45, 0) << -0.1 << -0.2 << -0.3 << 1.0;
+ QTest::newRow("clamped center positive") << QGeoCoordinate(86, 38, 0) << QGeoCoordinate(80.8728, 38, 0) << -0.1 << -0.2 << -0.3 << 1.0;
+}
+
+bool almostEqual(float x, float y) // qFuzzyCompare is too strict for this test
+{
+ const float epsilon = 1e-5;
+ return std::abs(x - y) <= epsilon * std::abs(x);
+ // see Knuth section 4.2.2 pages 217-218
}
void tst_QGeoMapController::constructorTest()
{
QFETCH(QGeoCoordinate, center);
+ QFETCH(QGeoCoordinate, expectedCenter);
QFETCH(double, bearing);
QFETCH(double, tilt);
QFETCH(double, roll);
@@ -163,10 +174,27 @@ void tst_QGeoMapController::constructorTest()
m_map->setCameraData(cameraData);
QGeoMapController mapController(m_map.data());
+
// make sure the values come out the same
// also make sure the values match what they were actually set to
- QCOMPARE(mapController.center(), cameraData.center());
- QCOMPARE(mapController.center(), center);
+ if (qIsNaN(cameraData.center().longitude())) {
+ QVERIFY(qIsNaN(mapController.center().longitude()));
+ } else {
+ QCOMPARE(mapController.center().longitude(), expectedCenter.longitude());
+ }
+ if (qIsNaN(cameraData.center().altitude())) {
+ QVERIFY(qIsNaN(mapController.center().altitude()));
+ } else {
+ QCOMPARE(mapController.center().altitude(), expectedCenter.altitude());
+ }
+
+ // Verify that the latitude is either what was set or that it has been clamped correctly
+ if (qIsNaN(cameraData.center().latitude())) {
+ QVERIFY(qIsNaN(mapController.center().latitude()));
+ } else {
+ QVERIFY(almostEqual(mapController.center().latitude(), expectedCenter.latitude()));
+ }
+
QCOMPARE(mapController.zoom(), cameraData.zoomLevel());
QCOMPARE(mapController.zoom(), zoom);