diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-01-13 00:47:50 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2016-01-14 00:40:03 -0800 |
commit | 8bad15bf8785bf7d47eef9f1bf3ab86cfa393481 (patch) | |
tree | 9401b99d37cc447dbca519d569008209ea6cbde2 /src | |
parent | a3d4aeefecadc3717dc27a53ae170a4c0e878ce8 (diff) | |
download | qtlocation-mapboxgl-8bad15bf8785bf7d47eef9f1bf3ab86cfa393481.tar.gz |
[core] Consolidated zoom and angle anchor logic
Made anchor a CameraOption for easeTo().
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/map/transform.cpp | 69 | ||||
-rw-r--r-- | src/mbgl/map/transform.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.cpp | 20 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.hpp | 5 |
4 files changed, 61 insertions, 35 deletions
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index dc541bc391..ab93b84fc0 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -35,6 +35,10 @@ static double _normalizeAngle(double angle, double anchorAngle) return angle; } +inline bool _validPoint(const PrecisionPoint& point) { + return !std::isnan(point.x) && !std::isnan(point.y); +} + Transform::Transform(View &view_, ConstrainMode constrainMode) : view(view_) , state(constrainMode) @@ -72,7 +76,7 @@ void Transform::jumpTo(const CameraOptions& camera) { } void Transform::moveBy(const PrecisionPoint& offset, const Duration& duration) { - if (!offset) { + if (!_validPoint(offset)) { return; } @@ -153,26 +157,14 @@ double Transform::getScale() const { return state.scale; } -void Transform::setScale(double scale, const PrecisionPoint& flippedAnchor, const Duration& duration) { +void Transform::setScale(double scale, const PrecisionPoint& anchor, const Duration& duration) { if (std::isnan(scale)) { return; } CameraOptions camera; - if (flippedAnchor) { - const double factor = scale / state.scale; - PrecisionPoint center = { - state.width / 2.0, - state.height / 2.0, - }; - PrecisionPoint anchor = { - flippedAnchor.x, - state.height - flippedAnchor.y, - }; - PrecisionPoint offset = anchor - center; - camera.center = state.pointToLatLng(anchor - offset / factor); - } camera.zoom = state.scaleZoom(scale); + camera.anchor = anchor; easeTo(camera, duration); } @@ -202,10 +194,27 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim } } + PrecisionPoint anchor = camera.anchor ? *camera.anchor : PrecisionPoint(NAN, NAN); + LatLng anchorLatLng; + if (_validPoint(anchor)) { + anchor.y = state.getHeight() - anchor.y; + anchorLatLng = state.pointToLatLng(anchor); + } + + const PrecisionPoint startPoint = { + state.lngX(startLatLng.longitude), + state.latY(startLatLng.latitude), + }; + const PrecisionPoint endPoint = { + state.lngX(latLng.longitude), + state.latY(latLng.latitude), + }; + Update update = state.getZoom() == zoom ? Update::Repaint : Update::Zoom; // Constrain camera options. zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom()); + const double scale = state.zoomScale(zoom); pitch = util::clamp(pitch, 0., util::PITCH_MAX); // Minimize rotation by taking the shorter path around the circle. @@ -219,6 +228,9 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim state.setLatLngZoom(latLng, zoom); state.angle = angle; state.pitch = pitch; + if (_validPoint(anchor)) { + state.moveLatLng(anchorLatLng, anchor); + } if (animation.transitionFinishFn) { animation.transitionFinishFn(); @@ -231,7 +243,6 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim state.Bc = startWorldSize / 360; state.Cc = startWorldSize / util::M2PI; - const double scale = state.zoomScale(zoom); const double startScale = state.scale; const double startAngle = state.angle; const double startPitch = state.pitch; @@ -245,9 +256,10 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim return ease.solve(t, 0.001); }, [=](double t) { + PrecisionPoint framePoint = util::interpolate(startPoint, endPoint, t); LatLng frameLatLng = { - util::interpolate(startLatLng.latitude, latLng.latitude, t), - util::interpolate(startLatLng.longitude, latLng.longitude, t), + state.yLat(framePoint.y, startWorldSize), + state.xLng(framePoint.x, startWorldSize), }; double frameScale = util::interpolate(startScale, scale, t); state.setLatLngZoom(frameLatLng, state.scaleZoom(frameScale)); @@ -258,6 +270,9 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim if (pitch != startPitch) { state.pitch = util::interpolate(startPitch, pitch, t); } + if (_validPoint(anchor)) { + state.moveLatLng(anchorLatLng, anchor); + } // At t = 1.0, a DidChangeAnimated notification should be sent from finish(). if (t < 1.0) { @@ -509,29 +524,15 @@ void Transform::setAngle(double angle, const Duration& duration) { setAngle(angle, {NAN, NAN}, duration); } -void Transform::setAngle(double angle, const PrecisionPoint& flippedAnchor, const Duration& duration) { +void Transform::setAngle(double angle, const PrecisionPoint& anchor, const Duration& duration) { if (std::isnan(angle)) { return; } - - PrecisionPoint anchor = { - flippedAnchor.x, - state.height - flippedAnchor.y, - }; - LatLng anchorLatLng; - - if (flippedAnchor) { - anchorLatLng = state.pointToLatLng(anchor); - setLatLng(anchorLatLng); - } CameraOptions camera; camera.angle = angle; + camera.anchor = anchor; easeTo(camera, duration); - - if (flippedAnchor) { - setLatLng(anchorLatLng, anchor); - } } double Transform::getAngle() const { diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp index b8dd808f58..69b09e5a4b 100644 --- a/src/mbgl/map/transform.hpp +++ b/src/mbgl/map/transform.hpp @@ -100,6 +100,8 @@ public: bool isPanning() const { return state.isPanning(); } private: + void moveLatLng(const LatLng&, const PrecisionPoint&); + View &view; TransformState state; diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index 9d01657494..c9c904dab9 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -369,6 +369,26 @@ void TransformState::constrain(double& scale_, double& x_, double& y_) const { y_ = std::max(-max_y, std::min(y_, max_y)); } +void TransformState::moveLatLng(const LatLng& latLng, const PrecisionPoint& anchor) { + if (!latLng || !anchor) { + return; + } + + auto coord = latLngToCoordinate(latLng); + auto coordAtPoint = pointToCoordinate(anchor); + auto coordCenter = pointToCoordinate({ width / 2.0f, height / 2.0f }); + + float columnDiff = coordAtPoint.column - coord.column; + float rowDiff = coordAtPoint.row - coord.row; + + auto newLatLng = coordinateToLatLng({ + coordCenter.column - columnDiff, + coordCenter.row - rowDiff, + coordCenter.zoom + }); + setLatLngZoom(newLatLng, coordCenter.zoom); +} + void TransformState::setLatLngZoom(const LatLng &latLng, double zoom) { double newScale = zoomScale(zoom); const double newWorldSize = newScale * util::tileSize; diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp index 2aa031fa16..2911d8624a 100644 --- a/src/mbgl/map/transform_state.hpp +++ b/src/mbgl/map/transform_state.hpp @@ -101,8 +101,11 @@ private: mat4 coordinatePointMatrix(double z) const; mat4 getPixelMatrix() const; + /** Recenter the map so that the given coordinate is located at the given + point on screen. */ + void moveLatLng(const LatLng&, const PrecisionPoint&); void setLatLngZoom(const LatLng &latLng, double zoom); - void setScalePoint(const double scale, const PrecisionPoint &point); + void setScalePoint(const double scale, const PrecisionPoint& point); private: ConstrainMode constrainMode; |