From dfeb479011bbbd99de37863f5bea5fc1a8b0e02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 13 Aug 2015 10:00:05 -0700 Subject: [PATCH 1/2] MGLUserTrackingModeFollowWithCourse Added course-tracking. However, rotation has to happen atomically without animation until #1834 is fixed. Fixes #1605. --- include/mbgl/ios/MGLMapView.h | 2 +- include/mbgl/ios/MGLTypes.h | 4 +++- ios/app/MBXViewController.mm | 25 +++++++++++--------- platform/darwin/settings_nsuserdefaults.mm | 2 +- platform/ios/MGLMapView.mm | 21 ++++++++++++---- platform/ios/MGLUserLocationAnnotationView.m | 3 ++- 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 913d4976312..2b9a3d29138 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -486,7 +486,7 @@ IB_DESIGNABLE /** Tells the delegate that the location of the user was updated. * -* While the showsUserLocation property is set to `YES`, this method is called whenever a new location update is received by the map view. This method is also called if the map view’s user tracking mode is set to MGLUserTrackingModeFollowWithHeading and the heading changes. +* While the showsUserLocation property is set to `YES`, this method is called whenever a new location update is received by the map view. This method is also called if the map view’s user tracking mode is set to MGLUserTrackingModeFollowWithHeading and the heading changes, or if it is set to MGLUserTrackingModeFollowWithCourse and the course changes. * * This method is not called if the application is currently running in the background. If you want to receive location updates while running in the background, you must use the Core Location framework. * diff --git a/include/mbgl/ios/MGLTypes.h b/include/mbgl/ios/MGLTypes.h index 75a0d4619f3..f36fc3f44ee 100644 --- a/include/mbgl/ios/MGLTypes.h +++ b/include/mbgl/ios/MGLTypes.h @@ -21,7 +21,9 @@ typedef NS_ENUM(NSUInteger, MGLUserTrackingMode) { /** The map follows the user location. */ MGLUserTrackingModeFollow, /** The map follows the user location and rotates when the heading changes. */ - MGLUserTrackingModeFollowWithHeading + MGLUserTrackingModeFollowWithHeading, + /** The map follows the user location and rotates when the course changes. */ + MGLUserTrackingModeFollowWithCourse, }; NS_ASSUME_NONNULL_END diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index e11f7eea5cc..037a6a02ca0 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -310,18 +310,20 @@ - (void)cycleStyles - (void)locateUser { - if (self.mapView.userTrackingMode == MGLUserTrackingModeNone) - { - self.mapView.userTrackingMode = MGLUserTrackingModeFollow; - } - else if (self.mapView.userTrackingMode == MGLUserTrackingModeFollow) - { - self.mapView.userTrackingMode = MGLUserTrackingModeFollowWithHeading; - } - else - { - self.mapView.userTrackingMode = MGLUserTrackingModeNone; + MGLUserTrackingMode nextMode; + switch (self.mapView.userTrackingMode) { + case MGLUserTrackingModeNone: + nextMode = MGLUserTrackingModeFollow; + break; + case MGLUserTrackingModeFollow: + nextMode = MGLUserTrackingModeFollowWithHeading; + break; + case MGLUserTrackingModeFollowWithHeading: + case MGLUserTrackingModeFollowWithCourse: + nextMode = MGLUserTrackingModeNone; + break; } + self.mapView.userTrackingMode = nextMode; } #pragma mark - Destruction @@ -413,6 +415,7 @@ - (void)mapView:(__unused MGLMapView *)mapView didChangeUserTrackingMode:(MGLUse break; case MGLUserTrackingModeFollowWithHeading: + case MGLUserTrackingModeFollowWithCourse: newButtonImage = [UIImage imageNamed:@"TrackingHeadingMask.png"]; break; } diff --git a/platform/darwin/settings_nsuserdefaults.mm b/platform/darwin/settings_nsuserdefaults.mm index 168cba172d7..f6f9bbeedb1 100644 --- a/platform/darwin/settings_nsuserdefaults.mm +++ b/platform/darwin/settings_nsuserdefaults.mm @@ -30,7 +30,7 @@ unsigned uncheckedTrackingMode = [settings[@"trackingMode"] unsignedIntValue]; if (uncheckedTrackingMode > MGLUserTrackingModeNone && - uncheckedTrackingMode <= MGLUserTrackingModeFollowWithHeading) + uncheckedTrackingMode <= MGLUserTrackingModeFollowWithCourse) { userTrackingMode = (MGLUserTrackingMode)uncheckedTrackingMode; } diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index edb3d74a3f4..db18ea01281 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -828,7 +828,11 @@ - (void)handleCompassTapGesture:(__unused id)sender { [self resetNorthAnimated:YES]; - if (self.userTrackingMode == MGLUserTrackingModeFollowWithHeading) self.userTrackingMode = MGLUserTrackingModeFollow; + if (self.userTrackingMode == MGLUserTrackingModeFollowWithHeading || + self.userTrackingMode == MGLUserTrackingModeFollowWithCourse) + { + self.userTrackingMode = MGLUserTrackingModeFollow; + } } - (void)touchesBegan:(__unused NS_SET_OF(UITouch *) *)touches withEvent:(__unused UIEvent *)event @@ -2278,7 +2282,8 @@ - (void)setUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated { if (mode == _userTrackingMode) return; - if (mode == MGLUserTrackingModeFollowWithHeading && ! CLLocationCoordinate2DIsValid(self.userLocation.coordinate)) + if ((mode == MGLUserTrackingModeFollowWithHeading || mode == MGLUserTrackingModeFollowWithCourse) && + ! CLLocationCoordinate2DIsValid(self.userLocation.coordinate)) { mode = MGLUserTrackingModeNone; } @@ -2288,7 +2293,6 @@ - (void)setUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated switch (_userTrackingMode) { case MGLUserTrackingModeNone: - default: { [self.locationManager stopUpdatingHeading]; @@ -2311,6 +2315,7 @@ - (void)setUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated break; } case MGLUserTrackingModeFollowWithHeading: + case MGLUserTrackingModeFollowWithCourse: { self.showsUserLocation = YES; @@ -2404,6 +2409,12 @@ - (void)locationManager:(__unused CLLocationManager *)manager didUpdateToLocatio } } + CLLocationDirection course = self.userLocation.location.course; + if (course >= 0 && self.userTrackingMode == MGLUserTrackingModeFollowWithCourse) + { + _mbglMap->setBearing(course); + } + self.userLocationAnnotationView.haloLayer.hidden = ! CLLocationCoordinate2DIsValid(self.userLocation.coordinate) || newLocation.horizontalAccuracy > 10; @@ -2432,9 +2443,9 @@ - (void)locationManager:(__unused CLLocationManager *)manager didUpdateHeading:( if ( ! _showsUserLocation) return; } - CLLocationDirection headingDirection = (newHeading.trueHeading > 0 ? newHeading.trueHeading : newHeading.magneticHeading); + CLLocationDirection headingDirection = (newHeading.trueHeading >= 0 ? newHeading.trueHeading : newHeading.magneticHeading); - if (headingDirection > 0 && self.userTrackingMode == MGLUserTrackingModeFollowWithHeading) + if (headingDirection >= 0 && self.userTrackingMode == MGLUserTrackingModeFollowWithHeading) { _mbglMap->setBearing(headingDirection, secondsAsDuration(MGLAnimationDuration)); } diff --git a/platform/ios/MGLUserLocationAnnotationView.m b/platform/ios/MGLUserLocationAnnotationView.m index 536326d1f6e..7733674e631 100644 --- a/platform/ios/MGLUserLocationAnnotationView.m +++ b/platform/ios/MGLUserLocationAnnotationView.m @@ -74,7 +74,8 @@ - (void)setupLayers // if (_headingIndicatorLayer) { - _headingIndicatorLayer.hidden = (_mapView.userTrackingMode == MGLUserTrackingModeFollowWithHeading) ? NO : YES; + _headingIndicatorLayer.hidden = !(_mapView.userTrackingMode == MGLUserTrackingModeFollowWithHeading || + _mapView.userTrackingMode == MGLUserTrackingModeFollowWithCourse); if (_oldHeadingAccuracy != self.annotation.heading.headingAccuracy) { From 20ad0d51f6e6d82587e2beac34f390356409e152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Fri, 14 Aug 2015 09:46:09 -0700 Subject: [PATCH 2/2] Added UI for course tracking --- ios/app/MBXViewController.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index 037a6a02ca0..d260f5cabbe 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -319,6 +319,8 @@ - (void)locateUser nextMode = MGLUserTrackingModeFollowWithHeading; break; case MGLUserTrackingModeFollowWithHeading: + nextMode = MGLUserTrackingModeFollowWithCourse; + break; case MGLUserTrackingModeFollowWithCourse: nextMode = MGLUserTrackingModeNone; break; @@ -404,6 +406,7 @@ - (UIColor *)mapView:(__unused MGLMapView *)mapView fillColorForPolygonAnnotatio - (void)mapView:(__unused MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(__unused BOOL)animated { UIImage *newButtonImage; + NSString *newButtonTitle; switch (mode) { case MGLUserTrackingModeNone: @@ -415,11 +418,15 @@ - (void)mapView:(__unused MGLMapView *)mapView didChangeUserTrackingMode:(MGLUse break; case MGLUserTrackingModeFollowWithHeading: - case MGLUserTrackingModeFollowWithCourse: newButtonImage = [UIImage imageNamed:@"TrackingHeadingMask.png"]; break; + case MGLUserTrackingModeFollowWithCourse: + newButtonImage = nil; + newButtonTitle = @"Course"; + break; } + self.navigationItem.rightBarButtonItem.title = newButtonTitle; [UIView animateWithDuration:0.25 animations:^{ self.navigationItem.rightBarButtonItem.image = newButtonImage; }];