Skip to content

Commit fcd34bf

Browse files
authored
added waypoint names (#831)
1 parent ac79724 commit fcd34bf

11 files changed

Lines changed: 323 additions & 8 deletions

File tree

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ directions-fixtures:
130130
curl "https://api.mapbox.com/directions/v5/mapbox/driving/13.4301,52.5109;13.432507621760521,52.501725088556014?approaches=unrestricted;curb&access_token=$(MAPBOX_ACCESS_TOKEN)" \
131131
-o services-directions/src/test/resources/directions_v5_approaches.json
132132

133+
# Directions: includes waypoint_names
134+
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)" \
135+
-o services-directions/src/test/resources/directions_v5_waypoint_names.json
136+
133137
mapmatching-fixtures:
134138
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?geometries=polyline&language=sv&steps=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \
135139
-o services-matching/src/test/resources/map_matching_v5_polyline.json
@@ -142,6 +146,9 @@ mapmatching-fixtures:
142146
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)" \
143147
-o services-matching/src/test/resources/mapmatching_v5_approaches.json
144148

149+
# MapMatching request with waypoint_names:
150+
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)" \
151+
-o services-matching/src/test/resources/mapmatching_v5_waypoint_names.json
145152

146153
optimization-fixtures:
147154
# request an optimized car trip with no additional options

services-core/src/main/java/com/mapbox/core/utils/TextUtils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,21 @@ public static String formatApproaches(String[] approaches) {
182182
}
183183
return TextUtils.join(";", approaches);
184184
}
185+
186+
/**
187+
* Converts String array with waypoint_names values
188+
* to a string ready for API consumption.
189+
*
190+
* @param waypointNames a string representing approaches to each coordinate.
191+
* @return a formatted string.
192+
* @since 3.3.0
193+
*/
194+
public static String formatWaypointNames(String[] waypointNames) {
195+
for (int i = 0; i < waypointNames.length; i++) {
196+
if (waypointNames[i] == null) {
197+
waypointNames[i] = "";
198+
}
199+
}
200+
return TextUtils.join(";", waypointNames);
201+
}
185202
}

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
@@ -45,7 +45,8 @@ public interface DirectionsService {
4545
* useful for navigation
4646
* @param voiceUnits voice units
4747
* @param exclude exclude tolls, motorways or more along your route
48-
* @param approaches which side of the road to approach a waypoint.
48+
* @param approaches which side of the road to approach a waypoint
49+
* @param waypointNames custom names for waypoints used for the arrival instruction.
4950
* @return the {@link DirectionsResponse} in a Call wrapper
5051
* @since 1.0.0
5152
*/
@@ -70,6 +71,7 @@ Call<DirectionsResponse> getCall(
7071
@Query("banner_instructions") Boolean bannerInstructions,
7172
@Query("voice_units") String voiceUnits,
7273
@Query("exclude") String exclude,
73-
@Query("approaches") String approaches
74+
@Query("approaches") String approaches,
75+
@Query("waypoint_names") String waypointNames
7476
);
7577
}

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

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ protected Call<DirectionsResponse> initializeCall() {
8686
bannerInstructions(),
8787
voiceUnits(),
8888
exclude(),
89-
approaches());
89+
approaches(),
90+
waypointNames());
9091
}
9192

