/*
* Copyright 2014 Google Inc. All rights reserved.
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.google.maps;
import static com.google.maps.internal.StringJoin.join;
import com.google.maps.model.DirectionsResult;
import com.google.maps.model.LatLng;
import com.google.maps.model.TrafficModel;
import com.google.maps.model.TransitMode;
import com.google.maps.model.TransitRoutingPreference;
import com.google.maps.model.TravelMode;
import com.google.maps.model.Unit;
import org.joda.time.ReadableInstant;
/**
* Request for the Directions API.
*/
public class DirectionsApiRequest
extends PendingResultBase<DirectionsResult, DirectionsApiRequest, DirectionsApi.Response> {
DirectionsApiRequest(GeoApiContext context) {
super(context, DirectionsApi.API_CONFIG, DirectionsApi.Response.class);
}
protected boolean optimizeWaypoints;
protected String[] waypoints;
@Override
protected void validateRequest() {
if (!params().containsKey("origin")) {
throw new IllegalArgumentException("Request must contain 'origin'");
}
if (!params().containsKey("destination")) {
throw new IllegalArgumentException("Request must contain 'destination'");
}
if (TravelMode.TRANSIT.toString().equals(params().get("mode"))
&& (params().containsKey("arrival_time") && params().containsKey("departure_time"))) {
throw new IllegalArgumentException(
"Transit request must not contain both a departureTime and an arrivalTime");
}
if (params().containsKey("traffic_model") && !params().containsKey("departure_time")) {
throw new IllegalArgumentException("Specifying a traffic model requires that departure time"
+ " be provided.");
}
}
/**
* The address or textual latitude/longitude value from which you wish to calculate directions. If
* you pass an address as a string, the Directions service will geocode the string and convert it
* to a latitude/longitude coordinate to calculate directions. If you pass coordinates, ensure
* that no space exists between the latitude and longitude values.
*/
public DirectionsApiRequest origin(String origin) {
return param("origin", origin);
}
/**
* The address or textual latitude/longitude value from which you wish to calculate directions. If
* you pass an address as a string, the Directions service will geocode the string and convert it
* to a latitude/longitude coordinate to calculate directions. If you pass coordinates, ensure
* that no space exists between the latitude and longitude values.
*/
public DirectionsApiRequest destination(String destination) {
return param("destination", destination);
}
/**
* The origin, as a latitude,longitude location.
*/
public DirectionsApiRequest origin(LatLng origin) {
return origin(origin.toString());
}
/**
* The destination, as a latitude,longitude location.
*/
public DirectionsApiRequest destination(LatLng destination) {
return destination(destination.toString());
}
/**
* Specifies the mode of transport to use when calculating directions. The mode defaults to
* driving if left unspecified. If you set the mode to {@code TRANSIT} you must also specify
* either a {@code departureTime} or an {@code arrivalTime}.
*
* @param mode The travel mode to request directions for.
*/
public DirectionsApiRequest mode(TravelMode mode) {
return param("mode", mode);
}
/**
* Indicates that the calculated route(s) should avoid the indicated features.
*
* @param restrictions one or more of {@link DirectionsApi.RouteRestriction#TOLLS}, {@link
* DirectionsApi.RouteRestriction#HIGHWAYS}, {@link DirectionsApi.RouteRestriction#FERRIES}
*/
public DirectionsApiRequest avoid(DirectionsApi.RouteRestriction... restrictions) {
return param("avoid", join('|', restrictions));
}
/**
* Specifies the unit system to use when displaying results.
*/
public DirectionsApiRequest units(Unit units) {
return param("units", units);
}
/**
* @param region The region code, specified as a ccTLD ("top-level domain") two-character value.
*/
public DirectionsApiRequest region(String region) {
return param("region", region);
}
/**
* Set the arrival time for a Transit directions request.
*
* @param time The arrival time to calculate directions for.
*/
public DirectionsApiRequest arrivalTime(ReadableInstant time) {
return param("arrival_time", Long.toString(time.getMillis() / 1000L));
}
/**
* Set the departure time for a transit or driving directions request. If both departure time and
* traffic model are not provided, then "now" is assumed. If traffic model is supplied, then
* departure time must be specified.
*
* @param time The departure time to calculate directions for.
*/
public DirectionsApiRequest departureTime(ReadableInstant time) {
return param("departure_time", Long.toString(time.getMillis() / 1000L));
}
/**
* Specifies a list of waypoints. Waypoints alter a route by routing it through the specified
* location(s). A waypoint is specified as either a latitude/longitude coordinate or as an address
* which will be geocoded. Waypoints are only supported for driving, walking and bicycling
* directions.
*
* <p>For more information on waypoints, see <a href="https://developers.google.com/maps/documentation/directions/intro#Waypoints">
* Using Waypoints in Routes</a>.
*/
public DirectionsApiRequest waypoints(String... waypoints) {
this.waypoints = waypoints;
if (waypoints == null || waypoints.length == 0) {
return this;
} else if (waypoints.length == 1) {
return param("waypoints", waypoints[0]);
} else {
return param("waypoints", (optimizeWaypoints ? "optimize:true|" : "") + join('|', waypoints));
}
}
/**
* The list of waypoints as latitude,longitude locations.
*/
public DirectionsApiRequest waypoints(LatLng... waypoints) {
if (waypoints == null) {
return this;
}
int length = waypoints.length;
String[] waypointStrings = new String[length];
for (int i = 0; i < length; i++) {
waypointStrings[i] = waypoints[i].toString();
}
return waypoints(waypointStrings);
}
/**
* Allow the Directions service to optimize the provided route by rearranging the waypoints in a
* more efficient order.
*/
public DirectionsApiRequest optimizeWaypoints(boolean optimize) {
optimizeWaypoints = optimize;
if (waypoints != null) {
return waypoints(waypoints);
} else {
return this;
}
}
/**
* If set to true, specifies that the Directions service may provide more than one route
* alternative in the response. Note that providing route alternatives may increase the response
* time from the server.
*/
public DirectionsApiRequest alternatives(boolean alternateRoutes) {
if (alternateRoutes) {
return param("alternatives", "true");
} else {
return param("alternatives", "false");
}
}
/**
* Specifies one or more preferred modes of transit. This parameter may only be specified for
* requests where the mode is transit.
*/
public DirectionsApiRequest transitMode(TransitMode... transitModes) {
return param("transit_mode", join('|', transitModes));
}
/**
* Specifies preferences for transit requests. Using this parameter, you can bias the options
* returned, rather than accepting the default best route chosen by the API.
*/
public DirectionsApiRequest transitRoutingPreference(TransitRoutingPreference pref) {
return param("transit_routing_preference", pref);
}
/**
* Specifies the traffic model to use when requesting future driving directions. Once set, you
* must specify a departure time.
*/
public DirectionsApiRequest trafficModel(TrafficModel trafficModel) {
return param("traffic_model", trafficModel);
}
}