From 49bfdd662ff37ac77cd702c2cef92d2de8874be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Sun, 20 Dec 2015 04:11:14 -0800 Subject: [PATCH] [ios, osx] Optional peak altitude for flying --- include/mbgl/ios/MGLMapView.h | 10 ++++++++++ include/mbgl/osx/MGLMapView.h | 19 +++++++++++++++++++ platform/ios/src/MGLMapView.mm | 16 ++++++++++++++-- platform/osx/src/MGLMapView.mm | 10 ++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 32d68aa2cd1..e10932bd27a 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -235,6 +235,16 @@ IB_DESIGNABLE * @param completion The block to execute after the animation finishes. */ - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration completionHandler:(nullable void (^)(void))completion; +/** Moves the viewpoint to a different location using a transition animation that evokes powered flight and an optional transition duration and peak altitude. +* +* The transition animation seamlessly incorporates zooming and panning to help the user find his or her bearings even after traversing a great distance. +* +* @param camera The new viewpoint. +* @param duration The amount of time, measured in seconds, that the transition animation should take. Specify `0` to jump to the new viewpoint instantaneously. Specify a negative value to use the default duration, which is based on the length of the flight path. +* @param peakAltitude The altitude, measured in meters, at the midpoint of the animation. The value of this parameter is ignored if it is negative or if the animation transition resulting from a similar call to `-setCamera:animated:` would have a midpoint at a higher altitude. +* @param completion The block to execute after the animation finishes. */ +- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion; + #pragma mark - Converting Map Coordinates /** @name Converting Map Coordinates */ diff --git a/include/mbgl/osx/MGLMapView.h b/include/mbgl/osx/MGLMapView.h index 6f468254483..ae701de27ad 100644 --- a/include/mbgl/osx/MGLMapView.h +++ b/include/mbgl/osx/MGLMapView.h @@ -274,6 +274,25 @@ IB_DESIGNABLE @param completion The block to execute after the animation finishes. */ - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration completionHandler:(nullable void (^)(void))completion; +/** Moves the viewpoint to a different location using a transition animation + that evokes powered flight and an optional transition duration and peak + altitude. + + The transition animation seamlessly incorporates zooming and panning to help + the user find his or her bearings even after traversing a great distance. + + @param camera The new viewpoint. + @param duration The amount of time, measured in seconds, that the transition + animation should take. Specify `0` to jump to the new viewpoint + instantaneously. Specify a negative value to use the default duration, + which is based on the length of the flight path. + @param peakAltitude The altitude, measured in meters, at the midpoint of the + animation. The value of this parameter is ignored if it is negative or + if the animation transition resulting from a similar call to + `-setCamera:animated:` would have a midpoint at a higher altitude. + @param completion The block to execute after the animation finishes. */ +- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion; + /** The geographic coordinate bounds visible in the receiver’s viewport. Changing the value of this property updates the receiver immediately. If you diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 84b82a64047..d6980e16569 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1750,12 +1750,12 @@ - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration a - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion { + _mbglMap->cancelTransitions(); if ([self.camera isEqual:camera]) { return; } - _mbglMap->cancelTransitions(); mbgl::CameraOptions options = [self cameraOptionsObjectForAnimatingToCamera:camera]; if (duration > 0) { @@ -1783,17 +1783,29 @@ - (void)flyToCamera:(MGLMapCamera *)camera completionHandler:(nullable void (^)( - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration completionHandler:(nullable void (^)(void))completion { + [self flyToCamera:camera withDuration:duration peakAltitude:-1 completionHandler:completion]; +} + +- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion +{ + _mbglMap->cancelTransitions(); if ([self.camera isEqual:camera]) { return; } - _mbglMap->cancelTransitions(); mbgl::CameraOptions options = [self cameraOptionsObjectForAnimatingToCamera:camera]; if (duration >= 0) { options.duration = MGLDurationInSeconds(duration); } + if (peakAltitude >= 0) + { + CLLocationDegrees peakLatitude = (self.centerCoordinate.latitude + camera.centerCoordinate.latitude) / 2; + CLLocationDegrees peakPitch = (self.camera.pitch + camera.pitch) / 2; + options.minZoom = MGLZoomLevelForAltitude(peakAltitude, peakPitch, + peakLatitude, self.frame.size); + } if (completion) { options.transitionFinishFn = [completion]() { diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm index b0f402ff7a2..9e95ef66601 100644 --- a/platform/osx/src/MGLMapView.mm +++ b/platform/osx/src/MGLMapView.mm @@ -976,6 +976,10 @@ - (void)flyToCamera:(MGLMapCamera *)camera completionHandler:(nullable void (^)( } - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration completionHandler:(nullable void (^)(void))completion { + [self flyToCamera:camera withDuration:duration peakAltitude:-1 completionHandler:completion]; +} + +- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion { _mbglMap->cancelTransitions(); if ([self.camera isEqual:camera]) { return; @@ -985,6 +989,12 @@ - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration if (duration >= 0) { options.duration = MGLDurationInSeconds(duration); } + if (peakAltitude >= 0) { + CLLocationDegrees peakLatitude = (self.centerCoordinate.latitude + camera.centerCoordinate.latitude) / 2; + CLLocationDegrees peakPitch = (self.camera.pitch + camera.pitch) / 2; + options.minZoom = MGLZoomLevelForAltitude(peakAltitude, peakPitch, + peakLatitude, self.frame.size); + } if (completion) { options.transitionFinishFn = [completion]() { // Must run asynchronously after the transition is completely over.