Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
First pass at simultaneous pan and rotate
Browse files Browse the repository at this point in the history
ref #1834
  • Loading branch information
1ec5 committed Jul 30, 2015
1 parent 58b9355 commit ad70296
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 54 deletions.
2 changes: 2 additions & 0 deletions include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ class Map : private util::noncopyable {
void cancelTransitions();
void setGestureInProgress(bool);

void easeTo(CameraOptions options, const Duration& = Duration::zero());

// Position
void moveBy(double dx, double dy, const Duration& = Duration::zero());
void setLatLng(LatLng latLng, const Duration& = Duration::zero());
Expand Down
8 changes: 8 additions & 0 deletions include/mbgl/util/geo.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef MBGL_UTIL_GEO
#define MBGL_UTIL_GEO

#include "optional.hpp"

namespace mbgl {

class TileID;
Expand Down Expand Up @@ -61,6 +63,12 @@ struct LatLngBounds {
}
};

struct CameraOptions {
mapbox::util::optional<LatLng> center;
mapbox::util::optional<double> zoom;
mapbox::util::optional<double> angle;
};

}

#endif
7 changes: 7 additions & 0 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ void Map::setGestureInProgress(bool inProgress) {
update();
}

#pragma mark -

void Map::easeTo(CameraOptions options, const Duration& duration) {
transform->easeTo(options, duration);
update();
}

#pragma mark - Position

void Map::moveBy(double dx, double dy, const Duration& duration) {
Expand Down
96 changes: 42 additions & 54 deletions src/mbgl/map/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ bool Transform::resize(const std::array<uint16_t, 2> size) {

#pragma mark - Position

void Transform::easeTo(const CameraOptions options, const Duration& duration) {
LatLng latLng = options.center ? *options.center : getLatLng();
double zoom = options.zoom ? *options.zoom : getZoom();
double angle = options.angle ? *options.angle : getAngle();
if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude) || std::isnan(zoom)) {
return;
}

double new_scale = std::pow(2.0, zoom);

const double s = new_scale * util::tileSize;
state.Bc = s / 360;
state.Cc = s / util::M2PI;

const double m = 1 - 1e-15;
const double f = std::fmin(std::fmax(std::sin(util::DEG2RAD * latLng.latitude), -m), m);

double xn = -latLng.longitude * state.Bc;
double yn = 0.5 * state.Cc * std::log((1 + f) / (1 - f));

_setScaleXYθ(new_scale, angle, xn, yn, duration);
}

void Transform::moveBy(const double dx, const double dy, const Duration& duration) {
if (std::isnan(dx) || std::isnan(dy)) {
return;
Expand Down Expand Up @@ -96,37 +119,13 @@ void Transform::_moveBy(const double dx, const double dy, const Duration& durati
}

void Transform::setLatLng(const LatLng latLng, const Duration& duration) {
if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude)) {
return;
}

const double m = 1 - 1e-15;
const double f = std::fmin(std::fmax(std::sin(util::DEG2RAD * latLng.latitude), -m), m);

double xn = -latLng.longitude * state.Bc;
double yn = 0.5 * state.Cc * std::log((1 + f) / (1 - f));

_setScaleXY(state.scale, xn, yn, duration);
CameraOptions options = { latLng, getZoom(), getAngle() };
easeTo(options, duration);
}

void Transform::setLatLngZoom(const LatLng latLng, const double zoom, const Duration& duration) {
if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude) || std::isnan(zoom)) {
return;
}

double new_scale = std::pow(2.0, zoom);

const double s = new_scale * util::tileSize;
state.Bc = s / 360;
state.Cc = s / util::M2PI;

const double m = 1 - 1e-15;
const double f = std::fmin(std::fmax(std::sin(util::DEG2RAD * latLng.latitude), -m), m);

double xn = -latLng.longitude * state.Bc;
double yn = 0.5 * state.Cc * std::log((1 + f) / (1 - f));

_setScaleXY(new_scale, xn, yn, duration);
CameraOptions options = { latLng, zoom, getAngle() };
easeTo(options, duration);
}


