Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
Mapbox welcomes participation and contributions from everyone.

### main
- Added `RouteOptions#waypointsPerRoute()` and `RouteOption.Builders#waypointsPerRoute()` methods. [#1509](https://github.com/mapbox/mapbox-java/pull/1509)
- Added `DirectionsRoute#waypoints`. [#1509](https://github.com/mapbox/mapbox-java/pull/1509)

### v6.9.0 - November 09, 2022
- Removed `RouteOptions#waypointsPerRoute()` and `RouteOption.Builders#waypointsPerRoute()` methods. [#1506](https://github.com/mapbox/mapbox-java/pull/1506)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.mapbox.samples;

import com.mapbox.api.directions.v5.DirectionsCriteria;
import com.mapbox.api.directions.v5.MapboxDirections;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.RouteOptions;
import com.mapbox.geojson.Point;
import com.mapbox.sample.BuildConfig;
import retrofit2.Response;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* Shows how to make a directions request using `waypoints_per_route=true` and access the waypoints from the response.
*/
public class BasicDirectionsWaypointsPerRoute {

public static void main(String[] args) throws IOException {
simpleMapboxDirectionsWithWaypointsPerRouteRequest();
}

private static void simpleMapboxDirectionsWithWaypointsPerRouteRequest() throws IOException {
MapboxDirections.Builder builder = MapboxDirections.builder();

// 1. Pass in all the required information to get a simple directions route.
List<Point> coordinates = new ArrayList<>();
coordinates.add(Point.fromLngLat(-95.6332, 29.7890));
coordinates.add(Point.fromLngLat(-95.3591, 29.7576));
RouteOptions routeOptions = RouteOptions.builder()
.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
.geometries(DirectionsCriteria.GEOMETRY_POLYLINE6)
.coordinatesList(coordinates)
.waypointsPerRoute(true)
.alternatives(true)
.build();
builder.routeOptions(routeOptions);
builder.accessToken(BuildConfig.MAPBOX_ACCESS_TOKEN);

// 2. That's it! Now execute the command and get the response.
Response<DirectionsResponse> response = builder.build().executeCall();

// 3. Log information from the response
System.out.printf("%nCheck that the GET response is successful %b", response.isSuccessful());
System.out.printf("%nFirst route's waypoints: %s", response.body().routes().get(0).waypoints());
System.out.printf("%nSecond route's waypoints: %s", response.body().routes().get(1).waypoints());
System.out.printf("%nRoot waypoints: %s", response.body().waypoints());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ public static Builder builder() {
@Nullable
public abstract List<RouteLeg> legs();

/**
* List of {@link DirectionsWaypoint} objects. Each {@code waypoint} is an input coordinate
* snapped to the road and path network. The {@code waypoint} appear in the list in the order of
* the input coordinates.
* Waypoints are returned in the {@link DirectionsRoute} object only when
* {@link RouteOptions#waypointsPerRoute()} is set to true. Otherwise they are returned
* in the root: {@link DirectionsResponse#waypoints()}.
*
* @return list of {@link DirectionsWaypoint} objects ordered from start of route till the end
*/
@Nullable
public abstract List<DirectionsWaypoint> waypoints();

/**
* Holds onto the parameter information used when making the directions request. Useful for
* re-requesting a directions route using the same information previously used.
Expand Down Expand Up @@ -301,6 +314,21 @@ public abstract static class Builder extends DirectionsJsonObject.Builder<Builde
@NonNull
public abstract Builder legs(@Nullable List<RouteLeg> legs);

/**
* List of {@link DirectionsWaypoint} objects. Each {@code waypoint} is an input coordinate
* snapped to the road and path network. The {@code waypoint} appear in the list in the order of
* the input coordinates.
* Waypoints are returned in the {@link DirectionsRoute} object only when
* {@link RouteOptions#waypointsPerRoute()} is set to true. Otherwise they are returned
* in the root: {@link DirectionsResponse#waypoints()}.
*
* @param waypoints list of {@link DirectionsWaypoint} objects ordered from start of route
* till the end
* @return this builder for chaining options together
*/
@NonNull
public abstract Builder waypoints(@Nullable List<DirectionsWaypoint> waypoints);

/**
* Holds onto the parameter information used when making the directions request.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,18 @@ public List<Point> waypointTargetsList() {
return ParseUtils.parseToPoints(waypointTargets());
}

/**
* If true, the waypoints array is returned within the route object, else its returned
* at the root of the response body. Defaults to false if unspecified.
* Setting `waypoints_per_route` to true is necessary when asking for an EV-optimized
* route with alternatives, since each alternative route may produce separate
* sets of waypoints (charging stations).
* @return boolean representing the waypoints_per_route value
*/
@SerializedName("waypoints_per_route")
@Nullable
public abstract Boolean waypointsPerRoute();

/**
* A scale from -1 to 1, where -1 biases the route against alleys
* and 1 biases the route toward alleys. If null, default is 0, which is neutral.
Expand Down Expand Up @@ -1031,6 +1043,7 @@ public URL toUrl(@NonNull String accessToken) {
appendQueryParameter(sb, "max_width", maxWidth());
appendQueryParameter(sb, "max_weight", maxWeight());
appendQueryParameter(sb, "compute_toll_cost", computeTollCost());
appendQueryParameter(sb, "waypoints_per_route", waypointsPerRoute());
appendQueryParameter(sb, "metadata", metadata());

Map<String, SerializableJsonElement> unrecognized = unrecognized();
Expand Down Expand Up @@ -2031,6 +2044,19 @@ public Builder snappingIncludeStaticClosuresList(
@SuppressWarnings("checkstyle:javadocmethod")
public abstract Builder computeTollCost(@Nullable Boolean computeTollCost);

/**
* If true, the waypoints array is returned within the route object, else its returned
* at the root of the response body. Defaults to false if unspecified.
* Setting `waypoints_per_route` to true is necessary when asking for an EV-optimized
* route with alternatives, since each alternative route may produce separate
* sets of waypoints (charging stations).
*
* @param waypointsPerRoute boolean representing the `waypoints_per_route` value
* @return this builder
*/
@NonNull
public abstract Builder waypointsPerRoute(@Nullable Boolean waypointsPerRoute);

/**
* Whether the response should contain metadata holding versioning information.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.hamcrest.junit.ExpectedException;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -130,9 +133,7 @@ public void directionsRoute_hasTollCosts() throws IOException {
String uuid = "123";
DirectionsRoute route = DirectionsRoute.fromJson(json, options, uuid);

DirectionsRoute newRoute = route.toBuilder().routeIndex("0").build();

assertEquals(2, newRoute.tollCosts().size());
assertEquals(2, route.tollCosts().size());
}

@Test
Expand All @@ -148,8 +149,72 @@ public void directionsRoute_noTollCosts() throws IOException {
String uuid = "123";
DirectionsRoute route = DirectionsRoute.fromJson(json, options, uuid);

DirectionsRoute newRoute = route.toBuilder().routeIndex("0").build();
assertNull(route.tollCosts());
}

@Test
public void directionsRoute_hasWaypoints() throws IOException {
String json = loadJsonFixture("directions_v5_with_waypoints.json");
RouteOptions options = RouteOptions.builder()
.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
.coordinatesList(new ArrayList<Point>() {{
add(Point.fromLngLat(1.0, 1.0));
add(Point.fromLngLat(2.0, 2.0));
}})
.waypointsPerRoute(true)
.build();
String uuid = "123";
DirectionsRoute route = DirectionsRoute.fromJson(json, options, uuid);

assertEquals(2, route.waypoints().size());
}

@Test
public void directionsRouteBuilder_hasWaypoints() {
List<DirectionsWaypoint> waypoints = Arrays.asList(
DirectionsWaypoint.builder()
.name("name1")
.rawLocation(new double[] { 5.6, 7.8 })
.build(),
DirectionsWaypoint.builder()
.name("name2")
.rawLocation(new double[] { 1.2, 3.4 })
.build()
);
DirectionsRoute route = DirectionsRoute.builder()
.duration(12.12)
.distance(34.34)
.waypoints(waypoints)
.build();

assertEquals(waypoints, route.waypoints());
}


@Test
public void directionsRoute_noWaypoints() throws IOException {
String json = loadJsonFixture("directions_v5-with-closure_precision_6.json");
RouteOptions options = RouteOptions.builder()
.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
.coordinatesList(new ArrayList<Point>() {{
add(Point.fromLngLat(1.0, 1.0));
add(Point.fromLngLat(2.0, 2.0));
}})
.waypointsPerRoute(true)
.build();
String uuid = "123";
DirectionsRoute route = DirectionsRoute.fromJson(json, options, uuid);

assertNull(route.waypoints());
}

@Test
public void directionsRouteBuilder_noWaypoints() {
DirectionsRoute route = DirectionsRoute.builder()
.duration(12.12)
.distance(34.34)
.build();

assertNull(newRoute.tollCosts());
assertNull(route.waypoints());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class RouteOptionsTest extends TestUtils {
*/
private static final String ROUTE_OPTIONS_JSON = "route_options_v5.json";
private static final String ROUTE_OPTIONS_URL =
"https://api.mapbox.com/directions/v5/mapbox/driving/-122.4003312,37.7736941;-122.4187529,37.7689715;-122.4255172,37.7775835?access_token=pk.token&geometries=polyline6&alternatives=false&overview=full&radiuses=%3Bunlimited%3B5.1&steps=true&avoid_maneuver_radius=200.0&bearings=0%2C90%3B90%2C0%3B&layers=-42%3B%3B0&continue_straight=false&annotations=congestion%2Cdistance%2Cduration&language=ru&roundabout_exits=false&voice_instructions=true&banner_instructions=true&voice_units=metric&exclude=toll%2Cferry%2Cpoint%2811.0+-22.0%29&include=hot%2Chov2&approaches=%3Bcurb%3B&waypoints=0%3B1%3B2&waypoint_names=%3BSerangoon+Garden+Market+%26+Food+Centre%3BFunky+%26nAmE*&waypoint_targets=%3B12.2%2C21.2%3B&enable_refresh=true&walking_speed=5.11&walkway_bias=-0.2&alley_bias=0.75&snapping_include_closures=%3Bfalse%3Btrue&snapping_include_static_closures=true%3B%3Bfalse&arrive_by=2021-01-01%27T%2701%3A01&depart_at=2021-02-02%27T%2702%3A02&max_height=1.5&max_width=1.4&max_weight=2.9&compute_toll_cost=true&metadata=true";
"https://api.mapbox.com/directions/v5/mapbox/driving/-122.4003312,37.7736941;-122.4187529,37.7689715;-122.4255172,37.7775835?access_token=pk.token&geometries=polyline6&alternatives=false&overview=full&radiuses=%3Bunlimited%3B5.1&steps=true&avoid_maneuver_radius=200.0&bearings=0%2C90%3B90%2C0%3B&layers=-42%3B%3B0&continue_straight=false&annotations=congestion%2Cdistance%2Cduration&language=ru&roundabout_exits=false&voice_instructions=true&banner_instructions=true&voice_units=metric&exclude=toll%2Cferry%2Cpoint%2811.0+-22.0%29&include=hot%2Chov2&approaches=%3Bcurb%3B&waypoints=0%3B1%3B2&waypoint_names=%3BSerangoon+Garden+Market+%26+Food+Centre%3BFunky+%26nAmE*&waypoint_targets=%3B12.2%2C21.2%3B&enable_refresh=true&walking_speed=5.11&walkway_bias=-0.2&alley_bias=0.75&snapping_include_closures=%3Bfalse%3Btrue&snapping_include_static_closures=true%3B%3Bfalse&arrive_by=2021-01-01%27T%2701%3A01&depart_at=2021-02-02%27T%2702%3A02&max_height=1.5&max_width=1.4&max_weight=2.9&compute_toll_cost=true&waypoints_per_route=true&metadata=true";
private static final String ACCESS_TOKEN = "pk.token";

private final String optionsJson = loadJsonFixture(ROUTE_OPTIONS_JSON);
Expand Down Expand Up @@ -349,13 +349,27 @@ public void computeTollCostIsValid_fromJson() {
assertEquals(true, options.computeTollCost());
}

@Test
public void waypointsPerRouteAreValid_fromJson() {
RouteOptions routeOptions = RouteOptions.fromJson(optionsJson);

assertEquals(true, routeOptions.waypointsPerRoute());
}

@Test
public void defaultTollCost() {
RouteOptions options = defaultRouteOptions();

assertNull(options.computeTollCost());
}

@Test
public void defaultWaypointsPerRoute() {
RouteOptions options = defaultRouteOptions();

assertNull(options.waypointsPerRoute());
}

@Test
public void routeOptions_toJson() {
RouteOptions options = routeOptions();
Expand Down Expand Up @@ -1046,6 +1060,7 @@ private RouteOptions routeOptions() {
.enableRefresh(true)
.metadata(true)
.computeTollCost(true)
.waypointsPerRoute(true)
.build();
}

Expand Down Expand Up @@ -1152,6 +1167,7 @@ private RouteOptions routeOptionsList() {
.enableRefresh(true)
.metadata(true)
.computeTollCost(true)
.waypointsPerRoute(true)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"weight_typical":49.666,"duration_typical":36.767,"weight_name":"auto","weight":49.666,"duration":36.767,"distance":265.56,"waypoints":[{"name":"Köpenicker Straße","location":[13.426579,52.508068]},{"name":"Engeldamm","location":[13.427292,52.506902]}],"legs":[{"admins":[{"iso_3166_1_alpha3":"USA","iso_3166_1":"US"}],"closures":[{"geometry_index_end":21,"geometry_index_start":13}],"incidents":[{"id":"12887387251066566","type":"road_closure","description":"Washington Blvd: road closed from Kobbe Ave to Lincoln Blvd","long_description":"Road closed due to Slow Streets Program on Washington Blvd both ways from Kobbe Ave to Lincoln Blvd.","creation_time":"2021-03-29T20:25:39Z","start_time":"2020-07-02T15:26:14Z","end_time":"2021-06-14T22:59:00Z","impact":"low","sub_type":"CONSTRUCTION","alertc_codes":[401,703],"lanes_blocked":[],"closed":true,"congestion":{"value":101},"geometry_index_start":13,"geometry_index_end":19}],"annotation":{"congestion":["low","low","low","low","low","low","low","low","low","low","low","low","low","unknown","severe","severe","severe","severe","severe","severe","severe"],"distance":[8.5,28.8,10.6,8.3,8,8.1,8.9,8,10.9,27.4,8.3,2.4,7,5.9,5.7,6.4,12.7,17.1,18.6,19.4,34.9]},"weight_typical":49.666,"duration_typical":36.767,"weight":49.666,"duration":36.767,"steps":[{"intersections":[{"entry":[true],"bearings":[198],"duration":3.749,"mapbox_streets_v8":{"class":"secondary"},"is_urban":false,"admin_index":0,"out":0,"weight":3.562,"geometry_index":0,"location":[-122.477426,37.801498]},{"entry":[false,true],"in":0,"bearings":[19,204],"duration":5.282,"turn_weight":0.5,"turn_duration":0.01,"mapbox_streets_v8":{"class":"secondary"},"is_urban":false,"admin_index":0,"out":1,"weight":5.508,"geometry_index":3,"location":[-122.477599,37.801089]},{"entry":[false,true],"in":0,"bearings":[29,213],"duration":6.3,"turn_weight":0.5,"mapbox_streets_v8":{"class":"secondary"},"is_urban":false,"admin_index":0,"out":1,"weight":6.485,"geometry_index":8,"location":[-122.477809,37.800758]},{"bearings":[33,210],"entry":[false,true],"in":0,"turn_weight":2,"lanes":[{"indications":["left","straight"],"valid_indication":"left","valid":true,"active":true}],"turn_duration":0.021,"mapbox_streets_v8":{"class":"secondary"},"is_urban":false,"admin_index":0,"out":1,"geometry_index":12,"location":[-122.478115,37.800389]}],"maneuver":{"type":"depart","instruction":"Drive south on Lincoln Boulevard.","bearing_after":198,"bearing_before":0,"location":[-122.477426,37.801498]},"name":"Lincoln Boulevard","weight_typical":18.409,"duration_typical":16.252,"duration":16.252,"distance":144.905,"driving_side":"right","weight":18.409,"mode":"driving","geometry":"s`fbgAbvlrhFpCz@jNjErDpAhCfA`CjA`CpAjC~AzB|AdDbCvK|I|BdBd@ZjBnA"},{"intersections":[{"bearings":[30,161],"entry":[false,true],"in":0,"turn_weight":12.5,"lanes":[{"indications":["left","straight"],"valid_indication":"left","valid":true,"active":true}],"turn_duration":0.772,"mapbox_streets_v8":{"class":"tertiary"},"is_urban":false,"admin_index":0,"out":1,"geometry_index":13,"location":[-122.478155,37.800335]}],"maneuver":{"type":"turn","instruction":"Turn left onto Washington Boulevard.","modifier":"left","bearing_after":161,"bearing_before":210,"location":[-122.478155,37.800335]},"name":"Washington Boulevard","weight_typical":31.256,"duration_typical":20.516,"duration":20.516,"distance":120.655,"driving_side":"right","weight":31.256,"mode":"driving","geometry":"}wcbgAtcnrhFlAyA~Ai@pBUbFLpHShIcArIcBhQ}G"},{"intersections":[{"bearings":[339],"entry":[true],"in":0,"admin_index":0,"geometry_index":21,"location":[-122.477848,37.799296]}],"maneuver":{"type":"arrive","instruction":"You have arrived at your destination.","bearing_after":0,"bearing_before":159,"location":[-122.477848,37.799296]},"name":"Washington Boulevard","weight_typical":0,"duration_typical":0,"duration":0,"distance":0,"driving_side":"right","weight":0,"mode":"driving","geometry":"_wabgAnpmrhF??"}],"distance":265.56,"summary":"Lincoln Boulevard, Washington Boulevard"}],"geometry":"s`fbgAbvlrhFpCz@jNjErDpAhCfA`CjA`CpAjC~AzB|AdDbCvK|I|BdBd@ZjBnAlAyA~Ai@pBUbFLpHShIcArIcBhQ}G"}
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@
"max_weight": 2.9,
"enable_refresh": true,
"metadata": true,
"waypoints_per_route": true,
"compute_toll_cost": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ interface DirectionsService {
* @param maxHeight {@link RouteOptions#maxHeight()}
* @param maxWidth {@link RouteOptions#maxWidth()}
* @param computeTollCost {@link RouteOptions#computeTollCost()}
* @param waypointsPerRoute {@link RouteOptions#waypointsPerRoute()}
* @param metadata {@link RouteOptions#metadata()}
* @return the {@link DirectionsResponse} in a Call wrapper
*/
Expand Down Expand Up @@ -100,6 +101,7 @@ Call<DirectionsResponse> getCall(
@Query("max_width") Double maxWidth,
@Query("max_weight") Double maxWeight,
@Query("compute_toll_cost") Boolean computeTollCost,
@Query("waypoints_per_route") Boolean waypointsPerRoute,
@Query("metadata") Boolean metadata
);

Expand Down Expand Up @@ -143,6 +145,7 @@ Call<DirectionsResponse> getCall(
* @param maxHeight {@link RouteOptions#maxHeight()}
* @param maxWidth {@link RouteOptions#maxWidth()}
* @param computeTollCost {@link RouteOptions#computeTollCost()}
* @param waypointsPerRoute {@link RouteOptions#waypointsPerRoute()}
* @param metadata {@link RouteOptions#metadata()}
* @return the {@link DirectionsResponse} in a Call wrapper
*/
Expand Down Expand Up @@ -187,6 +190,7 @@ Call<DirectionsResponse> postCall(
@Field("max_width") Double maxWidth,
@Field("max_weight") Double maxWeight,
@Field("compute_toll_cost") Boolean computeTollCost,
@Field("waypoints_per_route") Boolean waypointsPerRoute,
@Field("metadata") Boolean metadata
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ private Call<DirectionsResponse> get() {
routeOptions().maxWidth(),
routeOptions().maxWeight(),
routeOptions().computeTollCost(),
routeOptions().waypointsPerRoute(),
routeOptions().metadata()
);
}
Expand Down Expand Up @@ -154,6 +155,7 @@ private Call<DirectionsResponse> post() {
routeOptions().maxWidth(),
routeOptions().maxWeight(),
routeOptions().computeTollCost(),
routeOptions().waypointsPerRoute(),
routeOptions().metadata()
);
}
Expand Down
Loading