diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/route/RouteFetcher.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/route/RouteFetcher.java index 4e8634f9bd4..82a61b8dca7 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/route/RouteFetcher.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/route/RouteFetcher.java @@ -92,6 +92,7 @@ private NavigationRoute.Builder buildRequestFromLocation(Location location, Rout } addDestination(remainingWaypoints, builder); addWaypoints(remainingWaypoints, builder); + addWaypointNames(progress, builder); return builder; } @@ -114,6 +115,13 @@ private void addWaypoints(List remainingCoordinates, NavigationRoute.Buil } } + private void addWaypointNames(RouteProgress progress, NavigationRoute.Builder builder) { + String[] remainingWaypointNames = routeUtils.calculateRemainingWaypointNames(progress); + if (remainingWaypointNames != null) { + builder.addWaypointNames(remainingWaypointNames); + } + } + private void executeRouteCall(NavigationRoute.Builder builder) { if (builder != null) { builder.accessToken(accessToken); diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/utils/RouteUtils.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/utils/RouteUtils.java index 75187a223aa..c9ce611a9b9 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/utils/RouteUtils.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/utils/RouteUtils.java @@ -10,6 +10,7 @@ import com.mapbox.api.directions.v5.models.DirectionsRoute; import com.mapbox.api.directions.v5.models.LegStep; import com.mapbox.api.directions.v5.models.RouteLeg; +import com.mapbox.api.directions.v5.models.RouteOptions; import com.mapbox.api.directions.v5.models.VoiceInstructions; import com.mapbox.core.utils.TextUtils; import com.mapbox.geojson.Point; @@ -17,9 +18,10 @@ import com.mapbox.services.android.navigation.v5.milestone.Milestone; import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -30,8 +32,8 @@ public class RouteUtils { private static final String FORCED_LOCATION = "Forced Location"; private static final int FIRST_COORDINATE = 0; - private static final int ZERO_INSTRUCTIONS = 0; private static final int FIRST_INSTRUCTION = 0; + private static final String SEMICOLON = ";"; private static final Set VALID_PROFILES = new HashSet() { { add(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC); @@ -136,6 +138,25 @@ public List calculateRemainingWaypoints(RouteProgress routeProgress) { return coordinates; } + /** + * Given a {@link RouteProgress}, this method will calculate the remaining waypoint names + * along the given route based on route option waypoint names and the progress remaining coordinates. + * + * @param routeProgress for route waypoint names and remaining coordinates + * @return String array of remaining waypoint names + * @since 0.19.0 + */ + @Nullable + public String[] calculateRemainingWaypointNames(RouteProgress routeProgress) { + RouteOptions routeOptions = routeProgress.directionsRoute().routeOptions(); + if (routeOptions == null || TextUtils.isEmpty(routeOptions.waypointNames())) { + return null; + } + String waypointNames = routeOptions.waypointNames(); + String[] names = waypointNames.split(SEMICOLON); + return Arrays.copyOfRange(names, FIRST_COORDINATE, routeProgress.remainingWaypoints()); + } + /** * If navigation begins, a location update is sometimes needed to force a * progress change update as soon as navigation is started. diff --git a/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/utils/RouteUtilsTest.java b/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/utils/RouteUtilsTest.java index 5af35b36c8c..042ce7149dc 100644 --- a/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/utils/RouteUtilsTest.java +++ b/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/utils/RouteUtilsTest.java @@ -8,7 +8,9 @@ import com.mapbox.api.directions.v5.models.DirectionsRoute; import com.mapbox.api.directions.v5.models.LegStep; import com.mapbox.api.directions.v5.models.RouteLeg; +import com.mapbox.api.directions.v5.models.RouteOptions; import com.mapbox.api.directions.v5.models.VoiceInstructions; +import com.mapbox.geojson.Point; import com.mapbox.services.android.navigation.v5.BaseTest; import com.mapbox.services.android.navigation.v5.milestone.BannerInstructionMilestone; import com.mapbox.services.android.navigation.v5.routeprogress.RouteLegProgress; @@ -16,6 +18,7 @@ import org.junit.Test; +import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertEquals; @@ -397,6 +400,67 @@ public void findCurrentVoiceInstructions_returnsCorrectInstructionsEndOfStepDist assertEquals(currentStep.voiceInstructions().get(2), currentVoiceInstructions); } + @Test + public void calculateRemainingWaypoints() { + DirectionsRoute route = mock(DirectionsRoute.class); + RouteOptions routeOptions = mock(RouteOptions.class); + when(routeOptions.coordinates()).thenReturn(buildCoordinateList()); + when(route.routeOptions()).thenReturn(routeOptions); + RouteProgress routeProgress = mock(RouteProgress.class); + when(routeProgress.remainingWaypoints()).thenReturn(2); + when(routeProgress.directionsRoute()).thenReturn(route); + RouteUtils routeUtils = new RouteUtils(); + + List remainingWaypoints = routeUtils.calculateRemainingWaypoints(routeProgress); + + assertEquals(2, remainingWaypoints.size()); + } + + @Test + public void calculateRemainingWaypoints_handlesNullOptions() { + DirectionsRoute route = mock(DirectionsRoute.class); + when(route.routeOptions()).thenReturn(null); + RouteProgress routeProgress = mock(RouteProgress.class); + when(routeProgress.remainingWaypoints()).thenReturn(2); + when(routeProgress.directionsRoute()).thenReturn(route); + RouteUtils routeUtils = new RouteUtils(); + + List remainingWaypoints = routeUtils.calculateRemainingWaypoints(routeProgress); + + assertNull(remainingWaypoints); + } + + @Test + public void calculateRemainingWaypointNames() { + DirectionsRoute route = mock(DirectionsRoute.class); + RouteOptions routeOptions = mock(RouteOptions.class); + when(routeOptions.coordinates()).thenReturn(buildCoordinateList()); + when(routeOptions.waypointNames()).thenReturn("first;second;third;fourth"); + when(route.routeOptions()).thenReturn(routeOptions); + RouteProgress routeProgress = mock(RouteProgress.class); + when(routeProgress.remainingWaypoints()).thenReturn(2); + when(routeProgress.directionsRoute()).thenReturn(route); + RouteUtils routeUtils = new RouteUtils(); + + String[] remainingWaypointNames = routeUtils.calculateRemainingWaypointNames(routeProgress); + + assertEquals(2, remainingWaypointNames.length); + } + + @Test + public void calculateRemainingWaypointNames_handlesNullOptions() { + DirectionsRoute route = mock(DirectionsRoute.class); + when(route.routeOptions()).thenReturn(null); + RouteProgress routeProgress = mock(RouteProgress.class); + when(routeProgress.remainingWaypoints()).thenReturn(2); + when(routeProgress.directionsRoute()).thenReturn(route); + RouteUtils routeUtils = new RouteUtils(); + + String[] remainingWaypointNames = routeUtils.calculateRemainingWaypointNames(routeProgress); + + assertNull(remainingWaypointNames); + } + @NonNull private RouteProgress buildRouteProgress(int first, DirectionsRoute route, LegStep currentStep, LegStep upcomingStep) { @@ -415,4 +479,13 @@ private void buildBannerInstruction(int first, BannerInstructionMilestone banner BannerInstructions bannerInstructions = currentStepBannerInstructions.get(first); when(bannerInstructionMilestone.getBannerInstructions()).thenReturn(bannerInstructions); } + + private List buildCoordinateList() { + List coordinates = new ArrayList<>(); + coordinates.add(Point.fromLngLat(1.234, 5.678)); + coordinates.add(Point.fromLngLat(1.234, 5.678)); + coordinates.add(Point.fromLngLat(1.234, 5.678)); + coordinates.add(Point.fromLngLat(1.234, 5.678)); + return coordinates; + } } \ No newline at end of file