Skip to content

Commit f21558a

Browse files
osanaGuardiola31337
authored andcommitted
Added waypoint targets to MapboxDirections request (#942)
1 parent 49db7f9 commit f21558a

6 files changed

Lines changed: 142 additions & 22 deletions

File tree

Makefile

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,31 +136,35 @@ directions-fixtures:
136136

137137
# Directions: includes waypoint_names
138138
curl "https://api.mapbox.com/directions/v5/mapbox/cycling/-122.42,37.78;-77.03,38.91?steps=true&voice_instructions=true&banner_instructions=true&voice_units=imperial&waypoint_names=Home;Work&access_token=$(MAPBOX_ACCESS_TOKEN)" \
139-
-o services-directions/src/test/resources/directions_v5_waypoint_names.json
139+
-o services-directions/src/test/resources/directions_v5_waypoint_names.json
140+
141+
# Directions: includes waypoint_targets
142+
curl "https://api.mapbox.com/directions/v5/mapbox/driving-traffic/-6.80904429026134,62.00015328799685;-6.800065040588378,62.00012400993553?waypoint_targets=;-6.799936294555664,61.99987216574813&steps=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \
143+
-o services-directions/src/test/resources/directions_v5_waypoint_targets.json
140144

141145
mapmatching-fixtures:
142146
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?geometries=polyline&language=sv&steps=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \
143147
-o services-matching/src/test/resources/map_matching_v5_polyline.json
144148

145149
# Unmatchable MapMatching request
146-
curl "https://api.mapbox.com/matching/v5/mapbox/driving/0,-40;0,-20?access_token=$(MAPBOX_ACCESS_TOKEN)" \
147-
-o services-matching/src/test/resources/mapmatching_nosegment_v5_polyline.json
150+
curl "https://api.mapbox.com/matching/v5/mapbox/driving/0,-40;0,-20?access_token=$(MAPBOX_ACCESS_TOKEN)" \
151+
-o services-matching/src/test/resources/mapmatching_nosegment_v5_polyline.json
148152

149153
# MapMatching request with approaches
150-
curl "https://api.mapbox.com/matching/v5/mapbox/driving/-117.1728265285492,32.71204416018209;-117.17334151268004,32.71254065549407?approaches=unrestricted;curb&access_token=$(MAPBOX_ACCESS_TOKEN)" \
154+
curl "https://api.mapbox.com/matching/v5/mapbox/driving/-117.1728265285492,32.71204416018209;-117.17334151268004,32.71254065549407?approaches=unrestricted;curb&access_token=$(MAPBOX_ACCESS_TOKEN)" \
151155
-o services-matching/src/test/resources/mapmatching_v5_approaches.json
152156

153157
# MapMatching request with waypoint_names:
154-
curl "https://api.mapbox.com/matching/v5/mapbox/driving/2.344003915786743,48.85805170891599;2.346750497817993,48.85727523615161;2.348681688308716,48.85936462637049;2.349550724029541,48.86084691113991;2.349550724029541,48.8608892614883;2.349625825881958,48.86102337068847;2.34982967376709,48.86125629633996?steps=true&tidy=true&waypoints=0;6&waypoint_names=Home;Work&banner_instructions=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \
155-
-o services-matching/src/test/resources/mapmatching_v5_waypoint_names.json
158+
curl "https://api.mapbox.com/matching/v5/mapbox/driving/2.344003915786743,48.85805170891599;2.346750497817993,48.85727523615161;2.348681688308716,48.85936462637049;2.349550724029541,48.86084691113991;2.349550724029541,48.8608892614883;2.349625825881958,48.86102337068847;2.34982967376709,48.86125629633996?steps=true&tidy=true&waypoints=0;6&waypoint_names=Home;Work&banner_instructions=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \
159+
-o services-matching/src/test/resources/mapmatching_v5_waypoint_names.json
156160

157161
# MapMatching with valid voiceLanguage
158-
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?steps=true&overview=full&geometries=polyline6&roundabout_exits=true&voice_instructions=true&language=en&access_token=$(MAPBOX_ACCESS_TOKEN)" \
159-
-o services-matching/src/test/resources/map_matching_v5_voice_language.json
162+
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?steps=true&overview=full&geometries=polyline6&roundabout_exits=true&voice_instructions=true&language=en&access_token=$(MAPBOX_ACCESS_TOKEN)" \
163+
-o services-matching/src/test/resources/map_matching_v5_voice_language.json
160164

161165
# MapMatching with invalid voiceLanguage
162-
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?steps=true&overview=full&geometries=polyline6&roundabout_exits=true&voice_instructions=true&language=he&access_token=$(MAPBOX_ACCESS_TOKEN)" \
163-
-o services-matching/src/test/resources/map_matching_v5_invalid_voice_language.json
166+
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?steps=true&overview=full&geometries=polyline6&roundabout_exits=true&voice_instructions=true&language=he&access_token=$(MAPBOX_ACCESS_TOKEN)" \
167+
-o services-matching/src/test/resources/map_matching_v5_invalid_voice_language.json
164168

165169
optimization-fixtures:
166170
# request an optimized car trip with no additional options

services-directions/src/main/java/com/mapbox/api/directions/v5/DirectionsService.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public interface DirectionsService {
4646
* @param voiceUnits voice units
4747
* @param exclude exclude tolls, motorways or more along your route
4848
* @param approaches which side of the road to approach a waypoint
49-
* @param waypointNames custom names for waypoints used for the arrival instruction.
49+
* @param waypointNames custom names for waypoints used for the arrival instruction
50+
* @param waypointTargets list of coordinate pairs for drop-off locations
5051
* @return the {@link DirectionsResponse} in a Call wrapper
5152
* @since 1.0.0
5253
*/
@@ -72,6 +73,7 @@ Call<DirectionsResponse> getCall(
7273
@Query("voice_units") String voiceUnits,
7374
@Query("exclude") String exclude,
7475
@Query("approaches") String approaches,
75-
@Query("waypoint_names") String waypointNames
76+
@Query("waypoint_names") String waypointNames,
77+
@Query("waypoint_targets") String waypointTargets
7678
);
7779
}

services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ protected Call<DirectionsResponse> initializeCall() {
8787
voiceUnits(),
8888
exclude(),
8989
approaches(),
90-
waypointNames());
90+
waypointNames(),
91+
waypointTargets());
9192
}
9293

