65.9K
CodeProject 正在变化。 阅读更多。
Home

TomTom 产品评测:交通 API

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (1投票)

2019 年 1 月 11 日

CPOL
viewsIcon

9039

在本文中,我们将深入探讨 TomTom 的交通 API 的工作原理,以及如何利用交通套件中的 Web 服务(基于 TomTom 实时交通数据)来检索某个区域的详细交通信息,用于您的 Web 和移动应用程序。

如果您是一名开发者,您可能已经知道 API 的价值所在——通过将 API 集成到您的项目中,您可以利用行业领导者提供的解决方案和预先提供的代码,极大地简化和加速您正在构建的任何内容。

交通 API 是 API 对开发者(更不用说那些可以利用 API 驱动的交通应用程序的终端用户)的价值的绝佳体现。交通 API 为您提供了构建更优用户体验的基石,您可以使用实时交通数据来构建有趣的工具和应用程序,并深入了解交通状况。

TomTom 是导航、地图和交通产品领域的行业领导者,并持续创造有影响力、易于使用的导航系统。多年来,公司已将其业务重点从设备制造扩展到软件开发。现在,他们决定分享他们最擅长的:先进的交通信息。TomTom 生产创新的软件和服务,并提供了一个全面的 API,允许您检索某个区域的详细交通信息。

在本文中,我们将深入探讨 TomTom 的交通 API 的工作原理,以及如何利用交通套件中的 Web 服务(基于 TomTom 实时交通数据)来检索某个区域的详细交通信息,用于您的 Web 和移动应用程序。在示例中,我们将使用一些 JavaScript 和 ReactJS,以及 bash 脚本。

TomTom 交通如何工作?

TomTom 交通 API 是一项基于云的实时交通监控信息服务,它检测高速公路和次级道路上的交通状况,其运行原理是利用来自全球数十亿条匿名交通测量数据(GPS 轨迹或探针数据)。该服务已存在十年,公司掌握了大量关于人们在世界各地何处、何时、如何驾驶的大数据。

为了提供高质量的服务,数据结合了来自传统来源(例如,道路感应线圈、交通监控摄像头)、现代来源(例如,数百万匿名手机用户的数据)以及历史数据。然后,信息由 TomTom 数据中心进行整理,以便进一步过滤和改进,然后再以相关、实时的交通信息分发给客户,更新频率为每两分钟发送一次。交通数据可靠、准确、频繁且覆盖范围广。即使是小路,也提供了大量详细信息(例如,交通拥堵、道路封闭、延误)。

考虑到 TomTom 交通数据的质量,我们可以放心地通过使用其基于此数据的交通 API 套件,来创建有用、可靠且高质量的应用程序。

开始使用 TomTom 和交通 API

