diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2016-12-02 18:22:12 +0100 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-01-16 16:18:27 +0000 |
commit | 762dc9dd2b47f908c3739173aa1e108dd7386717 (patch) | |
tree | 201747076f1ee6deda535a6e58cafc4edaa37cbe | |
parent | 45b1f2c23cf0e782c0b99f38e4d01a88da765753 (diff) | |
download | qtlocation-762dc9dd2b47f908c3739173aa1e108dd7386717.tar.gz |
Move the coordinate <-> item position conversion to QGeoProjection
This patch simplifies the QGeoMap API removing all the API
necessary to convert to and from screen.
This is now demanded to a specific QGeoProjection class, that will
be independent of the map, except for using the same Geo projection
(currently only WebMercator, or EPSG:3857, although we use a sphere
instead of an ellipsoid, i believe)
The benefits are
- This relieves subclasses of QGeoMap from implementing a
GeoProjection API, especially since QtLocation currently supports
only WebMercator, and reimplementations would have to anyway
produce the same results as the inbuilt one.
- This avoids the several indirection steps previously necessary
to perform a map projection (qgeotiledmap -> private->mapscene->
private). Since these operation are quite frequent one per
map item coordinate at every redraw, shortening the indirection
chain is beneficial
- It simplifies the highly complex QGeoTiledMapScene, separating
all the logic that is not needed to draw the scene, but only
to perform geo coordinate <-> screen coordinate conversion
Change-Id: I9e3ca5280166f2d6430a32deb44c030d02d9d4e1
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
26 files changed, 506 insertions, 434 deletions
diff --git a/src/imports/location/qdeclarativecirclemapitem.cpp b/src/imports/location/qdeclarativecirclemapitem.cpp index 077ba385..e107091c 100644 --- a/src/imports/location/qdeclarativecirclemapitem.cpp +++ b/src/imports/location/qdeclarativecirclemapitem.cpp @@ -150,7 +150,7 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QGeoMap &map) return; } - QPointF origin = map.coordinateToItemPosition(srcOrigin_, false).toPointF(); + QPointF origin = map.geoProjection().coordinateToItemPosition(srcOrigin_, false).toPointF(); QPainterPath ppi = srcPath_; @@ -169,9 +169,9 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QGeoMap &map) // calculate actual width of map on screen in pixels QGeoCoordinate mapCenter(0, map.cameraData().center().longitude()); - QDoubleVector2D midPoint = map.coordinateToItemPosition(mapCenter, false); + QDoubleVector2D midPoint = map.geoProjection().coordinateToItemPosition(mapCenter, false); QDoubleVector2D midPointPlusOne = QDoubleVector2D(midPoint.x() + 1.0, midPoint.y()); - QGeoCoordinate coord1 = map.itemPositionToCoordinate(midPointPlusOne, false); + QGeoCoordinate coord1 = map.geoProjection().itemPositionToCoordinate(midPointPlusOne, false); double geoDistance = coord1.longitude() - map.cameraData().center().longitude(); if ( geoDistance < 0 ) geoDistance += 360.0; @@ -568,7 +568,7 @@ void QDeclarativeCircleMapItem::geometryChanged(const QRectF &newGeometry, const } QDoubleVector2D newPoint = QDoubleVector2D(x(),y()) + QDoubleVector2D(width(), height()) / 2; - QGeoCoordinate newCoordinate = map()->itemPositionToCoordinate(newPoint, false); + QGeoCoordinate newCoordinate = map()->geoProjection().itemPositionToCoordinate(newPoint, false); if (newCoordinate.isValid()) setCenter(newCoordinate); @@ -603,19 +603,19 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinat return; QList<int> wrapPathIndex; // calculate actual width of map on screen in pixels - QDoubleVector2D midPoint = map()->coordinateToItemPosition(map()->cameraData().center(), false); + QDoubleVector2D midPoint = map()->geoProjection().coordinateToItemPosition(map()->cameraData().center(), false); QDoubleVector2D midPointPlusOne(midPoint.x() + 1.0, midPoint.y()); - QGeoCoordinate coord1 = map()->itemPositionToCoordinate(midPointPlusOne, false); + QGeoCoordinate coord1 = map()->geoProjection().itemPositionToCoordinate(midPointPlusOne, false); qreal geoDistance = coord1.longitude() - map()->cameraData().center().longitude(); if ( geoDistance < 0 ) geoDistance += 360; qreal mapWidth = 360.0 / geoDistance; mapWidth = qMin(static_cast<int>(mapWidth), map()->viewportWidth()); - QDoubleVector2D prev = map()->coordinateToItemPosition(path.at(0), false); + QDoubleVector2D prev = map()->geoProjection().coordinateToItemPosition(path.at(0), false); // find the points in path where wrapping occurs for (int i = 1; i <= path.count(); ++i) { int index = i % path.count(); - QDoubleVector2D point = map()->coordinateToItemPosition(path.at(index), false); + QDoubleVector2D point = map()->geoProjection().coordinateToItemPosition(path.at(index), false); if ( (qAbs(point.x() - prev.x())) >= mapWidth/2.0 ) { wrapPathIndex << index; if (wrapPathIndex.size() == 2 || !(crossNorthPole && crossSouthPole)) diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp index 761fcdc5..d19f6929 100644 --- a/src/imports/location/qdeclarativegeomap.cpp +++ b/src/imports/location/qdeclarativegeomap.cpp @@ -311,7 +311,7 @@ void QDeclarativeGeoMap::initialize() // try to keep center change signal in the end bool centerHasChanged = false; - setMinimumZoomLevel(m_map->minimumZoomAtViewportSize(width(), height())); + setMinimumZoomLevel(m_map->minimumZoom()); // set latitude bundary check m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(m_cameraData.zoomLevel()); @@ -638,8 +638,9 @@ void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel) qreal oldMinimumZoomLevel = this->minimumZoomLevel(); if (m_map) { + minimumZoomLevel = qBound(qreal(m_map->cameraCapabilities().minimumZoomLevelAt256()), minimumZoomLevel, maximumZoomLevel()); - double minimumViewportZoomLevel = m_map->minimumZoomAtViewportSize(width(),height()); + double minimumViewportZoomLevel = m_map->minimumZoom(); if (minimumZoomLevel < minimumViewportZoomLevel) minimumZoomLevel = minimumViewportZoomLevel; } @@ -840,8 +841,8 @@ QGeoShape QDeclarativeGeoMap::visibleRegion() const if (!m_map || !width() || !height()) return m_region; - QGeoCoordinate tl = m_map->itemPositionToCoordinate(QDoubleVector2D(0, 0)); - QGeoCoordinate br = m_map->itemPositionToCoordinate(QDoubleVector2D(width(), height())); + QGeoCoordinate tl = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0, 0)); + QGeoCoordinate br = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(width(), height())); return QGeoRectangle(tl, br); } @@ -967,8 +968,8 @@ void QDeclarativeGeoMap::fitViewportToGeoShape() return; } - QDoubleVector2D topLeftPoint = m_map->geoToMapProjection(topLeft); - QDoubleVector2D bottomRightPoint = m_map->geoToMapProjection(bottomRight); + QDoubleVector2D topLeftPoint = m_map->geoProjection().geoToMapProjection(topLeft); + QDoubleVector2D bottomRightPoint = m_map->geoProjection().geoToMapProjection(bottomRight); if (bottomRightPoint.x() < topLeftPoint.x()) // crossing the dateline bottomRightPoint.setX(bottomRightPoint.x() + 1.0); @@ -981,7 +982,7 @@ void QDeclarativeGeoMap::fitViewportToGeoShape() // find center of the bounding box QDoubleVector2D center = (topLeftPoint + bottomRightPoint) * 0.5; center.setX(center.x() > 1.0 ? center.x() - 1.0 : center.x()); - QGeoCoordinate centerCoordinate = m_map->mapProjectionToGeo(center); + QGeoCoordinate centerCoordinate = m_map->geoProjection().mapProjectionToGeo(center); // position camera to the center of bounding box setCenter(centerCoordinate); @@ -1023,7 +1024,7 @@ QQmlListProperty<QDeclarativeGeoMapType> QDeclarativeGeoMap::supportedMapTypes() QGeoCoordinate QDeclarativeGeoMap::toCoordinate(const QPointF &position, bool clipToViewPort) const { if (m_map) - return m_map->itemPositionToCoordinate(QDoubleVector2D(position), clipToViewPort); + return m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(position), clipToViewPort); else return QGeoCoordinate(); } @@ -1039,7 +1040,7 @@ QGeoCoordinate QDeclarativeGeoMap::toCoordinate(const QPointF &position, bool cl QPointF QDeclarativeGeoMap::fromCoordinate(const QGeoCoordinate &coordinate, bool clipToViewPort) const { if (m_map) - return m_map->coordinateToItemPosition(coordinate, clipToViewPort).toPointF(); + return m_map->geoProjection().coordinateToItemPosition(coordinate, clipToViewPort).toPointF(); else return QPointF(qQNaN(), qQNaN()); } @@ -1061,7 +1062,8 @@ void QDeclarativeGeoMap::pan(int dx, int dy) return; if (dx == 0 && dy == 0) return; - QGeoCoordinate coord = m_map->itemPositionToCoordinate( + + QGeoCoordinate coord = m_map->geoProjection().itemPositionToCoordinate( QDoubleVector2D(m_map->viewportWidth() / 2 + dx, m_map->viewportHeight() / 2 + dy)); setCenter(coord); @@ -1428,7 +1430,7 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF if (!m_initialized) { initialize(); } else { - setMinimumZoomLevel(m_map->minimumZoomAtViewportSize(newGeometry.width(), newGeometry.height())); + setMinimumZoomLevel(m_map->minimumZoom()); // Update the center latitudinal threshold double maximumCenterLatitudeAtZoom = m_map->maximumCenterLatitudeAtZoom(m_cameraData.zoomLevel()); @@ -1548,7 +1550,7 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine) // position camera to the center of bounding box QGeoCoordinate coordinate; - coordinate = m_map->itemPositionToCoordinate(QDoubleVector2D(bboxCenterX, bboxCenterY), false); + coordinate = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(bboxCenterX, bboxCenterY), false); setProperty("center", QVariant::fromValue(coordinate)); // adjust zoom diff --git a/src/imports/location/qdeclarativegeomapitembase.cpp b/src/imports/location/qdeclarativegeomapitembase.cpp index b4ba761d..84bf757d 100644 --- a/src/imports/location/qdeclarativegeomapitembase.cpp +++ b/src/imports/location/qdeclarativegeomapitembase.cpp @@ -177,7 +177,7 @@ void QDeclarativeGeoMapItemBase::setPositionOnMap(const QGeoCoordinate &coordina if (!map_ || !quickMap_) return; - QPointF topLeft = map_->coordinateToItemPosition(coordinate, false).toPointF() - offset; + QPointF topLeft = map_->geoProjection().coordinateToItemPosition(coordinate, false).toPointF() - offset; setPosition(topLeft); } diff --git a/src/imports/location/qdeclarativegeomapquickitem.cpp b/src/imports/location/qdeclarativegeomapquickitem.cpp index 41f2a821..78fd4f8f 100644 --- a/src/imports/location/qdeclarativegeomapquickitem.cpp +++ b/src/imports/location/qdeclarativegeomapquickitem.cpp @@ -174,7 +174,7 @@ void QDeclarativeGeoMapQuickItem::geometryChanged(const QRectF &newGeometry, con return; } - QGeoCoordinate newCoordinate = map()->itemPositionToCoordinate(QDoubleVector2D(x(), y()) + (scaleFactor() * QDoubleVector2D(anchorPoint_)), false); + QGeoCoordinate newCoordinate = map()->geoProjection().itemPositionToCoordinate(QDoubleVector2D(x(), y()) + (scaleFactor() * QDoubleVector2D(anchorPoint_)), false); if (newCoordinate.isValid()) setCoordinate(newCoordinate); diff --git a/src/imports/location/qdeclarativepolygonmapitem.cpp b/src/imports/location/qdeclarativepolygonmapitem.cpp index ee603f8c..0e11db79 100644 --- a/src/imports/location/qdeclarativepolygonmapitem.cpp +++ b/src/imports/location/qdeclarativepolygonmapitem.cpp @@ -157,7 +157,7 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map, double unwrapBelowX = 0; if (preserveGeometry_ ) - unwrapBelowX = map.coordinateToItemPosition(geoLeftBound_, false).x(); + unwrapBelowX = map.geoProjection().coordinateToItemPosition(geoLeftBound_, false).x(); for (int i = 0; i < path.size(); ++i) { const QGeoCoordinate &coord = path.at(i); @@ -165,7 +165,7 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map, if (!coord.isValid()) continue; - QDoubleVector2D point = map.coordinateToItemPosition(coord, false); + QDoubleVector2D point = map.geoProjection().coordinateToItemPosition(coord, false); // We can get NaN if the map isn't set up correctly, or the projection // is faulty -- probably best thing to do is abort @@ -213,7 +213,7 @@ void QGeoMapPolygonGeometry::updateScreenPoints(const QGeoMap &map) return; } - QDoubleVector2D origin = map.coordinateToItemPosition(srcOrigin_, false); + QDoubleVector2D origin = map.geoProjection().coordinateToItemPosition(srcOrigin_, false); // Create the viewport rect in the same coordinate system // as the actual points @@ -613,7 +613,7 @@ void QDeclarativePolygonMapItem::geometryChanged(const QRectF &newGeometry, cons } QDoubleVector2D newPoint = QDoubleVector2D(x(),y()) + QDoubleVector2D(geometry_.firstPointOffset()); - QGeoCoordinate newCoordinate = map()->itemPositionToCoordinate(newPoint, false); + QGeoCoordinate newCoordinate = map()->geoProjection().itemPositionToCoordinate(newPoint, false); if (newCoordinate.isValid()) { double firstLongitude = path_.at(0).longitude(); double firstLatitude = path_.at(0).latitude(); diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp index 623629dc..5fe0535d 100644 --- a/src/imports/location/qdeclarativepolylinemapitem.cpp +++ b/src/imports/location/qdeclarativepolylinemapitem.cpp @@ -205,7 +205,7 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map, const double mapWidthHalf = map.viewportWidth()/2.0; double unwrapBelowX = 0; if (preserveGeometry_) - unwrapBelowX = map.coordinateToItemPosition(geoLeftBound_, false).x(); + unwrapBelowX = map.geoProjection().coordinateToItemPosition(geoLeftBound_, false).x(); for (int i = 0; i < path.size(); ++i) { const QGeoCoordinate &coord = path.at(i); @@ -213,7 +213,7 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map, if (!coord.isValid()) continue; - QDoubleVector2D point = map.coordinateToItemPosition(coord, false); + QDoubleVector2D point = map.geoProjection().coordinateToItemPosition(coord, false); // We can get NaN if the map isn't set up correctly, or the projection // is faulty -- probably best thing to do is abort @@ -391,7 +391,7 @@ void QGeoMapPolylineGeometry::updateScreenPoints(const QGeoMap &map, if (!screenDirty_) return; - QPointF origin = map.coordinateToItemPosition(srcOrigin_, false).toPointF(); + QPointF origin = map.geoProjection().coordinateToItemPosition(srcOrigin_, false).toPointF(); if (!qIsFinite(origin.x()) || !qIsFinite(origin.y())) { clear(); @@ -825,7 +825,7 @@ void QDeclarativePolylineMapItem::geometryChanged(const QRectF &newGeometry, con } QDoubleVector2D newPoint = QDoubleVector2D(x(),y()) + QDoubleVector2D(geometry_.firstPointOffset()); - QGeoCoordinate newCoordinate = map()->itemPositionToCoordinate(newPoint, false); + QGeoCoordinate newCoordinate = map()->geoProjection().itemPositionToCoordinate(newPoint, false); if (newCoordinate.isValid()) { double firstLongitude = path_.at(0).longitude(); double firstLatitude = path_.at(0).latitude(); diff --git a/src/imports/location/qdeclarativerectanglemapitem.cpp b/src/imports/location/qdeclarativerectanglemapitem.cpp index f50d0340..b91c4c08 100644 --- a/src/imports/location/qdeclarativerectanglemapitem.cpp +++ b/src/imports/location/qdeclarativerectanglemapitem.cpp @@ -131,8 +131,8 @@ void QGeoMapRectangleGeometry::updatePoints(const QGeoMap &map, if (!screenDirty_ && !sourceDirty_) return; - QDoubleVector2D tl = map.coordinateToItemPosition(topLeft, false); - QDoubleVector2D br = map.coordinateToItemPosition(bottomRight, false); + QDoubleVector2D tl = map.geoProjection().coordinateToItemPosition(topLeft, false); + QDoubleVector2D br = map.geoProjection().coordinateToItemPosition(bottomRight, false); // We can get NaN if the map isn't set up correctly, or the projection // is faulty -- probably best thing to do is abort @@ -142,7 +142,7 @@ void QGeoMapRectangleGeometry::updatePoints(const QGeoMap &map, return; if ( preserveGeometry_ ) { - double unwrapBelowX = map.coordinateToItemPosition(geoLeftBound_, false).x(); + double unwrapBelowX = map.geoProjection().coordinateToItemPosition(geoLeftBound_, false).x(); if (br.x() < unwrapBelowX) br.setX(tl.x() + screenBounds_.width()); } @@ -418,7 +418,7 @@ void QDeclarativeRectangleMapItem::geometryChanged(const QRectF &newGeometry, co } QDoubleVector2D newTopLeftPoint = QDoubleVector2D(x(),y()); - QGeoCoordinate newTopLeft = map()->itemPositionToCoordinate(newTopLeftPoint, false); + QGeoCoordinate newTopLeft = map()->geoProjection().itemPositionToCoordinate(newTopLeftPoint, false); if (newTopLeft.isValid()) { // calculate new geo width while checking for dateline crossing const double lonW = bottomRight_.longitude() > topLeft_.longitude() ? diff --git a/src/imports/location/qgeomapitemgeometry.cpp b/src/imports/location/qgeomapitemgeometry.cpp index a22be0af..ab90d0dd 100644 --- a/src/imports/location/qgeomapitemgeometry.cpp +++ b/src/imports/location/qgeomapitemgeometry.cpp @@ -125,14 +125,14 @@ double QGeoMapItemGeometry::geoDistanceToScreenWidth(const QGeoMap &map, // Do not wrap around half the globe Q_ASSERT(!qFuzzyCompare(fromCoord.longitude(), toCoord.longitude())); - QGeoCoordinate mapMid = map.itemPositionToCoordinate(QDoubleVector2D(map.viewportWidth()/2.0, 0)); + QGeoCoordinate mapMid = map.geoProjection().itemPositionToCoordinate(QDoubleVector2D(map.viewportWidth()/2.0, 0)); double halfGeoDist = toCoord.longitude() - fromCoord.longitude(); if (toCoord.longitude() < fromCoord.longitude()) halfGeoDist += 360; halfGeoDist /= 2.0; QGeoCoordinate geoDelta = QGeoCoordinate(0, QLocationUtils::wrapLong(mapMid.longitude() + halfGeoDist)); - QDoubleVector2D halfScreenDist = map.coordinateToItemPosition(geoDelta, false) + QDoubleVector2D halfScreenDist = map.geoProjection().coordinateToItemPosition(geoDelta, false) - QDoubleVector2D(map.viewportWidth()/2.0, 0); return halfScreenDist.x() * 2.0; } diff --git a/src/imports/location/qquickgeomapgesturearea.cpp b/src/imports/location/qquickgeomapgesturearea.cpp index fe5a04dd..50709292 100644 --- a/src/imports/location/qquickgeomapgesturearea.cpp +++ b/src/imports/location/qquickgeomapgesturearea.cpp @@ -691,12 +691,12 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event) if (!m_map) return; - QGeoCoordinate wheelGeoPos = m_map->itemPositionToCoordinate(QDoubleVector2D(event->posF()), false); - QPointF preZoomPoint = m_map->coordinateToItemPosition(wheelGeoPos, false).toPointF(); + QGeoCoordinate wheelGeoPos = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(event->posF()), false); + QPointF preZoomPoint = m_map->geoProjection().coordinateToItemPosition(wheelGeoPos, false).toPointF(); double zoomLevelDelta = event->angleDelta().y() * qreal(0.001); m_declarativeMap->setZoomLevel(m_declarativeMap->zoomLevel() + zoomLevelDelta); - QPointF postZoomPoint = m_map->coordinateToItemPosition(wheelGeoPos, false).toPointF(); + QPointF postZoomPoint = m_map->geoProjection().coordinateToItemPosition(wheelGeoPos, false).toPointF(); if (preZoomPoint != postZoomPoint) { @@ -704,7 +704,7 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event) qreal dy = postZoomPoint.y() - preZoomPoint.y(); QPointF mapCenterPoint(m_map->viewportWidth() / 2.0 + dx, m_map->viewportHeight() / 2.0 + dy); - QGeoCoordinate mapCenterCoordinate = m_map->itemPositionToCoordinate(QDoubleVector2D(mapCenterPoint), false); + QGeoCoordinate mapCenterCoordinate = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(mapCenterPoint), false); m_declarativeMap->setCenter(mapCenterCoordinate); } event->accept(); @@ -810,7 +810,7 @@ void QQuickGeoMapGestureArea::touchPointStateMachine() if (m_allPoints.count() == 0) { m_touchPointState = touchPoints0; } else if (m_allPoints.count() == 2) { - m_touchCenterCoord = m_map->itemPositionToCoordinate(QDoubleVector2D(m_sceneCenter), false); + m_touchCenterCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_sceneCenter), false); startTwoTouchPoints(); m_touchPointState = touchPoints2; } @@ -819,7 +819,7 @@ void QQuickGeoMapGestureArea::touchPointStateMachine() if (m_allPoints.count() == 0) { m_touchPointState = touchPoints0; } else if (m_allPoints.count() == 1) { - m_touchCenterCoord = m_map->itemPositionToCoordinate(QDoubleVector2D(m_sceneCenter), false); + m_touchCenterCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_sceneCenter), false); startOneTouchPoint(); m_touchPointState = touchPoints1; } @@ -847,7 +847,7 @@ void QQuickGeoMapGestureArea::startOneTouchPoint() m_sceneStartPoint1 = mapFromScene(m_allPoints.at(0).scenePos()); m_lastPos = m_sceneStartPoint1; m_lastPosTime.start(); - QGeoCoordinate startCoord = m_map->itemPositionToCoordinate(QDoubleVector2D(m_sceneStartPoint1), false); + QGeoCoordinate startCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_sceneStartPoint1), false); // ensures a smooth transition for panning m_startCoord.setLongitude(m_startCoord.longitude() + startCoord.longitude() - m_touchCenterCoord.longitude()); @@ -875,7 +875,7 @@ void QQuickGeoMapGestureArea::startTwoTouchPoints() QPointF startPos = (m_sceneStartPoint1 + m_sceneStartPoint2) * 0.5; m_lastPos = startPos; m_lastPosTime.start(); - QGeoCoordinate startCoord = m_map->itemPositionToCoordinate(QDoubleVector2D(startPos), false); + QGeoCoordinate startCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(startPos), false); m_startCoord.setLongitude(m_startCoord.longitude() + startCoord.longitude() - m_touchCenterCoord.longitude()); m_startCoord.setLatitude(m_startCoord.latitude() + startCoord.latitude() - @@ -1070,7 +1070,7 @@ void QQuickGeoMapGestureArea::panStateMachine() case flickInactive: if (canStartPan()) { // Update startCoord_ to ensure smooth start for panning when going over startDragDistance - QGeoCoordinate newStartCoord = m_map->itemPositionToCoordinate(QDoubleVector2D(m_sceneCenter), false); + QGeoCoordinate newStartCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_sceneCenter), false); m_startCoord.setLongitude(newStartCoord.longitude()); m_startCoord.setLatitude(newStartCoord.latitude()); m_declarativeMap->setKeepMouseGrab(true); @@ -1145,13 +1145,13 @@ bool QQuickGeoMapGestureArea::canStartPan() */ void QQuickGeoMapGestureArea::updatePan() { - QPointF startPoint = m_map->coordinateToItemPosition(m_startCoord, false).toPointF(); + QPointF startPoint = m_map->geoProjection().coordinateToItemPosition(m_startCoord, false).toPointF(); int dx = static_cast<int>(m_sceneCenter.x() - startPoint.x()); int dy = static_cast<int>(m_sceneCenter.y() - startPoint.y()); QPointF mapCenterPoint; mapCenterPoint.setY(m_map->viewportHeight() / 2.0 - dy); mapCenterPoint.setX(m_map->viewportWidth() / 2.0 - dx); - QGeoCoordinate animationStartCoordinate = m_map->itemPositionToCoordinate(QDoubleVector2D(mapCenterPoint), false); + QGeoCoordinate animationStartCoordinate = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(mapCenterPoint), false); m_declarativeMap->setCenter(animationStartCoordinate); } diff --git a/src/location/maps/maps.pri b/src/location/maps/maps.pri index 3f76f737..aaad5897 100644 --- a/src/location/maps/maps.pri +++ b/src/location/maps/maps.pri @@ -59,6 +59,7 @@ PRIVATE_HEADERS += \ maps/qgeorouteparser_p_p.h \ maps/qgeorouteparserosrmv5_p.h \ maps/qgeorouteparserosrmv4_p.h \ + maps/qgeoprojection_p.h \ maps/qcache3q_p.h SOURCES += \ @@ -93,4 +94,5 @@ SOURCES += \ maps/qgeorouteparser.cpp \ maps/qgeorouteparserosrmv5.cpp \ maps/qgeorouteparserosrmv4.cpp \ - maps/qgeomapparameter.cpp + maps/qgeomapparameter.cpp \ + maps/qgeoprojection.cpp diff --git a/src/location/maps/qgeocameradata_p.h b/src/location/maps/qgeocameradata_p.h index e311bb0c..c245fbfd 100644 --- a/src/location/maps/qgeocameradata_p.h +++ b/src/location/maps/qgeocameradata_p.h @@ -47,8 +47,8 @@ // We mean it. // -#include "qlocationglobal.h" -#include "qgeocoordinate.h" +#include <QtLocation/private/qlocationglobal_p.h> +#include <QtPositioning/qgeocoordinate.h> #include <QMetaType> @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE class QGeoCameraDataPrivate; -class Q_LOCATION_EXPORT QGeoCameraData +class Q_LOCATION_PRIVATE_EXPORT QGeoCameraData { public: QGeoCameraData(); @@ -82,6 +82,8 @@ public: void setRoll(double roll); double roll() const; + // Zoom level is intended to be relative to a tileSize of 256^2 pixels. + // E.g., a zoom level of 0 must result in a mapWidth of 256, and so on. void setZoomLevel(double zoomLevel); double zoomLevel() const; diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index f30dbce7..325ca83f 100644 --- a/src/location/maps/qgeomap.cpp +++ b/src/location/maps/qgeomap.cpp @@ -57,6 +57,7 @@ void QGeoMap::setViewportSize(const QSize& size) if (size == d->m_viewportSize) return; d->m_viewportSize = size; + d->m_geoProjection->setViewportSize(size); d->changeViewportSize(size); } @@ -84,6 +85,7 @@ void QGeoMap::setCameraData(const QGeoCameraData &cameraData) if (cameraData == d->m_cameraData) return; d->m_cameraData = cameraData; + d->m_geoProjection->setCameraData(cameraData); d->changeCameraData(cameraData); emit cameraDataChanged(d->m_cameraData); } @@ -110,48 +112,44 @@ const QGeoMapType QGeoMap::activeMapType() const return d->m_activeMapType; } - -QGeoCameraCapabilities QGeoMap::cameraCapabilities() const +double QGeoMap::minimumZoom() const { Q_D(const QGeoMap); - if (!d->m_engine.isNull()) - return d->m_engine->cameraCapabilities(); - else - return QGeoCameraCapabilities(); + return d->m_geoProjection->minimumZoom(); } -/* Default implementations */ -QGeoCoordinate QGeoMap::itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport) const +double QGeoMap::maximumCenterLatitudeAtZoom(double zoomLevel) const { - if (clipToViewport) { - int w = viewportWidth(); - int h = viewportHeight(); - - if ((pos.x() < 0) || (w < pos.x()) || (pos.y() < 0) || (h < pos.y())) - return QGeoCoordinate(); - } + Q_D(const QGeoMap); + return d->m_geoProjection->maximumCenterLatitudeAtZoom(zoomLevel); +} - QDoubleVector2D wrappedMapProjection = itemPositionToWrappedMapProjection(pos); - // With rotation/tilting, a screen position might end up outside the projection space. - // TODO: test for it - return mapProjectionToGeo(unwrapMapProjection(wrappedMapProjection)); +double QGeoMap::mapWidth() const +{ + Q_D(const QGeoMap); + return d->m_geoProjection->mapWidth(); } -QDoubleVector2D QGeoMap::coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport) const +double QGeoMap::mapHeight() const { - QDoubleVector2D pos = wrappedMapProjectionToItemPosition(wrapMapProjection(geoToMapProjection(coordinate))); + Q_D(const QGeoMap); + return d->m_geoProjection->mapHeight(); +} - if (clipToViewport) { - int w = viewportWidth(); - int h = viewportHeight(); - double x = pos.x(); - double y = pos.y(); - if ((x < -0.5) || (x > w + 0.5) || (y < -0.5) || (y > h + 0.5) || qIsNaN(x) || qIsNaN(y)) - return QDoubleVector2D(qQNaN(), qQNaN()); - } - return pos; +const QGeoProjection &QGeoMap::geoProjection() const +{ + Q_D(const QGeoMap); + return *(d->m_geoProjection); } +QGeoCameraCapabilities QGeoMap::cameraCapabilities() const +{ + Q_D(const QGeoMap); + if (!d->m_engine.isNull()) + return d->m_engine->cameraCapabilities(); + else + return QGeoCameraCapabilities(); +} void QGeoMap::prefetchData() { @@ -189,8 +187,9 @@ void QGeoMap::clearParameters() d->m_mapParameters.clear(); } -QGeoMapPrivate::QGeoMapPrivate(QGeoMappingManagerEngine *engine) +QGeoMapPrivate::QGeoMapPrivate(QGeoMappingManagerEngine *engine, QGeoProjection *geoProjection) : QObjectPrivate(), + m_geoProjection(geoProjection), m_engine(engine), m_activeMapType(QGeoMapType()) { @@ -198,6 +197,8 @@ QGeoMapPrivate::QGeoMapPrivate(QGeoMappingManagerEngine *engine) QGeoMapPrivate::~QGeoMapPrivate() { + if (m_geoProjection) + delete m_geoProjection; } void QGeoMapPrivate::addParameter(QGeoMapParameter *param) diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h index 09da93b4..b5e51014 100644 --- a/src/location/maps/qgeomap_p.h +++ b/src/location/maps/qgeomap_p.h @@ -51,6 +51,7 @@ #include <QtLocation/private/qgeomaptype_p.h> #include <QtCore/QObject> #include <QtPositioning/private/qdoublevector2d_p.h> +#include <QtLocation/private/qgeoprojection_p.h> QT_BEGIN_NAMESPACE @@ -84,28 +85,15 @@ public: void setActiveMapType(const QGeoMapType mapType); const QGeoMapType activeMapType() const; - virtual double minimumZoomAtViewportSize(int viewportWidth, int viewportHeight) const = 0; - virtual double maximumCenterLatitudeAtZoom(double zoomLevel) const = 0; + // returns the minimum zoom at the current viewport size + double minimumZoom() const; + double maximumCenterLatitudeAtZoom(double zoomLevel) const; - // The size of the underlying map, at the current zoom level. Unrelated to width()/height()/size(). - virtual double mapWidth() const = 0; - virtual double mapHeight() const = 0; + // returns the size of the underlying map, at the current zoom level. Unrelated to width()/height()/size(). + double mapWidth() const; + double mapHeight() const; - // Conversion methods for QGeoCoordinate <-> screen. - // This currently assumes that the "MapProjection" space is [0, 1][0, 1] for every type of possibly supported map projection - virtual QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const = 0; - virtual QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const = 0; - - virtual QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const = 0; - virtual QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const = 0; - - virtual QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const = 0; - virtual QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const = 0; - - // Convenience methods to avoid the chain itemPositionToWrappedProjection(wrapProjection(geoToProjection())) - // These also come with a default implementation that can, however, be overridden. - virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const; - virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const; + const QGeoProjection &geoProjection() const; virtual void prefetchData(); virtual void clearData(); diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h index 91938903..625cd676 100644 --- a/src/location/maps/qgeomap_p_p.h +++ b/src/location/maps/qgeomap_p_p.h @@ -50,6 +50,7 @@ #include <QtLocation/private/qlocationglobal_p.h> #include <QtLocation/private/qgeocameradata_p.h> #include <QtLocation/private/qgeomaptype_p.h> +#include <QtLocation/private/qgeoprojection_p.h> #include <QtCore/private/qobject_p.h> #include <QtCore/QSize> #include <QtCore/QSet> @@ -66,9 +67,10 @@ class Q_LOCATION_PRIVATE_EXPORT QGeoMapPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGeoMap) public: - QGeoMapPrivate(QGeoMappingManagerEngine *engine); + QGeoMapPrivate(QGeoMappingManagerEngine *engine, QGeoProjection *geoProjection); virtual ~QGeoMapPrivate(); + const QGeoProjection *geoProjection() const; protected: /* Hooks into the actual map implementations */ virtual void addParameter(QGeoMapParameter *param); @@ -80,6 +82,7 @@ protected: protected: QSize m_viewportSize; + QGeoProjection *m_geoProjection; QPointer<QGeoMappingManagerEngine> m_engine; QGeoCameraData m_cameraData; QGeoMapType m_activeMapType; diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp new file mode 100644 index 00000000..ed85fc67 --- /dev/null +++ b/src/location/maps/qgeoprojection.cpp @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeoprojection_p.h" +#include <QtPositioning/private/qwebmercator_p.h> +#include <QSize> +#include <cmath> + +QT_BEGIN_NAMESPACE + +QGeoProjection::QGeoProjection() +{ + +} + +QGeoProjection::~QGeoProjection() +{ + +} + +/* + * QGeoProjectionWebMercator implementation +*/ + + +QGeoProjectionWebMercator::QGeoProjectionWebMercator() + : QGeoProjection(), + m_mapEdgeSize(256), // at zl 0 + m_minimumZoom(0), + m_cameraCenterXMercator(0), + m_cameraCenterYMercator(0), + m_cameraWidthMercator(1), + m_cameraHeightMercator(1), + m_1_cameraWidthMercator(0), + m_1_cameraHeightMercator(0), + m_viewportWidth(1), + m_viewportHeight(1), + m_1_viewportWidth(0), + m_1_viewportHeight(0) +{ + +} + +QGeoProjectionWebMercator::~QGeoProjectionWebMercator() +{ + +} + +// This method returns the minimum zoom level that this specific qgeomap type allows +// at the current viewport size and for the default tile size of 256^2. +double QGeoProjectionWebMercator::minimumZoom() const +{ + return m_minimumZoom; +} + +// This method recalculates the "no-trespassing" limits for the map center. +// This has to be used 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 +double QGeoProjectionWebMercator::maximumCenterLatitudeAtZoom(double zoomLevel) const +{ + double mapEdgeSize = std::pow(2.0, zoomLevel) * 256.0; + + // At init time weird things happen + int clampedWindowHeight = (m_viewportHeight > mapEdgeSize) ? mapEdgeSize : m_viewportHeight; + + // 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 = QWebMercator::mercatorToCoord(QDoubleVector2D(0.0, mercatorTopmost)); + + return topMost.latitude(); +} + +double QGeoProjectionWebMercator::mapWidth() const +{ + return m_mapEdgeSize; +} + +double QGeoProjectionWebMercator::mapHeight() const +{ + return m_mapEdgeSize; +} + +void QGeoProjectionWebMercator::setViewportSize(const QSize &size) +{ + m_viewportWidth = size.width(); + m_viewportHeight = size.height(); + m_1_viewportWidth = 1.0 / m_viewportWidth; + m_1_viewportHeight = 1.0 / m_viewportHeight; + m_minimumZoom = std::log(qMax(m_viewportWidth, m_viewportHeight) / 256.0) / std::log(2.0); + setupCamera(); +} + +void QGeoProjectionWebMercator::setCameraData(const QGeoCameraData &cameraData) +{ + m_cameraData = cameraData; + m_mapEdgeSize = std::pow(2.0, cameraData.zoomLevel()) * 256.0; + setupCamera(); +} + +QDoubleVector2D QGeoProjectionWebMercator::geoToMapProjection(const QGeoCoordinate &coordinate) const +{ + return QWebMercator::coordToMercator(coordinate); +} + +QGeoCoordinate QGeoProjectionWebMercator::mapProjectionToGeo(const QDoubleVector2D &projection) const +{ + return QWebMercator::mercatorToCoord(projection); +} + +//wraps around center +QDoubleVector2D QGeoProjectionWebMercator::wrapMapProjection(const QDoubleVector2D &projection) const +{ + double x = projection.x(); + if (m_cameraCenterXMercator < 0.5) { + if (x - m_cameraCenterXMercator > 0.5 ) + x -= 1.0; + } else if (m_cameraCenterXMercator > 0.5) { + if (x - m_cameraCenterXMercator < -0.5 ) + x += 1.0; + } + + return QDoubleVector2D(x, projection.y()); +} + +QDoubleVector2D QGeoProjectionWebMercator::unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const +{ + double x = wrappedProjection.x(); + if (x > 1.0) + return QDoubleVector2D(x - 1.0, wrappedProjection.y()); + if (x <= 0.0) + return QDoubleVector2D(x + 1.0, wrappedProjection.y()); + return wrappedProjection; +} + +QDoubleVector2D QGeoProjectionWebMercator::wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const +{ + // TODO: Support tilt/bearing through a projection matrix. + double x = ((wrappedProjection.x() - m_cameraCenterXMercator) * m_1_cameraWidthMercator + 0.5) * m_viewportWidth; + double y = ((wrappedProjection.y() - m_cameraCenterYMercator) * m_1_cameraHeightMercator + 0.5) * m_viewportHeight; + return QDoubleVector2D(x, y); +} + +QDoubleVector2D QGeoProjectionWebMercator::itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const +{ + // TODO: Support tilt/bearing through an inverse projection matrix. + double x = itemPosition.x(); + x *= m_1_viewportWidth; + x -= 0.5; + x *= m_cameraWidthMercator; + x += m_cameraCenterXMercator; + + double y = itemPosition.y(); + y *= m_1_viewportHeight; + y -= 0.5; + y *= m_cameraHeightMercator; + y += m_cameraCenterYMercator; + + return QDoubleVector2D(x, y); +} + +/* Default implementations */ +QGeoCoordinate QGeoProjectionWebMercator::itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport) const +{ + if (clipToViewport) { + int w = m_viewportWidth; + int h = m_viewportHeight; + + if ((pos.x() < 0) || (w < pos.x()) || (pos.y() < 0) || (h < pos.y())) + return QGeoCoordinate(); + } + + QDoubleVector2D wrappedMapProjection = itemPositionToWrappedMapProjection(pos); + // With rotation/tilting, a screen position might end up outside the projection space. + // TODO: test for it + return mapProjectionToGeo(unwrapMapProjection(wrappedMapProjection)); +} + +QDoubleVector2D QGeoProjectionWebMercator::coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport) const +{ + QDoubleVector2D pos = wrappedMapProjectionToItemPosition(wrapMapProjection(geoToMapProjection(coordinate))); + + if (clipToViewport) { + int w = m_viewportWidth; + int h = m_viewportHeight; + double x = pos.x(); + double y = pos.y(); + if ((x < -0.5) || (x > w + 0.5) || (y < -0.5) || (y > h + 0.5) || qIsNaN(x) || qIsNaN(y)) + return QDoubleVector2D(qQNaN(), qQNaN()); + } + return pos; +} + +void QGeoProjectionWebMercator::setupCamera() +{ + m_cameraWidthMercator = m_viewportWidth / m_mapEdgeSize; + m_cameraHeightMercator = m_viewportHeight / m_mapEdgeSize; + m_1_cameraWidthMercator = 1.0 / m_cameraWidthMercator; + m_1_cameraHeightMercator = 1.0 / m_cameraHeightMercator; + QDoubleVector2D camCenterMercator = QWebMercator::coordToMercator(m_cameraData.center()); + m_cameraCenterXMercator = camCenterMercator.x(); + m_cameraCenterYMercator = camCenterMercator.y(); +} + +QT_END_NAMESPACE diff --git a/src/location/maps/qgeoprojection_p.h b/src/location/maps/qgeoprojection_p.h new file mode 100644 index 00000000..f36bf9ac --- /dev/null +++ b/src/location/maps/qgeoprojection_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGEOPROJECTION_H +#define QGEOPROJECTION_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtLocation/private/qlocationglobal_p.h> +#include <QtLocation/private/qgeocameradata_p.h> +#include <QtPositioning/private/qdoublevector2d_p.h> + +QT_BEGIN_NAMESPACE + +class Q_LOCATION_PRIVATE_EXPORT QGeoProjection +{ +public: + QGeoProjection(); + virtual ~QGeoProjection(); + + virtual void setViewportSize(const QSize &size) = 0; + virtual void setCameraData(const QGeoCameraData &cameraData) = 0; + + // returns the minimum zoom at the current viewport size + virtual double minimumZoom() const = 0; + virtual double maximumCenterLatitudeAtZoom(double zoomLevel) const = 0; + + // returns the size of the underlying map, at the current zoom level. + virtual double mapWidth() const = 0; + virtual double mapHeight() const = 0; + + // Conversion methods for QGeoCoordinate <-> screen. + // This currently assumes that the "MapProjection" space is [0, 1][0, 1] for every type of possibly supported map projection + virtual QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const = 0; + virtual QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const = 0; + + virtual QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const = 0; + virtual QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const = 0; + + virtual QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const = 0; + virtual QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const = 0; + + // Convenience methods to avoid the chain itemPositionToWrappedProjection(wrapProjection(geoToProjection())) + // These also come with a default implementation that can, however, be overridden. + virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const = 0; + virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const = 0; +}; + +class Q_LOCATION_PRIVATE_EXPORT QGeoProjectionWebMercator : public QGeoProjection +{ +public: + QGeoProjectionWebMercator(); + ~QGeoProjectionWebMercator(); + + double minimumZoom() const Q_DECL_OVERRIDE; + double maximumCenterLatitudeAtZoom(double zoomLevel) const Q_DECL_OVERRIDE; + + // The size of the underlying map, at the current zoom level. + double mapWidth() const Q_DECL_OVERRIDE; + double mapHeight() const Q_DECL_OVERRIDE; + + void setViewportSize(const QSize &size) Q_DECL_OVERRIDE; + void setCameraData(const QGeoCameraData &cameraData) Q_DECL_OVERRIDE; + + QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const Q_DECL_OVERRIDE; + QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const Q_DECL_OVERRIDE; + + QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const Q_DECL_OVERRIDE; + QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE; + + QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE; + QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const Q_DECL_OVERRIDE; + + QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const Q_DECL_OVERRIDE; + QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const Q_DECL_OVERRIDE; + +private: + void setupCamera(); + +private: + QGeoCameraData m_cameraData; + double m_mapEdgeSize; + double m_minimumZoom; + // mercator to camera transform for coordinates (not tiles!) + double m_cameraCenterXMercator; + double m_cameraCenterYMercator; + double m_cameraWidthMercator; + double m_cameraHeightMercator; + double m_1_cameraWidthMercator; + double m_1_cameraHeightMercator; + + // cameraToScreen transform + double m_viewportWidth; // in pixels + double m_viewportHeight; // in pixels + double m_1_viewportWidth; + double m_1_viewportHeight; +}; + +QT_END_NAMESPACE + +#endif // QGEOPROJECTION_H diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp index 0916c7b7..fc08fe62 100644 --- a/src/location/maps/qgeotiledmap.cpp +++ b/src/location/maps/qgeotiledmap.cpp @@ -39,6 +39,7 @@ #include "qgeotiledmappingmanagerengine_p.h" #include "qabstractgeotilecache_p.h" #include "qgeotilespec_p.h" +#include "qgeoprojection_p.h" #include "qgeocameratiles_p.h" #include "qgeotilerequestmanager_p.h" @@ -56,11 +57,6 @@ 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) { @@ -161,43 +157,8 @@ void QGeoTiledMap::evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles) Q_UNUSED(visibleTiles); } -// This method returns the minimum zoom level that this specific qgeomap type allows -// 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 / 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. -// 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 -double QGeoTiledMap::maximumCenterLatitudeAtZoom(double zoomLevel) const -{ - Q_D(const QGeoTiledMap); - double mapEdgeSize = std::pow(2.0,zoomLevel); - mapEdgeSize *= d->m_visibleTiles->tileSize(); - - // At init time weird things happen - int clampedWindowHeight = (viewportHeight() > mapEdgeSize) ? mapEdgeSize : viewportHeight(); - - // 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 = QWebMercator::mercatorToCoord(QDoubleVector2D(0.0,mercatorTopmost)); - - return topMost.latitude(); -} - QGeoTiledMapPrivate::QGeoTiledMapPrivate(QGeoTiledMappingManagerEngine *engine) - : QGeoMapPrivate(engine), + : QGeoMapPrivate(engine, new QGeoProjectionWebMercator), m_cache(engine->tileCache()), m_visibleTiles(new QGeoCameraTiles()), m_prefetchTiles(new QGeoCameraTiles()), @@ -359,91 +320,6 @@ void QGeoTiledMapPrivate::changeTileVersion(int version) updateScene(); } -double QGeoTiledMap::mapWidth() const -{ - Q_D(const QGeoTiledMap); - return d->m_mapScene->mapEdgeSize(); -} - -double QGeoTiledMap::mapHeight() const -{ - return mapWidth(); // WebMercator, the only projection supported by QGeoTiledMap, is square. -} - -QDoubleVector2D QGeoTiledMap::geoToMapProjection(const QGeoCoordinate &coordinate) const -{ - Q_D(const QGeoTiledMap); - return d->m_mapScene->geoToMapProjection(coordinate); -} - -QGeoCoordinate QGeoTiledMap::mapProjectionToGeo(const QDoubleVector2D &projection) const -{ - Q_D(const QGeoTiledMap); - return d->m_mapScene->mapProjectionToGeo(projection); -} - -QDoubleVector2D QGeoTiledMap::wrapMapProjection(const QDoubleVector2D &projection) const -{ - Q_D(const QGeoTiledMap); - return d->m_mapScene->wrapMapProjection(projection); -} - -QDoubleVector2D QGeoTiledMap::unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const -{ - Q_D(const QGeoTiledMap); - return d->m_mapScene->unwrapMapProjection(wrappedProjection); -} - -QDoubleVector2D QGeoTiledMap::wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const -{ - Q_D(const QGeoTiledMap); - return d->m_mapScene->wrappedMapProjectionToItemPosition(wrappedProjection); -} - -QDoubleVector2D QGeoTiledMap::itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const -{ - Q_D(const QGeoTiledMap); - return d->m_mapScene->itemPositionToWrappedMapProjection(itemPosition); -} - -QGeoCoordinate QGeoTiledMap::itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport) const -{ - if (clipToViewport) { - int w = viewportWidth(); - int h = viewportHeight(); - - if ((pos.x() < 0) || (w < pos.x()) || (pos.y() < 0) || (h < pos.y())) - return QGeoCoordinate(); - } - -#if 0 // Old code, no tilt/rotation - Q_D(const QGeoTiledMap); - return d->itemPositionToCoordinate(pos); -#else - return mapProjectionToGeo(unwrapMapProjection(itemPositionToWrappedMapProjection(pos))); -#endif -} - -QDoubleVector2D QGeoTiledMap::coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport) const -{ -#if 0 // Old code, no tilt/rotation - Q_D(const QGeoTiledMap); - QDoubleVector2D pos = d->coordinateToItemPosition(coordinate); -#else - QDoubleVector2D pos = wrappedMapProjectionToItemPosition(wrapMapProjection(geoToMapProjection(coordinate))); -#endif - if (clipToViewport) { - int w = viewportWidth(); - int h = viewportHeight(); - 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()); - } - - return pos; -} - void QGeoTiledMapPrivate::clearScene() { m_mapScene->clearTexturedTiles(); @@ -496,14 +372,4 @@ QSGNode *QGeoTiledMapPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow *w return m_mapScene->updateSceneGraph(oldNode, window); } -QGeoCoordinate QGeoTiledMapPrivate::itemPositionToCoordinate(const QDoubleVector2D &pos) const -{ - return QWebMercator::mercatorToCoord(m_mapScene->itemPositionToMercator(pos)); -} - -QDoubleVector2D QGeoTiledMapPrivate::coordinateToItemPosition(const QGeoCoordinate &coordinate) const -{ - return m_mapScene->mercatorToItemPosition(QWebMercator::coordToMercator(coordinate)); -} - QT_END_NAMESPACE diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h index 7bb9b210..9c9b819f 100644 --- a/src/location/maps/qgeotiledmap_p.h +++ b/src/location/maps/qgeotiledmap_p.h @@ -84,24 +84,6 @@ public: void updateTile(const QGeoTileSpec &spec); void setPrefetchStyle(PrefetchStyle style); - double minimumZoomAtViewportSize(int viewportWidth, int viewportHeight) const Q_DECL_OVERRIDE; - double maximumCenterLatitudeAtZoom(double zoomLevel) const Q_DECL_OVERRIDE; - - double mapWidth() const Q_DECL_OVERRIDE; - double mapHeight() const Q_DECL_OVERRIDE; - - QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const Q_DECL_OVERRIDE; - QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const Q_DECL_OVERRIDE; - - QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const Q_DECL_OVERRIDE; - QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE; - - QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE; - QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const Q_DECL_OVERRIDE; - - QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const Q_DECL_OVERRIDE; - QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const Q_DECL_OVERRIDE; - void prefetchData() Q_DECL_OVERRIDE; void clearData() Q_DECL_OVERRIDE; diff --git a/src/location/maps/qgeotiledmap_p_p.h b/src/location/maps/qgeotiledmap_p_p.h index 72873d77..7106adf3 100644 --- a/src/location/maps/qgeotiledmap_p_p.h +++ b/src/location/maps/qgeotiledmap_p_p.h @@ -76,9 +76,6 @@ public: QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window); - QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos) const; - QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate) const; - void updateTile(const QGeoTileSpec &spec); void prefetchTiles(); QGeoMapType activeMapType(); diff --git a/src/location/maps/qgeotiledmapscene.cpp b/src/location/maps/qgeotiledmapscene.cpp index 5f9a52b0..404dcd19 100644 --- a/src/location/maps/qgeotiledmapscene.cpp +++ b/src/location/maps/qgeotiledmapscene.cpp @@ -75,7 +75,6 @@ public: // the number of tiles in each direction for the whole map (earth) at the current zoom level. // it is 1<<zoomLevel int m_sideLength; - double m_mapEdgeSize; QHash<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > m_textures; @@ -86,14 +85,6 @@ public: int m_maxTileY; int m_tileXWrapsBelow; // the wrap point as a tile index - // mercator to camera transform for coordinates (not tiles!) - double m_cameraCenterXMercator; - double m_cameraCenterYMercator; - double m_cameraWidthMercator; - double m_cameraHeightMercator; - double m_1_cameraWidthMercator; - double m_1_cameraHeightMercator; - // cameraToScreen transform double m_screenWidth; // in pixels double m_screenHeight; // in pixels @@ -151,7 +142,6 @@ void QGeoTiledMapScene::setCameraData(const QGeoCameraData &cameraData) float delta = cameraData.zoomLevel() - d->m_intZoomLevel; d->m_linearScaling = qAbs(delta) > 0.05; d->m_sideLength = 1 << d->m_intZoomLevel; - d->m_mapEdgeSize = std::pow(2.0, cameraData.zoomLevel()) * d->m_tileSize; } void QGeoTiledMapScene::setVisibleTiles(const QSet<QGeoTileSpec> &tiles) @@ -172,60 +162,6 @@ void QGeoTiledMapScene::addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTil d->addTile(spec, texture); } -double QGeoTiledMapScene::mapEdgeSize() const -{ - Q_D(const QGeoTiledMapScene); - return d->m_mapEdgeSize; -} - -QDoubleVector2D QGeoTiledMapScene::itemPositionToMercator(const QDoubleVector2D &pos) const -{ - Q_D(const QGeoTiledMapScene); - return d->itemPositionToMercator(pos); -} - -QDoubleVector2D QGeoTiledMapScene::mercatorToItemPosition(const QDoubleVector2D &mercator) const -{ - Q_D(const QGeoTiledMapScene); - return d->mercatorToItemPosition(mercator); -} - -QDoubleVector2D QGeoTiledMapScene::geoToMapProjection(const QGeoCoordinate &coordinate) const -{ - Q_D(const QGeoTiledMapScene); - return d->geoToMapProjection(coordinate); -} - -QGeoCoordinate QGeoTiledMapScene::mapProjectionToGeo(const QDoubleVector2D &projection) const -{ - Q_D(const QGeoTiledMapScene); - return d->mapProjectionToGeo(projection); -} - -QDoubleVector2D QGeoTiledMapScene::wrapMapProjection(const QDoubleVector2D &projection) const -{ - Q_D(const QGeoTiledMapScene); - return d->wrapMapProjection(projection); -} - -QDoubleVector2D QGeoTiledMapScene::unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const -{ - Q_D(const QGeoTiledMapScene); - return d->unwrapMapProjection(wrappedProjection); -} - -QDoubleVector2D QGeoTiledMapScene::wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const -{ - Q_D(const QGeoTiledMapScene); - return d->wrappedMapProjectionToItemPosition(wrappedProjection); -} - -QDoubleVector2D QGeoTiledMapScene::itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const -{ - Q_D(const QGeoTiledMapScene); - return d->itemPositionToWrappedMapProjection(itemPosition); -} - QSet<QGeoTileSpec> QGeoTiledMapScene::texturedTiles() { Q_D(QGeoTiledMapScene); @@ -254,10 +190,6 @@ QGeoTiledMapScenePrivate::QGeoTiledMapScenePrivate() m_maxTileX(-1), m_maxTileY(-1), m_tileXWrapsBelow(0), - m_cameraCenterXMercator(0), - m_cameraCenterYMercator(0), - m_cameraWidthMercator(0), - m_cameraHeightMercator(0), m_screenWidth(0.0), m_screenHeight(0.0), m_linearScaling(false), @@ -269,79 +201,6 @@ QGeoTiledMapScenePrivate::~QGeoTiledMapScenePrivate() { } -// Old screenToMercator logic -QDoubleVector2D QGeoTiledMapScenePrivate::itemPositionToMercator(const QDoubleVector2D &pos) const -{ - return unwrapMapProjection(itemPositionToWrappedMapProjection(pos)); -} - -// Old mercatorToScreen logic -QDoubleVector2D QGeoTiledMapScenePrivate::mercatorToItemPosition(const QDoubleVector2D &mercator) const -{ - return wrappedMapProjectionToItemPosition(wrapMapProjection(mercator)); -} - -QDoubleVector2D QGeoTiledMapScenePrivate::geoToMapProjection(const QGeoCoordinate &coordinate) const -{ - return QWebMercator::coordToMercator(coordinate); -} - -QGeoCoordinate QGeoTiledMapScenePrivate::mapProjectionToGeo(const QDoubleVector2D &projection) const -{ - return QWebMercator::mercatorToCoord(projection); -} - -//wraps around center -QDoubleVector2D QGeoTiledMapScenePrivate::wrapMapProjection(const QDoubleVector2D &projection) const -{ - double x = projection.x(); - if (m_cameraCenterXMercator < 0.5) { - if (x - m_cameraCenterXMercator > 0.5 ) - x -= 1.0; - } else if (m_cameraCenterXMercator > 0.5) { - if (x - m_cameraCenterXMercator < -0.5 ) - x += 1.0; - } - - return QDoubleVector2D(x, projection.y()); -} - -QDoubleVector2D QGeoTiledMapScenePrivate::unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const -{ - double x = wrappedProjection.x(); - if (x > 1.0) - return QDoubleVector2D(x - 1.0, wrappedProjection.y()); - if (x <= 0.0) - return QDoubleVector2D(x + 1.0, wrappedProjection.y()); - return wrappedProjection; -} - -QDoubleVector2D QGeoTiledMapScenePrivate::wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const -{ - // TODO: Support tilt/bearing through a projection matrix. - double x = ((wrappedProjection.x() - m_cameraCenterXMercator) * m_1_cameraWidthMercator + 0.5) * m_screenSize.width(); - double y = ((wrappedProjection.y() - m_cameraCenterYMercator) * m_1_cameraHeightMercator + 0.5) * m_screenSize.height(); - return QDoubleVector2D(x, y); -} - -QDoubleVector2D QGeoTiledMapScenePrivate::itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const -{ - // TODO: Support tilt/bearing through an inverse projection matrix. - double x = itemPosition.x(); - x /= m_screenSize.width(); - x -= 0.5; - x *= m_cameraWidthMercator; - x += m_cameraCenterXMercator; - - double y = itemPosition.y(); - y /= m_screenSize.height(); - y -= 0.5; - y *= m_cameraHeightMercator; - y += m_cameraCenterYMercator; - - return QDoubleVector2D(x, y); -} - bool QGeoTiledMapScenePrivate::buildGeometry(const QGeoTileSpec &spec, QSGImageNode *imageNode) { int x = spec.x(); @@ -508,19 +367,12 @@ void QGeoTiledMapScenePrivate::setupCamera() // the tiles or repeated tiles) double altitude = f / (2.0 * z) ; - m_cameraWidthMercator = m_screenSize.width() / m_mapEdgeSize; - m_cameraHeightMercator = m_screenSize.height() / m_mapEdgeSize; - m_1_cameraWidthMercator = 1.0 / m_cameraWidthMercator; - m_1_cameraHeightMercator = 1.0 / m_cameraHeightMercator; - // calculate center double edge = m_scaleFactor * m_tileSize; // first calculate the camera center in map space in the range of 0 <-> sideLength (2^z) QDoubleVector2D camCenterMercator = QWebMercator::coordToMercator(m_cameraData.center()); QDoubleVector3D center = m_sideLength * camCenterMercator; - m_cameraCenterXMercator = camCenterMercator.x(); - m_cameraCenterYMercator = camCenterMercator.y(); // wrap the center if necessary (due to dateline crossing) if (center.x() < m_tileXWrapsBelow) diff --git a/src/location/maps/qgeotiledmapscene_p.h b/src/location/maps/qgeotiledmapscene_p.h index 1e84457f..da7829a3 100644 --- a/src/location/maps/qgeotiledmapscene_p.h +++ b/src/location/maps/qgeotiledmapscene_p.h @@ -78,20 +78,6 @@ public: void addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture); - double mapEdgeSize() const; - - QDoubleVector2D itemPositionToMercator(const QDoubleVector2D &pos) const; - QDoubleVector2D mercatorToItemPosition(const QDoubleVector2D &mercator) const; - - QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const; - QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const; - - QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const; - QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const; - - QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const; - QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const; - QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window); QSet<QGeoTileSpec> texturedTiles(); diff --git a/tests/auto/qgeocameradata/qgeocameradata.pro b/tests/auto/qgeocameradata/qgeocameradata.pro index f2d6d5d8..80069ea1 100644 --- a/tests/auto/qgeocameradata/qgeocameradata.pro +++ b/tests/auto/qgeocameradata/qgeocameradata.pro @@ -6,4 +6,4 @@ INCLUDEPATH += ../../../src/location/maps SOURCES += tst_qgeocameradata.cpp -QT += location positioning-private testlib +QT += location-private positioning-private testlib diff --git a/tests/auto/qgeocameratiles/qgeocameratiles.pro b/tests/auto/qgeocameratiles/qgeocameratiles.pro index 816e4240..63ab2771 100644 --- a/tests/auto/qgeocameratiles/qgeocameratiles.pro +++ b/tests/auto/qgeocameratiles/qgeocameratiles.pro @@ -5,4 +5,4 @@ INCLUDEPATH += ../../../src/location/maps SOURCES += tst_qgeocameratiles.cpp -QT += location positioning-private testlib +QT += location-private positioning-private testlib diff --git a/tests/auto/qgeocameratiles/tst_qgeocameratiles.cpp b/tests/auto/qgeocameratiles/tst_qgeocameratiles.cpp index 7a3ab513..33ebda67 100644 --- a/tests/auto/qgeocameratiles/tst_qgeocameratiles.cpp +++ b/tests/auto/qgeocameratiles/tst_qgeocameratiles.cpp @@ -28,10 +28,10 @@ //TESTED_COMPONENT=src/location/maps -#include "qgeotilespec_p.h" -#include "qgeocameratiles_p.h" -#include "qgeocameradata_p.h" -#include "qgeomaptype_p.h" +#include <QtLocation/private/qgeotilespec_p.h> +#include <QtLocation/private/qgeocameratiles_p.h> +#include <QtLocation/private/qgeocameradata_p.h> +#include <QtLocation/private/qgeomaptype_p.h> #include <QtPositioning/private/qwebmercator_p.h> #include <QtPositioning/private/qdoublevector2d_p.h> diff --git a/tests/auto/qgeotiledmapscene/qgeotiledmapscene.pro b/tests/auto/qgeotiledmapscene/qgeotiledmapscene.pro index c3ec6e91..0db4b544 100644 --- a/tests/auto/qgeotiledmapscene/qgeotiledmapscene.pro +++ b/tests/auto/qgeotiledmapscene/qgeotiledmapscene.pro @@ -5,4 +5,4 @@ INCLUDEPATH += ../../../src/location/maps SOURCES += tst_qgeotiledmapscene.cpp -QT += location positioning-private testlib +QT += location-private positioning-private testlib diff --git a/tests/auto/qgeotiledmapscene/tst_qgeotiledmapscene.cpp b/tests/auto/qgeotiledmapscene/tst_qgeotiledmapscene.cpp index 0935c3f7..91b3eda8 100644 --- a/tests/auto/qgeotiledmapscene/tst_qgeotiledmapscene.cpp +++ b/tests/auto/qgeotiledmapscene/tst_qgeotiledmapscene.cpp @@ -33,7 +33,7 @@ #include "qgeocameratiles_p.h" #include "qgeocameradata_p.h" #include "qabstractgeotilecache_p.h" - +#include <QtLocation/private/qgeoprojection_p.h> #include <QtPositioning/private/qwebmercator_p.h> #include <QtPositioning/private/qdoublevector2d_p.h> @@ -247,8 +247,8 @@ class tst_QGeoTiledMapScene : public QObject int screenWidth; int screenHeight; QString name; - tileSize = 16; - zoom = 1.0; // 4 tiles in the map. map size = 32x32 + tileSize = 256; + zoom = 1.0; // 4 tiles in the map. map size = 2*tileSize x 2*tileSize /* ScreenWidth = t @@ -317,8 +317,12 @@ class tst_QGeoTiledMapScene : public QObject mapGeometry.setCameraData(camera); mapGeometry.setVisibleTiles(ct.createTiles()); + QGeoProjectionWebMercator projection; + projection.setViewportSize(QSize(screenWidth,screenHeight)); + projection.setCameraData(camera); + QDoubleVector2D point(screenX,screenY); - QDoubleVector2D mercartorPos = mapGeometry.itemPositionToMercator(point); + QDoubleVector2D mercartorPos = projection.unwrapMapProjection(projection.itemPositionToWrappedMapProjection(point)); QCOMPARE(mercartorPos.x(), mercatorX); QCOMPARE(mercartorPos.y(), mercatorY); @@ -358,8 +362,12 @@ class tst_QGeoTiledMapScene : public QObject mapGeometry.setCameraData(camera); mapGeometry.setVisibleTiles(ct.createTiles()); + QGeoProjectionWebMercator projection; + projection.setViewportSize(QSize(screenWidth,screenHeight)); + projection.setCameraData(camera); + QDoubleVector2D mercatorPos(mercatorX, mercatorY); - QPointF point = mapGeometry.mercatorToItemPosition(mercatorPos).toPointF(); + QPointF point = projection.wrappedMapProjectionToItemPosition(projection.wrapMapProjection(mercatorPos)).toPointF(); QVERIFY2((point.x() == screenX) || (point.x() == screenX2), qPrintable(QString("Accepted: { %1 , %2 } Actual: %3") |