Routing and ETA: Anatomy of a Trip
Learn how to work with the TomTom Routing API, using a little JavaScript, to deliver ETA. We’ll look at how different options and time of day change how the ETA is calculated, using two simple applications: ride-hailing services and package delivery.
When plotting a route, the time it takes to get somewhere is usually the most important consideration.
Whether you are organizing fleet logistics, calculating product delivery routes, or ensuring your customers arrive at their appointments on time, accurately estimating travel time to arrival is essential.
Drivers tend to stick to their usual, familiar routes, but they might be better off taking a different, faster route. Road conditions and accidents can affect their travel time at any time of day. TomTom calculates the estimated time of arrival (ETA) from all known conditions to help your drivers choose the best route. Powered by unmatched traffic data, TomTom ETAs reliably calculate optimal routes.
Once a route is selected, the ETA can update constantly in response to the driver’s progress. Accidents, road closures, and even the type of roads available will change the predicted ETA — and there are many reasons why drivers might end up taking different turns along the way.
TomTom’s Routing API pulls together information about all these factors, as well as the known speed limits for each road. It can even factor in situational preferences, such as avoiding left turns, highways, or one way roads. Its unique smart routing algorithm provides the ETA for each route within a summary output, giving the developer — and the user — the data they need to plan the optimal route.
Even better, TomTom takes privacy seriously. If you use TomTom APIs and SDKs in your application you can rest assured that TomTom is GDPR compliant and never shares user information with third parties for commercial use.
Let’s dive into this with some examples of how to work with the TomTom Routing API, using a little JavaScript, to deliver ETA. We’ll look at how different options and time of day change how the ETA is calculated, using two simple applications: ride-hailing services and package delivery.
Table of Contents:Working DemosRide-Hailing ServicesPackage Delivery[Working Demos]
To try the Routing API for yourself, you need a TomTom developer account, granting you access to the API, API Explorer, and existing examples to play with. If you don't already have an account, register one first, then log in and we’ll get started.
Setup:
Register or log in to a TomTom developer account.
Get a unique TomTom API key that allows you to use the SDK.
To explore examples of how to set up your demo app, check out these articles:
In real life, your client program would not be doing much of the processing. Instead, it makes calls to the server, and the server returns data that can then be ordered and displayed using the Maps SDK and HTML5. That is the type of API access we will focus on, though we demonstrate both application and server side variations.
We recommend using a JavaScript and Node server to process these calls directly from the API. This also has the benefit of hiding your primary API key.
Our setup consists of a basic Node REST server with Axios for TomTom calls. Ideally, you’d get the route start and end from a call to your application API, but we’ll use fixed coordinates to make things a bit easier. For visuals, we use a small demo app to show the difference between direct API and web calls, running on a Node Express server with Browsersync.
[Ride-Hailing Services]
Let’s consider the case of a taxi or independent driver.
Using a car on the road as a starting point for our routes, our driver’s initial coordinates are:
{ 32.71897,-96.75822 }
This is on the south edge of Charlotte, North Carolina, a city we chose at random.
We use these coordinates — along with the passenger’s coordinates — to generate a route and calculate the ETA. A direct API endpoint call looks something like this, from the command line:
curl -X GET "https://api.tomtom.com/routing/1/calculateRoute/32.71897%2C-96.75822%3A32.77752%2C-96.60824/xml?avoid=unpavedRoads&key=*****" -H "accept: */*"
Of course, it would be inefficient (and dangerous) to access the API manually while driving. Our driver instead has an application that automatically submits their location to our API server, which then calculates the routes.
The app developer can set options to save time, or prefer certain routes on this server. The request made by the application can also send options in its format, and should at least include the user’s coordinates, or their current address. If it’s an address, it converts to GPS coordinates through geolocation.
A server-side API call looks more like this:
app.get('/route', (req, res) => {
let coordGroupOneLocation = "32.720141" + "," + "-96.758121";
let coordGroupOneDestination = "32.77752" + "," + "-96.60824";
let routeOne = coordGroupOneLocation + ":" + coordGroupOneDestination;
// Options //
let traffic = true;
let commercial = false;
let routeType = "shortest";
let avoidRoads = "unpavedRoads";
let outputFull = false;
let travelTime = "all";
let currentRoute = routeOne;
let APICall = "https://api.tomtom.com/routing/1/calculateRoute/"
+ currentRoute +"/json?routeType="
+ routeType + "&traffic=" + traffic
+ "&avoid="+ avoidRoads
+ "&computeTravelTimeFor=" + travelTime
+ "&vehicleCommercial=" + commercial
+"&key=" + APIKey;
axios.get(APICall)
.then(response => {
let output = JSON.parse(JSON.stringify(response.data));
if (!outputFull)
{
res.status(200).json(output['routes'][0].summary);
} else {
res.status(200).json(output['routes'][0]);
}
}).catch(error => {
res.send("Error: " + error);
});
});
On the application side, if you did not send it to a server, the route call might look like this instead:
if (!this.state.start || !this.state.finish) {
return;
}
var startPos = this.state.start.join(',');
var finalPos = this.state.finish.join(',');
var combinedAddress = startPos + ':' + finalPos;
let options = {
key: window.config.apiKey,
traffic: this.flowChecked,
locations: combinedAddress
}
tt.services.calculateRoute(options).then(function(response) {
let summary = response.routes[0].summary;
this.getETA = (summary.travelTimeInSeconds / 60);
this.outputETA.innerHTML = "ETA: " + this.getETA.toFixed(2) + " minutes.";
var geojson = response.toGeoJson();
this.map.addLayer({
'id': 'route',
'type': 'line',
'source': {
'type': 'geojson',
'data': geojson
},
'paint': {
'line-color': '#2faaff',
'line-width': 8
}
}, this.findFirstBuildingLayerId());
var coordinates = geojson.features[0].geometry.coordinates;
this.updateRoutesBounds(coordinates);
}.bind(this))
.catch(this.handleError.bind(this));
Both versions give you a route, which includes a summary:
"summary": {
"lengthInMeters": 20639,
"travelTimeInSeconds": 1680,
"trafficDelayInSeconds": 0,
"departureTime": "2021-02-27T06:34:16-06:00",
"arrivalTime": "2021-02-27T07:02:15-06:00"
}
The Routing API delivers a travel and arrival time (in seconds and date, respectively), which can equally serve as an ETA in the summary, alongside the leg information for the route itself. We’ll primarily use the travelTimeInSeconds data point.
Converting the travel time into minutes gives us roughly 20 minutes, which can be updated as the driver travels to the waiting passenger.
What happens if the driver misses a turn or cannot take the exact route? That changes the ETA, and the arrival time can be updated accordingly.
When the trip is arranged at a different time of day, it’s likely that traffic conditions will not be the same. Let’s take a look at that and take traffic into consideration. The original coordinates can be used here, so let’s use the “departAt” option in the API call. Logically, when setting “departAt”, the “arriveAt” option cannot be set, as these variables are calculated based on one another.
The app delivers another route and summary:
"summary": {
"lengthInMeters": 20639,
"travelTimeInSeconds": 1783,
"trafficDelayInSeconds": 0,
"departureTime": "2021-02-27T13:05:41-06:00",
"arrivalTime": "2021-02-27T13:35:23-06:00"
}
We have calculated a new route that accounts for the time, factoring in probable traffic conditions. Although there is no report of a specific delay, the flow of traffic has changed and so a different route has been selected. With the new optimized route, the ETA is still roughly 20 minutes.
[Package Delivery]
For one more demo, we look at delivering packages to a customer within a set amount of time on a completely different route. We use the “arriveAt” query option, which lets you set a predicted arrival time.
Times for the Routing API are in the ISOString format and can be generated using the system clock or date object in JavaScript.
Let’s change up the city and set the starting point to Sacramento, California. Our driver is taking a package from one place to another within a set amount of time. Our starting coordinates are:
{ 38.52491, -121.46051 }
We’ll be making a delivery to { 38.646156,-121.343628 }, and we want to get there within 20 minutes. This should be doable, presuming there isn’t much traffic. To get some extra data, we’ll set the “computeTravelTimeFor” option to “all”, which returns information such as historic and live travel times. The “routeType” option will also be set to “shortest”, and we’ll tell the Routing API the vehicle is a commercial vehicle, so we can avoid routes unsuitable for commercial travel:
let coordGroupTwoLocation = "38.524854" + "," + "-121.472144";
let coordGroupTwoDestination = "38.584340" + "," + "-121.490333";
let currentRoute = coordGroupTwoLocation + ":" + coordGroupTwoDestination;
let arriveAt = time(20).toISOString();
let APICallWithArrive = "https://api.tomtom.com/routing/1/calculateRoute/"
+ currentRoute
+"/json?routeType=" + "shortest"
+ "&traffic=" + traffic
+ "&vehicleCommercial=" + true
+ "&computeTravelTimeFor=" + "all"
+ "&arriveAt="+ arriveAt
+ "&key=" + APIKey;
The estimated travel time here is 1016 seconds, or approximately 16 minutes. This is our default output. However, including the “computeTravelTimeFor” option on “all” delivers additional traffic data. The TomTom algorithm takes your arriveAt ETA requirement into account. This summary gives you an estimate for how long the journey would take with no traffic (905 seconds or 15 minutes) as well as historic and live data.
"summary": {
"lengthInMeters": 20859,
"travelTimeInSeconds": 1016,
"trafficDelayInSeconds": 0,
"departureTime": "2021-02-15T10:21:53-08:00",
"arrivalTime": "2021-02-15T10:38:49-08:00",
"noTrafficTravelTimeInSeconds": 905,
"historicTrafficTravelTimeInSeconds": 1016,
"liveTrafficIncidentsTravelTimeInSeconds": 1016
}
Just like in the passenger example, the ETA is useful to the customer while the route and traffic information is useful to the driver. The customer’s application could show them exactly how long until their delivery arrives!
Next Steps
No matter your route preferences, TomTom will always calculate optimal routes with reliable ETAs. The estimated time of arrival is useful to everyone — including businesses, drivers, passengers, and even delivery recipients.
With a little setup and a small server handling the requests, TomTom’s smart routing algorithm gives your users the information they need to find a route with the best ETA. Now that you know how the Routing API works, you can incorporate it into your ridesharing or delivery app, or any other app where you need to provide an ETA.
The Routing API pulls information from TomTom’s award-winning traffic data. Powered by more than 600 million connected devices, the TomTom Traffic Index provides insights into traffic flow and interruptions across the world.
Ready to take advantage of TomTom’s advanced ETA calculations? Become a TomTom developer to create your own routes and connect with us in our Developer Forum for any questions you may have as you get building.
Want to learn more about ETA? Check out these related articles:
- Understanding how the TomTom Routing API Provides Accurate ETAs
- Leverage Routing, Geofencing, and Notifications APIs to Send ETA Alerts
- How to Use the TomTom Routing API for Estimated Time of Arrival
Happy mapping!