Skip to content

Commit

Permalink
add getting mapmatching through POST method
Browse files Browse the repository at this point in the history
  • Loading branch information
osana committed Jan 31, 2019
1 parent 22a324f commit 40d0001
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ mapmatching-fixtures:
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?steps=true&overview=full&geometries=polyline6&roundabout_exits=true&voice_instructions=true&language=he&access_token=$(MAPBOX_ACCESS_TOKEN)" \
-o services-matching/src/test/resources/map_matching_v5_invalid_voice_language.json

# MapMatching with post request
curl -d "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&steps=true&tidy=true&waypoints=0;6" "https://api.mapbox.com/matching/v5/mapbox/driving?access_token=$(MAPBOX_ACCESS_TOKEN)" \
-o services-matching/src/test/resources/map_matching_v5_post.json

optimization-fixtures:
# request an optimized car trip with no additional options
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)" \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import com.mapbox.api.matching.v5.models.MapMatchingResponse;

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;

Expand All @@ -16,7 +19,7 @@
public interface MapMatchingService {

/**
* Constructs the html call using the information passed in through the
* Constructs the GET call using the information passed in through the
* {@link MapboxMapMatching.Builder}.
*
* @param userAgent user agent
Expand Down Expand Up @@ -84,4 +87,76 @@ Call<MapMatchingResponse> getCall(
@Query("waypoints") String waypoints,
@Query("waypoint_names") String waypointNames,
@Query("approaches") String approaches);


/**
* Constructs the POSt call using the information passed in through the
* {@link MapboxMapMatching.Builder}.
*
* @param userAgent user agent
* @param user user
* @param profile directions profile ID; either mapbox/driving, mapbox/walking,
* or mapbox/cycling
* @param coordinates inaccurate traces from a GPS unit or a phone
* @param accessToken Mapbox access token
* @param geometries format of the returned geometry. Allowed values are: geojson
* (as LineString), polyline with precision 5, polyline6. The default
* value is polyline
* @param radiuses a list of integers in meters indicating the assumed precision of
* the used tracking device. There must be as many radiuses as there
* are coordinates in the request, each separated by ;. Values can be
* a number between 0 and 30. Use higher numbers (20-30) for noisy
* traces and lower numbers (1-10) for clean traces. The default value
* is 5
* @param steps whether to return steps and turn-by-turn instructions. Can be true
* or false. The default is false
* @param overview type of returned overview geometry. Can be full (the most detailed
* geometry available), simplified (a simplified version of the full
* geometry), or false (no overview geometry). The default is simplified
* @param timestamps timestamps corresponding to each coordinate provided in the request;
* must be numbers in Unix time (seconds since the Unix epoch). There
* must be as many timestamps as there are coordinates in the request,
* each separated by {@code ;}
* @param annotations whether or not to return additional metadata for each coordinate
* along the match geometry. Can be one or all of 'duration',
* 'distance', or 'nodes', each separated by ,. See the response
* object for more details on what it is included with annotations
* @param language language of returned turn-by-turn text instructions
* @param tidy whether or not to transparently remove clusters and re-sample
* traces for improved map matching results
* @param roundaboutExits Whether or not to emit instructions at roundabout exits.
* @param bannerInstructions Whether or not to return banner objects associated with
* the `routeSteps`. Should be used in conjunction with `steps`.
* @param voiceInstructions whether or not to return
* marked-up text for voice guidance along the route.
* @param voiceUnits voice units
* @param waypoints Which input coordinates should be treated as waypoints.
* @param waypointNames wustom names for waypoints used for the arrival instruction.
* @param approaches which side of the road to approach a waypoint.
* @return the MapMatchingResponse in a Call wrapper
* @since 4.4.0
*/
@FormUrlEncoded
@POST("matching/v5/{user}/{profile}")
Call<MapMatchingResponse> postCall(
@Header("User-Agent") String userAgent,
@Path("user") String user,
@Path("profile") String profile,
@Field("coordinates") String coordinates,
@Query("access_token") String accessToken,
@Field("geometries") String geometries,
@Field("radiuses") String radiuses,
@Field("steps") Boolean steps,
@Field("overview") String overview,
@Field("timestamps") String timestamps,
@Field("annotations") String annotations,
@Field("language") String language,
@Field("tidy") Boolean tidy,
@Field("roundabout_exits") Boolean roundaboutExits,
@Field("banner_instructions") Boolean bannerInstructions,
@Field("voice_instructions") Boolean voiceInstructions,
@Field("voice_units") String voiceUnits,
@Field("waypoints") String waypoints,
@Field("waypoint_names") String waypointNames,
@Field("approaches") String approaches);
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,29 @@ protected GsonBuilder getGsonBuilder() {

@Override
protected Call<MapMatchingResponse> initializeCall() {
if (usePostMethod()) {
return getService().postCall(
ApiCallHelper.getHeaderUserAgent(clientAppName()),
user(),
profile(),
coordinates(),
accessToken(),
geometries(),
radiuses(),
steps(),
overview(),
timestamps(),
annotations(),
language(),
tidy(),
roundaboutExits(),
bannerInstructions(),
voiceInstructions(),
voiceUnits(),
waypoints(),
waypointNames(),
approaches());
}
return getService().getCall(
ApiCallHelper.getHeaderUserAgent(clientAppName()),
user(),
Expand Down Expand Up @@ -242,6 +265,8 @@ private static List<Point> formatCoordinates(String coordinates) {
return coordinatesFormatted;
}

@NonNull
abstract Boolean usePostMethod();

@Nullable
abstract String clientAppName();
Expand Down Expand Up @@ -319,7 +344,8 @@ public static Builder builder() {
.baseUrl(Constants.BASE_API_URL)
.profile(DirectionsCriteria.PROFILE_DRIVING)
.geometries(DirectionsCriteria.GEOMETRY_POLYLINE6)
.user(DirectionsCriteria.PROFILE_DEFAULT_USER);
.user(DirectionsCriteria.PROFILE_DEFAULT_USER)
.usePostMethod(false);
}

/**
Expand All @@ -338,6 +364,28 @@ public abstract static class Builder {
private String[] waypointNames;
private String[] approaches;

/**
* Use GET method to request data (default).
* @return this builder for chaining options together
* @since 4.4.0
*/
public Builder post() {
usePostMethod(true);
return this;
}

/**
* Use POST 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);

/**
* Required to call when this is being built. If no access token provided,
* {@link ServicesException} will be thrown.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -678,4 +678,31 @@ public void testWithWaypointNames() throws Exception {
assertEquals(200, response.code());
assertEquals("Ok", response.body().code());
}

@Test
public void testUsePostMethod() throws Exception {
MapboxMapMatching mapMatching = MapboxMapMatching.builder()
.accessToken(ACCESS_TOKEN)
.baseUrl(mockUrl.toString())
.profile(PROFILE_DRIVING)
.steps(true)
.tidy(true)
.waypoints("0;6")
.coordinates(Arrays.asList(
Point.fromLngLat(2.344003915786743,48.85805170891599),
Point.fromLngLat(2.346750497817993,48.85727523615161),
Point.fromLngLat(2.348681688308716,48.85936462637049),
Point.fromLngLat(2.349550724029541,48.86084691113991),
Point.fromLngLat(2.349550724029541,48.8608892614883),
Point.fromLngLat(2.349625825881958,48.86102337068847),
Point.fromLngLat(2.34982967376709,48.86125629633996)))
.post()
.build();
Response<MapMatchingResponse> response = mapMatching.executeCall();
assertEquals(200, response.code());
assertEquals("Ok", response.body().code());

assertNotNull(response.body().matchings());
assertEquals(1, response.body().matchings().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"matchings":[{"confidence":0.8646240884788093,"geometry":"{qeiHayhMjDkSOm@cDaB{R}I","legs":[{"summary":"Quai de la Mégisserie, Boulevard de Sébastopol","weight":204.3,"duration":140.5,"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.345408,48.857687]},{"out":0,"in":1,"entry":[true,false,false],"bearings":[120,285,330],"location":[2.346993,48.857275]},{"out":0,"in":2,"entry":[true,false,false],"bearings":[105,195,300],"location":[2.34712,48.857239]}],"driving_side":"right","geometry":"{qeiHayhMRiAt@mEReADUTqARqA@EJu@FYF]","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.099999999999994,"duration":43.800000000000004,"name":"Quai de la Mégisserie","distance":257.2},{"intersections":[{"out":0,"in":2,"entry":[true,true,false],"bearings":[60,120,285],"location":[2.347272,48.857201]},{"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.34833,48.858721]},{"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,90,195],"location":[2.349062,48.860069]}],"driving_side":"right","geometry":"oleiHmmiMIa@EKGGCCCAc@SQIQKWKs@]{@a@EAMGGCSKOGuCoAKE}As@MGaBs@eAi@_Ac@IE","mode":"driving","maneuver":{"bearing_after":66,"bearing_before":109,"location":[2.347272,48.857201],"modifier":"left","type":"turn","instruction":"Turn left onto Place du Châtelet"},"weight":145.2,"duration":96.7,"name":"Place du Châtelet","distance":493.20000000000005},{"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 your destination, on the right"},"weight":0,"duration":0,"name":"Boulevard de Sébastopol","distance":0}],"distance":750.4}],"weight_name":"routability","weight":204.3,"duration":140.5,"distance":750.4}],"tracepoints":[{"alternatives_count":0,"waypoint_index":0,"matchings_index":0,"distance":1.4298733755647755,"name":"Quai de la Mégisserie","location":[2.344011,48.858064]},{"alternatives_count":0,"waypoint_index":null,"matchings_index":0,"distance":6.317472000209194,"name":"Quai de la Mégisserie","location":[2.346781,48.857328]},{"alternatives_count":0,"waypoint_index":null,"matchings_index":0,"distance":0.6275897933079265,"name":"Boulevard de Sébastopol","location":[2.348674,48.859367]},{"alternatives_count":0,"waypoint_index":null,"matchings_index":0,"distance":3.765538759196103,"name":"Boulevard de Sébastopol","location":[2.349503,48.860859]},null,{"alternatives_count":0,"waypoint_index":null,"matchings_index":0,"distance":2.090012803498222,"name":"Boulevard de Sébastopol","location":[2.349599,48.861029]},{"alternatives_count":0,"waypoint_index":1,"matchings_index":0,"distance":7.178624584475835,"name":"Boulevard de Sébastopol","location":[2.349738,48.861278]}],"code":"Ok"}

0 comments on commit 40d0001

Please sign in to comment.