summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-01-13 00:47:50 -0800
committerMinh Nguyễn <mxn@1ec5.org>2016-01-14 00:40:03 -0800
commit8bad15bf8785bf7d47eef9f1bf3ab86cfa393481 (patch)
tree9401b99d37cc447dbca519d569008209ea6cbde2 /src
parenta3d4aeefecadc3717dc27a53ae170a4c0e878ce8 (diff)
downloadqtlocation-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.cpp69
-rw-r--r--src/mbgl/map/transform.hpp2
-rw-r--r--src/mbgl/map/transform_state.cpp20
-rw-r--r--src/mbgl/map/transform_state.hpp5
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;