-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update vanishing point calculation with a location based implementation #2737
Conversation
The problem so far mainly comes from two parts during navigation tests. First, the method of Second, for the |
65e2b36
to
88128c9
Compare
The constant location gap between the vanishing route line point and the puck may be caused by the calling of the |
One thing I would suggest is looking at MapRouteLineTest.kt on the Android side and using the unit tests against your implementation to see if you get the same results. The routes we test with can be found here. |
After updating the callers to receive the
To solve this problem, the vanishing route line could add the animating effect to allow the smoothly transition during the 1 second, similar toas the puck view.
|
Is the animation of the puck constant and completely predictable? On the Android side, the puck's transition animation is variable, so we opted to expose a listener from the Maps SDK that's invoked whenever the transition animation of the puck ticks. On each of those ticks, we can precisely update the vanishing point. |
To add to what Lukas has written, on the Android side we add a listener called OnIndicatorPositionChangedListener to the map location component. This was recently added to the Maps SDK. I assume it was added on the IOS version. See also here. The call is consumed here. During the puck's animation this is called with every point the puck is moving to. It is called many times per second. So the vanishing point adjusts a very small amount along with the puck's movements. I haven't had a chance to review your code yet so maybe you're already implementing this. If so, disregard this. But in case it's not clear how to get a smooth vanishing point transition, this is how it's done. |
Thanks for the suggestion above! I'll try the methods as provided to see how to get a smooth vanishing point transition synchronized with the puck animation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR. Please check initial iteration of my comments. As discussed earlier let's concentrate of following tasks:
- Since after updating calculation algorithm user course view is in sync with vanishing route line let's try to cover implemented functionality with tests (minor fixes).
NavigationMapView
becomes pretty large, do you think we can extract added functionality into separate entity orNavigationMapView
extension?- Find out whether Maps SDK for iOS provides callback similar to
onIndicatorPositionChanged
as on Android.
/** | ||
Calculates the distance between 2 points using [EPSG:3857 projection](https://epsg.io/3857). | ||
*/ | ||
private func calculateDistance(point1: CLLocationCoordinate2D, point2: CLLocationCoordinate2D) -> Double { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these calculation methods should be tested either directly of indirectly.
Right now the After that, we could work on providing the location change to the update the vanishing route line. No matter from the puck view location, or from the animation and frame rate. |
Because the MapSDK on iOS side doesn't have the Besides, in the |
The NSTimer could not repeat the function at a constant time interval and may call the action multiple times. It cause the lineGradient calculation problem, which is based on even distributed time interval. I'll work on to fix this problem. |
c4b6af4
to
bccb8d5
Compare
Now the problem is that the user puck view is updated evenly during every second, but the vanishing route line is updated with the Timer. But the Timer called the time interval not at an evenly distributed rate. So the changing puck view and the changing vanishing route line is still not synchronous when zoom pretty in. So the next step is to update the Timer event at a constant time interval to allow the two synced. Maybe try |
By updating the Timer, the vanishing route line bow could implement the smoothly transition as above above . But because the time interval of the Timer is not evenly distributed, when zoom pretty in, the puck view and the vanishing route line may still sometimes not at the same location. And the route line casing layer also sometimes has a flash under layer. |
4fdcbac
to
39195a9
Compare
if coordinates.isEmpty { | ||
return nil | ||
} else { | ||
return calculateGranularDistances(coordinates) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about more traditional:
if coordinates.isEmpty { | |
return nil | |
} else { | |
return calculateGranularDistances(coordinates) | |
} | |
if !coordinates.isEmpty { | |
return calculateGranularDistances(coordinates) | |
} | |
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion, I'll fix it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion. At the start of the navigation, because the fractionTraveled
hasn't be updated, there's no available lineGradient to update. I think it can be solved by a fixer to use the routeProgress.fractionTraveled
instead or use speed to update the lineGradient. I'll work on this problem to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The refresh problem and the start of the navigation problem are both caused by the navigationMapView.show(_ routes: [Route], legIndex: Int = 0)
. inside the function, it defines the mainRouteLayer
and parentLayer
with a lineGradient
that forms from a 0.0 fractionTraveled.
So at the start of the navigation, before it receives the routeProgress to call func updateRoute(_ routeProgress:)
, it shows the vanishing route line with the stop at the start point. It causes the gap between the puck view and not perfectly synced.
When refresh, the func navigationService(_ service: NavigationService, didRefresh routeProgress: RouteProgress)
also call the navigationMapView.show(_ routes: [Route], legIndex: Int = 0)
first to make the vanishing route line stop at the start point. Then it calls the func updateRoute(_ routeProgress:)
to update the vanishing route line.
To fix the problem, inside the navigationMapView.show(_ routes: [Route], legIndex: Int = 0)
, it should replace the default 0.0
value with the fractionTraveled
. And prepare a resonnable value of the fractionTraveled to be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I create a new ticket to handle this problem in #2757
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the new commit, the refresh problem is solved with using the old fractionTraveled
to form the two layers for vanishing route line. Then it receive updates from route progress, and slight change from the old fractionTraveled
stop.
Description
This pr is to solve the inconsistency of route progress, puck and vanishing route line during the navigation, when speed is fast or when zooming in. This is pr is mainly following the the Android implementation as #3422 and 3661.
fractionTraveled
calculation method to be synchronized with puckImplementation
Instead of using the sum of previous route steps’ distance as the traveled distance, and calculating the
fractionTraveled
based on the distance fraction, this pr stores the coordinates and route line index along the route. The distance is calculated by the coordinates instead of the line string. ThefractionTraveled
is based on the route line index and the distance, which improve the accuracy. It also keeps the location andfractionTraveled
of route line synchronized with puck to avoid the inconsistency.Add a NSTimer (Timer) to update the vanishing route line, slicing the
fractionTraveled
into small pieces and updating each of them during a small time interval. It allows the smoothly transition during each 1 second update of the route progress.Screenshots or Gifs
From the .gif below, we could see that the vanishing route line is at the same location of the puck view, and also move smoothly when zoom in and at high speed
/cc @mapbox/navigation-ios