Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Affix user dot on screen in user tracking mode #3589

Merged
merged 13 commits into from
Jan 20, 2016
Merged

Conversation

1ec5
Copy link
Contributor

@1ec5 1ec5 commented Jan 17, 2016

Place the user dot at a fixed location on screen in user tracking mode, eliminating the jumping effect between user location updates. In course tracking mode, weight the user puck down towards the bottom of the view, since it’s more important to see the road ahead than to see whoever’s tailgating you. Added a new property to MGLMapView that controls the position of the user dot or user puck. By default, the user dot/puck is fixed in the center of the view, but it can be shifted to the top or bottom (e.g. for a GPS-style turn-by-turn view).

Conceptually, we now rely on entity interpolation to smooth out the large jumps between location updates. As in MapKit, the user dot may be up to one second behind where Core Location thinks the device is. When user tracking is initially enabled, MGLMapView “flies” to the first location reported by Core Location. This process may take longer than a second, but it gives the user more context as to their current location than the standard easing that MapKit performs.

Depends on #3583. Fixes #1041 and fixes #2600. #1582 complements this PR by smoothing the user dot’s motion outside of user tracking mode, using view-based animation.

/cc @friedbunny @zugaldia

@1ec5 1ec5 added feature iOS Mapbox Maps SDK for iOS labels Jan 17, 2016
@1ec5 1ec5 self-assigned this Jan 17, 2016
@1ec5 1ec5 added this to the ios-v3.2.0 milestone Jan 17, 2016
This was referenced Jan 17, 2016
else if (self.direction < snapTolerance || self.direction > 360 - snapTolerance)
else if ((self.direction < snapTolerance || self.direction > 360 - snapTolerance)
&& self.userTrackingMode != MGLUserTrackingModeFollowWithHeading
&& self.userTrackingMode != MGLUserTrackingModeFollowWithCourse)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self to remove this change once #3588 lands.

@1ec5 1ec5 modified the milestones: ios-v3.1.0, ios-v3.2.0 Jan 18, 2016
@1ec5
Copy link
Contributor Author

1ec5 commented Jan 18, 2016

Tentatively putting on 3.1.0, since it’s ready. Just needs lots of testing.

@1ec5 1ec5 force-pushed the 1ec5-dot-jank-1041-2 branch 2 times, most recently from bc445aa to 44800c9 Compare January 19, 2016 01:48
MGLMapCamera *camera = self.camera;
camera.centerCoordinate = self.userLocation.location.coordinate;
camera.heading = course;
camera.altitude = newLocation.horizontalAccuracy;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach seems to be more reliable, and it also works when the map is tilted, something unsupported by the old code, which was ported from the raster SDK, which didn’t support tilting.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy that this is simplified! The camera movement is much slicker, too.

One continued quibble is that highly-accurate location fixes zoom in too far and context is lost. This is somewhat mitigated by the camera animation, but perhaps we could also adopt a minimum altitude?

~~We should additionally consider only zooming in if the map's zoom level is relatively low; i.e., Apple Maps doesn't change the altitude/zoom unless the map is zoomed out to ~z8.~~ Strike that, we already do this at <z10.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also seeing this zoom in beyond the accuracy ring, which is unintuitive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, it does always seem to zoom into z18 for some reason. Perhaps it's because iOS-specific code assumes a field of view of 30 degrees, which is less than what some mbgl calculations assume.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in dbfc363. I haven’t nailed down exactly what MapKit does, but it does seem to like z14 quite a lot.

@friedbunny
Copy link
Contributor

Quick zoom and two-finger zoom do not appear to take into account the content insets, which means the user dot is moved during these gestures while user tracking is enabled... and then moved back to the proper placement afterwards.

ezgif com-optimize

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 19, 2016

Ah, good catch. All the gestures need to be updated to account for the content inset.

Additionally, heading changes, which come in much more frequently than location changes, tend to interrupt any running animation to the new location during heading tracking mode. The animation for heading changes needs to also pan to the current location, not just rotate.

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 19, 2016

Quick zoom and two-finger zoom do not appear to take into account the content insets

Fixed in d32e0e6ed7d1a27b31b374e34a6fac1ea48551ee. In that change, for MapKit parity, I also removed the logic that kicks you out of user tracking mode if your zoom gesture is centered somewhere other than the user dot.

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 19, 2016

Failing builds are due to #1828.

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 20, 2016

Additionally, heading changes, which come in much more frequently than location changes, tend to interrupt any running animation to the new location during heading tracking mode.

This is also the current behavior. Fixing it will require #3625 and is out of scope for this PR.

@friedbunny
Copy link
Contributor

YEAAAAAAAAAAH

In user tracking mode, keep the user dot in a fixed location on screen, instead easing the map view so that the fixed location corresponds to the new user location. There is one exception: MGLMapView reacts to the first location update the same way as before, so that it appears to move to where the user dot has been all along.

In course tracking mode, weight the user dot down towards the bottom of the view, since it’s more important to see the road ahead than the road behind.

Fixes #2600, and #1041 to some extent.
Fly to the user location when entering user tracking mode. Keep user location updates from interfering with the initial flight.
Don’t close the user location annotation’s callout when the user location changes in user tracking mode.
Don’t update the user location annotation’s coordinates until after the transition to the first reported location is complete.
Outside of user tracking mode, the user dot moves in spurts, so view synchronization performance isn’t an issue.
Calling -setUserTrackingMode:animated: with animated set to NO should jump instantaneously to the first reported location.
The user dot or user puck’s position is now configurable via a new alignment property in any user tracking mode. Also, -setUserTrackingMode:animated: is now exposed publicly, and setting its animated parameter to NO skips the initial animation.
Per MapKit behavior, zooming or rotating with a gesture can no longer kick the user out of user tracking mode. In user tracking mode, the zoom animation is always anchored on the user dot, wherever it may be.
When entering user tracking mode from a low zoom level, zoom in to z14 regardless of the location’s horizontal accuracy.
@1ec5
Copy link
Contributor Author

1ec5 commented Jan 20, 2016

Everything passes; merging.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature iOS Mapbox Maps SDK for iOS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Offset map center User location tracking is rough
2 participants