Skip to content

Commit 6772257

Browse files
Support for StepIntersection.formOfWays and StepIntersection.geometries
1 parent e5f63f2 commit 6772257

File tree

8 files changed

+363
-5
lines changed

8 files changed

+363
-5
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Mapbox welcomes participation and contributions from everyone.
44

55
### main
66

7+
- Added `StepIntersection#formOfWays` property which provides a list representing the "form of way" values for all roads at the step intersection. [#1611](https://github.com/mapbox/mapbox-java/pull/1611)
8+
- Added `StepIntersection#geometries` property which provides a list representing geometry for all roads at the step intersection. [#1611](https://github.com/mapbox/mapbox-java/pull/1611)
9+
710
### v7.4.0 - April 11, 2025
811

912
- Added `IntersectionLanes#access` property which provides lane access attributes, such as allowed vehicle types for designated lanes. [#1608](https://github.com/mapbox/mapbox-java/pull/1608)

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

+101
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,40 @@ public List<String> paymentMethodsList() {
946946
@Nullable
947947
public abstract Boolean suppressVoiceInstructionLocalNames();
948948

949+
/**
950+
* Defines whether to return "form of way" values for roads at each {@link StepIntersection}.
951+
* See {@link StepIntersection#formOfWays()} for details.
952+
*
953+
* @return boolean representing the `intersectionLinkFormOfWay` value
954+
*/
955+
@SerializedName("intersection_link_form_of_way")
956+
@Nullable
957+
public abstract Boolean intersectionLinkFormOfWay();
958+
959+
/**
960+
* A comma-separated list of road types for which intersection geometry data should be included
961+
* at each {@link StepIntersection}. See {@link StepIntersection#geometries()} for details.
962+
* Possible values include:
963+
* - "motorway"
964+
* - "trunk"
965+
* - "primary"
966+
* - "secondary"
967+
* - "tertiary"
968+
* - "unclassified"
969+
* - "residential"
970+
* - "service_other"
971+
* Geometry data will be provided for each intersection along the requested route.
972+
* Be aware that enabling this option can significantly increase the response size
973+
* and the memory required to store the response object. Use this option selectively, for example,
974+
* if geometry is only needed for motorways, specify only "motorway".
975+
*
976+
* @return a comma-separated list of road types for which intersection geometry data
977+
* should be included
978+
*/
979+
@SerializedName("intersection_link_geometry")
980+
@Nullable
981+
public abstract String intersectionLinkGeometry();
982+
949983
/**
950984
* Gson type adapter for parsing Gson to this class.
951985
*
@@ -1088,6 +1122,8 @@ public URL toUrl(@NonNull String accessToken) {
10881122
"suppress_voice_instruction_local_names",
10891123
suppressVoiceInstructionLocalNames()
10901124
);
1125+
appendQueryParameter(sb, "intersection_link_form_of_way", intersectionLinkFormOfWay());
1126+
appendQueryParameter(sb, "intersection_link_geometry", intersectionLinkGeometry());
10911127

10921128
Map<String, SerializableJsonElement> unrecognized = unrecognized();
10931129
if (unrecognized != null) {
@@ -2127,6 +2163,71 @@ public abstract Builder suppressVoiceInstructionLocalNames(
21272163
@Nullable Boolean suppressVoiceInstructionLocalNames
21282164
);
21292165

2166+
/**
2167+
* Defines whether to return "form of way" values for roads at each {@link StepIntersection}.
2168+
* See {@link StepIntersection#formOfWays()} for details.
2169+
*
2170+
* @param intersectionLinkFormOfWay whether to return "form of way" values
2171+
* @return this builder
2172+
*/
2173+
@NonNull
2174+
public abstract Builder intersectionLinkFormOfWay(
2175+
@Nullable Boolean intersectionLinkFormOfWay
2176+
);
2177+
2178+
/**
2179+
* A comma-separated list of road types for which intersection geometry data should be included
2180+
* at each {@link StepIntersection}. See {@link StepIntersection#geometries()} for details.
2181+
* Possible values include:
2182+
* - "motorway"
2183+
* - "trunk"
2184+
* - "primary"
2185+
* - "secondary"
2186+
* - "tertiary"
2187+
* - "unclassified"
2188+
* - "residential"
2189+
* - "service_other"
2190+
* Geometry data will be provided for each intersection along the requested route.
2191+
* Be aware that enabling this option can significantly increase the response size
2192+
* and the memory required to store the response object. Use this option selectively,
2193+
* for example, if geometry is only needed for motorways, specify only "motorway".
2194+
*
2195+
* @param intersectionLinkGeometry a comma-separated list of road types for which intersection
2196+
* geometry data should be included
2197+
* @return this builder
2198+
*/
2199+
@NonNull
2200+
public abstract Builder intersectionLinkGeometry(
2201+
@Nullable String intersectionLinkGeometry
2202+
);
2203+
2204+
/**
2205+
* A list of road types for which intersection geometry data should be included
2206+
* at each {@link StepIntersection}. See {@link StepIntersection#geometries()} for details.
2207+
* Possible values include:
2208+
* - "motorway"
2209+
* - "trunk"
2210+
* - "primary"
2211+
* - "secondary"
2212+
* - "tertiary"
2213+
* - "unclassified"
2214+
* - "residential"
2215+
* - "service_other"
2216+
* Geometry data will be provided for each intersection along the requested route.
2217+
* Be aware that enabling this option can significantly increase the response size
2218+
* and the memory required to store the response object. Use this option selectively,
2219+
* for example, if geometry is only needed for motorways, specify only "motorway".
2220+
*
2221+
* @param intersectionLinkGeometry a list of road types for which intersection geometry data
2222+
* should be included
2223+
* @return this builder
2224+
*/
2225+
@NonNull
2226+
public Builder intersectionLinkGeometry(@Nullable List<String> intersectionLinkGeometry) {
2227+
String result = FormatUtils.join(",", intersectionLinkGeometry);
2228+
return intersectionLinkGeometry(result);
2229+
}
2230+
21302231
/**
21312232
* Use this method to add request parameters,
21322233
* which are not present in the model yet but are supported on the Directions API,

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

+77
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,44 @@ public Point location() {
9292
@Nullable
9393
public abstract List<Boolean> entry();
9494

95+
/**
96+
* A list representing the "form of way" values for all roads at the step intersection.
97+
* This list has a 1:1 correspondence with the {@link #bearings()}, {@link #entry()},
98+
* and {@link #geometries()} lists.
99+
* Each element is either:
100+
* - A list of strings representing the form(s) of way for a specific road, or
101+
* - `null` if the form of way is unknown.
102+
* Possible values for the form of way include:
103+
* - "ramp"
104+
* - "elevated"
105+
* - "roundabout"
106+
* - "service_road"
107+
* Example:
108+
* "form_of_way": [
109+
* ["ramp", "elevated"],
110+
* ["ramp"],
111+
* null
112+
* ]
113+
*
114+
* @return A list of form of way values for all roads at the step intersection
115+
*/
116+
@Nullable
117+
@SerializedName("form_of_way")
118+
public abstract List<List<String>> formOfWays();
119+
120+
/**
121+
* A list representing geometry for all roads at the step intersection.
122+
* This list has a 1:1 correspondence with the {@link #bearings()}, {@link #entry()},
123+
* and {@link #formOfWays()} lists.
124+
* Each element is either:
125+
* - A strings representing geometry of a specific road, or
126+
* - `null` if the geometry is unknown.
127+
* @return A list of geometry for all roads at the step intersection
128+
*/
129+
@Nullable
130+
@SerializedName("geometries")
131+
public abstract List<String> geometries();
132+
95133
/**
96134
* Index into bearings/entry array. Used to calculate the bearing before the turn. Namely, the
97135
* clockwise angle from true north to the direction of travel before the maneuver/passing the
@@ -360,6 +398,45 @@ public abstract static class Builder extends DirectionsJsonObject.Builder<Builde
360398
@NonNull
361399
public abstract Builder entry(@Nullable List<Boolean> entry);
362400

401+
/**
402+
* A list representing the "form of way" values for all roads at the step intersection.
403+
* This list has a 1:1 correspondence with the {@link #bearings()}, {@link #entry()},
404+
* and {@link #geometries()} lists.
405+
* Each element is either:
406+
* - A list of strings representing the form(s) of way for a specific road, or
407+
* - `null` if the form of way is unknown.
408+
* Possible values for the form of way include:
409+
* - "ramp"
410+
* - "elevated"
411+
* - "roundabout"
412+
* - "service_road"
413+
* Example:
414+
* "form_of_way": [
415+
* ["ramp", "elevated"],
416+
* ["ramp"],
417+
* null
418+
* ]
419+
*
420+
* @param formOfWays a list of form of way values for all roads at the step intersection
421+
* @return this builder for chaining options together
422+
*/
423+
@NonNull
424+
public abstract Builder formOfWays(List<List<String>> formOfWays);
425+
426+
/**
427+
* A list representing geometry for all roads at the step intersection.
428+
* This list has a 1:1 correspondence with the {@link #bearings()}, {@link #entry()},
429+
* and {@link #formOfWays()} lists.
430+
* Each element is either:
431+
* - A strings representing geometry of a specific road, or
432+
* - `null` if the geometry is unknown.
433+
*
434+
* @param geometries a list of geometry for all roads at the step intersection
435+
* @return this builder for chaining options together
436+
*/
437+
@NonNull
438+
public abstract Builder geometries(List<String> geometries);
439+
363440
/**
364441
* Index into bearings/entry array. Used to calculate the bearing before the turn. Namely, the
365442
* clockwise angle from true north to the direction of travel before the maneuver/passing the

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

+51
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.io.IOException;
1111
import java.util.ArrayList;
1212
import java.util.Arrays;
13+
import java.util.Collections;
1314
import java.util.List;
1415

1516
import org.hamcrest.junit.ExpectedException;
@@ -261,4 +262,54 @@ public void directionsRoute_hasLaneAttributes() throws IOException {
261262
.build();
262263
assertEquals(access, lane.access());
263264
}
265+
266+
@Test
267+
public void directionsRoute_hasFormOfWays() throws IOException {
268+
String json = loadJsonFixture("directions_v5_with_toll_costs_and_lanes.json");
269+
RouteOptions options = RouteOptions.builder()
270+
.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
271+
.coordinatesList(new ArrayList<Point>() {{
272+
add(Point.fromLngLat(1.0, 1.0));
273+
add(Point.fromLngLat(2.0, 2.0));
274+
}})
275+
.build();
276+
String uuid = "123";
277+
DirectionsRoute route = DirectionsRoute.fromJson(json, options, uuid);
278+
279+
final List<List<String>> formOfWays = route.legs().get(0).steps().get(0).intersections().get(0)
280+
.formOfWays();
281+
282+
final List<List<String>> expectedFormOfWays = Arrays.asList(
283+
Collections.singletonList("ramp"),
284+
Arrays.asList("ramp", "elevated"),
285+
null
286+
);
287+
288+
assertEquals(expectedFormOfWays, formOfWays);
289+
}
290+
291+
@Test
292+
public void directionsRoute_hasGeometries() throws IOException {
293+
String json = loadJsonFixture("directions_v5_with_toll_costs_and_lanes.json");
294+
RouteOptions options = RouteOptions.builder()
295+
.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
296+
.coordinatesList(new ArrayList<Point>() {{
297+
add(Point.fromLngLat(1.0, 1.0));
298+
add(Point.fromLngLat(2.0, 2.0));
299+
}})
300+
.build();
301+
String uuid = "123";
302+
DirectionsRoute route = DirectionsRoute.fromJson(json, options, uuid);
303+
304+
final List<String> geometries = route.legs().get(0).steps().get(0).intersections().get(0)
305+
.geometries();
306+
307+
final List<String> expectedGeometries = Arrays.asList(
308+
"k}fiyAcxhgOjCRrD?rDS~CSrDSbQ{@rIg@nFSfES~HSjMSrNRjMz@jHz@jMjCnK~CzJrD~MvG",
309+
null,
310+
null
311+
);
312+
313+
assertEquals(expectedGeometries, geometries);
314+
}
264315
}

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

+29-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class RouteOptionsTest extends TestUtils {
3838
*/
3939
private static final String ROUTE_OPTIONS_JSON = "route_options_v5.json";
4040
private static final String ROUTE_OPTIONS_URL =
41-
"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&payment_methods=general&suppress_voice_instruction_local_names=true";
41+
"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&payment_methods=general&suppress_voice_instruction_local_names=true&intersection_link_form_of_way=true&intersection_link_geometry=motorway%2Ctrunk%2Cprimary";
4242
private static final String ACCESS_TOKEN = "pk.token";
4343

4444
private final String optionsJson = loadJsonFixture(ROUTE_OPTIONS_JSON);
@@ -364,6 +364,18 @@ public void waypointsPerRouteAreValid_fromJson() {
364364
assertEquals(true, routeOptions.waypointsPerRoute());
365365
}
366366

367+
@Test
368+
public void intersectionLinkGeometryAreValid_fromJson() {
369+
RouteOptions routeOptions = RouteOptions.fromJson(optionsJson);
370+
assertEquals("motorway,trunk,primary", routeOptions.intersectionLinkGeometry());
371+
}
372+
373+
@Test
374+
public void intersectionLinkFormOfWayAreValid_fromJson() {
375+
RouteOptions routeOptions = RouteOptions.fromJson(optionsJson);
376+
assertEquals(true, routeOptions.intersectionLinkFormOfWay());
377+
}
378+
367379
@Test
368380
public void defaultTollCost() {
369381
RouteOptions options = defaultRouteOptions();
@@ -385,6 +397,18 @@ public void defaultWaypointsPerRoute() {
385397
assertNull(options.waypointsPerRoute());
386398
}
387399

400+
@Test
401+
public void defaultIntersectionLinkFormOfWay() {
402+
RouteOptions options = defaultRouteOptions();
403+
assertNull(options.intersectionLinkFormOfWay());
404+
}
405+
406+
@Test
407+
public void defaultIntersectionLinkGeometry() {
408+
RouteOptions options = defaultRouteOptions();
409+
assertNull(options.intersectionLinkGeometry());
410+
}
411+
388412
@Test
389413
public void routeOptions_toJson() {
390414
RouteOptions options = routeOptions();
@@ -1128,6 +1152,8 @@ private RouteOptions routeOptions() {
11281152
.waypointsPerRoute(true)
11291153
.paymentMethods(DirectionsCriteria.PAYMENT_METHOD_GENERAL)
11301154
.suppressVoiceInstructionLocalNames(true)
1155+
.intersectionLinkFormOfWay(true)
1156+
.intersectionLinkGeometry("motorway,trunk,primary")
11311157
.build();
11321158
}
11331159

@@ -1237,6 +1263,8 @@ private RouteOptions routeOptionsList() {
12371263
.waypointsPerRoute(true)
12381264
.suppressVoiceInstructionLocalNames(true)
12391265
.paymentMethodsList(Arrays.asList(DirectionsCriteria.PAYMENT_METHOD_GENERAL))
1266+
.intersectionLinkFormOfWay(true)
1267+
.intersectionLinkGeometry(Arrays.asList("motorway", "trunk", "primary"))
12401268
.build();
12411269
}
12421270
}

0 commit comments

Comments
 (0)