Skip to content

Commit 278cfbc

Browse files
author
Cameron Mace
authored
Support for directions matrix (#418)
* added support for directions matrix * removed rest of conflict message * fixed test
1 parent 946e4d2 commit 278cfbc

13 files changed

Lines changed: 1078 additions & 1 deletion

File tree

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ navigation-fixtures:
7070
curl "https://api.mapbox.com/directions/v5/mapbox/driving/-122.413165,37.795042;-122.433378,37.7727?geometries=polyline6&overview=full&steps=true&access_token=$(MAPBOX_ACCESS_TOKEN)" \
7171
-o mapbox/libandroid-services/src/test/resources/navigation.json
7272

73+
directions-matrix-fixtures:
74+
# request a symmetric 3x3 matrix for cars
75+
curl "https://api.mapbox.com/directions-matrix/v1/mapbox/driving/-122.42,37.78;-122.45,37.91;-122.48,37.73?access_token=$(MAPBOX_ACCESS_TOKEN)" \
76+
-o mapbox/libjava-services/src/test/fixtures/directions_matrix_3x3.json
77+
78+
# request an asymmetric 2x3 matrix for bicycles
79+
curl "https://api.mapbox.com/directions-matrix/v1/mapbox/cycling/-122.42,37.78;-122.45,37.91;-122.48,37.73?sources=0;2&destinations=all&access_token=$(MAPBOX_ACCESS_TOKEN)" \
80+
-o mapbox/libjava-services/src/test/fixtures/directions_matrix_2x3.json.json
81+
7382
geocoding-fixtures:
7483
# Geocoding: 1600 Pennsylvania Ave NW
7584
curl "https://api.mapbox.com/geocoding/v5/mapbox.places/1600+pennsylvania+ave+nw.json?access_token=$(MAPBOX_ACCESS_TOKEN)" \
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.mapbox.services.api.rx.directionsmatrix.v1;
2+
3+
import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;
4+
5+
import io.reactivex.Observable;
6+
import retrofit2.http.GET;
7+
import retrofit2.http.Header;
8+
import retrofit2.http.Path;
9+
import retrofit2.http.Query;
10+
11+
/**
12+
* Interface that defines the directions matrix service (v5).
13+
*
14+
* @since 2.1.0
15+
*/
16+
public interface DirectionsMatrixServiceRx {
17+
18+
/**
19+
* Call-based interface
20+
*
21+
* @param userAgent The user.
22+
* @param user The user.
23+
* @param profile The profile directions should use.
24+
* @param coordinates The coordinates the route should follow.
25+
* @param accessToken Mapbox access token.
26+
* @param destinations Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
27+
* network. The waypoints appear in the array in the order of the input coordinates, or in the
28+
* order as specified in the destinations query parameter.
29+
* @param sources Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
30+
* network. The waypoints appear in the array in the order of the input coordinates, or in the
31+
* order as specified in the sources query parameter.
32+
* @since 2.1.0
33+
*/
34+
@GET("directions-matrix/v1/{user}/{profile}/{coordinates}")
35+
Observable<DirectionsMatrixResponse> getObservable(
36+
@Header("User-Agent") String userAgent,
37+
@Path("user") String user,
38+
@Path("profile") String profile,
39+
@Path("coordinates") String coordinates,
40+
@Query("access_token") String accessToken,
41+
@Query("destinations") String destinations,
42+
@Query("sources") String sources
43+
);
44+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.mapbox.services.api.rx.directionsmatrix.v1;
2+
3+
import com.mapbox.services.api.ServicesException;
4+
import com.mapbox.services.api.directionsmatrix.v1.MapboxDirectionsMatrix;
5+
import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;
6+
7+
import io.reactivex.Observable;
8+
import retrofit2.Retrofit;
9+
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
10+
import retrofit2.converter.gson.GsonConverterFactory;
11+
12+
/**
13+
* The Directions Matrix API allows the calculation of routes between coordinates.
14+
* <p>
15+
* This class has support for Rx Observables.
16+
*
17+
* @since 2.1.0
18+
*/
19+
public class MapboxDirectionsMatrixRx extends MapboxDirectionsMatrix {
20+
21+
private DirectionsMatrixServiceRx serviceRx = null;
22+
private Observable<DirectionsMatrixResponse> observable = null;
23+
24+
public MapboxDirectionsMatrixRx(Builder builder) {
25+
super(builder);
26+
}
27+
28+
private DirectionsMatrixServiceRx getServiceRx() {
29+
// No need to recreate it
30+
if (serviceRx != null) {
31+
return serviceRx;
32+
}
33+
34+
// Retrofit instance
35+
Retrofit retrofit = new Retrofit.Builder()
36+
.client(getOkHttpClient())
37+
.baseUrl(builder.getBaseUrl())
38+
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
39+
.addConverterFactory(GsonConverterFactory.create())
40+
.build();
41+
42+
// Directions service
43+
serviceRx = retrofit.create(DirectionsMatrixServiceRx.class);
44+
return serviceRx;
45+
}
46+
47+
public Observable<DirectionsMatrixResponse> getObservable() {
48+
// No need to recreate it
49+
if (observable != null) {
50+
return observable;
51+
}
52+
53+
observable = getServiceRx().getObservable(
54+
getHeaderUserAgent(builder.getClientAppName()),
55+
builder.getUser(),
56+
builder.getProfile(),
57+
builder.getCoordinates(),
58+
builder.getAccessToken(),
59+
builder.getDestinations(),
60+
builder.getSources());
61+
62+
// Done
63+
return observable;
64+
}
65+
66+
public static class Builder extends MapboxDirectionsMatrix.Builder<Builder> {
67+
@Override
68+
public MapboxDirectionsMatrixRx build() throws ServicesException {
69+
super.build();
70+
return new MapboxDirectionsMatrixRx(this);
71+
}
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package com.mapbox.services.api.rx.directionsmatrix.v1;
2+
3+
import com.mapbox.services.api.ServicesException;
4+
import com.mapbox.services.api.directions.v5.DirectionsCriteria;
5+
import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;
6+
import com.mapbox.services.commons.models.Position;
7+
8+
import org.junit.After;
9+
import org.junit.Before;
10+
import org.junit.Rule;
11+
import org.junit.Test;
12+
import org.junit.rules.ExpectedException;
13+
14+
import java.io.IOException;
15+
import java.nio.charset.Charset;
16+
import java.nio.file.Files;
17+
import java.nio.file.Paths;
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
import io.reactivex.observers.TestObserver;
22+
import okhttp3.HttpUrl;
23+
import okhttp3.mockwebserver.MockResponse;
24+
import okhttp3.mockwebserver.MockWebServer;
25+
import okhttp3.mockwebserver.RecordedRequest;
26+
27+
import static org.junit.Assert.assertEquals;
28+
29+
public class MapboxDirectionsMatrixRxTest {
30+
31+
public static final String DIRECTIONS_MATRIX_3X3_FIXTURE
32+
= "../libjava-services/src/test/fixtures/directions_matrix_3x3.json";
33+
34+
private MockWebServer server;
35+
private HttpUrl mockUrl;
36+
37+
private List<Position> positions;
38+
39+
@Before
40+
public void setUp() throws IOException {
41+
server = new MockWebServer();
42+
43+
server.setDispatcher(new okhttp3.mockwebserver.Dispatcher() {
44+
@Override
45+
public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
46+
try {
47+
String body = new String(
48+
Files.readAllBytes(Paths.get(DIRECTIONS_MATRIX_3X3_FIXTURE)), Charset.forName("utf-8")
49+
);
50+
return new MockResponse().setBody(body);
51+
} catch (IOException ioException) {
52+
throw new RuntimeException(ioException);
53+
}
54+
55+
}
56+
});
57+
58+
server.start();
59+
60+
mockUrl = server.url("");
61+
62+
positions = new ArrayList<>();
63+
positions.add(Position.fromCoordinates(-122.42, 37.78));
64+
positions.add(Position.fromCoordinates(-122.45, 37.91));
65+
positions.add(Position.fromCoordinates(-122.48, 37.73));
66+
}
67+
68+
@After
69+
public void tearDown() throws IOException {
70+
server.shutdown();
71+
}
72+
73+
@Rule
74+
public ExpectedException thrown = ExpectedException.none();
75+
76+
@Test
77+
public void testSanityRX() throws ServicesException {
78+
MapboxDirectionsMatrixRx client = new MapboxDirectionsMatrixRx.Builder()
79+
.setAccessToken("pk.XXX")
80+
.setCoordinates(positions)
81+
.setProfile(DirectionsCriteria.PROFILE_DRIVING)
82+
.setBaseUrl(mockUrl.toString())
83+
.build();
84+
85+
TestObserver<DirectionsMatrixResponse> testObserver = new TestObserver();
86+
client.getObservable().subscribe(testObserver);
87+
testObserver.assertComplete();
88+
testObserver.assertNoErrors();
89+
testObserver.assertValueCount(1);
90+
91+
List<List<Object>> events = testObserver.getEvents();
92+
assertEquals(1, events.get(0).size());
93+
94+
DirectionsMatrixResponse response = (DirectionsMatrixResponse) events.get(0).get(0);
95+
assertEquals(response.getCode(), DirectionsCriteria.RESPONSE_OK);
96+
}
97+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ public String getProfile() {
387387
* <p>
388388
* {longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]
389389
* <p>
390-
* - Each coordinate is a pair of a longitude float and latitude float, which are separated by a ,
390+
* - Each coordinate is a pair of a longitude double and latitude double, which are separated by a ,
391391
* - Coordinates are separated by a ; from each other
392392
* - A query must at minimum have 2 coordinates and may at maximum have 25 coordinates
393393
*
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.mapbox.services.api.directionsmatrix.v1;
2+
3+
import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;
4+
5+
import retrofit2.Call;
6+
import retrofit2.http.GET;
7+
import retrofit2.http.Header;
8+
import retrofit2.http.Path;
9+
import retrofit2.http.Query;
10+
11+
/**
12+
* Interface that defines the directions matrix service (v1).
13+
*
14+
* @since 2.1.0
15+
*/
16+
public interface DirectionsMatrixService {
17+
18+
/**
19+
* Call-based interface
20+
*
21+
* @param userAgent The user.
22+
* @param user The user.
23+
* @param profile The profile directions should use.
24+
* @param coordinates The coordinates the route should follow.
25+
* @param accessToken Mapbox access token.
26+
* @param destinations Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
27+
* network. The waypoints appear in the array in the order of the input coordinates, or in the
28+
* order as specified in the destinations query parameter.
29+
* @param sources Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
30+
* network. The waypoints appear in the array in the order of the input coordinates, or in the
31+
* order as specified in the sources query parameter.
32+
* @since 2.1.0
33+
*/
34+
@GET("directions-matrix/v1/{user}/{profile}/{coordinates}")
35+
Call<DirectionsMatrixResponse> getCall(
36+
// NOTE: DirectionsMatrixServiceRx should be updated as well
37+
@Header("User-Agent") String userAgent,
38+
@Path("user") String user,
39+
@Path("profile") String profile,
40+
@Path("coordinates") String coordinates,
41+
@Query("access_token") String accessToken,
42+
@Query("destinations") String destinations,
43+
@Query("sources") String sources
44+
);
45+
}

0 commit comments

Comments
 (0)