9293
@Override
@@ -204,6 +205,7 @@ private List<DirectionsRoute> generateRouteOptions(Response<DirectionsResponse>
204205
RouteOptions.builder()
205206
.profile(profile())
206207
.coordinates(coordinates())
208+
.waypointNames(waypointNames())
207209
.continueStraight(continueStraight())
208210
.annotations(annotation())
209211
.approaches(approaches())
@@ -304,6 +306,9 @@ private static String formatCoordinates(List<Point> coordinates) {
304306
@Nullable
305307
abstract String approaches();
306308

309+
@Nullable
310+
abstract String waypointNames();
311+
307312
/**
308313
* Build a new {@link MapboxDirections} object with the initial values set for
309314
* {@link #baseUrl()}, {@link #profile()}, {@link #user()}, and {@link #geometries()}.
@@ -352,6 +357,7 @@ public abstract static class Builder {
352357
private Point destination;
353358
private Point origin;
354359
private String[] approaches;
360+
private String[] waypointNames;
355361

356362
/**
357363
* The username for the account that the directions engine runs on. In most cases, this should
@@ -707,6 +713,22 @@ public Builder addApproaches(String... approaches) {
707713

708714
abstract Builder approaches(@Nullable String approaches);
709715

716+
/**
717+
* Custom names for waypoints used for the arrival instruction,
718+
* each separated by ; . Values can be any string and total number of all characters cannot
719+
* exceed 500. If provided, the list of waypointNames must be the same length as the list of
720+
* coordinates, but you can skip a coordinate and show its position with the ; separator.
721+
* @param waypointNames Custom names for waypoints used for the arrival instruction.
722+
* @return this builder for chaining options together
723+
* @since 3.3.0
724+
*/
725+
public Builder addWaypointNames(@Nullable String... waypointNames) {
726+
this.waypointNames = waypointNames;
727+
return this;
728+
}
729+
730+
abstract Builder waypointNames(@Nullable String waypointNames);
731+
710732
abstract MapboxDirections autoBuild();
711733

712734
/**
@@ -730,6 +752,18 @@ public MapboxDirections build() {
730752
+ " directions API request.");
731753
}
732754

755+
if (waypointNames != null) {
756+
if (waypointNames.length != coordinates.size()) {
757+
throw new ServicesException("Number of waypoint names must match "
758+
+ " the number of waypoints provided.");
759+
}
760+
final String waypointNamesStr = TextUtils.formatWaypointNames(waypointNames);
761+
if (!waypointNamesStr.isEmpty() && waypointNamesStr.length() > 500) {
762+
throw new ServicesException("Waypoint names exceed 500 character limit.");
763+
}
764+
waypointNames(waypointNamesStr);
765+
}
766+
733767
if (approaches != null) {
734768
if (approaches.length != coordinates.size()) {
735769
throw new ServicesException("Number of approach elements must match "

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,18 @@ public static Builder builder() {
256256
@Nullable
257257
public abstract String approaches();
258258

259+
/**
260+
* Custom names for waypoints used for the arrival instruction in banners and voice instructions,
261+
* each separated by ; . Values can be any string and total number of all characters cannot
262+
* exceed 500. If provided, the list of waypoint_names must be the same length as the list of
263+
* coordinates, but you can skip a coordinate and show its position with the ; separator.
264+
* @return a string representing names for each waypoint
265+
* @since 3.3.0
266+
*/
267+
@Nullable
268+
public abstract String waypointNames();
269+
270+
259271
/**
260272
* Gson type adapter for parsing Gson to this class.
261273
*
@@ -486,6 +498,17 @@ public abstract Builder overview(
486498
@Nullable
487499
public abstract Builder approaches(String approaches);
488500

501+
/**
502+
* The same approaches the user originally made when the request was made.
503+
*
504+
* @param waypointNames unrestricted, curb or omitted (;)
505+
* @return this builder for chaining options together
506+
* @since 3.3.0
507+
*/
508+
509+
@Nullable
510+
public abstract Builder waypointNames(@Nullable String waypointNames);
511+
489512
/**
490513
* Builds a new instance of the {@link RouteOptions} object.
491514
*

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

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import static com.mapbox.api.directions.v5.DirectionsCriteria.APPROACH_CURB;
3434
import static com.mapbox.api.directions.v5.DirectionsCriteria.APPROACH_UNRESTRICTED;
3535
import static com.mapbox.api.directions.v5.DirectionsCriteria.GEOMETRY_POLYLINE;
36+
import static com.mapbox.api.directions.v5.DirectionsCriteria.PROFILE_CYCLING;
3637
import static com.mapbox.api.directions.v5.DirectionsCriteria.PROFILE_DRIVING;
3738
import static org.hamcrest.CoreMatchers.containsString;
3839
import static org.hamcrest.Matchers.startsWith;
@@ -52,6 +53,7 @@ public class MapboxDirectionsTest extends TestUtils {
5253
private static final String DIRECTIONS_V5_MAX_SPEED_ANNOTATION = "directions_v5_max_speed_annotation.json";
5354
private static final String DIRECTIONS_V5_BANNER_INSTRUCTIONS = "directions_v5_banner_instructions.json";
5455
private static final String DIRECTIONS_V5_APPROACHES_REQUEST = "directions_v5_approaches.json";
56+
private static final String DIRECTIONS_V5_WAYPOINT_NAMES_FIXTURE = "directions_v5_waypoint_names.json";
5557

5658
private MockWebServer server;
5759
private HttpUrl mockUrl;
@@ -70,7 +72,9 @@ public MockResponse dispatch(RecordedRequest request) throws InterruptedExceptio
7072
resource = DIRECTIONS_ROTARY_FIXTURE;
7173
} else if (request.getPath().contains("annotations")) {
7274
resource = DIRECTIONS_V5_ANNOTATIONS_FIXTURE;
73-
} else if (request.getPath().contains("approaches")) {
75+
} else if (request.getPath().contains("waypoint_names")) {
76+
resource = DIRECTIONS_V5_WAYPOINT_NAMES_FIXTURE;
77+
}else if (request.getPath().contains("approaches")) {
7478
resource = DIRECTIONS_V5_APPROACHES_REQUEST;
7579
} else if (request.getPath().contains("-151.2302")) {
7680
resource = DIRECTIONS_V5_NO_ROUTE;
@@ -575,6 +579,7 @@ public void sanityApproachesInstructions() throws Exception {
575579
assertTrue(mapboxDirections.cloneCall().request().url().toString()
576580
.contains("approaches=unrestricted;;;curb"));
577581
}
582+
578583
@Test
579584
public void build_exceptionThrownWhenNumApproachesDoesNotMatchCoordinates() throws Exception {
580585
thrown.expect(ServicesException.class);
@@ -637,4 +642,88 @@ public void testRouteOptionsApproaches() throws Exception {
637642

638643
assertEquals("unrestricted;curb", routeOptions.approaches());
639644
}
645+
646+
@Test
647+
public void sanityWaypointNamesInstructions() throws Exception {
648+
MapboxDirections mapboxDirections = MapboxDirections.builder()
649+
.origin(Point.fromLngLat(1.0, 1.0))
650+
.addWaypoint(Point.fromLngLat(2.0, 2.0))
651+
.destination(Point.fromLngLat(4.0, 4.0))
652+
.addWaypointNames("Home", "Store", "Work")
653+
.baseUrl("https://foobar.com")
654+
.accessToken(ACCESS_TOKEN)
655+
.build();
656+
assertNotNull(mapboxDirections);
657+
assertTrue(mapboxDirections.cloneCall().request().url().toString()
658+
.contains("waypoint_names=Home;Store;Work"));
659+
}
660+
661+
@Test
662+
public void build_exceptionThrownWhenWaypointNamesDoNotMatchCoordinates() throws Exception {
663+
thrown.expect(ServicesException.class);
664+
thrown.expectMessage(
665+
startsWith("Number of waypoint names must match"));
666+
MapboxDirections mapboxDirections = MapboxDirections.builder()
667+
.origin(Point.fromLngLat(2.0, 2.0))
668+
.addWaypoint(Point.fromLngLat(2.0, 2.0))
669+
.addWaypoint(Point.fromLngLat(3.0, 3.0))
670+
.destination(Point.fromLngLat(4.0, 4.0))
671+
.addWaypointNames("Home", "Work")
672+
.baseUrl("https://foobar.com")
673+
.accessToken(ACCESS_TOKEN)
674+
.build();
675+
}
676+
677+
@Test
678+
public void build_exceptionThrownWhenWaypointNamesExceedLimit() throws Exception {
679+
thrown.expect(ServicesException.class);
680+
thrown.expectMessage(
681+
startsWith("Waypoint names exceed 500 character limit"));
682+
683+
StringBuffer longWpName = new StringBuffer();
684+
for (int i = 0; i < 124; i++) {
685+
longWpName.append("Home");
686+
}
687+
MapboxDirections mapboxDirections = MapboxDirections.builder()
688+
.origin(Point.fromLngLat(2.0, 2.0))
689+
.destination(Point.fromLngLat(4.0, 4.0))
690+
.addWaypointNames(longWpName.toString(), "Work")
691+
.baseUrl("https://foobar.com")
692+
.accessToken(ACCESS_TOKEN)
693+
.build();
694+
695+
assertTrue(mapboxDirections.cloneCall().request().url().toString()
696+
.contains("waypoint_names=Home"));
697+
698+
// one more char results in exception
699+
mapboxDirections = MapboxDirections.builder()
700+
.origin(Point.fromLngLat(2.0, 2.0))
701+
.destination(Point.fromLngLat(4.0, 4.0))
702+
.addWaypointNames(longWpName.toString(), "Work1")
703+
.baseUrl("https://foobar.com")
704+
.accessToken(ACCESS_TOKEN)
705+
.build();
706+
}
707+
708+
@Test
709+
public void testWithWaypointNames() throws Exception {
710+
711+
MapboxDirections mapboxDirections = MapboxDirections.builder()
712+
.profile(PROFILE_CYCLING)
713+
.origin(Point.fromLngLat(-122.42,37.78))
714+
.destination(Point.fromLngLat(-77.03,38.91))
715+
.steps(true)
716+
.voiceInstructions(true)
717+
.voiceUnits(DirectionsCriteria.IMPERIAL)
718+
.addWaypointNames("Home", "Work")
719+
.accessToken(ACCESS_TOKEN)
720+
.baseUrl(mockUrl.toString())
721+
.build();
722+
723+
mapboxDirections.setCallFactory(null);
724+
Response<DirectionsResponse> response = mapboxDirections.executeCall();
725+
assertEquals(200, response.code());
726+
assertEquals("Ok", response.body().code());
727+
}
728+
640729
}

services-directions/src/test/resources/directions_v5_waypoint_names.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

services-matching/src/main/java/com/mapbox/api/matching/v5/MapMatchingService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public interface MapMatchingService {
5757
* marked-up text for voice guidance along the route.
5858
* @param voiceUnits voice units
5959
* @param waypoints Which input coordinates should be treated as waypoints.
60+
* @param waypointNames wustom names for waypoints used for the arrival instruction.
6061
* @param approaches which side of the road to approach a waypoint.
6162
* @return the MapMatchingResponse in a Call wrapper
6263
* @since 2.0.0
@@ -81,5 +82,6 @@ Call<MapMatchingResponse> getCall(
8182
@Query("voice_instructions") Boolean voiceInstructions,
8283
@Query("voice_units") String voiceUnits,
8384
@Query("waypoints") String waypoints,
85+
@Query("waypoint_names") String waypointNames,
8486
@Query("approaches") String approaches);
8587
}

services-matching/src/main/java/com/mapbox/api/matching/v5/MapboxMapMatching.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ protected Call<MapMatchingResponse> initializeCall() {
9191
voiceInstructions(),
9292
voiceUnits(),
9393
waypoints(),
94+
waypointNames(),
9495
approaches());
9596
}
9697

@@ -222,6 +223,7 @@ private List<MapMatchingMatching> generateRouteOptions(Response<MapMatchingRespo
222223
.requestUuid(PLACEHOLDER_UUID)
223224
.accessToken(accessToken())
224225
.approaches(approaches())
226+
.waypointNames(waypointNames())
225227
.baseUrl(baseUrl())
226228
.build()
227229
).build());
@@ -296,6 +298,9 @@ private static List<Point> formatCoordinates(String coordinates) {
296298
@Nullable
297299
abstract String waypoints();
298300

301+
@Nullable
302+
abstract String waypointNames();
303+
299304
@Nullable
300305
abstract String approaches();
301306

@@ -331,6 +336,7 @@ public abstract static class Builder {
331336
private String[] timestamps;
332337
private Double[] radiuses;
333338
private Integer[] waypoints;
339+
private String[] waypointNames;
334340
private String[] approaches;
335341

336342
/**
@@ -648,6 +654,23 @@ public Builder addApproaches(@Nullable String... approaches) {
648654

649655
abstract Builder approaches(@Nullable String approaches);
650656

657+
/**
658+
* Custom names for waypoints used for the arrival instruction,
659+
* each separated by ; . Values can be any string and total number of all characters cannot
660+
* exceed 500. If provided, the list of waypointNames must be the same length as the list of
661+
* waypoints, but you can skip a coordinate and show its position with the ; separator.
662+
*
663+
* @param waypointNames Custom names for waypoints used for the arrival instruction.
664+
* @returnthis builder for chaining options together
665+
* @since 3.3.0
666+
*/
667+
public Builder addWaypointNames(@Nullable String... waypointNames) {
668+
this.waypointNames = waypointNames;
669+
return this;
670+
}
671+
672+
abstract Builder waypointNames(@Nullable String waypointNames);
673+
651674
/**
652675
* Optionally change the APIs base URL to something other then the default Mapbox one.
653676
*
@@ -707,6 +730,17 @@ public MapboxMapMatching build() {
707730
}
708731
}
709732

733+
if (waypointNames != null) {
734+
if (waypointNames.length != waypoints.length) {
735+
throw new ServicesException("Number of waypoint names must match "
736+
+ " the number of waypoints provided.");
737+
}
738+
final String waypointNamesStr = TextUtils.formatWaypointNames(waypointNames);
739+
if (!waypointNamesStr.isEmpty() && waypointNamesStr.length() > 500) {
740+
throw new ServicesException("Waypoint names exceed 500 character limit.");
741+
}
742+
waypointNames(waypointNamesStr);
743+
}
710744

711745
if (approaches != null) {
712746
if (approaches.length != coordinates.size()) {

0 commit comments

Comments
 (0)