diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 54 | ||||
-rw-r--r-- | platform/ios/src/MGLUserLocationAnnotationView.m | 4 |
3 files changed, 37 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 3561c9f9e1..0d6f10b62f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,8 @@ Known issues: - MGLMapCamera’s `altitude` values now match those of MKMapCamera. ([#3362](https://github.com/mapbox/mapbox-gl-native/pull/3362)) - MGLMapView properties like `centerCoordinate` and `camera` now offset the center to account for any translucent top or bottom bar. As a result, when user tracking is enabled and the map view is an immediate child of a view controller, the user dot is centered in the unobscured portion of the map view. To override this offset, modify the `contentInset` property; you may also need to set the containing view controller’s `automaticallyAdjustsScrollViewInsets` property to `NO`. ([#3583](https://github.com/mapbox/mapbox-gl-native/pull/3583)) - In user tracking mode, the user dot stays in a fixed position within MGLMapView while the map pans smoothly. A new property, `userLocationVerticalAlignment`, determines the user dot’s fixed position. ([#3589](https://github.com/mapbox/mapbox-gl-native/pull/3589)) +- When the user tracking mode is set to `MGLUserTrackingModeFollowWithCourse`, an optional `targetCoordinate` is kept within sight at all times as the user changes location. This property, in conjunction with the `userLocationVerticalAlignment` property, may be useful for displaying the user’s progress toward a waypoint. ([#3680](https://github.com/mapbox/mapbox-gl-native/pull/3680)) +- Heading or course tracking mode can now be enabled as soon as an MGLMapView is initialized. ([#3680](https://github.com/mapbox/mapbox-gl-native/pull/3680)) - Zooming and rotation gestures no longer disable user tracking mode. ([#3589](https://github.com/mapbox/mapbox-gl-native/pull/3589)) - User tracking mode starts out at a lower zoom level by default. ([#3589](https://github.com/mapbox/mapbox-gl-native/pull/3589)) - Fixed an issue with small map views not properly fitting annotations within bounds. (#[3407](https://github.com/mapbox/mapbox-gl-native/pull/3407)) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index db93488abe..d499dc7474 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -2993,6 +2993,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) if ( ! [newAnnotationView isEqual:_userLocationAnnotationView]) { _userLocationAnnotationView = newAnnotationView; + [self updateUserLocationAnnotationView]; } } @@ -3040,15 +3041,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) _userTrackingMode = mode; - if (_userTrackingMode == MGLUserTrackingModeNone - || _userTrackingMode == MGLUserTrackingModeFollowWithCourse) - { - self.userTrackingState = MGLUserTrackingStatePossible; - } - if ( ! animated) - { - self.userTrackingState = MGLUserTrackingStateChanged; - } + self.userTrackingState = animated ? MGLUserTrackingStatePossible : MGLUserTrackingStateChanged; switch (_userTrackingMode) { @@ -3150,9 +3143,10 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) if ( ! _showsUserLocation || ! newLocation || ! CLLocationCoordinate2DIsValid(newLocation.coordinate)) return; - if (! oldLocation || ! CLLocationCoordinate2DIsValid(oldLocation.coordinate) || [newLocation distanceFromLocation:oldLocation]) + if (! oldLocation || ! CLLocationCoordinate2DIsValid(oldLocation.coordinate) || [newLocation distanceFromLocation:oldLocation] + || oldLocation.course != newLocation.course) { - if (self.userTrackingState != MGLUserTrackingStateBegan) + if ( ! oldLocation || ! CLLocationCoordinate2DIsValid(oldLocation.coordinate) || self.userTrackingState != MGLUserTrackingStateBegan) { self.userLocation.location = newLocation; } @@ -3163,10 +3157,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) } } - if (self.userTrackingMode != MGLUserTrackingModeNone) - { - [self didUpdateLocationWithUserTrackingAnimated:animated]; - } + [self didUpdateLocationWithUserTrackingAnimated:animated]; self.userLocationAnnotationView.haloLayer.hidden = ! CLLocationCoordinate2DIsValid(self.userLocation.coordinate) || newLocation.horizontalAccuracy > 10; @@ -3176,11 +3167,20 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) - (void)didUpdateLocationWithUserTrackingAnimated:(BOOL)animated { + CLLocation *location = self.userLocation.location; + if ( ! _showsUserLocation || ! location + || ! CLLocationCoordinate2DIsValid(location.coordinate) + || self.userTrackingMode == MGLUserTrackingModeNone) + { + return; + } + // If the user location annotation is already where it’s supposed to be, // don’t change the viewport. CGPoint correctPoint = self.userLocationAnnotationViewCenter; CGPoint currentPoint = [self convertCoordinate:self.userLocation.coordinate toPointToView:self]; - if (std::abs(currentPoint.x - correctPoint.x) <= 1.0 && std::abs(currentPoint.y - correctPoint.y) <= 1.0) + if (std::abs(currentPoint.x - correctPoint.x) <= 1.0 && std::abs(currentPoint.y - correctPoint.y) <= 1.0 + && self.userTrackingMode != MGLUserTrackingModeFollowWithCourse) { return; } @@ -3242,7 +3242,10 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) peakAltitude:-1 completionHandler:^{ MGLMapView *strongSelf = weakSelf; - strongSelf.userTrackingState = MGLUserTrackingStateChanged; + if (strongSelf.userTrackingState == MGLUserTrackingStateBegan) + { + strongSelf.userTrackingState = MGLUserTrackingStateChanged; + } }]; } @@ -3258,7 +3261,10 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) __weak MGLMapView *weakSelf = self; completion = ^{ MGLMapView *strongSelf = weakSelf; - strongSelf.userTrackingState = MGLUserTrackingStateChanged; + if (strongSelf.userTrackingState == MGLUserTrackingStateBegan) + { + strongSelf.userTrackingState = MGLUserTrackingStateChanged; + } }; } @@ -3361,7 +3367,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) CLLocationDirection headingDirection = (newHeading.trueHeading >= 0 ? newHeading.trueHeading : newHeading.magneticHeading); - if (headingDirection >= 0 && self.userTrackingMode == MGLUserTrackingModeFollowWithHeading) + if (headingDirection >= 0 && self.userTrackingMode == MGLUserTrackingModeFollowWithHeading + && self.userTrackingState != MGLUserTrackingStateBegan) { [self _setDirection:headingDirection animated:YES]; } @@ -3455,7 +3462,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) /// Rotate back to true north if the map view is zoomed too far out. - (void)unrotateIfNeededAnimated:(BOOL)animated { - if (self.direction != 0 && ! self.isRotationAllowed) + if (self.direction != 0 && ! self.isRotationAllowed + && self.userTrackingState != MGLUserTrackingStateBegan) { if (animated) { @@ -3595,7 +3603,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { MGLUserLocationAnnotationView *annotationView = self.userLocationAnnotationView; if ( ! CLLocationCoordinate2DIsValid(self.userLocation.coordinate)) { - annotationView.layer.hidden = YES; + annotationView.hidden = YES; return; } @@ -3616,7 +3624,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) -MGLAnnotationUpdateViewportOutset.height), userPoint)) { annotationView.center = userPoint; - annotationView.layer.hidden = NO; + annotationView.hidden = NO; [annotationView setupLayers]; if (_userLocationAnnotationIsSelected) @@ -3636,7 +3644,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { // User has moved far enough outside of the viewport that showing it or // its callout would be useless. - annotationView.layer.hidden = YES; + annotationView.hidden = YES; if (_userLocationAnnotationIsSelected) { diff --git a/platform/ios/src/MGLUserLocationAnnotationView.m b/platform/ios/src/MGLUserLocationAnnotationView.m index 9adbd45f24..b59f4586b3 100644 --- a/platform/ios/src/MGLUserLocationAnnotationView.m +++ b/platform/ios/src/MGLUserLocationAnnotationView.m @@ -267,6 +267,10 @@ const CGFloat MGLUserLocationAnnotationArrowSize = MGLUserLocationAnnotationPuck _oldHeadingAccuracy = self.annotation.heading.headingAccuracy; } + if (self.annotation.heading.trueHeading >= 0) + { + _headingIndicatorLayer.affineTransform = CGAffineTransformRotate(CGAffineTransformIdentity, -MGLRadiansFromDegrees(self.mapView.direction - self.annotation.heading.trueHeading)); + } } else { |