summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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(); }