summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-08-24 16:44:46 -0400
committerMinh Nguyễn <mxn@1ec5.org>2015-10-26 12:48:03 -0700
commit750c72f324464e8c2a91c8148299cc57c520c5c4 (patch)
treea8bbfe397a7d225a11b182913e8688feb9da8bbd /src
parentbb6241844a092cf632fe740e6ac79c920117dd4e (diff)
downloadqtlocation-mapboxgl-750c72f324464e8c2a91c8148299cc57c520c5c4.tar.gz
improve gestures in perspective view
The location under your finger stays under your finger as you pan. The location you double tap to zoom stays at the same point. The location at the center of a pinch zoom stays at the center. The location at the center of a rotation stays at the center.
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/map.cpp5
-rw-r--r--src/mbgl/map/transform.cpp60
-rw-r--r--src/mbgl/map/transform.hpp1
3 files changed, 44 insertions, 22 deletions
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 729726837d..a1823dc8e1 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -166,6 +166,11 @@ void Map::setLatLng(LatLng latLng, const Duration& duration) {
update(Update::Repaint);
}
+void Map::setLatLng(LatLng latLng, vec2<double> point, const Duration& duration) {
+ transform->setLatLng(latLng, point, duration);
+ update(Update::Repaint);
+}
+
LatLng Map::getLatLng() const {
return transform->getLatLng();
}
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index bb55909149..87e86ea3e6 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -6,6 +6,7 @@
#include <mbgl/util/math.hpp>
#include <mbgl/util/unitbezier.hpp>
#include <mbgl/util/interpolate.hpp>
+#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/platform/platform.hpp>
#include <cstdio>
@@ -113,6 +114,27 @@ void Transform::setLatLng(const LatLng latLng, const Duration& duration) {
easeTo(options);
}
+void Transform::setLatLng(const LatLng latLng, vec2<double> point, const Duration& duration) {
+ if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude)) {
+ return;
+ }
+
+ auto coord = state.latLngToCoordinate(latLng);
+ auto coordAtPoint = state.pointToCoordinate(point);
+ auto coordCenter = state.pointToCoordinate({ state.width / 2.0f, state.height / 2.0f });
+
+ float columnDiff = coordAtPoint.column - coord.column;
+ float rowDiff = coordAtPoint.row - coord.row;
+
+ auto newLatLng = state.coordinateToLatLng({
+ coordCenter.column - columnDiff,
+ coordCenter.row - rowDiff,
+ coordCenter.zoom
+ });
+
+ setLatLng(newLatLng, duration);
+}
+
void Transform::setLatLngZoom(const LatLng latLng, const double zoom, const Duration& duration) {
CameraOptions options;
options.center = latLng;
@@ -173,25 +195,20 @@ void Transform::_setScale(double new_scale, double cx, double cy, const Duration
new_scale = state.max_scale;
}
- // Zoom in on the center if we don't have click or gesture anchor coordinates.
- if (cx < 0 || cy < 0) {
- cx = static_cast<double>(state.width) / 2.0;
- cy = static_cast<double>(state.height) / 2.0;
- }
-
- // Account for the x/y offset from the center (= where the user clicked or pinched)
const double factor = new_scale / state.scale;
- const double dx = (cx - static_cast<double>(state.width) / 2.0) * (1.0 - factor);
- const double dy = (cy - static_cast<double>(state.height) / 2.0) * (1.0 - factor);
-
- // Account for angle
- const double angle_sin = std::sin(-state.angle);
- const double angle_cos = std::cos(-state.angle);
- const double ax = angle_cos * dx - angle_sin * dy;
- const double ay = angle_sin * dx + angle_cos * dy;
+ double dx = 0;
+ double dy = 0;
+
+ if (cx > 0 || cy > 0) {
+ auto coord = state.pointToCoordinate({ cx, state.getHeight() - cy }).zoomTo(state.getZoom());
+ auto centerCoord = state.pointToCoordinate({ state.width / 2.0f, state.height / 2.0f }).zoomTo(state.getZoom());
+ auto coordDiff = centerCoord - coord;
+ dx = coordDiff.column * util::tileSize * (1.0 - factor);
+ dy = coordDiff.row * util::tileSize * (1.0 - factor);
+ }
- const double xn = state.x * factor + ax;
- const double yn = state.y * factor + ay;
+ const double xn = state.x * factor - dx;
+ const double yn = state.y * factor - dy;
_setScaleXY(new_scale, xn, yn, duration);
}
@@ -318,18 +335,17 @@ void Transform::setAngle(const double new_angle, const double cx, const double c
return;
}
- double dx = 0, dy = 0;
+ LatLng rotationCenter;
if (cx >= 0 && cy >= 0) {
- dx = (static_cast<double>(state.width) / 2.0) - cx;
- dy = (static_cast<double>(state.height) / 2.0) - cy;
- _moveBy(dx, dy, Duration::zero());
+ rotationCenter = state.pointToLatLng({ cx, cy });
+ setLatLng(rotationCenter, Duration::zero());
}
_setAngle(new_angle);
if (cx >= 0 && cy >= 0) {
- _moveBy(-dx, -dy, Duration::zero());
+ setLatLng(rotationCenter, { cx, cy }, Duration::zero());
}
}
diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp
index 545d8a3b21..a72e9f24ef 100644
--- a/src/mbgl/map/transform.hpp
+++ b/src/mbgl/map/transform.hpp
@@ -29,6 +29,7 @@ public:
// Position
void moveBy(double dx, double dy, const Duration& = Duration::zero());
void setLatLng(LatLng latLng, const Duration& = Duration::zero());
+ void setLatLng(LatLng latLng, vec2<double> point, const Duration& duration = Duration::zero());
void setLatLngZoom(LatLng latLng, double zoom, const Duration& = Duration::zero());
inline const LatLng getLatLng() const { return state.getLatLng(); }