summaryrefslogtreecommitdiff
path: root/src/mbgl/map/transform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/map/transform.cpp')
-rw-r--r--src/mbgl/map/transform.cpp76
1 files changed, 35 insertions, 41 deletions
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index e97f0da3f1..88b559592e 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -77,13 +77,13 @@ void Transform::jumpTo(const CameraOptions& camera) {
}
/**
- * Change any combination of center, zoom, bearing, and pitch, with a smooth animation
- * between old and new values. The map will retain the current values for any options
- * not included in `options`.
+ * Change any combination of center, zoom, bearing, pitch and edgeInsets, with a
+ * smooth animation between old and new values. The map will retain the current
+ * values for any options not included in `options`.
*/
void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& animation) {
- const EdgeInsets& padding = camera.padding;
- LatLng startLatLng = getLatLng(padding, LatLng::Unwrapped);
+ const EdgeInsets& padding = camera.padding.value_or(state.edgeInsets);
+ LatLng startLatLng = getLatLng(LatLng::Unwrapped);
const LatLng& unwrappedLatLng = camera.center.value_or(startLatLng);
const LatLng& latLng = state.bounds != LatLngBounds::unbounded() ? unwrappedLatLng : unwrappedLatLng.wrapped();
double zoom = camera.zoom.value_or(getZoom());
@@ -110,9 +110,6 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
const Point<double> startPoint = Projection::project(startLatLng, state.scale);
const Point<double> endPoint = Projection::project(latLng, state.scale);
- ScreenCoordinate center = getScreenCoordinate(padding);
- center.y = state.size.height - center.y;
-
// Constrain camera options.
zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
const double scale = state.zoomScale(zoom);
@@ -130,6 +127,7 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
state.panning = unwrappedLatLng != startLatLng;
state.scaling = scale != startScale;
state.rotating = bearing != startBearing;
+ const EdgeInsets startEdgeInsets = state.edgeInsets;
startTransition(camera, animation, [=](double t) {
Point<double> framePoint = util::interpolate(startPoint, endPoint, t);
@@ -143,9 +141,14 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
if (pitch != startPitch) {
state.pitch = util::interpolate(startPitch, pitch, t);
}
-
- if (!padding.isFlush()) {
- state.moveLatLng(frameLatLng, center);
+ if (padding != startEdgeInsets) {
+ // Interpolate edge insets
+ state.edgeInsets = {
+ util::interpolate(startEdgeInsets.top(), padding.top(), t),
+ util::interpolate(startEdgeInsets.left(), padding.left(), t),
+ util::interpolate(startEdgeInsets.bottom(), padding.bottom(), t),
+ util::interpolate(startEdgeInsets.right(), padding.right(), t)
+ };
}
}, duration);
}
@@ -159,8 +162,8 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
Where applicable, local variable documentation begins with the associated
variable or function in van Wijk (2003). */
void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &animation) {
- const EdgeInsets& padding = camera.padding;
- const LatLng& latLng = camera.center.value_or(getLatLng(padding, LatLng::Unwrapped)).wrapped();
+ const EdgeInsets& padding = camera.padding.value_or(state.edgeInsets);
+ const LatLng& latLng = camera.center.value_or(getLatLng(LatLng::Unwrapped)).wrapped();
double zoom = camera.zoom.value_or(getZoom());
double bearing = camera.bearing ? -*camera.bearing * util::DEG2RAD : getBearing();
double pitch = camera.pitch ? *camera.pitch * util::DEG2RAD : getPitch();
@@ -170,15 +173,12 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
}
// Determine endpoints.
- LatLng startLatLng = getLatLng(padding, LatLng::Unwrapped).wrapped();
+ LatLng startLatLng = getLatLng(LatLng::Unwrapped).wrapped();
startLatLng.unwrapForShortestPath(latLng);
const Point<double> startPoint = Projection::project(startLatLng, state.scale);
const Point<double> endPoint = Projection::project(latLng, state.scale);
- ScreenCoordinate center = getScreenCoordinate(padding);
- center.y = state.size.height - center.y;
-
// Constrain camera options.
zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
pitch = util::clamp(pitch, util::PITCH_MIN, util::PITCH_MAX);
@@ -278,6 +278,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
state.panning = true;
state.scaling = true;
state.rotating = bearing != startBearing;
+ const EdgeInsets startEdgeInsets = state.edgeInsets;
startTransition(camera, animation, [=](double k) {
/// s: The distance traveled along the flight path, measured in
@@ -304,9 +305,14 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
if (pitch != startPitch) {
state.pitch = util::interpolate(startPitch, pitch, k);
}
-
- if (!padding.isFlush()) {
- state.moveLatLng(frameLatLng, center);
+ if (padding != startEdgeInsets) {
+ // Interpolate edge insets
+ state.edgeInsets = {
+ util::interpolate(startEdgeInsets.top(), padding.top(), us),
+ util::interpolate(startEdgeInsets.left(), padding.left(), us),
+ util::interpolate(startEdgeInsets.bottom(), padding.bottom(), us),
+ util::interpolate(startEdgeInsets.right(), padding.right(), us)
+ };
}
}, duration);
}
@@ -314,28 +320,16 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
#pragma mark - Position
void Transform::moveBy(const ScreenCoordinate& offset, const AnimationOptions& animation) {
- ScreenCoordinate centerOffset = { offset.x, -offset.y, };
- ScreenCoordinate centerPoint = getScreenCoordinate() - centerOffset;
- easeTo(CameraOptions().withCenter(state.screenCoordinateToLatLng(centerPoint)), animation);
-}
-
-LatLng Transform::getLatLng(const EdgeInsets& padding, LatLng::WrapMode wrap) const {
- if (padding.isFlush()) {
- return state.getLatLng(wrap);
- } else {
- return screenCoordinateToLatLng(padding.getCenter(state.size.width, state.size.height));
- }
+ ScreenCoordinate centerOffset = { offset.x, offset.y };
+ ScreenCoordinate pointOnScreen = state.edgeInsets.getCenter(state.size.width, state.size.height) - centerOffset;
+ // Use unwrapped LatLng to carry information about moveBy direction.
+ easeTo(CameraOptions().withCenter(screenCoordinateToLatLng(pointOnScreen, LatLng::Unwrapped)), animation);
}
-ScreenCoordinate Transform::getScreenCoordinate(const EdgeInsets& padding) const {
- if (padding.isFlush()) {
- return { state.size.width / 2., state.size.height / 2. };
- } else {
- return padding.getCenter(state.size.width, state.size.height);
- }
+LatLng Transform::getLatLng(LatLng::WrapMode wrap) const {
+ return state.getLatLng(wrap);
}
-
#pragma mark - Zoom
double Transform::getZoom() const {
@@ -364,7 +358,7 @@ void Transform::setMaxZoom(const double maxZoom) {
#pragma mark - Bearing
void Transform::rotateBy(const ScreenCoordinate& first, const ScreenCoordinate& second, const AnimationOptions& animation) {
- ScreenCoordinate center = getScreenCoordinate();
+ ScreenCoordinate center = state.edgeInsets.getCenter(state.size.width, state.size.height);
const ScreenCoordinate offset = first - center;
const double distance = std::sqrt(std::pow(2, offset.x) + std::pow(2, offset.y));
@@ -576,10 +570,10 @@ ScreenCoordinate Transform::latLngToScreenCoordinate(const LatLng& latLng) const
return point;
}
-LatLng Transform::screenCoordinateToLatLng(const ScreenCoordinate& point) const {
+LatLng Transform::screenCoordinateToLatLng(const ScreenCoordinate& point, LatLng::WrapMode wrapMode) const {
ScreenCoordinate flippedPoint = point;
flippedPoint.y = state.size.height - flippedPoint.y;
- return state.screenCoordinateToLatLng(flippedPoint).wrapped();
+ return state.screenCoordinateToLatLng(flippedPoint, wrapMode);
}
} // namespace mbgl