Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ navigation-fixtures:
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)" \
-o mapbox/libandroid-services/src/test/resources/navigation.json

directions-matrix-fixtures:
# request a symmetric 3x3 matrix for cars
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)" \
-o mapbox/libjava-services/src/test/fixtures/directions_matrix_3x3.json

# request an asymmetric 2x3 matrix for bicycles
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)" \
-o mapbox/libjava-services/src/test/fixtures/directions_matrix_2x3.json.json

geocoding-fixtures:
# Geocoding: 1600 Pennsylvania Ave NW
curl "https://api.mapbox.com/geocoding/v5/mapbox.places/1600+pennsylvania+ave+nw.json?access_token=$(MAPBOX_ACCESS_TOKEN)" \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.mapbox.services.api.rx.directionsmatrix.v1;

import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;

import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Path;
import retrofit2.http.Query;

/**
* Interface that defines the directions matrix service (v5).
*
* @since 2.1.0
*/
public interface DirectionsMatrixServiceRx {

/**
* Call-based interface
*
* @param userAgent The user.
* @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 destinations Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
* network. The waypoints appear in the array in the order of the input coordinates, or in the
* order as specified in the destinations query parameter.
* @param sources Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
* network. The waypoints appear in the array in the order of the input coordinates, or in the
* order as specified in the sources query parameter.
* @since 2.1.0
*/
@GET("directions-matrix/v1/{user}/{profile}/{coordinates}")
Observable<DirectionsMatrixResponse> getObservable(
@Header("User-Agent") String userAgent,
@Path("user") String user,
@Path("profile") String profile,
@Path("coordinates") String coordinates,
@Query("access_token") String accessToken,
@Query("destinations") String destinations,
@Query("sources") String sources
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.mapbox.services.api.rx.directionsmatrix.v1;

import com.mapbox.services.api.ServicesException;
import com.mapbox.services.api.directionsmatrix.v1.MapboxDirectionsMatrix;
import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;

import io.reactivex.Observable;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
* The Directions Matrix API allows the calculation of routes between coordinates.
* <p>
* This class has support for Rx Observables.
*
* @since 2.1.0
*/
public class MapboxDirectionsMatrixRx extends MapboxDirectionsMatrix {

private DirectionsMatrixServiceRx serviceRx = null;
private Observable<DirectionsMatrixResponse> observable = null;

public MapboxDirectionsMatrixRx(Builder builder) {
super(builder);
}

private DirectionsMatrixServiceRx getServiceRx() {
// No need to recreate it
if (serviceRx != null) {
return serviceRx;
}

// Retrofit instance
Retrofit retrofit = new Retrofit.Builder()
.client(getOkHttpClient())
.baseUrl(builder.getBaseUrl())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();

// Directions service
serviceRx = retrofit.create(DirectionsMatrixServiceRx.class);
return serviceRx;
}

public Observable<DirectionsMatrixResponse> getObservable() {
// No need to recreate it
if (observable != null) {
return observable;
}

observable = getServiceRx().getObservable(
getHeaderUserAgent(builder.getClientAppName()),
builder.getUser(),
builder.getProfile(),
builder.getCoordinates(),
builder.getAccessToken(),
builder.getDestinations(),
builder.getSources());

// Done
return observable;
}

public static class Builder extends MapboxDirectionsMatrix.Builder<Builder> {
@Override
public MapboxDirectionsMatrixRx build() throws ServicesException {
super.build();
return new MapboxDirectionsMatrixRx(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.mapbox.services.api.rx.directionsmatrix.v1;

import com.mapbox.services.api.ServicesException;
import com.mapbox.services.api.directions.v5.DirectionsCriteria;
import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;
import com.mapbox.services.commons.models.Position;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.observers.TestObserver;
import okhttp3.HttpUrl;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;

import static org.junit.Assert.assertEquals;

public class MapboxDirectionsMatrixRxTest {

public static final String DIRECTIONS_MATRIX_3X3_FIXTURE
= "../libjava-services/src/test/fixtures/directions_matrix_3x3.json";

private MockWebServer server;
private HttpUrl mockUrl;

private List<Position> positions;

@Before
public void setUp() throws IOException {
server = new MockWebServer();

server.setDispatcher(new okhttp3.mockwebserver.Dispatcher() {
@Override
public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
try {
String body = new String(
Files.readAllBytes(Paths.get(DIRECTIONS_MATRIX_3X3_FIXTURE)), Charset.forName("utf-8")
);
return new MockResponse().setBody(body);
} catch (IOException ioException) {
throw new RuntimeException(ioException);
}

}
});

server.start();

mockUrl = server.url("");

positions = new ArrayList<>();
positions.add(Position.fromCoordinates(-122.42, 37.78));
positions.add(Position.fromCoordinates(-122.45, 37.91));
positions.add(Position.fromCoordinates(-122.48, 37.73));
}

@After
public void tearDown() throws IOException {
server.shutdown();
}

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void testSanityRX() throws ServicesException {
MapboxDirectionsMatrixRx client = new MapboxDirectionsMatrixRx.Builder()
.setAccessToken("pk.XXX")
.setCoordinates(positions)
.setProfile(DirectionsCriteria.PROFILE_DRIVING)
.setBaseUrl(mockUrl.toString())
.build();

TestObserver<DirectionsMatrixResponse> testObserver = new TestObserver();
client.getObservable().subscribe(testObserver);
testObserver.assertComplete();
testObserver.assertNoErrors();
testObserver.assertValueCount(1);

List<List<Object>> events = testObserver.getEvents();
assertEquals(1, events.get(0).size());

DirectionsMatrixResponse response = (DirectionsMatrixResponse) events.get(0).get(0);
assertEquals(response.getCode(), DirectionsCriteria.RESPONSE_OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ public String getProfile() {
* <p>
* {longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]
* <p>
* - Each coordinate is a pair of a longitude float and latitude float, which are separated by a ,
* - Each coordinate is a pair of a longitude double and latitude double, which are separated by a ,
* - Coordinates are separated by a ; from each other
* - A query must at minimum have 2 coordinates and may at maximum have 25 coordinates
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.mapbox.services.api.directionsmatrix.v1;

import com.mapbox.services.api.directionsmatrix.v1.models.DirectionsMatrixResponse;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Path;
import retrofit2.http.Query;

/**
* Interface that defines the directions matrix service (v1).
*
* @since 2.1.0
*/
public interface DirectionsMatrixService {

/**
* Call-based interface
*
* @param userAgent The user.
* @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 destinations Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
* network. The waypoints appear in the array in the order of the input coordinates, or in the
* order as specified in the destinations query parameter.
* @param sources Array of waypoint objects. Each waypoints is an input coordinate snapped to the road and path
* network. The waypoints appear in the array in the order of the input coordinates, or in the
* order as specified in the sources query parameter.
* @since 2.1.0
*/
@GET("directions-matrix/v1/{user}/{profile}/{coordinates}")
Call<DirectionsMatrixResponse> getCall(
// NOTE: DirectionsMatrixServiceRx should be updated as well
@Header("User-Agent") String userAgent,
@Path("user") String user,
@Path("profile") String profile,
@Path("coordinates") String coordinates,
@Query("access_token") String accessToken,
@Query("destinations") String destinations,
@Query("sources") String sources
);
}
Loading