diff --git a/src/main/java/com/google/maps/NearestRoadsApiRequest.java b/src/main/java/com/google/maps/NearestRoadsApiRequest.java new file mode 100644 index 000000000..c713da089 --- /dev/null +++ b/src/main/java/com/google/maps/NearestRoadsApiRequest.java @@ -0,0 +1,40 @@ +package com.google.maps; + +import com.google.gson.FieldNamingPolicy; +import com.google.maps.RoadsApi.RoadsResponse; +import com.google.maps.internal.ApiConfig; +import com.google.maps.internal.StringJoin; +import com.google.maps.model.LatLng; +import com.google.maps.model.SnappedPoint; + +/** A request to the snap to roads API (part of Roads API). */ +public class NearestRoadsApiRequest + extends PendingResultBase { + + private static final ApiConfig NEAREST_ROADS_API_CONFIG = + new ApiConfig("/v1/nearestRoads") + .hostName(RoadsApi.API_BASE_URL) + .supportsClientId(false) + .fieldNamingPolicy(FieldNamingPolicy.IDENTITY); + + public NearestRoadsApiRequest(GeoApiContext context) { + super(context, NEAREST_ROADS_API_CONFIG, RoadsResponse.class); + } + + @Override + protected void validateRequest() { + if (!params().containsKey("points")) { + throw new IllegalArgumentException("Request must contain 'path"); + } + } + + /** + * The points from which to snap to roads. + * + * @param points the point to be snapped + * @return returns this {@link NearestRoadsApiRequest} for call chaining. + */ + public NearestRoadsApiRequest points(LatLng... points) { + return param("points", StringJoin.join('|', points)); + } +} diff --git a/src/main/java/com/google/maps/RoadsApi.java b/src/main/java/com/google/maps/RoadsApi.java index 67f72340c..1ecd3b165 100644 --- a/src/main/java/com/google/maps/RoadsApi.java +++ b/src/main/java/com/google/maps/RoadsApi.java @@ -15,16 +15,12 @@ package com.google.maps; -import static com.google.maps.internal.StringJoin.join; - -import com.google.gson.FieldNamingPolicy; import com.google.maps.errors.ApiError; import com.google.maps.errors.ApiException; -import com.google.maps.internal.ApiConfig; import com.google.maps.internal.ApiResponse; import com.google.maps.model.LatLng; import com.google.maps.model.SnappedPoint; -import com.google.maps.model.SnappedSpeedLimitResponse; +import com.google.maps.model.SnappedSpeedLimitResult; import com.google.maps.model.SpeedLimit; /** @@ -37,24 +33,6 @@ public class RoadsApi { static final String API_BASE_URL = "https://roads.googleapis.com"; - static final ApiConfig SNAP_TO_ROADS_API_CONFIG = - new ApiConfig("/v1/snapToRoads") - .hostName(API_BASE_URL) - .supportsClientId(false) - .fieldNamingPolicy(FieldNamingPolicy.IDENTITY); - - static final ApiConfig SPEEDS_API_CONFIG = - new ApiConfig("/v1/speedLimits") - .hostName(API_BASE_URL) - .supportsClientId(false) - .fieldNamingPolicy(FieldNamingPolicy.IDENTITY); - - static final ApiConfig NEAREST_ROADS_API_CONFIG = - new ApiConfig("/v1/nearestRoads") - .hostName(API_BASE_URL) - .supportsClientId(false) - .fieldNamingPolicy(FieldNamingPolicy.IDENTITY); - private RoadsApi() {} /** @@ -63,10 +41,10 @@ private RoadsApi() {} * * @param context The {@link GeoApiContext} to make requests through. * @param path The collected GPS points as a path. - * @return Returns the snapped points as a {@link PendingResult}. + * @return Returns the {@code SnapToRoadsApiRequest} for call chaining */ - public static PendingResult snapToRoads(GeoApiContext context, LatLng... path) { - return context.get(SNAP_TO_ROADS_API_CONFIG, RoadsResponse.class, "path", join('|', path)); + public static SnapToRoadsApiRequest snapToRoads(GeoApiContext context, LatLng... path) { + return snapToRoads(context, false, path); } /** @@ -81,17 +59,11 @@ public static PendingResult snapToRoads(GeoApiContext context, L * in a path that smoothly follows the geometry of the road, even around corners and through * tunnels. * @param path The path to be snapped. - * @return Returns the snapped points as a {@link PendingResult}. + * @return Returns the {@code SnapToRoadsApiRequest} for call chaining */ - public static PendingResult snapToRoads( + public static SnapToRoadsApiRequest snapToRoads( GeoApiContext context, boolean interpolate, LatLng... path) { - return context.get( - SNAP_TO_ROADS_API_CONFIG, - RoadsResponse.class, - "path", - join('|', path), - "interpolate", - String.valueOf(interpolate)); + return new SnapToRoadsApiRequest(context).path(path).interpolate(interpolate); } /** @@ -106,10 +78,10 @@ public static PendingResult snapToRoads( * * @param context The {@link GeoApiContext} to make requests through. * @param path The collected GPS points as a path. - * @return Returns the speed limits as a {@link PendingResult}. + * @return a {@link SpeedLimitsApiRequest} */ - public static PendingResult speedLimits(GeoApiContext context, LatLng... path) { - return context.get(SPEEDS_API_CONFIG, SpeedsResponse.class, "path", join('|', path)); + public static SpeedLimitsApiRequest speedLimits(GeoApiContext context, LatLng... path) { + return new SpeedLimitsApiRequest(context).path(path); } /** @@ -125,29 +97,10 @@ public static PendingResult speedLimits(GeoApiContext context, Lat * @param placeIds The Place ID of the road segment. Place IDs are returned by the {@link * #snapToRoads(GeoApiContext, com.google.maps.model.LatLng...)} method. You can pass up to * 100 placeIds with each request. - * @return Returns the speed limits as a {@link PendingResult}. + * @return a {@link SpeedLimitsApiRequest} */ - public static PendingResult speedLimits(GeoApiContext context, String... placeIds) { - String[] placeParams = new String[2 * placeIds.length]; - int i = 0; - for (String placeId : placeIds) { - placeParams[i++] = "placeId"; - placeParams[i++] = placeId; - } - - return context.get(SPEEDS_API_CONFIG, SpeedsResponse.class, placeParams); - } - - /** - * Returns the result of snapping the provided points to roads and retrieving the speed limits. - * - * @param context The {@link GeoApiContext} to make requests through. - * @param path The collected GPS points as a path. - * @return Returns the snapped points and speed limits as a {@link PendingResult}. - */ - public static PendingResult snappedSpeedLimits( - GeoApiContext context, LatLng... path) { - return context.get(SPEEDS_API_CONFIG, CombinedResponse.class, "path", join('|', path)); + public static SpeedLimitsApiRequest speedLimits(GeoApiContext context, String... placeIds) { + return new SpeedLimitsApiRequest(context).placeIds(placeIds); } /** @@ -156,11 +109,10 @@ public static PendingResult snappedSpeedLimits( * * @param context The {@link GeoApiContext} to make requests through. * @param points The sequence of points to be aligned to nearest roads - * @return Returns the snapped points as a {@link PendingResult}. + * @return a {@link NearestRoadsApiRequest} */ - public static PendingResult nearestRoads( - GeoApiContext context, LatLng... points) { - return context.get(NEAREST_ROADS_API_CONFIG, RoadsResponse.class, "points", join('|', points)); + public static NearestRoadsApiRequest nearestRoads(GeoApiContext context, LatLng... points) { + return new NearestRoadsApiRequest(context).points(points); } public static class RoadsResponse implements ApiResponse { @@ -183,27 +135,7 @@ public ApiException getError() { } } - public static class SpeedsResponse implements ApiResponse { - private SpeedLimit[] speedLimits; - private ApiError error; - - @Override - public boolean successful() { - return error == null; - } - - @Override - public SpeedLimit[] getResult() { - return speedLimits; - } - - @Override - public ApiException getError() { - return ApiException.from(error.status, error.message); - } - } - - public static class CombinedResponse implements ApiResponse { + public static class SpeedLimitsResponse implements ApiResponse { private SnappedPoint[] snappedPoints; private SpeedLimit[] speedLimits; private ApiError error; @@ -214,8 +146,8 @@ public boolean successful() { } @Override - public SnappedSpeedLimitResponse getResult() { - SnappedSpeedLimitResponse response = new SnappedSpeedLimitResponse(); + public SnappedSpeedLimitResult getResult() { + SnappedSpeedLimitResult response = new SnappedSpeedLimitResult(); response.snappedPoints = snappedPoints; response.speedLimits = speedLimits; return response; diff --git a/src/main/java/com/google/maps/SnapToRoadsApiRequest.java b/src/main/java/com/google/maps/SnapToRoadsApiRequest.java new file mode 100644 index 000000000..c9eee2a79 --- /dev/null +++ b/src/main/java/com/google/maps/SnapToRoadsApiRequest.java @@ -0,0 +1,50 @@ +package com.google.maps; + +import com.google.gson.FieldNamingPolicy; +import com.google.maps.RoadsApi.RoadsResponse; +import com.google.maps.internal.ApiConfig; +import com.google.maps.internal.StringJoin; +import com.google.maps.model.LatLng; +import com.google.maps.model.SnappedPoint; + +/** A request to the snap to roads API (part of Roads API). */ +public class SnapToRoadsApiRequest + extends PendingResultBase { + + private static final ApiConfig SNAP_TO_ROADS_API_CONFIG = + new ApiConfig("/v1/snapToRoads") + .hostName(RoadsApi.API_BASE_URL) + .supportsClientId(false) + .fieldNamingPolicy(FieldNamingPolicy.IDENTITY); + + public SnapToRoadsApiRequest(GeoApiContext context) { + super(context, SNAP_TO_ROADS_API_CONFIG, RoadsResponse.class); + } + + @Override + protected void validateRequest() { + if (!params().containsKey("path")) { + throw new IllegalArgumentException("Request must contain 'path"); + } + } + + /** + * The path from which to snap to roads. + * + * @param path the path to be snapped + * @return returns this {@code SnapToRoadsApiRequest} for call chaining. + */ + public SnapToRoadsApiRequest path(LatLng... path) { + return param("path", StringJoin.join('|', path)); + } + + /** + * Whether to interpolate a path to include all points forming the full road-geometry. + * + * @param interpolate if the points should be interpolated or not + * @return returns this {@code SnapToRoadsApiRequest} for call chaining. + */ + public SnapToRoadsApiRequest interpolate(boolean interpolate) { + return param("interpolate", String.valueOf(interpolate)); + } +} diff --git a/src/main/java/com/google/maps/SpeedLimitsApiRequest.java b/src/main/java/com/google/maps/SpeedLimitsApiRequest.java new file mode 100644 index 000000000..3d99c1ad1 --- /dev/null +++ b/src/main/java/com/google/maps/SpeedLimitsApiRequest.java @@ -0,0 +1,53 @@ +package com.google.maps; + +import com.google.gson.FieldNamingPolicy; +import com.google.maps.RoadsApi.SpeedLimitsResponse; +import com.google.maps.internal.ApiConfig; +import com.google.maps.internal.StringJoin; +import com.google.maps.model.LatLng; +import com.google.maps.model.SnappedSpeedLimitResult; + +/** A request to the speed limits API (part of Roads API). */ +public class SpeedLimitsApiRequest + extends PendingResultBase { + + private static final ApiConfig SPEEDS_API_CONFIG = + new ApiConfig("/v1/speedLimits") + .hostName(RoadsApi.API_BASE_URL) + .supportsClientId(false) + .fieldNamingPolicy(FieldNamingPolicy.IDENTITY); + + public SpeedLimitsApiRequest(GeoApiContext context) { + super(context, SPEEDS_API_CONFIG, SpeedLimitsResponse.class); + } + + @Override + protected void validateRequest() { + if (!params().containsKey("path") && !params().containsKey("placeId")) { + throw new IllegalArgumentException("Request must contain either 'path' or 'placeId'"); + } + } + + /** + * A list of up to 100 lat/long pairs representing a path. + * + * @param path the path + * @return a {@code SpeedLimitsApiRequest} for call chaining. + */ + public SpeedLimitsApiRequest path(LatLng... path) { + return param("path", StringJoin.join('|', path)); + } + + /** + * A list of place ID/s representing one or more road segments. + * + * @param placeIds the place ID/s + * @return a {@code SpeedLimitsApiRequest} for call chaining. + */ + public SpeedLimitsApiRequest placeIds(String... placeIds) { + for (String placeId : placeIds) { + paramAddToList("placeId", placeId); + } + return this; + } +} diff --git a/src/main/java/com/google/maps/model/SnappedSpeedLimitResponse.java b/src/main/java/com/google/maps/model/SnappedSpeedLimitResult.java similarity index 95% rename from src/main/java/com/google/maps/model/SnappedSpeedLimitResponse.java rename to src/main/java/com/google/maps/model/SnappedSpeedLimitResult.java index d82dc00ad..067f56712 100644 --- a/src/main/java/com/google/maps/model/SnappedSpeedLimitResponse.java +++ b/src/main/java/com/google/maps/model/SnappedSpeedLimitResult.java @@ -18,7 +18,7 @@ import java.io.Serializable; /** A combined snap-to-roads and speed limit response. */ -public class SnappedSpeedLimitResponse implements Serializable { +public class SnappedSpeedLimitResult implements Serializable { private static final long serialVersionUID = 1L; diff --git a/src/test/java/com/google/maps/RoadsApiIntegrationTest.java b/src/test/java/com/google/maps/RoadsApiIntegrationTest.java index b9c975293..ea596a494 100644 --- a/src/test/java/com/google/maps/RoadsApiIntegrationTest.java +++ b/src/test/java/com/google/maps/RoadsApiIntegrationTest.java @@ -23,7 +23,7 @@ import com.google.maps.model.LatLng; import com.google.maps.model.SnappedPoint; -import com.google.maps.model.SnappedSpeedLimitResponse; +import com.google.maps.model.SnappedSpeedLimitResult; import com.google.maps.model.SpeedLimit; import java.util.Arrays; import org.junit.Test; @@ -86,7 +86,8 @@ public void testSpeedLimitsWithLatLngs() throws Exception { new LatLng(-33.867841, 151.194137), new LatLng(-33.868224, 151.194116) }; - SpeedLimit[] speeds = RoadsApi.speedLimits(sc.context, path).await(); + SpeedLimitsApiRequest request = RoadsApi.speedLimits(sc.context, path); + SpeedLimit[] speeds = request.await().speedLimits; assertNotNull(Arrays.toString(speeds)); assertEquals("/v1/speedLimits", sc.path()); @@ -113,7 +114,7 @@ public void testSpeedLimitsWithUsaLatLngs() throws Exception { new LatLng(33.773250, -84.388840), new LatLng(33.771991, -84.388840) }; - SpeedLimit[] speeds = RoadsApi.speedLimits(sc.context, path).await(); + SpeedLimit[] speeds = RoadsApi.speedLimits(sc.context, path).await().speedLimits; assertNotNull(Arrays.toString(speeds)); assertEquals("/v1/speedLimits", sc.path()); @@ -136,7 +137,7 @@ public void testSpeedLimitsWithPlaceIds() throws Exception { "ChIJyU-E2mEE9YgRftyNXxcfQYw", "ChIJc0BrC2EE9YgR71DvaFzNgrA" }; - SpeedLimit[] speeds = RoadsApi.speedLimits(sc.context, placeIds).await(); + SpeedLimit[] speeds = RoadsApi.speedLimits(sc.context, placeIds).await().speedLimits; assertNotNull(Arrays.toString(speeds)); assertEquals("/v1/speedLimits", sc.path()); @@ -162,7 +163,7 @@ public void testSnappedSpeedLimitRequest() throws Exception { new LatLng(-33.867841, 151.194137), new LatLng(-33.868224, 151.194116) }; - SnappedSpeedLimitResponse response = RoadsApi.snappedSpeedLimits(sc.context, path).await(); + SnappedSpeedLimitResult response = RoadsApi.speedLimits(sc.context, path).await(); assertNotNull(response.toString()); assertEquals("/v1/speedLimits", sc.path());