From a3c3a63cd587ae091c3cfb2160455ac4b6e6d4f6 Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 18 Feb 2019 11:51:53 -0500 Subject: [PATCH 1/2] Added directions post support --- .../com/mapbox/samples/BasicDirections.java | 31 +++++++- .../api/directions/v5/DirectionsService.java | 74 ++++++++++++++++++- .../api/directions/v5/MapboxDirections.java | 56 +++++++++++++- .../directions/v5/MapboxDirectionsTest.java | 23 ++++++ 4 files changed, 178 insertions(+), 6 deletions(-) diff --git a/samples/src/main/java/com/mapbox/samples/BasicDirections.java b/samples/src/main/java/com/mapbox/samples/BasicDirections.java index b3d2fd9fe..36f8a9b0d 100644 --- a/samples/src/main/java/com/mapbox/samples/BasicDirections.java +++ b/samples/src/main/java/com/mapbox/samples/BasicDirections.java @@ -5,12 +5,13 @@ import com.mapbox.api.directions.v5.models.DirectionsResponse; import com.mapbox.geojson.Point; import com.mapbox.sample.BuildConfig; + +import java.io.IOException; + import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; -import java.io.IOException; - /** * Shows how to make a directions request using some of the parameters offered. */ @@ -19,10 +20,11 @@ public class BasicDirections { public static void main(String[] args) throws IOException { simpleMapboxDirectionsRequest(); asyncMapboxDirectionsRequest(); + simpleMapboxDirectionsPostRequest(); } /** - * Demonstrates how to make the most basic directions request. + * Demonstrates how to make the most basic GET directions request. * * @throws IOException signals that an I/O exception of some sort has occurred */ @@ -39,7 +41,28 @@ private static void simpleMapboxDirectionsRequest() throws IOException { Response response = builder.build().executeCall(); // 3. Log information from the response - System.out.printf("Check that the response is successful %b", response.isSuccessful()); + System.out.printf("Check that the GET response is successful %b", response.isSuccessful()); + System.out.printf("%nGet the first routes distance from origin to destination: %f", + response.body().routes().get(0).distance()); + } + + /** + * Demonstrates how to make the most basic POST directions request. + * + * @throws IOException signals that an I/O exception of some sort has occurred + */ + private static void simpleMapboxDirectionsPostRequest() throws IOException { + + MapboxDirections.Builder builder = MapboxDirections.builder(); + + builder.accessToken(BuildConfig.MAPBOX_ACCESS_TOKEN); + builder.origin(Point.fromLngLat(-95.6332, 29.7890)); + builder.destination(Point.fromLngLat(-95.3591, 29.7576)); + builder.post(); + + Response response = builder.build().executeCall(); + + System.out.printf("%nCheck that the POST response is successful %b", response.isSuccessful()); System.out.printf("%nGet the first routes distance from origin to destination: %f", response.body().routes().get(0).distance()); } diff --git a/services-directions/src/main/java/com/mapbox/api/directions/v5/DirectionsService.java b/services-directions/src/main/java/com/mapbox/api/directions/v5/DirectionsService.java index 718c451b6..464a3357c 100644 --- a/services-directions/src/main/java/com/mapbox/api/directions/v5/DirectionsService.java +++ b/services-directions/src/main/java/com/mapbox/api/directions/v5/DirectionsService.java @@ -3,8 +3,11 @@ import com.mapbox.api.directions.v5.models.DirectionsResponse; import retrofit2.Call; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.Header; +import retrofit2.http.POST; import retrofit2.http.Path; import retrofit2.http.Query; @@ -16,7 +19,7 @@ public interface DirectionsService { /** - * Constructs the html call using the information passed in through the + * Constructs the html get call using the information passed in through the * {@link MapboxDirections.Builder}. * * @param userAgent the user agent @@ -82,4 +85,73 @@ Call getCall( @Query("waypoint_targets") String waypointTargets, @Query("enable_refresh") Boolean enableRefresh ); + + /** + * Constructs the post html call using the information passed in through the + * {@link MapboxDirections.Builder}. + * + * @param userAgent the user agent + * @param user the user + * @param profile the profile directions should use + * @param coordinates the coordinates the route should follow + * @param accessToken Mapbox access token + * @param alternatives define whether you want to receive more then one route + * @param geometries route geometry + * @param overview route full, simplified, etc. + * @param radiuses start at the most efficient point within the radius + * @param steps define if you'd like the route steps + * @param bearings used to filter the road segment the waypoint will be placed on by + * direction and dictates the angle of approach + * @param continueStraight define whether the route should continue straight even if the + * route will be slower + * @param annotations an annotations object that contains additional details about each + * line segment along the route geometry. Each entry in an + * annotations field corresponds to a coordinate along the route + * geometry + * @param language language of returned turn-by-turn text instructions + * @param roundaboutExits Add extra step when roundabouts occur with additional information + * for the user + * @param voiceInstructions request that the response contain voice instruction information, + * useful for navigation + * @param bannerInstructions request that the response contain banner instruction information, + * useful for navigation + * @param voiceUnits voice units + * @param exclude exclude tolls, motorways or more along your route + * @param approaches which side of the road to approach a waypoint + * @param waypointIndices which input coordinates should be treated as waypoints/separate legs. + * Note: coordinate indices not added here act as silent waypoints + * @param waypointNames custom names for waypoints used for the arrival instruction + * @param waypointTargets list of coordinate pairs for drop-off locations + * @param enableRefresh whether the routes should be refreshable + * @return the {@link DirectionsResponse} in a Call wrapper + * @since 4.6.0 + */ + @FormUrlEncoded + @POST("directions/v5/{user}/{profile}") + Call postCall( + @Header("User-Agent") String userAgent, + @Path("user") String user, + @Path("profile") String profile, + @Field("coordinates") String coordinates, + @Query("access_token") String accessToken, + @Field("alternatives") Boolean alternatives, + @Field("geometries") String geometries, + @Field("overview") String overview, + @Field("radiuses") String radiuses, + @Field("steps") Boolean steps, + @Field("bearings") String bearings, + @Field("continue_straight") Boolean continueStraight, + @Field("annotations") String annotations, + @Field("language") String language, + @Field("roundabout_exits") Boolean roundaboutExits, + @Field("voice_instructions") Boolean voiceInstructions, + @Field("banner_instructions") Boolean bannerInstructions, + @Field("voice_units") String voiceUnits, + @Field("exclude") String exclude, + @Field("approaches") String approaches, + @Field("waypoints") String waypointIndices, + @Field("waypoint_names") String waypointNames, + @Field("waypoint_targets") String waypointTargets, + @Field("enable_refresh") Boolean enableRefresh + ); } diff --git a/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java b/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java index 568393e1b..90b5f9ef1 100644 --- a/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java +++ b/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java @@ -63,6 +63,33 @@ protected MapboxDirections() { @Override protected Call initializeCall() { + if (usePostMethod()) { + return getService().postCall( + ApiCallHelper.getHeaderUserAgent(clientAppName()), + user(), + profile(), + formatCoordinates(coordinates()), + accessToken(), + alternatives(), + geometries(), + overview(), + radius(), + steps(), + bearing(), + continueStraight(), + annotation(), + language(), + roundaboutExits(), + voiceInstructions(), + bannerInstructions(), + voiceUnits(), + exclude(), + approaches(), + waypointIndices(), + waypointNames(), + waypointTargets(), + enableRefresh()); + } return getService().getCall( ApiCallHelper.getHeaderUserAgent(clientAppName()), user(), @@ -276,6 +303,9 @@ private static String formatWaypointTargets(Point[] waypointTargets) { @Nullable abstract EventListener eventListener(); + @NonNull + abstract Boolean usePostMethod(); + /** * Build a new {@link MapboxDirections} object with the initial values set for * {@link #baseUrl()}, {@link #profile()}, {@link #user()}, and {@link #geometries()}. @@ -288,7 +318,8 @@ public static Builder builder() { .baseUrl(Constants.BASE_API_URL) .profile(DirectionsCriteria.PROFILE_DRIVING) .user(DirectionsCriteria.PROFILE_DEFAULT_USER) - .geometries(DirectionsCriteria.GEOMETRY_POLYLINE6); + .geometries(DirectionsCriteria.GEOMETRY_POLYLINE6) + .usePostMethod(false); } /** @@ -758,6 +789,29 @@ public Builder addWaypointTargets(@Nullable Point... waypointTargets) { */ public abstract Builder enableRefresh(Boolean enableRefresh); + /** + * Use POST method to request data. + * The default is to use GET. + * @return this builder for chaining options together + * @since 4.4.0 + */ + public Builder post() { + usePostMethod(true); + return this; + } + + /** + * Use GET method to request data. + * @return this builder for chaining options together + * @since 4.4.0 + */ + public Builder get() { + usePostMethod(false); + return this; + } + + abstract Builder usePostMethod(@NonNull Boolean usePost); + abstract MapboxDirections autoBuild(); /** diff --git a/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java b/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java index dff1410f8..f50cc5a4a 100644 --- a/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java +++ b/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java @@ -823,4 +823,27 @@ public void callStart(Call call) { assertEquals(eventListener, mapboxDirections.eventListener()); } + + @Test + public void testPost() throws IOException { + MapboxDirections mapboxDirections = MapboxDirections.builder() + .profile(PROFILE_CYCLING) + .origin(Point.fromLngLat(-122.42,37.78)) + .destination(Point.fromLngLat(-77.03,38.91)) + .steps(true) + .voiceInstructions(true) + .voiceUnits(DirectionsCriteria.IMPERIAL) + .addWaypointNames("Home", "Work") + .accessToken(ACCESS_TOKEN) + .baseUrl(mockUrl.toString()) + .post() + .build(); + + Response response = mapboxDirections.executeCall(); + assertEquals(200, response.code()); + assertEquals("Ok", response.body().code()); + + assertNotNull(response.body().routes()); + assertEquals(1, response.body().routes().size()); + } } From 2cb96e21645fda4cb522091f2c49c3aeb47e640f Mon Sep 17 00:00:00 2001 From: Devota Aabel Date: Mon, 18 Feb 2019 16:38:02 -0500 Subject: [PATCH 2/2] Added json fixture for test and updated @since annotation versions --- Makefile | 7 +++++++ .../com/mapbox/api/directions/v5/MapboxDirections.java | 4 ++-- .../com/mapbox/api/directions/v5/MapboxDirectionsTest.java | 4 ++++ .../src/test/resources/directions_v5_post.json | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 services-directions/src/test/resources/directions_v5_post.json diff --git a/Makefile b/Makefile index cd88c175f..07d9ae2c7 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ # Used for Map Matching MAP_MATCHING_COORDINATES = 13.418946862220764,52.50055852688439;13.419011235237122,52.50113000479732;13.419756889343262,52.50171780290061;13.419885635375975,52.50237416816131;13.420631289482117,52.50294888790448 +# Used for directions +DIRECTIONS_POST_COORDINATES = 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 + build-config: ./gradlew compileBuildConfig @@ -142,6 +145,10 @@ directions-fixtures: 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)" \ -o services-directions/src/test/resources/directions_v5_waypoint_targets.json + # Directions: post request + curl -d "coordinates=$(DIRECTIONS_POST_COORDINATES)&steps=true&waypoints=0;6&waypoint_names=Home;Work&banner_instructions=true" "https://api.mapbox.com/directions/v5/mapbox/driving?access_token=$(MAPBOX_ACCESS_TOKEN)" \ + -o services-directions/src/test/resources/directions_v5_post.json + mapmatching-fixtures: curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?geometries=polyline&language=sv&steps=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \ -o services-matching/src/test/resources/map_matching_v5_polyline.json diff --git a/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java b/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java index 90b5f9ef1..dd0b02cd8 100644 --- a/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java +++ b/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java @@ -793,7 +793,7 @@ public Builder addWaypointTargets(@Nullable Point... waypointTargets) { * Use POST method to request data. * The default is to use GET. * @return this builder for chaining options together - * @since 4.4.0 + * @since 4.6.0 */ public Builder post() { usePostMethod(true); @@ -803,7 +803,7 @@ public Builder post() { /** * Use GET method to request data. * @return this builder for chaining options together - * @since 4.4.0 + * @since 4.6.0 */ public Builder get() { usePostMethod(false); diff --git a/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java b/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java index f50cc5a4a..8246c6ead 100644 --- a/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java +++ b/services-directions/src/test/java/com/mapbox/api/directions/v5/MapboxDirectionsTest.java @@ -60,6 +60,7 @@ public class MapboxDirectionsTest extends TestUtils { private static final String DIRECTIONS_V5_APPROACHES_REQUEST = "directions_v5_approaches.json"; private static final String DIRECTIONS_V5_WAYPOINT_NAMES_FIXTURE = "directions_v5_waypoint_names.json"; private static final String DIRECTIONS_V5_WAYPOINT_TARGETS_FIXTURE = "directions_v5_waypoint_targets.json"; + private static final String DIRECTIONS_V5_POST = "directions_v5_post.json"; private MockWebServer server; private HttpUrl mockUrl; @@ -92,6 +93,8 @@ public MockResponse dispatch(RecordedRequest request) throws InterruptedExceptio resource = DIRECTIONS_TRAFFIC_FIXTURE; } else if (request.getPath().contains("geometries=polyline6")) { resource = DIRECTIONS_V5_PRECISION6_FIXTURE; + } else if (request.getMethod().equals("POST")) { + resource = DIRECTIONS_V5_POST; } try { @@ -840,6 +843,7 @@ public void testPost() throws IOException { .build(); Response response = mapboxDirections.executeCall(); + System.out.print(response.raw().request().url()); assertEquals(200, response.code()); assertEquals("Ok", response.body().code()); diff --git a/services-directions/src/test/resources/directions_v5_post.json b/services-directions/src/test/resources/directions_v5_post.json new file mode 100644 index 000000000..ef3091b70 --- /dev/null +++ b/services-directions/src/test/resources/directions_v5_post.json @@ -0,0 +1 @@ +{"routes":[{"geometry":"{qeiHayhMlDoSQi@cDaB{R}I","legs":[{"summary":"Quai de la Mégisserie, Boulevard de Sébastopol","weight":211.2,"duration":145.6,"steps":[{"intersections":[{"out":0,"entry":[true],"bearings":[112],"location":[2.344011,48.858064]},{"out":1,"in":2,"entry":[false,true,false],"bearings":[30,105,285],"location":[2.344384,48.857963]},{"out":1,"in":2,"entry":[true,true,false],"bearings":[15,105,285],"location":[2.34542,48.857687]},{"out":1,"in":2,"entry":[false,true,false],"bearings":[0,120,285],"location":[2.346933,48.857292]},{"out":0,"in":2,"entry":[true,false,false],"bearings":[105,195,300],"location":[2.34712,48.857239]}],"driving_side":"right","geometry":"{qeiHayhMRiAt@oERcADUTqARqA@EHi@He@Ha@","mode":"driving","maneuver":{"bearing_after":112,"bearing_before":0,"location":[2.344011,48.858064],"type":"depart","instruction":"Head southeast on Quai de la Mégisserie"},"weight":59.7,"duration":42.5,"name":"Quai de la Mégisserie","distance":258.7,"bannerInstructions":[{"distanceAlongGeometry":258.7,"primary":{"text":"Place du Châtelet","components":[{"text":"Place","type":"text","abbr":"Pl","abbr_priority":0},{"text":"du Châtelet","type":"text"}],"type":"turn","modifier":"left"},"secondary":null}]},{"intersections":[{"out":0,"in":2,"entry":[true,true,false],"bearings":[60,120,285],"location":[2.347289,48.857193]},{"out":0,"in":2,"entry":[true,false,false,true],"bearings":[15,120,195,300],"location":[2.347777,48.857724]},{"out":0,"in":2,"entry":[true,false,false,true],"bearings":[15,120,195,300],"location":[2.348211,48.8585]},{"out":0,"in":2,"entry":[true,true,false],"bearings":[15,105,195],"location":[2.348335,48.858733]},{"out":0,"in":2,"entry":[true,true,false],"bearings":[15,120,195],"location":[2.348758,48.859525]},{"out":0,"in":2,"entry":[true,true,false],"bearings":[15,105,195],"location":[2.349062,48.860071]}],"driving_side":"right","geometry":"mleiHqmiMK]EKGGCCCAc@SQIQKWKs@]{@a@EAIECAGESIQIsCmAKE}As@MGcBu@cAg@_Ac@IE","mode":"driving","maneuver":{"bearing_after":60,"bearing_before":111,"location":[2.347289,48.857193],"modifier":"left","type":"turn","instruction":"Turn left onto Place du Châtelet"},"weight":151.5,"duration":103.1,"name":"Place du Châtelet","distance":492.5,"bannerInstructions":[{"distanceAlongGeometry":47.8,"primary":{"text":"Work","components":[{"text":"Work","type":"text"}],"type":"arrive","modifier":"right"},"secondary":null}]},{"intersections":[{"in":0,"entry":[true],"bearings":[200],"location":[2.349738,48.861278]}],"driving_side":"right","geometry":"_ffiH{|iM","mode":"driving","maneuver":{"bearing_after":0,"bearing_before":20,"location":[2.349738,48.861278],"modifier":"right","type":"arrive","instruction":"You have arrived at Work, on the right"},"weight":0,"duration":0,"name":"Boulevard de Sébastopol","distance":0,"bannerInstructions":[]}],"distance":751.2}],"weight_name":"routability","weight":211.2,"duration":145.6,"distance":751.2}],"waypoints":[{"distance":1.4298733755647755,"name":"Quai de la Mégisserie","location":[2.344011,48.858064]},{"distance":6.395738465807539,"name":"Quai de la Mégisserie","location":[2.34678,48.857329]},{"distance":0.6966709346040775,"name":"Boulevard de Sébastopol","location":[2.348673,48.859367]},{"distance":3.765538759196103,"name":"Boulevard de Sébastopol","location":[2.349503,48.860859]},{"distance":2.1281271687516483,"name":"Boulevard de Sébastopol","location":[2.349524,48.860896]},{"distance":2.090012803498222,"name":"Boulevard de Sébastopol","location":[2.349599,48.861029]},{"distance":7.178624584475835,"name":"Boulevard de Sébastopol","location":[2.349738,48.861278]}],"code":"Ok","uuid":"cjsatgenc01yx42rxlz3yilp7"} \ No newline at end of file