交通 API 是一套 Web 服务,可让您通过构建用户友好的应用程序和实时交通数据来释放您的创造力。该服务专为开发者而设计,可通过 RESTful API 使用,并且具有非常广泛的市场覆盖范围。(更完整的列表可在以下网址找到:https://developer.tomtom.com/online-traffic/market-coverage。)

TomTom 开发者门户是您开始使用此 API 的地方。首先,您需要在此门户上创建一个帐户。从主页输入您的电子邮件地址,然后点击“获取免费 API 密钥”按钮。

下一步是选择一个用户名并仔细阅读服务条款。您的免费帐户每天支持多达 2,500 次免费交易。请注意,如果每天 2,500 次 API 交易不足,可以通过访问开发者仪表板中的“我的积分”屏幕购买更多交易。

一封电子邮件将包含一个设置帐户密码的链接,完成此操作后,您就可以开始使用了。在请求 API 密钥之前,您需要配置一个应用程序。在您的仪表板中,点击“+ 添加应用”按钮。

应用程序需要一个名称,并且您需要启用应用程序需要访问的 API。在本示例中,我们将使用的产品是 **交通流量 API** 和 **交通事件 API**。如果您要跟进,请选择 **交通流量 API** 和 **交通事件 API** 产品,然后点击 **创建应用**。

交通事件 API 提供有关某个区域周围的交通拥堵、事件、事故和延误的准确信息,您可以在地图上显示这些信息。交通流量 API 提供有关特定道路网络的观察速度(当前速度、自由流速度)和行程时间的信息。

本文重点介绍如何使用 TomTom 交通流量 API 和交通事件 API,但开发者还可以获得包含类似功能的 Web 和移动 SDK。您可以通过以下链接了解有关每个 SDK 的更多信息。

示例用例 #1

让我们找到用户的地理位置,然后根据他们的位置显示实时交通拥堵和事件数据。当用户使用移动设备(即使他们只是连接到网站而不是使用原生应用程序)时,您可以询问他们的 GPS 位置。在本示例中,我们将仅根据用户的 IP 地址来定位用户。

我们将使用交通事件 API 套件中的交通事件详细信息 API。此 API 的请求 URL 格式如下:

https://api.tomtom.com/traffic/services/{versionNumber}/incidentDetails/{style}/{boundingBox}/{zoom}/{trafficModelID}/{format}?key={API_KEY}&language={string}&projection={string}&geometries={string}&expandCluster={boolean}&originalPosition={boolean}

让我们更深入地探讨每个参数的含义。

https://api.tomtom.com
/traffic/services                        // traffic services
/{versionNumber}                         // version of the service to call
/incidentDetails	                       // incident details service
/{style}                                 // style of tile to be rendered
/{boundingBox}                           // bottom-left latitude,                   
                                            bottom-left longitude,   
                                            top-right latitude, 
                                            top-right longitude
/{zoom}                                  // zoom level
/{trafficModelID}                        // traffic model ID (default -1)
/{format}                                // xml, json, jsonp
?key={API_KEY}                           // API key
&language={string}                       // language of descriptions
&projection={string}                     // type of coordinate system   
                                            (EPSG900913 or EPSG4326)
&geometries={string}                     // type of vector geometry added to  
                                            incidents
&expandCluster={boolean}                 // send clustered points
&originalPosition={boolean}              // return original position of  
                                            incident and the one shifted to  
                                            beginning of traffic tube

基于此请求的示例响应

{
    "tm": {
        "@id": "1537875895566",
        "poi": [
            {
                "id": "europe_CLUSTER_9_-1546746781",
                "p": {
                    "x": 11.368265,
                    "y": 48.002922
                },
                "ic": 13,
                "ty": 1,
                "cbl": {
                    "x": 11.28824,
                    "y": 47.969362
                },
                "ctr": {
                    "x": 11.44829,
                    "y": 48.03646
                },
                "cs": 13,
                "l": 27210
            },
            {
                "id": "europe_HD_DE_TTR131344535899136",
                "p": {
                    "x": 11.237004,
                    "y": 48.082583
                },
                "ic": 9,
                "ty": 1,
                "cs": 0,
                "d": "roadworks",
                "c": "new roadworks layout",
                "f": "Wörthsee (A96)",
                "t": "Germering-Süd (A96)",
                "l": 5840,
                "dl": 113,
                "r": "A96/E54"
            }
        ]
    }
}

现在我们对如何使用 API 有了更好的理解,让我们尝试用它构建一个简单的应用程序。我们可以使用 ReactJS 来使用 API 并像这样操作数据:

index.js

import React, { Component } from "react";
import ReactDOM from "react-dom";
import publicIP from "public-ip";
import geoPoint from "geopoint";
import IncidentCategory from './components/incident_category';
import IncidentData from './components/incident_data';
import IncidentLegend from './components/incident_legend';

// Your API KEY can be hardcoded, but I recommend setting it as an env variable.
const API_KEY = '*****';

class App extends Component {
 constructor() {
   super();
   this.state = {
       error: null,
       isLoaded: false,
       trafficData: []
   };
 }

 componentDidMount() {
   publicIP.v4()
   .then(ip => fetch(`https://ipapi.co/${ip}/json`))
   .then(res => res.json())
   .then(result => this.getBoundingBox(result.latitude, result.longitude))
   .then(
       values =>
       fetch(`https://api.tomtom.com/traffic/services/4/incidentDetails/s3/${values[0]._degLat},${values[0]._degLon},${values[1]._degLat},${values[1]._degLon}/10/-1/json?key=${API_KEY}&projection=EPSG4326`)
   ) 
   .then(res => res.json())
   .then(
       payload => {
           this.setState({
               isLoaded: true,
               trafficData: payload["tm"]["poi"]
           });
       },
       error => {
           this.setState({
               isLoaded: true,
               error
           });
       }
   )
 }

 getBoundingBox(latitude, longitude) {
   const bboxValues = new geoPoint(latitude, longitude).boundingCoordinates(10, true);
   return bboxValues;
 }

 render() {
   const { error, isLoaded, trafficData } = this.state;
   let date = new Date();
   let currentDate = date.toDateString();
   let currentTime = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
  
   if (error) {
       return <div>Error: {error.message}</div>;
   }
   else if (!isLoaded) {
       return <div>Loading...</div>;
   } 
   else {
       return (
           <div>
               <h1>Traffic Incidents</h1>
               <h5>{currentDate}</h5>
               <h5>Time: {currentTime}</h5>
               <table>
                   <IncidentCategory />
                   <IncidentData data={trafficData} />
               </table>
               <IncidentLegend />
           </div>
       );
   }
 }
}

export default App;
ReactDOM.render(<App />, document.querySelector('.container'));

components/incident_data.js

import React from 'react';

const IncidentData = (props) => {

   const incidents = props.data;
  
   return (
       <tbody>
           {incidents.map((el) => {  
               return (
                   <tr key={el["id"]}>
                       <td>{el["p"]["x"]}, {el["p"]["y"]}</td>   // location
                       <td>{el["l"]}</td>                                    // length of delay
                       <td>{el["d"]}</td>                                   // description
                       <td>{el["ic"]}</td>                                  // type
                       <td>{el["ty"]}</td>                                 // severity
                   </tr>
               )
           })}
       </tbody>
   );

};

export default IncidentData;

更多代码可以在此处查看:https://sourcegraph.com/github.com/infoverload/trafficincidents@f8ea4e88ea5471f7a91bbc3161c3390afbcbe3d8/-/blob/src/index.js

浏览器中的结果看起来像:

示例用例 #2

一种更简单的方式是将 TomTom API 集成到 CLI 工具中。在本示例中,我们将使用交通流量 API 套件中的一个 API。

流量路段数据 API 提供有关根据提供的坐标计算出的路段速度和行程时间的信息。

此 API 的请求 URL 格式如下:

https://api.tomtom.com/traffic/services/{versionNumber}/flowSegmentData/{style}/{zoom}/{format}?point={latitude},{longitude}&unit={string}&thickness={integer}&openLr={boolean}&key={API_KEY}

我们可以编写一个基本的 bash 脚本,它接受纬度和经度值作为输入。

#!/bin/bash

echo "---------- Traffic Flow Segment Data -----------"
echo "This service provides information about the speeds and travel times of the road segment closest to the given coordinates."

bail() {
  echo "${1}"
  exit 1
}

check_floating_point() {
  [ $(echo ${1} | grep "^[0-9]*[.][0-9]*$") ] || bail "Invalid input. Try again."
}  
	       
read -p "Latitude: " latitude
check_floating_point ${latitude}
	       
read -p "Longitude: " longitude
check_floating_point ${longitude}

echo "Here is the traffic flow segment data for the area near ${latitude} and ${longitude}"

curl --silent "https://api.tomtom.com/traffic/services/4/flowSegmentData/absolute/10/json?point=${latitude}%2C${longitude}&key=*****" -H "accept: */*" | jq

结果将类似于:

免责声明和其它用例

提供的示例仅旨在让您了解如何集成和使用 API,并非生产环境就绪的用法示例。有无数种方法可以在此基础上进行构建。

此外,请注意,本文仅探讨了交通 API 服务提供的一些 API。还有许多其他 API 可以执行其他操作,例如指示当前交通状况的严重性,或减速带的精确位置(在 TomTom 地图上显示彩色线条)。您还可以利用 TomTom API 提供的交通事件和流量速度信息,结合 Web 上其他与交通相关的实时开放数据,构建更全面的交通管理监控应用程序。可能性是无限的!但是,一如既往,请确保负责任地使用 API,并以一种与其他服务兼容的方式设计您的系统。

© . All rights reserved.