summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--platform/ios/src/MGLMapView.mm54
-rw-r--r--platform/ios/src/MGLUserLocationAnnotationView.m4
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
{