diff options
-rw-r--r-- | src/location/declarativemaps/qdeclarativegeomap.cpp | 23 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection.cpp | 20 | ||||
-rw-r--r-- | src/positioning/qlocationutils_p.h | 2 | ||||
-rw-r--r-- | tests/auto/declarative_ui/tst_map.qml | 41 |
4 files changed, 70 insertions, 16 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp index 90ae2b34..dedb590e 100644 --- a/src/location/declarativemaps/qdeclarativegeomap.cpp +++ b/src/location/declarativemaps/qdeclarativegeomap.cpp @@ -1323,20 +1323,21 @@ QGeoShape QDeclarativeGeoMap::visibleRegion() const const QList<QDoubleVector2D> &visibleRegion = m_map->geoProjection().visibleRegion(); QGeoPath path; - for (const QDoubleVector2D &c: visibleRegion) + for (int i = 0; i < visibleRegion.size(); ++i) { + const QDoubleVector2D &c = visibleRegion.at(i); + // If a segment spans more than half of the map longitudinally, split in 2. + if (i && qAbs(visibleRegion.at(i-1).x() - c.x()) >= 0.5) { // This assumes a segment is never >= 1.0 (whole map span) + QDoubleVector2D extraPoint = (visibleRegion.at(i-1) + c) * 0.5; + path.addCoordinate(m_map->geoProjection().wrappedMapProjectionToGeo(extraPoint)); + } path.addCoordinate(m_map->geoProjection().wrappedMapProjectionToGeo(c)); - - QGeoRectangle vr = path.boundingGeoRectangle(); - - bool empty = vr.topLeft().latitude() == vr.bottomRight().latitude() || - qFuzzyCompare(vr.topLeft().longitude(), vr.bottomRight().longitude()); // QTBUG-57690 - - if (empty) { - vr.setTopLeft(QGeoCoordinate(vr.topLeft().latitude(), -180)); - vr.setBottomRight(QGeoCoordinate(vr.bottomRight().latitude(), 180)); + } + if (visibleRegion.size() >= 2 && qAbs(visibleRegion.last().x() - visibleRegion.first().x()) >= 0.5) { + QDoubleVector2D extraPoint = (visibleRegion.last() + visibleRegion.first()) * 0.5; + path.addCoordinate(m_map->geoProjection().wrappedMapProjectionToGeo(extraPoint)); } - return vr; + return path.boundingGeoRectangle(); } /*! diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp index 609fb934..013a8c33 100644 --- a/src/location/maps/qgeoprojection.cpp +++ b/src/location/maps/qgeoprojection.cpp @@ -491,11 +491,17 @@ void QGeoProjectionWebMercator::updateVisibleRegion() QDoubleVector2D bl = viewportToWrappedMapProjection(QDoubleVector2D(-1, 1 )); QDoubleVector2D br = viewportToWrappedMapProjection(QDoubleVector2D( 1, 1 )); + // To make sure that what is returned can be safely converted back to lat/lon without risking overlaps + double mapLeftLongitude = QLocationUtils::mapLeftLongitude(m_cameraData.center().longitude()); + double mapRightLongitude = QLocationUtils::mapRightLongitude(m_cameraData.center().longitude()); + double leftX = geoToWrappedMapProjection(QGeoCoordinate(0, mapLeftLongitude)).x(); + double rightX = geoToWrappedMapProjection(QGeoCoordinate(0, mapRightLongitude)).x(); + QList<QDoubleVector2D> mapRect; - mapRect.push_back(QDoubleVector2D(-1.0, 1.0)); - mapRect.push_back(QDoubleVector2D( 2.0, 1.0)); - mapRect.push_back(QDoubleVector2D( 2.0, 0.0)); - mapRect.push_back(QDoubleVector2D(-1.0, 0.0)); + mapRect.push_back(QDoubleVector2D(leftX, 1.0)); + mapRect.push_back(QDoubleVector2D(rightX, 1.0)); + mapRect.push_back(QDoubleVector2D(rightX, 0.0)); + mapRect.push_back(QDoubleVector2D(leftX, 0.0)); QList<QDoubleVector2D> viewportRect; viewportRect.push_back(bl); @@ -514,6 +520,12 @@ void QGeoProjectionWebMercator::updateVisibleRegion() m_visibleRegion = QClipperUtils::pathToQList(res[0]); // Intersection between two convex quadrilaterals should always be a single polygon m_projectableRegion.clear(); + mapRect.clear(); + // The full map rectangle in extended mercator space + mapRect.push_back(QDoubleVector2D(-1.0, 1.0)); + mapRect.push_back(QDoubleVector2D( 2.0, 1.0)); + mapRect.push_back(QDoubleVector2D( 2.0, 0.0)); + mapRect.push_back(QDoubleVector2D(-1.0, 0.0)); if (m_cameraData.tilt() == 0) { m_projectableRegion = mapRect; } else { diff --git a/src/positioning/qlocationutils_p.h b/src/positioning/qlocationutils_p.h index 75c4b7f4..69cf0fee 100644 --- a/src/positioning/qlocationutils_p.h +++ b/src/positioning/qlocationutils_p.h @@ -55,7 +55,7 @@ #include <qmath.h> #include <QtPositioning/QGeoCoordinate> -static const double offsetEpsilon = 0.0000000000001; +static const double offsetEpsilon = 1e-12; // = 0.000000000001 static const double leftOffset = -180.0 + offsetEpsilon; static const double rightOffset = 180.0 - offsetEpsilon; diff --git a/tests/auto/declarative_ui/tst_map.qml b/tests/auto/declarative_ui/tst_map.qml index 846a621f..408bf96e 100644 --- a/tests/auto/declarative_ui/tst_map.qml +++ b/tests/auto/declarative_ui/tst_map.qml @@ -30,6 +30,7 @@ import QtQuick 2.0 import QtTest 1.0 import QtPositioning 5.5 import QtLocation 5.9 +import QtLocation.Test 5.6 Item { width:100 @@ -55,6 +56,10 @@ Item { property variant coordinate3: QtPositioning.coordinate(50, 50, 0) property variant coordinate4: QtPositioning.coordinate(80, 80, 0) property variant coordinate5: QtPositioning.coordinate(20, 180) + property variant coordinateCenterVisibleRegion: QtPositioning.coordinate(27, 77) + property variant coordinateVisible1: QtPositioning.coordinate(28, 77) + property variant coordinateVisible2: QtPositioning.coordinate(33, 79.1) + property variant coordinateVisible3: QtPositioning.coordinate(27, 80.5) property variant invalidCoordinate: QtPositioning.coordinate() property variant altitudelessCoordinate: QtPositioning.coordinate(50, 50) property bool allMapsReady: mapZoomOnCompleted.mapReady @@ -84,6 +89,9 @@ Item { } } + Map { id: mapVisibleRegion; width: 800; height: 600; + center: coordinateCenterVisibleRegion; plugin: testPlugin; zoomLevel: 1.0 } + Map {id: map; plugin: testPlugin; center: coordinate1; width: 100; height: 100} SignalSpy {id: mapCenterSpy; target: map; signalName: 'centerChanged'} @@ -148,6 +156,39 @@ Item { compare(map.center.latitude, 12) } + function test_map_visible_region() + { + mapVisibleRegion.zoomLevel = 1.0 + wait(50) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible1)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible2)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible3)) + + mapVisibleRegion.zoomLevel = 1.88 + verify(LocationTestHelper.waitForPolished(mapVisibleRegion)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible1)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible2)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible3)) + + mapVisibleRegion.zoomLevel = 2.12 + verify(LocationTestHelper.waitForPolished(mapVisibleRegion)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible1)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible2)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible3)) + + mapVisibleRegion.zoomLevel = 2.5 + verify(LocationTestHelper.waitForPolished(mapVisibleRegion)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible1)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible2)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible3)) + + mapVisibleRegion.zoomLevel = 2.7 + verify(LocationTestHelper.waitForPolished(mapVisibleRegion)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible1)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible2)) + verify(mapVisibleRegion.visibleRegion.contains(coordinateVisible3)) + } + function test_map_parameters() { // coordinate is set at map element declaration |