maplibre / maplibre-native

MapLibre Native - Interactive vector tile maps for iOS, Android and other platforms.
https://maplibre.org
BSD 2-Clause "Simplified" License
1.01k stars 297 forks source link

[iOS] MLNUserTrackingModeFollowWithHeading causing issue with MLNUserLocationAnnotationView location update #2134

Open JuLink opened 7 months ago

JuLink commented 7 months ago

Describe the bug Setting the userTrackingMode of the MapView to MLNUserTrackingModeFollowWithHeading leads to bumpy update of the MLNUserLocationAnnotationView.

To Reproduce Steps to reproduce the behavior:

  1. Use the MapLibre Sample app, but change the style to be able to see more clearly the updates.
  2. Set the userTrackingMode to MLNUserTrackingModeFollowWithHeading by clicking on the top right navigation bar item (until it represent an arrow with a line in front of it).
  3. Start walking around the neighborhood (I did not figure out how to reproduce it on the simulator unfortunately).
  4. Notice how the location jump from position to position instead of smoothly following the coordinates of the user.

Expected behavior The update to the MLNUserLocationAnnotationView should be smooth exactly like when you use the MLNUserTrackingModeFollow userTrackingMode.

Screenshots In the video you can see the difference of update between the MLNUserTrackingModeFollow and the MLNUserTrackingModeFollowWithHeading update to the user annotation. In the first part of the video, I'm using the Follow mode and in the second part I'm using the FollowWithHeading. You can see that in the second part of the video the update is not as good as in the first part. https://github.com/maplibre/maplibre-native/assets/1457215/d2ec55ad-9679-44ae-9fcd-3d520ba497d7

Here is the cut from the video that show the issue: Smooth update (follow) Jumping update (followWithHeading)
ok_480 not_ok_480

As you can see in the second case, the rotation of the map is smooth but the update to the location is not.

Platform information (please complete the following information):

Additional context By doing a few tests I came to the conclusion that the issue is some kind of animation issues between the annotation of the user and the rotation of the map. I suspect that when walking with the phone out, the heading goes all over the place and therefore leads to rotating the map very frequently and it conflict with the animation of centering the annotation on the correct coordinates. By commenting the line 6398 of the MLNMapView.mm which is the the [self _setDirection:headingDirection animated:YES]; of the method MLNMapView.locationManager:didUpdateHeading: the update of the user location is smooth again (of course the map doesn't turn anymore). I tried to fix the issue but can't figure it out 😥

louwers commented 6 months ago

Thanks for the super detailed bug report!

I hope with some more eyes we can find a fix for this.

JuLink commented 4 months ago

@louwers I tried to remove all the animation of the MLNMapView by setting the MLNAnimationDuration and MLNUserLocationAnimationDuration to 0. The result looks like this (note this is much more zoomed than the previous videos) : https://github.com/maplibre/maplibre-native/assets/1457215/f266d0fe-4c32-4d99-8e3e-abf11348d504

A bad quality gif to avoid looking at the video : RPReplay_Final1715957949

I think this is the expected result minus the animation between location update. This leads me to think that this issue is map animations cancelling each others out.

Since the heading is updated more frequently than the location, the main animation that can complete without being stop by the other is the rotation one (or at least if its cancelled, the next iteration is so quick to be called that this animation seems to not have been stopped).

It's quite difficult to understand all the code and the implication of a modification. And all my attempts were failure 😅

Do you have any idea how I can try to fix this issue ?