Google ODRD: Routes Preferred ComputeRoutes API
The first Google Mobility API we'll look at is Routes Preferred which is actually two separate APIs - ComputeRoutes, which we will look at in detail here and ComputeRouteMatrix, which we will touch on in the next post.
Part 1: Google Mobility: An introduction to Google ODRD, LMFS and Cloud Fleet Routing APIs
Part 2: Google ODRD: Routes Preferred ComputeRoutes API (this article)
Part 3: Google LMFS: Routes Preferred ComputeRouteMatrix API
Part 4: Google Cloud Fleet Routing: OptimizeTours API
Part 5: Google ODRD: Navigation SDK
Think of ComputeRoutes as an enhanced version of the Google Directions API. Like the Directions API, it calculates the best route from a start point to an end point, including any waypoints along the way. However, ComputeRoutes offers numerous performance enhancements compared to Directions. It's typically faster, provides more precise estimated times of arrival (ETAs), and employs field masks (through the X-Goog-FieldMask
header) to reduces latency by allowing you to specify which fields you want the API to return.
Initially bundled with On Demand Rides and Deliveries (ODRD), the ComputeRoutes API can now be used on its own or in combination with other Google Mobility APIs.
ODRD / Routes Preferred ComputeRoutes example
We'll start with a simple example of a point to point route from East Vancouver (circle marker) to Vancouver Airport (stop 1).
Endpoint POST
https://routespreferred.googleapis.com/v1:computeRoutes
Headers
Content-Type: application/json
X-Goog-Api-Key: YOUR_API_KEY (contact a Google Maps Partner for access)
X-Goog-FieldMask: routes.duration, routes.distanceMeters, routes.polyline
Body
{
"origin": {
"location": {
"latLng": {
"latitude": 49.2806962,
"longitude": -123.0828679
}
}
},
"destination": {
"location": {
"latLng": {
"latitude": 49.1951165,
"longitude": -123.1814231
}
}
},
"travelMode": "DRIVE",
"polylineQuality": "OVERVIEW",
"departureTime": "2023-09-25T15:00:00Z"
}
origin.location.latLng
are the coordinates of the route's start location.
destination.location.latLng
are the coordinates of the route's end location.
travelMode
refers to the mode of transport ("DRIVE", "WALK", "TRANSIT" or "BICYCLE"). Different modes use different routes (e.g. choosing "BICYCLE" means that the route chosen will prioritize bike paths), have different travel speeds and as such, result in different ETAs.
routingPreference
offers three choices: "TRAFFIC_UNAWARE," "TRAFFIC_AWARE," and "TRAFFIC_AWARE_OPTIMAL." When you select "TRAFFIC_AWARE," the routing algorithm factors in real-time traffic conditions when calculating routes. On the other hand, "TRAFFIC_AWARE_OPTIMAL" also considers traffic but prioritizes speed over absolute precision, resulting in faster route calculations (although slightly less accuracy) due to certain optimizations designed to reduce latency. If you opt for "TRAFFIC_UNAWARE," the routing relies solely on posted speed limits, which means this option is suitable for deliveries in rural areas or cities where traffic congestion is rarely an issue.
polylineQuality
lets you specify the resolution of the encoded polyline e.g. " used to draw the route on a map."HIGH_QUALITY" returns a polyline with a large number of points at the expense of speed while "OVERVIEW" returns one with less points but is much faster. Generally speaking, if you are just drawing the route on a static map and not allowing the user to zoom in, the "OVERVIEW" option works just fine. You can use Google's polyline decoding tool to view the encoded polyline string on the map.
departureTime
, when combined with routingPreference
: "TRAFFIC_AWARE", is probably the single most important field in the input. It allows you to specify the start time of the route as a datetime string in RFC3339 UTC "Zulu" format e.g. "2023-09-25T15:00:00Z" so that the travel time duration
returned by the API takes predicted "real time" traffic into account. The "Z" in the string stands for "Zulu" (GMT +0). Since our route is in Vancouver which is on Pacific Standard Time (GMT +7), "2023-09-25T15:00:00Z" resolves to 8 am on 25th September, 2023.
Note: If departureTime
is left empty, it defaults to the time that the request was made. Also, if you set this value to a time in the past, then the request fails.
The above API call returns the following:
Output
{
"routes": [
{
"distanceMeters": 16797,
"duration": "1802s",
"polyline": {
"encodedPolyline": "ecxkH|rfnV?sAfARl@TpBpAz@Rh@F`CHr@ClCDBgChBBJo`@hSHjNJf@Bb@JhELnD@tAKPIzPJtGHPHvNRhGIdIB~@Yj@g@R[Vm@h@}A\\k@j@e@r@Qn@ChUZlD@tF@|@F`HNxCBpFFVMd`@ZRNxIDvBL^FNGdEp@bBLxCJ~E@nIJZP`FHCzH?jFFTSrn@Kb@GtOEjOFj@Ol^Gb@S~Y?lDi@~j@IdGMrGUfQbEJtOPvSRjBHh\\d@ra@f@rMPxQ\\LBt@EzCxIPVxB~GFl@nB`GbDrKxDpLnCdJj@|Bj@lBfApCb@xA\\nBNRz@xCzB`Hj@vAj@`AbAfAt@h@xAh@zBp@LJbG~A`PvElAj@v@f@pAxA`A|Ax@pBh@lBJd@`AhIxC|XxBvTz@zHNjBNnDTtETlHBrBBvLEny@EtXGpBSdCQbAk@vBi@xAmCfGWhAe@nGa@vH@tBN`Cd@~CPb@DF"
}
}
]
}
The response from the API is simple enough to understand. routes
contains a single object with distanceMeters
, the total distance travelled, duration
, the total time in seconds taken to complete the route (the ETA at the end point is simply the start time (2023-09-25T15:00:00Z is 08:00:00 Vancouver time which when added to the 1802 seconds duration
, which gives you an ETA of 08:30:02).
Finally, the encoded polyline from the polyline.encodedPolyline
field can be used with the Google Maps Geometry Library to draw the route on a map like so:
Drawing the route polyline on Google Maps
Starting with a basic HTML template with a map <div/>, import the Geometry library.
/* routeMap.html */
<html>
<head>
<title>Draw Route</title>
<script src="https://maps.googleapis.com/maps/api/js?key=GOOGLE_API_KEY&v=3.exp&libraries=geometry&callback=Function.prototype"></script>
</head>
<body>
<div id="map" style="height: 600px; width: 100%;"></div>
</body>
</html>
Next, inside a script tag next to the map <div/>, create a Google base map and center it at the desired location. The code below calls initMap()
to create the map and bind it to a div with "map" as its ID.
/* routeMap.html */
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 49.2578182,
lng: -123.206304
},
zoom: 12 // Adjust the zoom level as needed
});
}
initMap();
</script>
Add two markers, one for the origin and the other for the destination. This code should be added after the call to initMap()
.
/* routeMap.html */
<script>
var startMarker = new google.maps.Marker({
position: {
lat: 49.2806962,
lng: -123.0828679
},
map: map,
title: 'Start'
});
var endMarker = new google.maps.Marker({
position: {
lat: 49.1951165,
lng: -123.1814231
},
map: map,
title: 'End'
});
</script>
Lastly, decode the polyline string, style it, and add it to the map.
/* routeMap.html */
<script>
var decodedPath = google.maps.geometry.encoding.decodePath("ecxkH|rfnV?sAfARl@TpBpAz@Rh@F`CHr@ClCDBgChBBJo`@hSHjNJf@Bb@JhELnD@tAKPIzPJtGHPHvNRhGIdIB~@Yj@g@R[Vm@h@}A\\k@j@e@r@Qn@ChUZlD@tF@|@F`HNxCBpFFVMd`@ZRNxIDvBL^FNGdEp@bBLxCJ~E@nIJZP`FHCzH?jFFTSrn@Kb@GtOEjOFj@Ol^Gb@S~Y?lDi@~j@IdGMrGUfQbEJtOPvSRjBHh\\d@ra@f@rMPxQ\\LBt@EzCxIPVxB~GFl@nB`GbDrKxDpLnCdJj@|Bj@lBfApCb@xA\\nBNRz@xCzB`Hj@vAj@`AbAfAt@h@xAh@zBp@LJbG~A`PvElAj@v@f@pAxA`A|Ax@pBh@lBJd@`AhIxC|XxBvTz@zHNjBNnDTtETlHBrBBvLEny@EtXGpBSdCQbAk@vBi@xAmCfGWhAe@nGa@vH@tBN`Cd@~CPb@DF");
var polyline = new google.maps.Polyline({
path: decodedPath,
geodesic: true,
strokeColor: '#4285F4', // Adjust the color as needed
strokeOpacity: 0.9,
strokeWeight: 3 // Adjust the line thickness as needed
});
polyline.setMap(map);
</script>
If everything worked correctly you should see the route clearly displayed on the map, with a marker at the start and end locations (full source code).
This concludes my introduction to the Routes Preferred ComputeRoutes API. In the next post, we'll look at another popular Routes Preferred API, ComputeRouteMatrix, which is used to generate travel time matrices with real time traffic.
👋 As always, if you have any questions or suggestions for me, please reach out or say hello on LinkedIn.
Next: Part 3: Google LMFS: Routes Preferred ComputeRouteMatrix API