Expand Down Expand Up @@ -206,11 +205,19 @@ void Transform::_setScale(double new_scale, double cx, double cy, const Duration

void Transform::_setScaleXY(const double new_scale, const double xn, const double yn,
const Duration& duration) {
_setScaleXYθ(new_scale, state.angle, xn, yn, duration);
}

void Transform::_setScaleXYθ(const double new_scale, const double new_angle, const double xn, const double yn,
const Duration& duration) {
double scale = new_scale;
double x = xn;
double y = yn;

state.constrain(scale, y);

double angle = _normalizeAngle(new_angle, state.angle);
state.angle = _normalizeAngle(state.angle, angle);

if (duration == Duration::zero()) {
view.notifyMapChange(MapChangeRegionWillChange);
Expand All @@ -221,16 +228,20 @@ void Transform::_setScaleXY(const double new_scale, const double xn, const doubl
const double s = state.scale * util::tileSize;
state.Bc = s / 360;
state.Cc = s / util::M2PI;

state.angle = angle;

view.notifyMapChange(MapChangeRegionDidChange);
} else {
view.notifyMapChange(MapChangeRegionWillChangeAnimated);

const double startS = state.scale;
const double startA = state.angle;
const double startX = state.x;
const double startY = state.y;
state.panning = true;
state.scaling = true;
state.rotating = true;

startTransition(
[=](double t) {
Expand All @@ -240,12 +251,14 @@ void Transform::_setScaleXY(const double new_scale, const double xn, const doubl
const double s = state.scale * util::tileSize;
state.Bc = s / 360;
state.Cc = s / util::M2PI;
state.angle = util::wrap(util::interpolate(startA, angle, t), -M_PI, M_PI);
view.notifyMapChange(MapChangeRegionIsChanging);
return Update::Zoom;
},
[=] {
state.panning = false;
state.scaling = false;
state.rotating = false;
view.notifyMapChange(MapChangeRegionDidChangeAnimated);
}, duration);
}
Expand Down Expand Up @@ -315,32 +328,7 @@ void Transform::setAngle(const double new_angle, const double cx, const double c
}

void Transform::_setAngle(double new_angle, const Duration& duration) {
double angle = _normalizeAngle(new_angle, state.angle);
state.angle = _normalizeAngle(state.angle, angle);

if (duration == Duration::zero()) {
view.notifyMapChange(MapChangeRegionWillChange);

state.angle = angle;

view.notifyMapChange(MapChangeRegionDidChange);
} else {
view.notifyMapChange(MapChangeRegionWillChangeAnimated);

const double startA = state.angle;
state.rotating = true;

startTransition(
[=](double t) {
state.angle = util::wrap(util::interpolate(startA, angle, t), -M_PI, M_PI);
view.notifyMapChange(MapChangeRegionIsChanging);
return Update::Nothing;
},
[=] {
state.rotating = false;
view.notifyMapChange(MapChangeRegionDidChangeAnimated);
}, duration);
}
easeTo({getLatLng(), getZoom(), new_angle}, duration);
}

double Transform::getAngle() const {
Expand Down
4 changes: 4 additions & 0 deletions src/mbgl/map/transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class Transform : private util::noncopyable {
// Map view
bool resize(std::array<uint16_t, 2> size);

void easeTo(const CameraOptions options, const Duration& = Duration::zero());

// Position
void moveBy(double dx, double dy, const Duration& = Duration::zero());
void setLatLng(LatLng latLng, const Duration& = Duration::zero());
Expand Down Expand Up @@ -56,6 +58,8 @@ class Transform : private util::noncopyable {
void _moveBy(double dx, double dy, const Duration& = Duration::zero());
void _setScale(double scale, double cx, double cy, const Duration& = Duration::zero());
void _setScaleXY(double new_scale, double xn, double yn, const Duration& = Duration::zero());
void _setScaleXYθ(const double new_scale, const double new_angle, const double xn, const double yn,
const Duration& duration = Duration::zero());
void _setAngle(double angle, const Duration& = Duration::zero());

View &view;
Expand Down

0 comments on commit ad70296

Please sign in to comment.