Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add getting mapmatching through POST method #948

Merged
merged 1 commit into from
Feb 4, 2019
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
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,29 @@ public abstract static class Builder {
private String[] waypointNames;
private String[] approaches;

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

/**
* 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"}