9394
@Override
@@ -206,6 +207,7 @@ private List<DirectionsRoute> generateRouteOptions(Response<DirectionsResponse>
206207
.profile(profile())
207208
.coordinates(coordinates())
208209
.waypointNames(waypointNames())
210+
.waypointTargets(waypointTargets())
209211
.continueStraight(continueStraight())
210212
.annotations(annotation())
211213
.approaches(approaches())
@@ -232,14 +234,38 @@ private List<DirectionsRoute> generateRouteOptions(Response<DirectionsResponse>
232234
}
233235

234236
private static String formatCoordinates(List<Point> coordinates) {
235-
List<String> coordinatesFormatted = new ArrayList<>();
237+
String[] coordinatesFormatted = new String[coordinates.size()];
238+
int index = 0;
236239
for (Point point : coordinates) {
237-
coordinatesFormatted.add(String.format(Locale.US, "%s,%s",
240+
coordinatesFormatted[index++] = String.format(Locale.US, "%s,%s",
238241
TextUtils.formatCoordinate(point.longitude()),
239-
TextUtils.formatCoordinate(point.latitude())));
242+
TextUtils.formatCoordinate(point.latitude()));
240243
}
241244

242-
return TextUtils.join(";", coordinatesFormatted.toArray());
245+
return TextUtils.join(";", coordinatesFormatted);
246+
}
247+
248+
/**
249+
* Converts array of Points with waypoint_targets values
250+
* to a string ready for API consumption.
251+
*
252+
* @param waypointTargets a string representing approaches to each coordinate.
253+
* @return a formatted string.
254+
* @since 4.3.0
255+
*/
256+
private static String formatWaypointTargets(Point[] waypointTargets) {
257+
String[] coordinatesFormatted = new String[waypointTargets.length];
258+
int index = 0;
259+
for (Point target : waypointTargets) {
260+
if (target == null) {
261+
coordinatesFormatted[index++] = "";
262+
} else {
263+
coordinatesFormatted[index++] = String.format(Locale.US, "%s,%s",
264+
TextUtils.formatCoordinate(target.longitude()),
265+
TextUtils.formatCoordinate(target.latitude()));
266+
}
267+
}
268+
return TextUtils.join(";", coordinatesFormatted);
243269
}
244270

245271
@NonNull
@@ -309,6 +335,9 @@ private static String formatCoordinates(List<Point> coordinates) {
309335
@Nullable
310336
abstract String waypointNames();
311337

338+
@Nullable
339+
abstract String waypointTargets();
340+
312341
/**
313342
* Build a new {@link MapboxDirections} object with the initial values set for
314343
* {@link #baseUrl()}, {@link #profile()}, {@link #user()}, and {@link #geometries()}.
@@ -358,6 +387,7 @@ public abstract static class Builder {
358387
private Point origin;
359388
private String[] approaches;
360389
private String[] waypointNames;
390+
private Point[] waypointTargets;
361391

362392
/**
363393
* The username for the account that the directions engine runs on. In most cases, this should
@@ -713,7 +743,7 @@ public Builder addApproaches(String... approaches) {
713743
* Custom names for waypoints used for the arrival instruction,
714744
* each separated by ; . Values can be any string and total number of all characters cannot
715745
* exceed 500. If provided, the list of waypointNames must be the same length as the list of
716-
* coordinates, but you can skip a coordinate and show its position with the ; separator.
746+
* coordinates, but you can skip a coordinate and show its position with the ; separator.
717747
* @param waypointNames Custom names for waypoints used for the arrival instruction.
718748
* @return this builder for chaining options together
719749
* @since 3.3.0
@@ -725,6 +755,23 @@ public Builder addWaypointNames(@Nullable String... waypointNames) {
725755

726756
abstract Builder waypointNames(@Nullable String waypointNames);
727757

758+
/**
759+
* A list of coordinate points used to specify drop-off locations
760+
* that are distinct from the locations specified in coordinates.
761+
* The number of waypoint targets must be the same as the number of coordinates,
762+
* but you can skip a coordinate with a null value.
763+
* Must be used with steps=true.
764+
* @param waypointTargets list of coordinate points for drop-off locations
765+
* @return this builder for chaining options together
766+
* @since 4.3.0
767+
*/
768+
public Builder addWaypointTargets(@Nullable Point... waypointTargets) {
769+
this.waypointTargets = waypointTargets;
770+
return this;
771+
}
772+
773+
abstract Builder waypointTargets(@Nullable String waypointTargets);
774+
728775
abstract MapboxDirections autoBuild();
729776

730777
/**
@@ -757,6 +804,15 @@ public MapboxDirections build() {
757804
waypointNames(waypointNamesStr);
758805
}
759806

807+
if (waypointTargets != null) {
808+
if (waypointTargets.length != coordinates.size()) {
809+
throw new ServicesException("Number of waypoint targets must match "
810+
+ " the number of waypoints provided.");
811+
}
812+
813+
waypointTargets(formatWaypointTargets(waypointTargets));
814+
}
815+
760816
if (approaches != null) {
761817
if (approaches.length != coordinates.size()) {
762818
throw new ServicesException("Number of approach elements must match "
@@ -783,4 +839,5 @@ public MapboxDirections build() {
783839
return directions;
784840
}
785841
}
842+
786843
}

services-directions/src/main/java/com/mapbox/api/directions/v5/models/RouteOptions.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,10 @@ public static Builder builder() {
255255
* Accepts unrestricted (default) or curb . If set to unrestricted ,
256256
* the route can approach waypoints from either side of the road.
257257
* If set to curb, the route will be returned so that on arrival,
258-
* the waypoint will be found on the side that corresponds with the driving_side of the region
258+
* the waypoint will be found on the side that corresponds with the driving_side of the region
259259
* in which the returned route is located.
260260
* If provided, the list of approaches must be the same length as the list of waypoints.
261-
* However, you can skip a coordinate and show its position in the list with the ; separator.
261+
* However, you can skip a coordinate and show its position in the list with the ; separator.
262262
*
263263
* @return a string representing approaches for each waypoint
264264
* @since 3.2.0
@@ -271,7 +271,7 @@ public static Builder builder() {
271271
* Custom names for waypoints used for the arrival instruction in banners and voice instructions,
272272
* each separated by ; . Values can be any string and total number of all characters cannot
273273
* exceed 500. If provided, the list of waypoint_names must be the same length as the list of
274-
* coordinates, but you can skip a coordinate and show its position with the ; separator.
274+
* coordinates, but you can skip a coordinate and show its position with the ; separator.
275275
* @return a string representing names for each waypoint
276276
* @since 3.3.0
277277
*/
@@ -280,6 +280,22 @@ public static Builder builder() {
280280
public abstract String waypointNames();
281281

282282

283+
/**
284+
* A semicolon-separated list of coordinate pairs used to specify drop-off
285+
* locations that are distinct from the locations specified in coordinates.
286+
* If this parameter is provided, the Directions API will compute the side of the street,
287+
* left or right, for each target based on the waypoint_targets and the driving direction.
288+
* The maneuver.modifier, banner and voice instructions will be updated with the computed
289+
* side of street. The number of waypoint targets must be the same as the number of coordinates,
290+
* but you can skip a coordinate pair and show its position in the list with the ; separator.
291+
* Must be used with steps=true.
292+
* @return a string representing coordinate pairs for drop-off locations
293+
* @since 4.3.0
294+
*/
295+
@SerializedName("waypoint_targets")
296+
@Nullable
297+
public abstract String waypointTargets();
298+
283299
/**
284300
* Gson type adapter for parsing Gson to this class.
285301
*
@@ -526,7 +542,7 @@ public abstract Builder overview(
526542
public abstract Builder approaches(String approaches);
527543

528544
/**
529-
* The same approaches the user originally made when the request was made.
545+
* The same waypoint names the user originally made when the request was made.
530546
*
531547
* @param waypointNames unrestricted, curb or omitted (;)
532548
* @return this builder for chaining options together
@@ -536,6 +552,17 @@ public abstract Builder overview(
536552
@Nullable
537553
public abstract Builder waypointNames(@Nullable String waypointNames);
538554

555+
/**
556+
* The same waypoint targets the user originally made when the request was made.
557+
*
558+
* @param waypointTargets list of coordinate pairs for drop-off locations (;)
559+
* @return this builder for chaining options together
560+
* @since 4.3.0
561+
*/
562+
563+
@Nullable
564+
public abstract Builder waypointTargets(@Nullable String waypointTargets);
565+
539566
/**
540567
* Builds a new instance of the {@link RouteOptions} object.
541568
*

services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.mapbox.api.directions.v5.models.DirectionsRoute;
99
import com.mapbox.api.directions.v5.models.LegAnnotation;
1010
import com.mapbox.api.directions.v5.models.RouteOptions;
11+
import com.mapbox.api.directions.v5.models.StepManeuver;
1112
import com.mapbox.core.TestUtils;
1213
import com.mapbox.core.exceptions.ServicesException;
1314
import com.mapbox.geojson.Point;
@@ -37,6 +38,7 @@
3738
import static com.mapbox.api.directions.v5.DirectionsCriteria.GEOMETRY_POLYLINE;
3839
import static com.mapbox.api.directions.v5.DirectionsCriteria.PROFILE_CYCLING;
3940
import static com.mapbox.api.directions.v5.DirectionsCriteria.PROFILE_DRIVING;
41+
import static com.mapbox.api.directions.v5.DirectionsCriteria.PROFILE_DRIVING_TRAFFIC;
4042
import static org.hamcrest.CoreMatchers.containsString;
4143
import static org.hamcrest.Matchers.startsWith;
4244
import static org.hamcrest.junit.MatcherAssert.assertThat;
@@ -56,6 +58,7 @@ public class MapboxDirectionsTest extends TestUtils {
5658
private static final String DIRECTIONS_V5_BANNER_INSTRUCTIONS = "directions_v5_banner_instructions.json";
5759
private static final String DIRECTIONS_V5_APPROACHES_REQUEST = "directions_v5_approaches.json";
5860
private static final String DIRECTIONS_V5_WAYPOINT_NAMES_FIXTURE = "directions_v5_waypoint_names.json";
61+
private static final String DIRECTIONS_V5_WAYPOINT_TARGETS_FIXTURE = "directions_v5_waypoint_targets.json";
5962

6063
private MockWebServer server;
6164
private HttpUrl mockUrl;
@@ -76,6 +79,8 @@ public MockResponse dispatch(RecordedRequest request) throws InterruptedExceptio
7679
resource = DIRECTIONS_V5_ANNOTATIONS_FIXTURE;
7780
} else if (request.getPath().contains("waypoint_names")) {
7881
resource = DIRECTIONS_V5_WAYPOINT_NAMES_FIXTURE;
82+
} else if (request.getPath().contains("waypoint_targets")) {
83+
resource = DIRECTIONS_V5_WAYPOINT_TARGETS_FIXTURE;
7984
}else if (request.getPath().contains("approaches")) {
8085
resource = DIRECTIONS_V5_APPROACHES_REQUEST;
8186
} else if (request.getPath().contains("-151.2302")) {
@@ -701,4 +706,28 @@ public void testWithWaypointNames() throws Exception {
701706
assertEquals("Ok", response.body().code());
702707
}
703708

709+
@Test
710+
public void testWithWaypointTargets() throws Exception {
711+
712+
MapboxDirections mapboxDirections = MapboxDirections.builder()
713+
.profile(PROFILE_DRIVING_TRAFFIC)
714+
.origin(Point.fromLngLat(-6.80904429026134,62.00015328799685))
715+
.destination(Point.fromLngLat(-6.800065040588378,62.00012400993553))
716+
.steps(true)
717+
.addWaypointTargets(null, Point.fromLngLat(-6.799936294555664,61.99987216574813))
718+
.accessToken(ACCESS_TOKEN)
719+
.baseUrl(mockUrl.toString())
720+
.build();
721+
722+
assertNotNull(mapboxDirections);
723+
assertNotNull(mapboxDirections.cloneCall().request().url().queryParameter("waypoint_targets"));
724+
725+
Response<DirectionsResponse> response = mapboxDirections.executeCall();
726+
assertEquals(200, response.code());
727+
assertEquals("Ok", response.body().code());
728+
assertEquals("left",
729+
response.body().routes().get(0).legs().get(0).steps().get(0).maneuver().modifier());
730+
731+
}
732+
704733
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"routes":[{"geometry":"mklyJf{ph@g@aHh@m@LeBD_BDuNAqC_@_R","legs":[{"summary":"Velbastaðarvegur, Gamli Velbastaðvegur","weight":74.2,"duration":65.3,"steps":[{"intersections":[{"out":0,"entry":[true],"bearings":[74],"location":[-6.808995,62.000073]}],"driving_side":"right","geometry":"mklyJf{ph@g@aH","mode":"driving","maneuver":{"bearing_after":74,"bearing_before":0,"location":[-6.808995,62.000073],"modifier":"left","type":"depart","instruction":"Head east on Velbastaðarvegur"},"weight":15.2,"duration":6.6,"name":"Velbastaðarvegur","distance":78.4},{"intersections":[{"out":1,"in":2,"entry":[true,true,false],"bearings":[75,150,255],"location":[-6.807551,62.000267]},{"out":0,"in":2,"entry":[true,true,false],"bearings":[90,195,270],"location":[-6.806054,61.999953]},{"out":0,"in":2,"entry":[true,true,false],"bearings":[90,180,270],"location":[-6.804462,61.999935]},{"out":0,"in":2,"entry":[true,true,false],"bearings":[90,180,270],"location":[-6.802712,61.999962]}],"driving_side":"right","geometry":"ullyJdrph@VUPWBY@KF_AD_B@w@?{@@eB?{A?_A@[?cBAqCCw@?SGiDIwCG_EAQ","mode":"driving","maneuver":{"bearing_after":156,"bearing_before":73,"location":[-6.807551,62.000267],"modifier":"right","type":"turn","instruction":"Turn right onto Gamli Velbastaðvegur"},"weight":58.99999999999999,"duration":58.7,"name":"Gamli Velbastaðvegur","distance":408.1},{"intersections":[{"in":0,"entry":[true],"bearings":[257],"location":[-6.800053,62.000099]}],"driving_side":"right","geometry":"sklyJhcoh@","mode":"driving","maneuver":{"bearing_after":0,"bearing_before":77,"location":[-6.800053,62.000099],"type":"arrive","modifier":"right","instruction":"You have arrived at your destination, on the right"},"weight":0,"duration":0,"name":"Gamli Velbastaðvegur","distance":0}],"distance":486.6}],"weight_name":"routability","weight":74.2,"duration":65.3,"distance":486.6}],"waypoints":[{"name":"Velbastaðarvegur","location":[-6.808995,62.000073]},{"name":"Gamli Velbastaðvegur","location":[-6.800053,62.000099]}],"code":"Ok","uuid":"cjpois8j900098anrxqn5kdc5"}

0 commit comments

Comments
 (0)