Why is the NavigationManager.RerouteListener not always called when I deviate from the route?
If this method is still called out, is it necessary to install a new Route in NavigationManager?
NavigationManager.getInstance().setRoute(route)
or does it happen automatically?
I can not find a parameter indicating whether I am on the route. Is there such a parameter and how to call it?
HereMaps SDK has some calculations to call the reroute listener. Like, is the user approaching the destination in any way or going away from the destination.
I observed the listener is called every time I try to go away from the destination.
Distance to reroute depends on many parameters like route, transport mode, traffice etc.
NavigationManager doesn't need to be set with the new route.
But, if you are showing the route object on Map, then clear the old route and redraw the new route.
Related
Is it possible to ensure that the location indicator doesn't keep pointing back to the route while you are deviating from it? It makes it very hard to see what's in front of the user as when camera tracking mode is turned on, it locks the camera to the location indicator's direction (e.g indicating to go back -> makes the camera look back),
What I want is to be able point the location indicator to wherever the user is going towards, so if they do a right turn and it just happens to deviate from the route, I want it to continue looking forward and not backwards to the route.
Figured it out.
Since I use a custom location provider, I have to create a custom "HERE Location" object, but there's a nice property in this object to set its bearings; "setBearingInDegrees", simply find the user's bearings and set it using this setter.
e.g:
var bearing = 0.0;
Location location = new Location.Builder()
.setCoordinates(geoCoordinates)
.setBearingInDegrees(bearing)
.build();
You would then set this 'location' back to the VisualNavigator so that it shows this location on the default indicator using its method 'onLocationUpdated'.
Even if you're on camera tracking mode, this will make you face the bearing you set in this location, which is perfect and exactly what I needed.
More information is found in the 'Add a Location Indicator' section:
https://developer.here.com/documentation/android-sdk-navigate/4.10.4.0/dev_guide/topics/map-items.html
I am using Here Map Android SDK. Currently my app can calculate the initial route and draw it through NavigationManager. Listeners are implemented and it will recalculate/redraw when the position changes, but I have a moving target: the destination is another vehicle position I get from a web service at 30 second intervals.
What is the proper way to have the route adjusted for a change in destination?
The easy way is to create a new route with an updated destination waypoint, have it calculated, then replace the old route and its listeners with the new one. I fear this wastes computing resources and produces lag/flicker on the map during the redraw. If this is indeed the path to take, how do we minimize screen issues?
I tried just changing the coordinates of the waypoint but it has no impact. I searched for a "route waypoint change" listener, similar to a traffic or position listener but could not find any.
Update: Since Here confirmed a route destination cannot be updated, I clarify my request for "howto":
What objects can I reuse in the new one? Which objects must we remove from the map and/or destroy to avoid leaks?
Initial plan:
keep handle on waypoint, original route (missing any?)
modify the destination waypoint coordinates
create a new route and have it calculated
move the destination map marker to the new destination
add new route
remove the original route (I assume the beginning of the route is similar in most update cases, so we avoid "flicker")
Anything missing? Listeners handling?
Here SDK does not provide such feature as of today. You can not change existing route or update its target. If you have new destination point you should calculate new route.
I'm using HERE android premium SDK.
App is generating a route with multiple waypoint, and start the navigation process.
I'm trying to find a way to detect each time a user has stop or pass through a route defined waypoint (defined as a stop point).
Is there a procedure for this?
You can use NavigationManager#ManeuverEventListener to listen for maneuver updates, then use the NavigationManager#getNextManeuver and NavigationManager#getAfterNextManeuver APIs to check the upcoming Maneuvers. Then, you can use Maneuver#getAction() API to check if the Action is STOPOVER.
API Docs:
NavigationManager
Maneuver
How I do/did it?
A combination of onStopoverReached(int index) and a dummy Passthrough as a Stopover.
Set your RoutePlan with the Passthrough waypoint and a dummy stopover waypoint of the same credentials as the Passthrough waypoint.
Call the NavigationEventManager's onStopoverReached method to tell you when the dummy Passthrough stopover has been reached or passed.
Other thing to note...
A ReRoute listener will never return a Passthrough Waypoint so...
You can use the reRouteEnd method to reinsert a Passthrough Waypoint in a new RoutePlan along with the Stopover Waypoints returned by reRouteEnd's RouteResult and recalculate a new route and of course pickup a fresh RouteResult at the Router listener's onCalculateRouteFinished.
I have been working on a android project.
Then I came up with 2 question.
Q1. how to implement navigation drive ?
My logic and some work
- I am be able to draw path between 2 address. And my thought is that, use the onLocationChanged(current) method then call https://maps.googleapis.com/maps/api/directions/output?parameters with the current location and destination which through some method to draw the path on the map.
Upon every onLocationChanged() method call, I redraw the path on the map again.
" Is it how we would do it for navigation ? "
Q2. how to implement voice navigation to work with Q1 ?
- Did some research, can't find anything that seems clearly helpful. All I know its that, in the return JSON from the /api/directions, there are direction instruction in it.
" Do I use it for voice from the return JSON ? Or there is a better way ? "
Would be very helpful with some link or example in details.
Thanks in adavnce
Here is what I know, hope it helps you out.
Regarding the first question:
After retrieving the directions and the necessary data, you have to draw the direction once and only once! yes, you have to use the onLocationChanged() but not to redraw the whole thing again.. if you notice in most of the navigation application they still keep the main route, they don't remove the passed parts... but you have to use onLocationChanged() to check if the user is out of the drawn path (by maybe 100m) so you have to re-calculate and redraw it again... redraw the path every time the user move is a costly operation it is better to be avoided...
For the second question:
As you said, the data retrieved already has the navigation commands.. so what you have to do is create a class to map the command with the voice.. and if you notice within the legs -> steps tags, there is a start and ending coordinates for each sub-path, so you can use these data to calculate the distance between them on each 200m say the command that "how far the user is to turn left" for example.
Hope this gives you a general idea of how it works. Good luck and happy programming.
My application has separate algorithms to fetch data for scroll change and on user location change . For location change am using com.google.android.gms.location.LocationListener Which is working fine.
But for on user scroll, I am getting mMap.setOnCameraChangeListener(new OnCameraChangeListener(). But the issue is com.google.android.gms.location.LocationListene also triggers mMap.setOnCameraChangeListener(new OnCameraChangeListener().
So how to distinguish. Presently I am using Boolean values to differentiate, but it's not reliable and dirty.
I had the same issue, was trying all sorts of stuff like wrapping the view to intercept touches, or wrapping any calls to change the viewport and listening to when it started and stopped changing so I could tell if something else changed it, or matching the current viewport to what I last set it to... it's all rather fiddly. Then someone pointed me at this, and it looks promising update: has now worked flawlessly for us for months without a single issue:
map.setOnCameraMoveStartedListener { reasonCode ->
if (reasonCode == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE) {
// I will no longer keep updating the camera location because
// the user interacted with it. This is my field I check before
// snapping the camera location to the latest value.
tracking = false
}
}
I doubt that there's an easy, reliable, and real-time way to do this. IOW, I suspect that it is going to be "dirty".
If I had to try, I would supply my own LocationSource, so that I knew when the map would be changing based upon position. I would then try to ignore the next call (calls?) to my OnCameraChangeListener, as being ones tied to the location change.
(BTW, note that LocationListener was deprecated)
Or, I would try to change my data-fetching algorithm to treat all camera changes equally. After all, if my objective is to make sure that I have data on all sides of the map from the current center, it doesn't matter how I got to that center, just so long as I am there.