Sorry, you need to enable JavaScript to visit this website.

Turning Location Data Points into Information About Your Fleet

Fleet Visibility With TomTom Maps APIs

Modern technology can provide us with a wealth of data about the location of vehicles and their states, but sometimes the path between those data points and the useful and actionable information isn’t easy to find. In this article, I’m going to introduce you to some of the APIs available from TomTom and demonstrate how you can leverage them to turn location data points into actionable information about your fleet.

We’ll look at some examples to determine the location of a specific vehicle in an understandable human form and then identify the route the vehicle followed to get there. Finally, we’ll investigate how to find out additional information about the route, and even identify if the vehicle violated speed limits while completing the route.

I’ll be sharing direct API calls to keep this article as coding language-agnostic as possible; however, any modern web language can access these APIs.

This article focuses on how to use the TomTom Search  and Routing APIs, but developers also have access to Web and Mobile SDKs which contain similar functionality. You can learn more about each of the SDKs from the following links:

Fig. 1 Application Details

Each of the examples below includes the phrase ReplaceWithYourAPIKeyHere. You’ll need to replace that phrase with the Consumer API Key from your unique application. Let’s see where our drivers have been taking the corporate vehicles.

Where Are They Now?

The scenario is this: We have a vehicle which is carrying a GPS locator and sending location information to our system in the form of latitude and longitude pairs. For this example, we’ll be working with the following pair of coordinates:

45.512077,-122.627832

Let’s see if we can find the address, and then we’ll see if we can also get the nearest cross street. The base URL is api.tomtom.com, and we’ll be accessing the search API. The current version of this API is 2, and we’re going to be performing a reverse geocoding option.

https://api.tomtom.com/search/2/reverseGeocode/45.512077,-122.627832.json?key=ReplaceWithYourAPIKeyHere

Fig. 2 Example URL for Reverse GeoCoding

If you receive a response similar to the one below, you’ll need to ensure that your API key is entered correctly.

<h1>Developer Inactive</h1>

Fig. 3 Error Received When the API Key is Incorrect

The JSON path parameter indicates that we would like to receive a response in JSON format. If this parameter is omitted, the default format of XML is used. The response from the URL above is shown below.

    {
    "summary":{
       "queryTime":134,
       "numResults":1
    },
    "addresses":[
       {
       "address":{
           "buildingNumber":"3527",
           "streetNumber":"3527",
           "routeNumbers":[],
           "street":"SE Hawthorne Blvd",
           "streetName":"SE Hawthorne Blvd",
           "streetNameAndNumber":"3527 SE Hawthorne Blvd",
           "countryCode":"US",
           "countrySubdivision":"OR",
           "countrySecondarySubdivision":"Multnomah",
           "municipality":"Portland",
           "postalCode":"97214",
           "country":"United States Of America",
           "countryCodeISO3":"USA",
           "freeformAddress":"3527 SE Hawthorne Blvd, Portland, OR 97214",
           "countrySubdivisionName":"Oregon"
       },
         "position":"45.512046,-122.627833"
       }
     ]
    }
    

Fig. 4 Reverse Geocoding Response

All right—I now know that the driver has parked the vehicle at 3527 SE Hawthorne Blvd in downtown Portland. If I’m not mistaken, Blue Star Donuts is right down the street. (I hope they bring a couple back to the office.)

While we wait for the donuts, let’s see if there is a way to get more information about exactly where they are. Hawthorne Blvd is a pretty long road. I’d like to know which cross street they’re closest to.

https://api.tomtom.com/search/2/reverseGeocode/crossStreet/45.512077,-122.627832.json?key=ReplaceWithYourAPIKeyHere

Fig. 5 Example URL for Reverse GeoCoding with Cross Street Information

    {
     "summary": {
       "numResults": 1,
       "queryTime": 209
     },
     "addresses": [
       {
         "address": {
           "streetName": "SE 35th Pl & SE Hawthorne Blvd",
           "crossStreet": "SE 35th Pl",
           "municipalitySubdivision": "Richmond, Portland",
           "municipality": "Portland",
           "countrySecondarySubdivision": "Multnomah",
           "countryTertiarySubdivision": "Portland East",
           "countrySubdivision": "OR",
           "postalCode": "97214",
           "countryCode": "US",
           "country": "United States Of America",
           "countryCodeISO3": "USA",
           "freeformAddress": "SE 35th Pl & SE Hawthorne Blvd, Portland, OR 97214",
           "countrySubdivisionName": "Oregon",
           "street": "SE Hawthorne Blvd"
         },
         "position": "45.51204,-122.62763"
       }
     ]    
    }
    

Fig. 6 Reverse Geocoding Response

The cross street option is especially useful in cases where the address doesn’t yield exact information, or if a precise location is necessary for emergency situations. Let’s see if we can find out more about how they traveled to this exact location.

How Did They Get There?

Our next challenge is to reconstruct the route the vehicle traveled to get from one location to another. We’ll use the Routing API to work this out. If we submit a POST request, we’re able to include a list of supporting points that allow us to reconstruct the route based on where the vehicle traveled. We can also include the start and end time to determine if there were any delays along the way.

We’ll use the following URL and then pass in a JSON body which includes the supporting point and other critical parameters. Here’s the information we know about the driver and the route they took:

  • The driver started at the PDX airport (45.5868227,-122.5937596) and ended up at the Blue Star Donut Shop (45.512077,-122.627832).

  • We have a series of points as pairs of latitude and longitude values, along which the vehicle drove.

