Skip to content

Commit ae32fcb

Browse files
authored
Added missing param to MapboxMapMatching Builder: (#718)
Added the following param to MapboxMapMatching Builder: -roundaboutExits -bannerInstructions -voiceInstructions -waypoints
1 parent 7cec5b9 commit ae32fcb

4 files changed

Lines changed: 228 additions & 2 deletions

File tree

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Used for Map Matching
2+
MAP_MATCHING_COORDINATES = 13.418946862220764,52.50055852688439;13.419011235237122,52.50113000479732;13.419756889343262,52.50171780290061;13.419885635375975,52.50237416816131;13.420631289482117,52.50294888790448
3+
14
build-config:
25
./gradlew compileBuildConfig
36

@@ -105,6 +108,7 @@ mapmatching-fixtures:
105108
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?geometries=polyline&language=sv&steps=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \
106109
-o services-matching/src/test/resources/mapmatching_v5_polyline.json
107110

111+
108112
optimization-fixtures:
109113
# request an optimized car trip with no additional options
110114
curl "https://api.mapbox.com/optimized-trips/v1/mapbox/driving/-122.42,37.78;-122.45,37.91;-122.48,37.73?access_token=$(MAPBOX_ACCESS_TOKEN)" \

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ public interface MapMatchingService {
5050
* @param language language of returned turn-by-turn text instructions
5151
* @param tidy whether or not to transparently remove clusters and re-sample traces for
5252
* improved map matching results
53+
* @param roundaboutExits Whether or not to emit instructions at roundabout exits.
54+
* @param bannerInstructions Whether or not to return banner objects associated with the `routeSteps`.
55+
* Should be used in conjunction with `steps`.
56+
* @param voiceInstructions whether or not to return
57+
* marked-up text for voice guidance along the route.
58+
* @param waypoints Which input coordinates should be treated as waypoints.
5359
* @return the MapMatchingResponse in a Call wrapper
5460
* @since 2.0.0
5561
*/
@@ -67,5 +73,9 @@ Call<MapMatchingResponse> getCall(
6773
@Query("timestamps") String timestamps,
6874
@Query("annotations") String annotations,
6975
@Query("language") String language,
70-
@Query("tidy") Boolean tidy);
76+
@Query("tidy") Boolean tidy,
77+
@Query("roundabout_exits") Boolean roundaboutExits,
78+
@Query("banner_instructions") Boolean bannerInstructions,
79+
@Query("voice_instructions") Boolean voiceInstructions,
80+
@Query("waypoints") String waypoints);
7181
}

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

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mapbox.api.matching.v5;
22

33
import android.support.annotation.FloatRange;
4+
import android.support.annotation.IntRange;
45
import android.support.annotation.NonNull;
56
import android.support.annotation.Nullable;
67
import com.google.auto.value.AutoValue;
@@ -97,7 +98,11 @@ public Call<MapMatchingResponse> getCall() {
9798
timestamps(),
9899
annotations(),
99100
language(),
100-
tidy()
101+
tidy(),
102+
roundaboutExits(),
103+
bannerInstructions(),
104+
voiceInstructions(),
105+
waypoints()
101106
);
102107

