I\'d like to implement navigation map for drivers in my Android app. I don\'t want to use URL scheme to open google Maps app to navigate it. I prefer to implement this navigatio
I also recommend you try looking into Open by Mapzen.
Here's a link to a blog post https://mapzen.com/blog/we-made-an-app and a video https://vimeo.com/112231821 for some insight.
I'll answer your questions below as if you're using the new Android Mapbox Directions API.
1. How do I know when is the proper time to prompt user he should turn right/left?
First, as you may know, you must call .setSteps(true)
within your MapboxDirections.Builder()
. This will return directions with all the information you will need. Now in order to prompt user the step at a correct location you will need to get the step maneuver coordinates which are given in a list. This is the absolute coordinate in which a step occurs therefore, it will be rare that a user actually maneuvers through the point while traversing the route. Therefore it's best to measure distance from user location to the next steps coordinate and if the user is within a given distance (say 0.0189394 miles which is ~100 feet) you then prompt user the next step. To measure distance I'll give a reliable method below you can use:
private double computeDistance(Waypoint from, Waypoint to) {
double dLat = Math.toRadians(to.getLatitude() - from.getLatitude());
double dLon = Math.toRadians(to.getLongitude() - from.getLongitude());
double lat1 = Math.toRadians(from.getLatitude());
double lat2 = Math.toRadians(to.getLatitude());
double a = Math.pow(Math.sin(dLat/2), 2) + Math.pow(Math.sin(dLon/2), 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double R = 3960;
double distance = R * c;
return distance;
}
Using this method you just compare the distance returned (in miles) to your threshold (in our example 0.0189394 miles) and if distance returned is less then threshold we know the users within range of the next step.
2. How do I know how far away from my current location to next maneuver/Steps? Do I need to recalculate the distance after my location is changed since my location is always changing?
The first part of your question's answered in question 1. To answer the second part, You can call mapView.setOnMyLocationChangeListener
and make a new MapView.OnMyLocationChangeListener()
. Within it is where you'd need to recalculate the distance between user and next steps coordinates like in the example in question 1.
3. How do I know user has made a wrong action? For example, it is supposed to turn right, but user turned left. I need to request your server to recalculate the route.
You can accomplish this by using the isOffRoute()
method which will calculate the distance between the provided userLocation
and every waypoint in the route, resulting in an off-route status if the distance is always bigger then a threshold (currently 0.1 miles). So in your case, since you want to recalculate a new route if user veers off route i'd create an if statement similar to this example:
if (route.isOffRoute(userLocation)) {
Toast.makeText(this, "You are off-route.", Toast.LENGTH_SHORT).show();
}
Instead of displaying a message the the user, I'd request a new route. It's important to note that there is currently a bug within the method that will be fixed in version 1.1 and will also allow you to set the threshold yourself. I'll try and update this answer once it gets released and the bug is fixed.
I hope I answered all your questions and feel free to ask questions below and i'll answer them as quick as possible.