@googlemaps/google-maps-services-js
Version:
Node.js client library for Google Maps API Web Services
231 lines (220 loc) • 11.4 kB
text/typescript
/**
* Copyright 2020 Google LLC
*
* 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.
*/
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import {
DirectionsRoute,
GeocodedWaypoint,
Language,
LatLng,
RequestParams,
ResponseData,
TrafficModel,
TransitMode,
TransitRoutingPreference,
TravelMode,
TravelRestriction,
UnitSystem,
} from "./common";
import { latLngToString, serializer, toTimestamp } from "./serialize";
import { defaultAxiosInstance } from "./client";
export interface DirectionsRequest extends Partial<AxiosRequestConfig> {
params: {
/**
* The address, textual latitude/longitude value, or place ID from which you wish to calculate directions.
* - If you pass an address, the Directions service geocodes the string and converts it to a latitude/longitude coordinate
* to calculate directions. This coordinate may be different from that returned by the Geocoding API, for example a building
* entrance rather than its center.
*
* `origin=24+Sussex+Drive+Ottawa+ON`
*
* - If you pass coordinates, they are used unchanged to calculate directions. Ensure that no space exists between the latitude
* and longitude values.
*
* `origin=41.43206,-81.38992`
*
* - Place IDs must be prefixed with `place_id:`. The place ID may only be specified if the request includes an API key or a
* Google Maps APIs Premium Plan client ID. You can retrieve place IDs from the Geocoding API and the Places SDK
* (including Place Autocomplete). For an example using place IDs from Place Autocomplete, see [Place Autocomplete and
* Directions](https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-directions).
*
* `origin=place_id:ChIJ3S-JXmauEmsRUcIaWtf4MzE`
*/
origin: LatLng;
/**
* The address, textual latitude/longitude value, or place ID to which you wish to calculate directions.
* The options for the `destination` parameter are the same as for the `origin` parameter, described above
*/
destination: LatLng;
/**
* Specifies the mode of transport to use when calculating directions
*
* @default TravelMode.driving
*/
mode?: TravelMode;
/**
* Specifies an array of waypoints.
* Waypoints alter a route by routing it through the specified location(s).
* A waypoint is specified as a latitude/longitude coordinate, an encoded polyline, a place ID, or an address which will be geocoded.
* Encoded polylines must be prefixed with `enc:` and followed by a colon (`:`). Place IDs must be prefixed with `place_id:`.
* The place ID may only be specified if the request includes an API key or a Google Maps APIs Premium Plan client ID.
* Waypoints are only supported for driving, walking and bicycling directions.
*/
waypoints?: (string | LatLng)[];
/**
* 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.
*/
alternatives?: boolean;
/** Indicates that the calculated route(s) should avoid the indicated features. */
avoid?: TravelRestriction[];
/**
* The language in which to return results.
*
* - If `language` is not supplied, the API attempts to use the preferred language as specified in the `Accept-Language` header,
* or the native language of the domain from which the request is sent.
* - The API does its best to provide a street address that is readable for both the user and locals. To achieve that goal,
* it returns street addresses in the local language, transliterated to a script readable by the user if necessary,
* observing the preferred language. All other addresses are returned in the preferred language.
* Address components are all returned in the same language, which is chosen from the first component.
* - If a name is not available in the preferred language, the API uses the closest match.
* - The preferred language has a small influence on the set of results that the API chooses to return,
* and the order in which they are returned. The geocoder interprets abbreviations differently depending on language,
* such as the abbreviations for street types, or synonyms that may be valid in one language but not in another.
* For example, utca and tér are synonyms for street in Hungarian.
*/
language?: Language;
/** Specifies the unit system to use when displaying results. */
units?: UnitSystem;
/** Specifies the region code, specified as a ccTLD ("top-level domain") two-character value. */
region?: string;
/**
* Specifies the desired time of arrival for transit directions, in seconds since midnight, January 1, 1970 UTC.
* You can specify either `departure_time` or `arrival_time`, but not both.
* Note that `arrival_time` must be specified as an integer.
*/
arrival_time?: Date | number;
/**
* Specifies the desired time of departure. You can specify the time as an integer in seconds since midnight, January 1, 1970 UTC.
* Alternatively, you can specify a value of `now`, which sets the departure time to the current time (correct to the nearest second).
*
* The departure time may be specified in two cases:
* - For requests where the travel mode is transit: You can optionally specify one of `departure_time` or `arrival_time`.
* If neither time is specified, the `departure_time` defaults to now (that is, the departure time defaults to the current time).
* - For requests where the travel mode is driving: You can specify the `departure_time` to receive a route and trip duration
* (response field: `duration_in_traffic`) that take traffic conditions into account.
* This option is only available if the request contains a valid API key, or a valid Google Maps APIs Premium Plan client ID
* and signature. The `departure_time` must be set to the current time or some time in the future. It cannot be in the past.
*/
departure_time?: Date | number | "now";
/**
* Specifies the assumptions to use when calculating time in traffic.
* This setting affects the value returned in the `duration_in_traffic` field in the response, which contains the predicted time
* in traffic based on historical averages. The `traffic_model` parameter may only be specified for driving directions
* where the request includes a `departure_time`, and only if the request includes an API key or a Google Maps APIs Premium Plan client ID.
*
* The default value of `best_guess` will give the most useful predictions for the vast majority of use cases.
* It is possible the `best_guess` travel time prediction may be *shorter* than `optimistic`, or alternatively,
* *longer* than `pessimistic`, due to the way the `best_guess` prediction model integrates live traffic information.
*
* @default TrafficModel.best_guess
*/
traffic_model?: TrafficModel;
/**
* Specifies one or more preferred modes of transit.
* This parameter may only be specified for transit directions, and only if the request includes an API key or
* a Google Maps APIs Premium Plan client ID.
*/
transit_mode?: TransitMode[];
/**
* Specifies preferences for transit routes.
* Using this parameter, you can bias the options returned, rather than accepting the default best route chosen by the API.
* This parameter may only be specified for transit directions, and only if the request includes an API key or
* a Google Maps APIs Premium Plan client ID.
*/
transit_routing_preference?: TransitRoutingPreference;
/** Wherever to optimize the provided route by rearranging the waypoints in a more efficient order. */
optimize?: boolean;
} & RequestParams;
}
export interface DirectionsResponseData extends ResponseData {
/**
* contains an array with details about the geocoding of origin, destination and waypoints.
*
* These details will not be present for waypoints specified as textual latitude/longitude values if the service returns no results.
* This is because such waypoints are only reverse geocoded to obtain their representative address after a route has been found.
* An empty JSON object will occupy the corresponding places in the `geocoded_waypoints` array.
*/
geocoded_waypoints: GeocodedWaypoint[];
/**
* contains an array of routes from the origin to the destination.
*
* When the Directions API returns results, it places them within a (JSON) `routes` array. Even if the service returns no results
* (such as if the origin and/or destination doesn't exist) it still returns an empty `routes` array.
* (XML responses consist of zero or more `<route>` elements.)
*
* Each element of the `routes` array contains a single result from the specified origin and destination.
* This route may consist of one or more `legs` depending on whether any waypoints were specified.
* As well, the route also contains copyright and warning information which must be displayed to the user in addition to the
* routing information.
*/
routes: DirectionsRoute[];
/**
* contains an array of available travel modes. This field is returned when a request specifies a travel `mode` and gets no results.
* The array contains the available travel modes in the countries of the given set of waypoints.
* This field is not returned if one or more of the waypoints are `via:` waypoints.
*/
available_travel_modes: string[];
}
export interface DirectionsResponse extends AxiosResponse {
data: DirectionsResponseData;
}
export const defaultUrl =
"https://maps.googleapis.com/maps/api/directions/json";
export const defaultParamsSerializer = serializer(
{
origin: latLngToString,
destination: latLngToString,
waypoints: (o) => o.map(latLngToString),
arrival_time: toTimestamp,
departure_time: toTimestamp,
},
defaultUrl
);
export function directions(
{
params,
method = "get",
url = defaultUrl,
paramsSerializer = defaultParamsSerializer,
...config
}: DirectionsRequest,
axiosInstance: AxiosInstance = defaultAxiosInstance
): Promise<DirectionsResponse> {
const { optimize } = params;
// optimize is passed as the first of the waypoint pipe array
// &waypoints=optimize:true|Barossa+Valley,SA|Clare,SA|Connawarra,SA|McLaren+Vale,SA
if (optimize) {
params.waypoints = ["optimize:true", ...params.waypoints];
}
delete params.optimize;
return axiosInstance({
params,
method,
url,
paramsSerializer,
...config,
}) as Promise<DirectionsResponse>;
}