103108
return call;
@@ -190,6 +195,19 @@ public Call<MapMatchingResponse> cloneCall() {
190195
@Nullable
191196
abstract String language();
192197

198+
@Nullable
199+
abstract Boolean roundaboutExits();
200+
201+
@Nullable
202+
abstract Boolean bannerInstructions();
203+
204+
@Nullable
205+
abstract Boolean voiceInstructions();
206+
207+
@Nullable
208+
abstract String waypoints();
209+
210+
193211
@NonNull
194212
abstract String baseUrl();
195213

@@ -220,6 +238,7 @@ public abstract static class Builder {
220238
private String[] annotations;
221239
private String[] timestamps;
222240
private Double[] radiuses;
241+
private Integer[] waypoints;
223242

224243
/**
225244
* Required to call when this is being built. If no access token provided,
@@ -303,6 +322,28 @@ public Builder radiuses(@Nullable @FloatRange(from = 0) Double... radiuses) {
303322
// Required for matching with MapboxMapMatching radiuses() method.
304323
abstract Builder radiuses(@Nullable String radiuses);
305324

325+
326+
/**
327+
* Optionally, set which input coordinates should be treated as waypoints.
328+
* <p>
329+
* Most useful in combination with steps=true and requests based on traces with high sample rates.
330+
* Can be an index corresponding to any of the input coordinates,
331+
* but must contain the first ( 0 ) and last coordinates' index separated by ; .
332+
* {@link #steps()}
333+
* </p>
334+
*
335+
* @param waypoints integer array of coordinate indices to be used as waypoints
336+
* @return this builder for chaining options together
337+
* @since 3.0.0
338+
*/
339+
public Builder waypoints(@Nullable @IntRange(from = 0) Integer... waypoints) {
340+
this.waypoints = waypoints;
341+
return this;
342+
}
343+
344+
// Required for matching with MapboxMapMatching waypoints() method.
345+
abstract Builder waypoints(@Nullable String waypoints);
346+
306347
/**
307348
* Setting this will determine whether to return steps and turn-by-turn instructions. Can be
308349
* set to either true or false to enable or disable respectively. null can also optionally be
@@ -327,6 +368,42 @@ public Builder radiuses(@Nullable @FloatRange(from = 0) Double... radiuses) {
327368
*/
328369
public abstract Builder overview(@Nullable @OverviewCriteria String overview);
329370

371+
/**
372+
* Setting this will determine Whether or not to return banner objects associated with the `routeSteps`.
373+
* Should be used in conjunction with `steps`. Can be set to either true or false to enable or
374+
* disable respectively. null can also optionally be
375+
* passed in to set the default behavior to match what the API does by default.
376+
*
377+
* @param bannerInstructions true if you'd like step information
378+
* @return this builder for chaining options together
379+
* @since 3.0.0
380+
*/
381+
public abstract Builder bannerInstructions(@Nullable Boolean bannerInstructions);
382+
383+
384+
/**
385+
* Setting this will determine whether to return steps and turn-by-turn instructions. Can be
386+
* set to either true or false to enable or disable respectively. null can also optionally be
387+
* passed in to set the default behavior to match what the API does by default.
388+
*
389+
* @param voiceInstructions true if you'd like step information
390+
* @return this builder for chaining options together
391+
* @since 3.0.0
392+
*/
393+
public abstract Builder voiceInstructions(@Nullable Boolean voiceInstructions);
394+
395+
396+
/**
397+
* Setting this will determine whether to return steps and turn-by-turn instructions. Can be
398+
* set to either true or false to enable or disable respectively. null can also optionally be
399+
* passed in to set the default behavior to match what the API does by default.
400+
*
401+
* @param roundaboutExits true if you'd like step information
402+
* @return this builder for chaining options together
403+
* @since 3.0.0
404+
*/
405+
public abstract Builder roundaboutExits(@Nullable Boolean roundaboutExits);
406+
330407
/**
331408
* Whether or not to return additional metadata along the route. Possible values are:
332409
* {@link DirectionsCriteria#ANNOTATION_DISTANCE},
@@ -486,10 +563,29 @@ public MapboxMapMatching build() {
486563
"There must be as many timestamps as there are coordinates.");
487564
}
488565

566+
if (waypoints != null) {
567+
if (waypoints.length < 2) {
568+
throw new ServicesException(
569+
"Waypoints must be a list of at least two indexes separated by ';'");
570+
}
571+
if (waypoints[0] != 0 || waypoints[waypoints.length - 1] != coordinates.size() - 1) {
572+
throw new ServicesException(
573+
"Waypoints must contain indices of the first and last coordinates"
574+
);
575+
}
576+
for (int i = 1; i < waypoints.length -1; i++) {
577+
if (waypoints[i] < 0 || waypoints[i] >= coordinates.size()) {
578+
throw new ServicesException(
579+
"Waypoints index too large (no corresponding coordinate)");
580+
}
581+
}
582+
}
583+
489584
coordinates(formatCoordinates(coordinates));
490585
timestamps(TextUtils.join(",", timestamps));
491586
annotations(TextUtils.join(",", annotations));
492587
radiuses(TextUtils.join(",", radiuses));
588+
waypoints(TextUtils.join(";", waypoints));
493589

494590
// Generate build so that we can check that values are valid.
495591
MapboxMapMatching mapMatching = autoBuild();

services-matching/src/test/java/com/mapbox/api/matching/v5/MapboxMapMatchingTest.java

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,120 @@ public void baseUrl_doesShowInUrlCorrectly() throws Exception {
333333
assertTrue(mapMatching.cloneCall().request().url().toString()
334334
.startsWith("https://foobar.com"));
335335
}
336+
337+
338+
@Test
339+
public void build_exceptionThrownWhenLessThanTwoWayPointsProvided() throws Exception {
340+
thrown.expect(ServicesException.class);
341+
thrown.expectMessage(
342+
startsWith("Waypoints must be a list of at least two indexes separated by"));
343+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
344+
.coordinate(Point.fromLngLat(2.0, 2.0))
345+
.coordinate(Point.fromLngLat(4.0, 4.0))
346+
.waypoints(0)
347+
.baseUrl("https://foobar.com")
348+
.accessToken(ACCESS_TOKEN)
349+
.build();
350+
}
351+
352+
@Test
353+
public void build_exceptionThrownWhenWaypointsDoNotStartWith0() throws Exception {
354+
thrown.expect(ServicesException.class);
355+
thrown.expectMessage(
356+
startsWith("Waypoints must contain indices of the first and last coordinates"));
357+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
358+
.coordinate(Point.fromLngLat(2.0, 2.0))
359+
.coordinate(Point.fromLngLat(3.0, 3.0))
360+
.coordinate(Point.fromLngLat(4.0, 4.0))
361+
.waypoints(1, 2)
362+
.baseUrl("https://foobar.com")
363+
.accessToken(ACCESS_TOKEN)
364+
.build();
365+
}
366+
367+
@Test
368+
public void build_exceptionThrownWhenWaypointDoNotEndWithLast() throws Exception {
369+
thrown.expect(ServicesException.class);
370+
thrown.expectMessage(
371+
startsWith("Waypoints must contain indices of the first and last coordinates"));
372+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
373+
.coordinate(Point.fromLngLat(2.0, 2.0))
374+
.coordinate(Point.fromLngLat(3.0, 3.0))
375+
.coordinate(Point.fromLngLat(4.0, 4.0))
376+
.waypoints(0, 1)
377+
.baseUrl("https://foobar.com")
378+
.accessToken(ACCESS_TOKEN)
379+
.build();
380+
}
381+
382+
@Test
383+
public void build_exceptionThrownWhenMiddleWaypointsAreWrong() throws Exception {
384+
thrown.expect(ServicesException.class);
385+
thrown.expectMessage(
386+
startsWith("Waypoints index too large (no corresponding coordinate)"));
387+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
388+
.coordinate(Point.fromLngLat(2.0, 2.0))
389+
.coordinate(Point.fromLngLat(3.0, 3.0))
390+
.coordinate(Point.fromLngLat(4.0, 4.0))
391+
.waypoints(0, 3, 2)
392+
.baseUrl("https://foobar.com")
393+
.accessToken(ACCESS_TOKEN)
394+
.build();
395+
}
396+
397+
@Test
398+
public void sanityWaypoints() throws Exception {
399+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
400+
.coordinate(Point.fromLngLat(2.0, 2.0))
401+
.coordinate(Point.fromLngLat(3.0, 3.0))
402+
.coordinate(Point.fromLngLat(4.0, 4.0))
403+
.waypoints(0, 1, 2)
404+
.baseUrl("https://foobar.com")
405+
.accessToken(ACCESS_TOKEN)
406+
.build();
407+
assertNotNull(mapMatching);
408+
}
409+
410+
@Test
411+
public void sanityVoiceInstructions() throws Exception {
412+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
413+
.coordinate(Point.fromLngLat(2.0, 2.0))
414+
.coordinate(Point.fromLngLat(4.0, 4.0))
415+
.voiceInstructions(true)
416+
.baseUrl("https://foobar.com")
417+
.accessToken(ACCESS_TOKEN)
418+
.build();
419+
assertNotNull(mapMatching);
420+
assertTrue(mapMatching.cloneCall().request().url().toString()
421+
.contains("voice_instructions=true"));
422+
}
423+
424+
@Test
425+
public void sanityBannerInstructions() throws Exception {
426+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
427+
.coordinate(Point.fromLngLat(2.0, 2.0))
428+
.coordinate(Point.fromLngLat(4.0, 4.0))
429+
.bannerInstructions(true)
430+
.baseUrl("https://foobar.com")
431+
.accessToken(ACCESS_TOKEN)
432+
.build();
433+
assertNotNull(mapMatching);
434+
assertTrue(mapMatching.cloneCall().request().url().toString()
435+
.contains("banner_instructions=true"));
436+
}
437+
438+
@Test
439+
public void sanityRoundExtsInstructions() throws Exception {
440+
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
441+
.coordinate(Point.fromLngLat(2.0, 2.0))
442+
.coordinate(Point.fromLngLat(4.0, 4.0))
443+
.roundaboutExits(true)
444+
.baseUrl("https://foobar.com")
445+
.accessToken(ACCESS_TOKEN)
446+
.build();
447+
assertNotNull(mapMatching);
448+
assertTrue(mapMatching.cloneCall().request().url().toString()
449+
.contains("roundabout_exits=true"));
450+
}
451+
336452
}

0 commit comments

Comments
 (0)