|
|
|
|
@@ -62,64 +62,29 @@ bool Transform::resize(const std::array<uint16_t, 2> size) {
|
|
|
|
|
|
|
|
|
|
#pragma mark - Position
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
/**
|
|
|
|
|
* Change any combination of center, zoom, bearing, and pitch, without
|
|
|
|
|
* a transition. The map will retain the current values for any options
|
|
|
|
|
* not included in `options`.
|
|
|
|
|
*/
|
|
|
|
|
void Transform::jumpTo(const CameraOptions& camera) {
|
|
|
|
|
easeTo(camera, {});
|
|
|
|
|
easeTo(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`.
|
|
|
|
|
*/
|
|
|
|
|
void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& animation) {
|
|
|
|
|
CameraOptions easeCamera(camera);
|
|
|
|
|
LatLng latLng = easeCamera.center ? *easeCamera.center : getLatLng();
|
|
|
|
|
double zoom = easeCamera.zoom ? *easeCamera.zoom : getZoom();
|
|
|
|
|
double angle = easeCamera.angle ? *easeCamera.angle : getAngle();
|
|
|
|
|
if (!latLng || std::isnan(zoom) || std::isnan(angle)) {
|
|
|
|
|
void Transform::moveBy(const PrecisionPoint& offset, const Duration& duration) {
|
|
|
|
|
if (!offset) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double new_scale = state.zoomScale(zoom);
|
|
|
|
|
PrecisionPoint centerOffset = {
|
|
|
|
|
offset.x,
|
|
|
|
|
-offset.y,
|
|
|
|
|
};
|
|
|
|
|
PrecisionPoint centerPoint = state.latLngToPoint(state.getLatLng()) - centerOffset;
|
|
|
|
|
|
|
|
|
|
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 = ::fmin(::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));
|
|
|
|
|
|
|
|
|
|
easeCamera.center.reset();
|
|
|
|
|
easeCamera.zoom.reset();
|
|
|
|
|
easeCamera.angle.reset();
|
|
|
|
|
_easeTo(easeCamera, animation, new_scale, angle, xn, yn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::moveBy(const PrecisionPoint& point, const Duration& duration) {
|
|
|
|
|
if (!point) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_moveBy(point, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::_moveBy(const PrecisionPoint& point, const Duration& duration) {
|
|
|
|
|
double x = state.x + std::cos(state.angle) * point.x + std::sin( state.angle) * point.y;
|
|
|
|
|
double y = state.y + std::cos(state.angle) * point.y + std::sin(-state.angle) * point.x;
|
|
|
|
|
|
|
|
|
|
state.constrain(state.scale, x, y);
|
|
|
|
|
|
|
|
|
|
AnimationOptions animation;
|
|
|
|
|
animation.duration = duration;
|
|
|
|
|
_easeTo({}, animation, state.scale, state.angle, x, y);
|
|
|
|
|
CameraOptions camera;
|
|
|
|
|
camera.center = state.pointToLatLng(centerPoint);
|
|
|
|
|
easeTo(camera, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::setLatLng(const LatLng& latLng, const Duration& duration) {
|
|
|
|
|
@@ -129,9 +94,7 @@ void Transform::setLatLng(const LatLng& latLng, const Duration& duration) {
|
|
|
|
|
|
|
|
|
|
CameraOptions camera;
|
|
|
|
|
camera.center = latLng;
|
|
|
|
|
AnimationOptions animation;
|
|
|
|
|
animation.duration = duration;
|
|
|
|
|
easeTo(camera, animation);
|
|
|
|
|
easeTo(camera, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::setLatLng(const LatLng& latLng, const PrecisionPoint& point, const Duration& duration) {
|
|
|
|
|
@@ -163,44 +126,23 @@ void Transform::setLatLngZoom(const LatLng& latLng, double zoom, const Duration&
|
|
|
|
|
CameraOptions camera;
|
|
|
|
|
camera.center = latLng;
|
|
|
|
|
camera.zoom = zoom;
|
|
|
|
|
AnimationOptions animation;
|
|
|
|
|
animation.duration = duration;
|
|
|
|
|
easeTo(camera, animation);
|
|
|
|
|
easeTo(camera, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark - Zoom
|
|
|
|
|
|
|
|
|
|
void Transform::scaleBy(double ds, const PrecisionPoint& center, const Duration& duration) {
|
|
|
|
|
if (std::isnan(ds) || !center) {
|
|
|
|
|
if (std::isnan(ds)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// clamp scale to min/max values
|
|
|
|
|
double new_scale = state.scale * ds;
|
|
|
|
|
if (new_scale < state.min_scale) {
|
|
|
|
|
new_scale = state.min_scale;
|
|
|
|
|
} else if (new_scale > state.max_scale) {
|
|
|
|
|
new_scale = state.max_scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_setScale(new_scale, center, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::setScale(double scale, const PrecisionPoint& center, const Duration& duration) {
|
|
|
|
|
if (std::isnan(scale) || !center) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_setScale(scale, center, duration);
|
|
|
|
|
double scale = util::clamp(state.scale * ds, state.min_scale, state.max_scale);
|
|
|
|
|
setScale(scale, center, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::setZoom(double zoom, const Duration& duration) {
|
|
|
|
|
if (std::isnan(zoom)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_setScale(std::pow(2.0, zoom), { 0, 0 }, duration);
|
|
|
|
|
setScale(state.zoomScale(zoom), {NAN, NAN}, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double Transform::getZoom() const {
|
|
|
|
|
@@ -211,52 +153,80 @@ double Transform::getScale() const {
|
|
|
|
|
return state.scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::_setScale(double new_scale, const PrecisionPoint& center, const Duration& duration) {
|
|
|
|
|
const double factor = new_scale / state.scale;
|
|
|
|
|
double dx = 0;
|
|
|
|
|
double dy = 0;
|
|
|
|
|
|
|
|
|
|
if (center.x > 0 || center.y > 0) {
|
|
|
|
|
auto coord = state.pointToCoordinate({ center.x, state.getHeight() - center.y }).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);
|
|
|
|
|
void Transform::setScale(double scale, const PrecisionPoint& anchor, const Duration& duration) {
|
|
|
|
|
if (std::isnan(scale)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const double factor = scale / state.scale;
|
|
|
|
|
PrecisionPoint offset = { 0, 0 };
|
|
|
|
|
PrecisionPoint center = {
|
|
|
|
|
state.width / 2.0f,
|
|
|
|
|
state.height / 2.0f,
|
|
|
|
|
};
|
|
|
|
|
if (anchor) {
|
|
|
|
|
offset = {
|
|
|
|
|
anchor.x - center.x,
|
|
|
|
|
center.y - anchor.y,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const double xn = state.x * factor - dx;
|
|
|
|
|
const double yn = state.y * factor - dy;
|
|
|
|
|
|
|
|
|
|
AnimationOptions animation;
|
|
|
|
|
animation.duration = duration;
|
|
|
|
|
_easeTo({}, animation, new_scale, state.angle, xn, yn);
|
|
|
|
|
CameraOptions camera;
|
|
|
|
|
camera.center = state.pointToLatLng(center + offset / factor);
|
|
|
|
|
camera.zoom = state.scaleZoom(scale);
|
|
|
|
|
easeTo(camera, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::_easeTo(const CameraOptions& camera, const AnimationOptions& animation,
|
|
|
|
|
double new_scale, double new_angle, double xn, double yn) {
|
|
|
|
|
Update update = state.scale == new_scale ? Update::Repaint : Update::Zoom;
|
|
|
|
|
double scale = new_scale;
|
|
|
|
|
double x = xn;
|
|
|
|
|
double y = yn;
|
|
|
|
|
|
|
|
|
|
state.constrain(scale, x, y);
|
|
|
|
|
/**
|
|
|
|
|
* 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`.
|
|
|
|
|
*/
|
|
|
|
|
void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& animation) {
|
|
|
|
|
LatLng latLng = camera.center ? *camera.center : getLatLng();
|
|
|
|
|
double zoom = camera.zoom ? *camera.zoom : getZoom();
|
|
|
|
|
double angle = camera.angle ? *camera.angle : getAngle();
|
|
|
|
|
double pitch = camera.pitch ? *camera.pitch : getPitch();
|
|
|
|
|
|
|
|
|
|
double angle = _normalizeAngle(new_angle, state.angle);
|
|
|
|
|
state.angle = _normalizeAngle(state.angle, angle);
|
|
|
|
|
double pitch = camera.pitch ? *camera.pitch : state.pitch;
|
|
|
|
|
if (!latLng || std::isnan(zoom)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If a path crossing the antemeridian would be shorter, extend the final
|
|
|
|
|
// coordinate so that interpolating between the two endpoints will cross it.
|
|
|
|
|
LatLng startLatLng = getLatLng();
|
|
|
|
|
if (std::abs(startLatLng.longitude) + std::abs(latLng.longitude) > 180) {
|
|
|
|
|
if (startLatLng.longitude > 0 && latLng.longitude < 0) {
|
|
|
|
|
latLng.longitude += 360;
|
|
|
|
|
} else if (startLatLng.longitude < 0 && latLng.longitude > 0) {
|
|
|
|
|
latLng.longitude -= 360;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const PrecisionPoint startPoint = {
|
|
|
|
|
state.lngX(startLatLng.longitude),
|
|
|
|
|
state.latY(startLatLng.latitude),
|
|
|
|
|
};
|
|
|
|
|
const PrecisionPoint endPoint = {
|
|
|
|
|
state.lngX(latLng.longitude),
|
|
|
|
|
state.latY(latLng.latitude),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Update update = state.getZoom() == zoom ? Update::Repaint : Update::Zoom;
|
|
|
|
|
|
|
|
|
|
// Constrain camera options.
|
|
|
|
|
zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
|
|
|
|
|
pitch = util::clamp(pitch, 0., util::PITCH_MAX);
|
|
|
|
|
|
|
|
|
|
// Minimize rotation by taking the shorter path around the circle.
|
|
|
|
|
angle = _normalizeAngle(angle, state.angle);
|
|
|
|
|
state.angle = _normalizeAngle(state.angle, angle);
|
|
|
|
|
|
|
|
|
|
Duration duration = animation.duration ? *animation.duration : Duration::zero();
|
|
|
|
|
if (duration == Duration::zero()) {
|
|
|
|
|
view.notifyMapChange(MapChangeRegionWillChange);
|
|
|
|
|
|
|
|
|
|
state.scale = scale;
|
|
|
|
|
state.x = x;
|
|
|
|
|
state.y = y;
|
|
|
|
|
const double s = state.scale * util::tileSize;
|
|
|
|
|
state.Bc = s / 360;
|
|
|
|
|
state.Cc = s / util::M2PI;
|
|
|
|
|
|
|
|
|
|
state.setLatLngZoom(latLng, zoom);
|
|
|
|
|
state.angle = angle;
|
|
|
|
|
state.pitch = pitch;
|
|
|
|
|
|
|
|
|
|
@@ -266,15 +236,18 @@ void Transform::_easeTo(const CameraOptions& camera, const AnimationOptions& ani
|
|
|
|
|
view.notifyMapChange(MapChangeRegionDidChange);
|
|
|
|
|
} else {
|
|
|
|
|
view.notifyMapChange(MapChangeRegionWillChangeAnimated);
|
|
|
|
|
|
|
|
|
|
const double startS = state.scale;
|
|
|
|
|
const double startA = state.angle;
|
|
|
|
|
const double startP = state.pitch;
|
|
|
|
|
const double startX = state.x;
|
|
|
|
|
const double startY = state.y;
|
|
|
|
|
state.panning = true;
|
|
|
|
|
state.scaling = true;
|
|
|
|
|
state.rotating = true;
|
|
|
|
|
|
|
|
|
|
const double startWorldSize = state.worldSize();
|
|
|
|
|
state.Bc = startWorldSize / 360;
|
|
|
|
|
state.Cc = startWorldSize / util::M2PI;
|
|
|
|
|
|
|
|
|
|
const double scale = state.zoomScale(zoom);
|
|
|
|
|
const double startScale = state.scale;
|
|
|
|
|
const double startAngle = state.angle;
|
|
|
|
|
const double startPitch = state.pitch;
|
|
|
|
|
state.panning = latLng != startLatLng;
|
|
|
|
|
state.scaling = scale != startScale;
|
|
|
|
|
state.rotating = angle != startAngle;
|
|
|
|
|
|
|
|
|
|
startTransition(
|
|
|
|
|
[=](double t) {
|
|
|
|
|
@@ -282,14 +255,24 @@ void Transform::_easeTo(const CameraOptions& camera, const AnimationOptions& ani
|
|
|
|
|
return ease.solve(t, 0.001);
|
|
|
|
|
},
|
|
|
|
|
[=](double t) {
|
|
|
|
|
state.scale = util::interpolate(startS, scale, t);
|
|
|
|
|
state.x = util::interpolate(startX, x, t);
|
|
|
|
|
state.y = util::interpolate(startY, y, t);
|
|
|
|
|
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);
|
|
|
|
|
state.pitch = util::interpolate(startP, pitch, t);
|
|
|
|
|
// Calculate the current point and zoom level along the flight path.
|
|
|
|
|
PrecisionPoint framePoint = util::interpolate(startPoint, endPoint, t);
|
|
|
|
|
double frameScale = util::interpolate(startScale, scale, t);
|
|
|
|
|
|
|
|
|
|
// Convert to geographic coordinates and set the new viewpoint.
|
|
|
|
|
LatLng frameLatLng = {
|
|
|
|
|
state.yLat(framePoint.y, startWorldSize),
|
|
|
|
|
state.xLng(framePoint.x, startWorldSize),
|
|
|
|
|
};
|
|
|
|
|
state.setLatLngZoom(frameLatLng, state.scaleZoom(frameScale));
|
|
|
|
|
|
|
|
|
|
if (angle != startAngle) {
|
|
|
|
|
state.angle = util::wrap(util::interpolate(startAngle, angle, t), -M_PI, M_PI);
|
|
|
|
|
}
|
|
|
|
|
if (pitch != startPitch) {
|
|
|
|
|
state.pitch = util::interpolate(startPitch, pitch, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// At t = 1.0, a DidChangeAnimated notification should be sent from finish().
|
|
|
|
|
if (t < 1.0) {
|
|
|
|
|
if (animation.transitionFrameFn) {
|
|
|
|
|
@@ -321,17 +304,17 @@ void Transform::_easeTo(const CameraOptions& camera, const AnimationOptions& ani
|
|
|
|
|
variable or function in van Wijk (2003). */
|
|
|
|
|
void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &animation) {
|
|
|
|
|
LatLng latLng = camera.center ? *camera.center : getLatLng();
|
|
|
|
|
LatLng startLatLng = getLatLng();
|
|
|
|
|
double zoom = camera.zoom ? *camera.zoom : getZoom();
|
|
|
|
|
double angle = camera.angle ? *camera.angle : getAngle();
|
|
|
|
|
double pitch = camera.pitch ? *camera.pitch : getPitch();
|
|
|
|
|
|
|
|
|
|
if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude) || std::isnan(zoom)) {
|
|
|
|
|
if (!latLng || std::isnan(zoom)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If a path crossing the antemeridian would be shorter, extend the final
|
|
|
|
|
// coordinate so that interpolating between the two endpoints will cross it.
|
|
|
|
|
LatLng startLatLng = getLatLng();
|
|
|
|
|
if (std::abs(startLatLng.longitude) + std::abs(latLng.longitude) > 180) {
|
|
|
|
|
if (startLatLng.longitude > 0 && latLng.longitude < 0) {
|
|
|
|
|
latLng.longitude += 360;
|
|
|
|
|
@@ -350,12 +333,11 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
|
|
|
|
|
pitch = util::clamp(pitch, 0., util::PITCH_MAX);
|
|
|
|
|
|
|
|
|
|
// Minimize rotation by taking the shorter path around the circle.
|
|
|
|
|
double normalizedAngle = _normalizeAngle(angle, state.angle);
|
|
|
|
|
state.angle = _normalizeAngle(state.angle, normalizedAngle);
|
|
|
|
|
|
|
|
|
|
pitch = util::clamp(pitch, 0., util::PITCH_MAX);
|
|
|
|
|
angle = _normalizeAngle(angle, state.angle);
|
|
|
|
|
state.angle = _normalizeAngle(state.angle, angle);
|
|
|
|
|
|
|
|
|
|
const double startZoom = state.scaleZoom(state.scale);
|
|
|
|
|
const double startAngle = state.angle;
|
|
|
|
|
@@ -469,7 +451,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
|
|
|
|
|
double us = u(s);
|
|
|
|
|
|
|
|
|
|
// Calculate the current point and zoom level along the flight path.
|
|
|
|
|
PrecisionPoint framePoint = startPoint + (endPoint - startPoint) * us;
|
|
|
|
|
PrecisionPoint framePoint = util::interpolate(startPoint, endPoint, us);
|
|
|
|
|
double frameZoom = startZoom + state.scaleZoom(1 / w(s));
|
|
|
|
|
|
|
|
|
|
// Convert to geographic coordinates and set the new viewpoint.
|
|
|
|
|
@@ -480,7 +462,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
|
|
|
|
|
state.setLatLngZoom(frameLatLng, frameZoom);
|
|
|
|
|
|
|
|
|
|
if (angle != startAngle) {
|
|
|
|
|
state.angle = util::wrap(util::interpolate(startAngle, normalizedAngle, k), -M_PI, M_PI);
|
|
|
|
|
state.angle = util::wrap(util::interpolate(startAngle, angle, k), -M_PI, M_PI);
|
|
|
|
|
}
|
|
|
|
|
if (pitch != startPitch) {
|
|
|
|
|
state.pitch = util::interpolate(startPitch, pitch, k);
|
|
|
|
|
@@ -531,43 +513,35 @@ void Transform::rotateBy(const PrecisionPoint& first, const PrecisionPoint& seco
|
|
|
|
|
const PrecisionPoint newFirst = first - center;
|
|
|
|
|
const PrecisionPoint newSecond = second - center;
|
|
|
|
|
const double ang = state.angle + util::angle_between(newFirst.x, newFirst.y, newSecond.x, newSecond.y);
|
|
|
|
|
|
|
|
|
|
_setAngle(ang, duration);
|
|
|
|
|
|
|
|
|
|
CameraOptions camera;
|
|
|
|
|
camera.angle = ang;
|
|
|
|
|
easeTo(camera, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::setAngle(double new_angle, const Duration& duration) {
|
|
|
|
|
if (std::isnan(new_angle)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_setAngle(new_angle, duration);
|
|
|
|
|
void Transform::setAngle(double angle, const Duration& duration) {
|
|
|
|
|
setAngle(angle, {NAN, NAN}, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::setAngle(double new_angle, const PrecisionPoint& center) {
|
|
|
|
|
if (std::isnan(new_angle) || !center) {
|
|
|
|
|
void Transform::setAngle(double angle, const PrecisionPoint& center, const Duration& duration) {
|
|
|
|
|
if (std::isnan(angle)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LatLng rotationCenter;
|
|
|
|
|
|
|
|
|
|
if (center.x > 0 || center.y > 0) {
|
|
|
|
|
if (center) {
|
|
|
|
|
rotationCenter = state.pointToLatLng(center);
|
|
|
|
|
setLatLng(rotationCenter, Duration::zero());
|
|
|
|
|
setLatLng(rotationCenter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_setAngle(new_angle);
|
|
|
|
|
|
|
|
|
|
if (center.x > 0 && center.y > 0) {
|
|
|
|
|
setLatLng(rotationCenter, center, Duration::zero());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::_setAngle(double new_angle, const Duration& duration) {
|
|
|
|
|
|
|
|
|
|
CameraOptions camera;
|
|
|
|
|
camera.angle = new_angle;
|
|
|
|
|
AnimationOptions animation;
|
|
|
|
|
animation.duration = duration;
|
|
|
|
|
easeTo(camera, animation);
|
|
|
|
|
camera.angle = angle;
|
|
|
|
|
easeTo(camera, duration);
|
|
|
|
|
|
|
|
|
|
if (center) {
|
|
|
|
|
setLatLng(rotationCenter, center);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double Transform::getAngle() const {
|
|
|
|
|
@@ -583,9 +557,7 @@ void Transform::setPitch(double pitch, const Duration& duration) {
|
|
|
|
|
|
|
|
|
|
CameraOptions camera;
|
|
|
|
|
camera.pitch = pitch;
|
|
|
|
|
AnimationOptions animation;
|
|
|
|
|
animation.duration = duration;
|
|
|
|
|
easeTo(camera, animation);
|
|
|
|
|
easeTo(camera, duration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double Transform::getPitch() const {
|
|
|
|
|
|