summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-08-24 16:44:46 -0400
committerAnsis Brammanis <brammanis@gmail.com>2015-09-03 15:42:43 -0400
commita126265b9780ee7cb8a2f1d9012b8902ff92f1a6 (patch)
tree9cb512c1d9a6f89fd62eaa5c6943a506a9b94eba
parent9607171612c4a40e41eddaff5230ad571571a5b9 (diff)
downloadqtlocation-mapboxgl-upstream/perspective-improved-gestures.tar.gz
improve gestures in perspective viewupstream/perspective-improved-gestures
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.
-rw-r--r--include/mbgl/map/map.hpp1
-rw-r--r--platform/default/glfw_view.cpp5
-rw-r--r--platform/ios/MGLMapView.mm11
-rw-r--r--src/mbgl/map/map.cpp5
-rw-r--r--src/mbgl/map/transform.cpp60
-rw-r--r--src/mbgl/map/transform.hpp1
6 files changed, 58 insertions, 25 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 6757691bb6..7ea803d310 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -104,6 +104,7 @@ public:
// Position
void moveBy(double dx, double dy, const Duration& = Duration::zero());
+ void setLatLng(LatLng latLng, vec2<double> point, const Duration& = Duration::zero());
void setLatLng(LatLng latLng, const Duration& = Duration::zero());
LatLng getLatLng() const;
void resetPosition();
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp
index 8453845d1e..762521d207 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/default/glfw_view.cpp
@@ -332,7 +332,10 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) {
double dx = x - view->lastX;
double dy = y - view->lastY;
if (dx || dy) {
- view->map->moveBy(dx, dy);
+ double flippedY = view->height - y;
+ view->map->setLatLng(
+ view->map->latLngForPixel(mbgl::vec2<double>(x - dx, flippedY + dy)),
+ mbgl::vec2<double>(x, flippedY));
}
} else if (view->rotating) {
view->map->rotateBy(view->lastX, view->lastY, x, y);
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 5fcd045b74..29377bf2c8 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -892,7 +892,14 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
CGPoint delta = CGPointMake([pan translationInView:pan.view].x - self.centerPoint.x,
[pan translationInView:pan.view].y - self.centerPoint.y);
- _mbglMap->moveBy(delta.x, delta.y);
+ double flippedY = self.bounds.size.height - [pan locationInView:pan.view].y;
+ _mbglMap->setLatLng(
+ _mbglMap->latLngForPixel(mbgl::vec2<double>(
+ [pan locationInView:pan.view].x - delta.x,
+ flippedY + delta.y)),
+ mbgl::vec2<double>(
+ [pan locationInView:pan.view].x,
+ flippedY));
self.centerPoint = CGPointMake(self.centerPoint.x + delta.x, self.centerPoint.y + delta.y);
@@ -1063,7 +1070,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
_mbglMap->setBearing(newDegrees,
[rotate locationInView:rotate.view].x,
- [rotate locationInView:rotate.view].y);
+ self.bounds.size.height - [rotate locationInView:rotate.view].y);
}
else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled)
{
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index f102b4570a..6ad754d03c 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -140,6 +140,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 5d3ccfdf56..50970727c3 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 eead72f4b1..365d7af446 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(); }