https://api.tomtom.com/routing/1/calculateRoute/45.5868227,-122.5937596:45.512077,-122.627832/json?key=ReplaceWithYourAPIKeyHere

Fig. 7 Base URL to Reconstruct Route with Supporting Points

The request body is in JSON format, so we’ll pass along a Content-Type header set to application/json. The body we’ll pass in with the request is shown below. I thinned out the list of supporting points to keep the snippet small.

    {
     "supportingPoints": [
       {
         "latitude": 45.58355,
         "longitude": -122.58545
       },
       {
         "latitude": 45.52641,
         "longitude": -122.61544
       },
       {
         "latitude": 45.51287,
         "longitude": -122.62296
       },
       {
         "latitude": 45.51204,
         "longitude": -122.62782
       }
     ]
    }
    

Fig. 8 Passing a Collection of Supporting Points to Accurately Map the Route

The following response is typical of what you can expect to receive from the Routes API with this request.

    {
     "formatVersion": "0.0.12",
     "copyright": "Copyright 2018 TomTom International BV. ...",
     "privacy": "TomTom keeps information that tells us how ...",
     "routes": [
       {
         "summary": {
           "lengthInMeters": 12201,
           "travelTimeInSeconds": 1479,
           "trafficDelayInSeconds": 0,
           "departureTime": "2018-09-24T23:01:26-07:00",
           "arrivalTime": "2018-09-24T23:26:04-07:00"
         },
         "legs": [
           {
             "summary": {
               "lengthInMeters": 12201,
               "travelTimeInSeconds": 1479,
               "trafficDelayInSeconds": 0,
               "departureTime": "2018-09-24T23:01:26-07:00",
               "arrivalTime": "2018-09-24T23:26:04-07:00"
             },
             "points": [
               {
                 "latitude": 45.58671,
                 "longitude": -122.59387
               },
               {
                 "latitude": 45.58638,
                 "longitude": -122.59324
               },
               //Data points removed to reduce space
               {
                 "latitude": 45.51287,
                 "longitude": -122.62588
               },
               {
                 "latitude": 45.51204,
                 "longitude": -122.62783
               }
             ]
           }
         ],
         "sections": [
           {
             "startPointIndex": 0,
             "endPointIndex": 10,
             "sectionType": "TRAVEL_MODE",
             "travelMode": "other"
           },
           {
             "startPointIndex": 10,
             "endPointIndex": 213,
             "sectionType": "TRAVEL_MODE",
             "travelMode": "car"
           }
         ]
       }
     ]
    }
    

Fig. 9 Reconstructed Route Based on Supporting Points

The full route information includes a complete set of points which you can plot on a map. The route also includes a summary section which provides details about the distance of the route, the time to travel the route, and an adjustment based on traffic.

Departure time and arrival time are optional parameters and mutually exclusive. These are useful if you want to plot a route based on specific departure time, or if you need to arrive by a particular time and need to know the best time to leave.

Exploring Additional Details of the Route

If you have a tracking system which includes speed readings from the vehicle, then you can compare these readings against speed information using the returnSpeedLimit parameter with the reverse geocoding request. We’ll pick a point on the route, and pass this to the Search API.

https://api.tomtom.com/search/2/reverseGeocode/45.531822,-122.596347.json?key=ReplaceWithYourAPIKeyHere&returnSpeedLimit=true

Fig. 10 Example URL for Reverse GeoCoding with Speed Limit Information

If you look at the response below, you’ll see that in addition to the address information, we also have a speed limit parameter which indicates the speed limit on this stretch of road. We can perform this query for each point of the route, and compare it programmatically with the speed data from the vehicle, allowing us to determine if any speed violations occurred en route to the destination.

    {
     "summary": {
       "queryTime": 109,
       "numResults": 1
     },
     "addresses": [
       {
         "address": {
           "routeNumbers": [
             "I-84",
             "US-30"
           ],
           "street": "I-84",
           "streetName": "I-84",
           "speedLimit": "55.00MPH",
           "countryCode": "US",
           "countrySubdivision": "OR",
           "countrySecondarySubdivision": "Multnomah",
           "municipality": "Portland",
           "postalCode": "97213",
           "country": "United States Of America",
           "countryCodeISO3": "USA",
           "freeformAddress": "I-84, Portland, OR 97213",
           "countrySubdivisionName": "Oregon"
         },
         "position": "45.531806,-122.596331"
       }
     ]
    }
    

Fig. 11 Response with Speed Limit Information

We can also pass in configuration parameters for the vehicle, such as:

  • Vehicle Engine Type

  • Consumption Information - collection of pairs of speed and the corresponding consumption rate.

  • Acceleration and Deceleration Efficiency

  • Vehicle Metrics - Weight, Load Type, Max Speed

With these configuration parameters, the API returns information about expected fuel consumption. You can learn about these parameters in the Routing API Documentation.

You can also add the vehicle configuration for more accurate route planning. Routes can be decided based on speed, distance or eco mode. Eco mode factors in fuel consumption, vehicle efficiency, traffic, and hilliness of the route to find the route which consumes the least fuel/energy possible.

Additional Information

If you would like to learn more about options available within the TomTom APIs, you can access the online documentation or use the API Explorer to try different parameters and see how they all work together.

First published: 
Monday, April 1, 2019 - 17:58
Last edited: 
Tuesday, April 16, 2019 - 17:50