概览
您可以使用 DirectionsService
对象来计算(使用各种交通方式时的)路线。此对象会与 Google Maps API 路线服务通信,后者可接收路线请求并返回高效路径。行程时间是主要因素且进行了优化,但也可以将距离、转弯次数及许多其他因素考虑在内。您可以自行处理这些路线查询结果,也可以使用 DirectionsRenderer
对象呈现这些结果。
在路线请求中指定出发地或目的地时,您可以指定查询字符串(例如,“伊利诺伊州芝加哥市”或“澳大利亚新南威尔士州达尔文市”)、LatLng
值或 Place 对象。
路线服务可使用一系列航点返回多段式路线。路线可在地图上显示为多段线(用于绘制路线),此外也可在 <div>
元素内显示为一系列文本说明(例如“右转上威廉斯堡大桥匝道”)。
开始使用
在使用 Maps JavaScript API 中的路线服务之前,请先确保在 Google Cloud 控制台中针对您为 Maps JavaScript API 设置的同一项目启用了 Directions API。
若要查看已启用的 API 列表,请按以下步骤操作:
- 前往 Google Cloud 控制台。
- 点击选择项目按钮,选择您为 Maps JavaScript API 设置的同一项目,然后点击打开。
- 在信息中心上的 API 列表中,查找 Directions API。
- 如果您在列表中看到该 API,就说明一切就绪。如果其中未列出该 API,请执行以下操作将其启用:
- 在页面顶部,选择启用 API 以显示库标签页。或者,您也可以从左侧菜单中选择库。
- 搜索 Directions API,然后从结果列表中选择它。
- 选择启用。该过程完成后,Directions API 会显示在信息中心上的 API 列表中。
定价和政策
定价
自 2018 年 7 月 16 日起,地图、路线和地点产品开始采用全新的随用随付定价方案。如需详细了解使用 JavaScript 路线服务时的新定价和用量限额,请参阅 Directions API 的用量和结算。
政策
使用路线服务时,必须遵守适用于 Directions API 的政策。
路线请求
Google Maps API 需要调用外部服务器,因此对路线服务的访问是异步进行的。因此,您需要传递一个在请求完成时执行的回调方法。该回调方法应该能够处理返回的结果。请注意,路线服务可能会以独立 routes[]
数组的形式返回多个可能的行程。
若要使用 Maps JavaScript API 中的路线服务,请创建类型为 DirectionsService
的对象并调用 DirectionsService.route()
,向路线服务发起请求,并向其传递一个 DirectionsRequest
对象字面量,后者包含输入字词和一个在收到响应后执行的回调方法。
DirectionsRequest
对象字面量包含以下字段:
{ origin: LatLng | String | google.maps.Place, destination: LatLng | String | google.maps.Place, travelMode: TravelMode, transitOptions: TransitOptions, drivingOptions: DrivingOptions, unitSystem: UnitSystem, waypoints[]: DirectionsWaypoint, optimizeWaypoints: Boolean, provideRouteAlternatives: Boolean, avoidFerries: Boolean, avoidHighways: Boolean, avoidTolls: Boolean, region: String }
这些字段的说明如下:
origin
(必需)指定用于计算路线的起始位置。该值可指定为String
(例如“伊利诺伊州芝加哥市”)、LatLng
值或 Place 对象。如果您使用的是 Place 对象,则可以指定地点 ID、查询字符串或LatLng
位置。您可以从 Maps JavaScript API 中的地理编码服务、地点搜索服务和地点自动补全服务检索地点 ID。如需查看使用来自地点自动补全服务的地点 ID 的示例,请参阅地点自动补全和路线。destination
(必需)指定用于计算路线的结束位置。其选项与上述origin
字段的选项相同。travelMode
(必需)指定计算路线时要使用的交通方式。下文的出行方式部分指定了有效值。transitOptions
(可选)- 此字段指定的值仅适用于travelMode
为TRANSIT
的请求。下文的公交选项部分介绍了有效值。drivingOptions
(可选)- 此字段指定的值仅适用于travelMode
为DRIVING
的请求。下文的行车选项部分介绍了有效值。unitSystem
(可选)指定显示结果时要使用的单位制。下文的单位制部分指定了有效值。waypoints[]
(可选)指定DirectionsWaypoint
数组。航点通过使路线经过指定位置来改变路线。航点可指定为对象字面量,后者包含的字段如下所示:location
将航点的位置指定为LatLng
、Place 对象或要进行地理编码的String
。stopover
是一个布尔值,表示航点是路线上的经停点,可将路线一分为二。
(如需详细了解航点,请参阅下文的在路线中使用航点部分。)
optimizeWaypoints
(可选)指定使用所提供的waypoints
的路线可以进行优化,方法是以更高效的顺序重新排列航点。如果设置为true
,路线服务将在waypoint_order
字段中返回重新排序的waypoints
(如需了解详情,请参阅下文的在路线中使用航点部分)。provideRouteAlternatives
(可选)指定路线服务可以在响应中提供多条备选路线(设置为true
时)。请注意,提供备选路线可能会增加服务器的响应时间。此字段仅适用于没有中间航点的请求。avoidFerries
(可选)表示计算出的路线应在可能的情况下避开轮渡(设置为true
时)。avoidHighways
(可选)表示计算出的路线应在可能的情况下避开主要公路(设置为true
时)。avoidTolls
(可选)表示计算出的路线应在可能的情况下避开收费路段(设置为true
时)。region
(可选)以 ccTLD(“顶级域名”)双字符值的形式指定地区代码(如需了解详情,请参阅下文的地区自定义调整部分)。
DirectionsRequest
示例如下:
{ origin: 'Chicago, IL', destination: 'Los Angeles, CA', waypoints: [ { location: 'Joplin, MO', stopover: false },{ location: 'Oklahoma City, OK', stopover: true }], provideRouteAlternatives: false, travelMode: 'DRIVING', drivingOptions: { departureTime: new Date(/* now, or future date */), trafficModel: 'pessimistic' }, unitSystem: google.maps.UnitSystem.IMPERIAL }
出行方式
计算路线时,您需要指定要使用的交通方式。目前支持以下出行方式:
DRIVING
(默认)表示使用道路网的标准行车路线。BICYCLING
请求经由自行车道和首选街道的骑车路线。TRANSIT
请求经由公共交通路线的路线。WALKING
请求经由步道和人行道的步行路线。
如需确定某个国家/地区支持的路线范围,请参阅 Google Maps Platform 覆盖范围详细信息。如果您针对某个地区请求路线,而该地区不支持相应路线类型,响应将返回 DirectionsStatus
="ZERO_RESULTS
"。
注意:步行路线可能不包含畅通无阻的步道,因此步行路线将在 DirectionsResult
中返回警告。必须始终向用户显示这些警告。如果您不使用默认 DirectionsRenderer
,则要负责确保显示警告。
公交选项
路线请求的可用选项因出行方式而异。请求公交路线时,系统将忽略 avoidHighways
、avoidTolls
、waypoints[]
和 optimizeWaypoints
选项。您可以通过 TransitOptions
对象字面量指定公交专属的路线安排选项。
公交路线具有时效性。系统仅针对未来的时间返回路线。
TransitOptions
对象字面量包含以下字段:
{ arrivalTime: Date, departureTime: Date, modes[]: TransitMode, routingPreference: TransitRoutePreference }
这些字段的说明如下:
arrivalTime
(可选)以Date
对象的形式指定预期到达时间。如果到达时间已指定,系统会忽略出发时间。departureTime
(可选)以Date
对象的形式指定预期出发时间。如果arrivalTime
已指定,系统会忽略departureTime
。如果没有为departureTime
或arrivalTime
指定任何值,则默认采用当前时间。modes[]
(可选)是一个数组,包含一个或多个TransitMode
对象字面量。只有在请求包含 API 密钥时,才能包含此字段。每个TransitMode
均指定一种首选公共交通方式。允许使用以下值:BUS
表示计算出的路线应首选公交出行。RAIL
表示计算出的路线应首选火车、有轨电车、轻轨和地铁出行。SUBWAY
表示计算出的路线应首选地铁出行。TRAIN
表示计算出的路线应首选火车出行。TRAM
表示计算出的路线应首选有轨电车和轻轨出行。
routingPreference
(可选)指定公交路线偏好。利用此选项,您可以自定义调整所返回的选项,而不是接受 API 选择的默认最佳路线。只有在请求包含 API 密钥时,才能指定此字段。允许使用以下值:FEWER_TRANSFERS
表示计算出的路线应首选换乘次数较少的路线。LESS_WALKING
表示计算出的路线应首选步行距离较短的路线。
针对公交路线的 DirectionsRequest
示例如下所示:
{ origin: 'Hoboken NJ', destination: 'Carroll Gardens, Brooklyn', travelMode: 'TRANSIT', transitOptions: { departureTime: new Date(1337675679473), modes: ['BUS'], routingPreference: 'FEWER_TRANSFERS' }, unitSystem: google.maps.UnitSystem.IMPERIAL }
行车选项
您可以通过 DrivingOptions
对象为行车路线指定路线安排选项。
DrivingOptions
对象包含以下字段:
{ departureTime: Date, trafficModel: TrafficModel }
这些字段的说明如下:
departureTime
(必须指定此字段,drivingOptions
对象字面量才有效)以Date
对象的形式指定预期出发时间。其值必须设置为当前时间或未来的某个时间,而不能是过去的时间(API 会将所有日期都转换为 UTC,以确保在各个时区实现一致的处理)。对于 Google Maps Platform 专业版方案客户,如果您在请求中包含departureTime
,API 会根据当时的预期路况信息返回最佳路线,并且在响应中包含预计交通时间 (duration_in_traffic
)。如果您未指定出发时间(即请求不包含drivingOptions
),则返回的路线通常是不考虑路况信息的较佳路线。trafficModel
(可选)指定计算交通时间时要使用的假设条件。此设置会影响响应中返回到duration_in_traffic
字段的值,该值包含根据历史平均数据预测的交通时间。此字段的默认值为bestguess
。允许使用以下值:bestguess
(默认)表示返回的duration_in_traffic
应该是最准确的行程时间估算值(根据已知的历史路况信息和实时路况信息得出)。departureTime
越接近当前时间,实时路况信息就越重要。pessimistic
表示返回的duration_in_traffic
在大多数日子里应该长于实际行程时间,但偶尔路况特别糟糕的时候,实际行程时间可能会超过该值。optimistic
表示返回的duration_in_traffic
在大多数日子里应该短于实际行程时间,但偶尔路况特别理想的时候,实际行程时间可能会小于该值。
针对行车路线的 DirectionsRequest
示例如下:
{ origin: 'Chicago, IL', destination: 'Los Angeles, CA', travelMode: 'DRIVING', drivingOptions: { departureTime: new Date(Date.now() + N), // for the time N milliseconds from now. trafficModel: 'optimistic' } }
单位制
默认情况下,路线是使用出发地所在国家或地区的单位制进行计算和显示的(请注意:以纬度/经度坐标而不是地址表示的出发地始终默认采用公制单位)。例如,从“伊利诺伊州芝加哥市”到“安大略省多伦多市”的路线结果将以英里显示,反向路线结果则以公里显示。您可以替换此单位制,只需使用以下任一 UnitSystem
值明确设置一种单位制即可:
UnitSystem.METRIC
指定使用公制。距离以公里为单位显示。UnitSystem.IMPERIAL
指定使用英制。距离以英里为单位显示。
请注意:此单位制设置仅影响向用户显示的文本。路线查询结果也包括不向用户显示的距离值,这些值始终以米为单位。
针对路线的地区自定义调整
Google Maps API 路线服务返回的地址结果受到您加载 JavaScript 引导程序所在网域(国家或地区)的影响(由于大多数用户都会加载 https://maps.googleapis.com/
,因此对于美国用户而言,这就设置了一个隐式网域)。如果您从其他支持的网域加载引导程序,获得的结果将受到该网域的影响。例如,搜索“旧金山”时,加载 https://maps.googleapis.com/
(美国)的应用与加载 http://maps.google.es/
(西班牙)的应用返回的结果可能会有所不同。
您也可以使用 region
参数,将路线服务设置为返回根据特定地区自定义调整的结果。此参数采用已指定为双字符(非数字)Unicode 地区子标记的地区代码。大多数情况下,这些标记会直接映射到 ccTLD(“顶级域名”)双字符值,例如“co.uk”中的“uk”。在某些情况下,region
标记也支持 ISO-3166-1 代码,后者有时会与 ccTLD 值有所不同(例如,“GB”代表“Great Britain”)。
使用 region
参数时:
- 请仅指定一个国家或地区。如果指定多个值,不仅会被系统忽略,还可能会导致请求失败。
- 请仅使用双字符地区子标记(Unicode CLDR 格式)。所有其他输入都会导致错误。
只有支持路线服务的国家和地区支持地区自定义调整。如需了解 Directions API 在全球的覆盖范围,请参阅 Google Maps Platform 覆盖范围详细信息。
渲染路线
如果使用 route()
方法向 DirectionsService
发起路线请求,则需要传递一个在该服务请求完成后执行的回调。此回调将在响应中返回 DirectionsResult
和 DirectionsStatus
代码。
路线查询状态
DirectionsStatus
可能会返回以下值:
OK
表示响应中包含有效的DirectionsResult
。NOT_FOUND
表示在请求的出发地、目的地或航点中,有至少一个指定的位置无法进行地理编码处理。ZERO_RESULTS
表示在出发地和目的地之间找不到路线。MAX_WAYPOINTS_EXCEEDED
表示DirectionsRequest
中提供的DirectionsWaypoint
字段过多。请参阅下文的航点限制部分。MAX_ROUTE_LENGTH_EXCEEDED
表示所请求的路线过长,无法进行处理。当系统返回更复杂的路线时,就会发生此错误。不妨尝试减少航点、转弯或指示的数量。INVALID_REQUEST
表示提供的DirectionsRequest
无效。导致出现此错误代码的最常见原因包括:请求中缺少出发地或目的地;或者公交请求中包含航点。OVER_QUERY_LIMIT
表示网页在允许的时间段内发送的请求过多。REQUEST_DENIED
表示不允许网页使用路线服务。UNKNOWN_ERROR
表示因服务器错误而无法处理路线请求。如果您重试,请求可能会成功。
您应在处理结果之前检查此值,以确保路线查询返回有效的结果。
显示 DirectionsResult
DirectionsResult
包含路线查询结果,您可以自行处理该结果,也可以将其传递到 DirectionsRenderer
对象,该对象会自动负责在地图上显示结果。
若要使用 DirectionsRenderer
显示 DirectionsResult
,您需要执行以下操作:
- 创建
DirectionsRenderer
对象。 - 对渲染程序调用
setMap()
,以将其绑定到所传递的地图。 - 对渲染程序调用
setDirections()
,并向其传递DirectionsResult
(如上所述)。由于渲染程序是一个MVCObject
,因此它会自动检测其属性发生的任何变化,并在其关联路线更改时更新地图。
以下示例计算了 66 号公路上两个位置之间的路线,其中出发地和目的地是根据下拉列表中给定的 "start"
和 "end"
值设置的。DirectionsRenderer
负责在指定位置之间显示多段线,并在出发地、目的地和任何航点放置标记(如适用)。
function initMap() { var directionsService = new google.maps.DirectionsService(); var directionsRenderer = new google.maps.DirectionsRenderer(); var chicago = new google.maps.LatLng(41.850033, -87.6500523); var mapOptions = { zoom:7, center: chicago } var map = new google.maps.Map(document.getElementById('map'), mapOptions); directionsRenderer.setMap(map); } function calcRoute() { var start = document.getElementById('start').value; var end = document.getElementById('end').value; var request = { origin: start, destination: end, travelMode: 'DRIVING' }; directionsService.route(request, function(result, status) { if (status == 'OK') { directionsRenderer.setDirections(result); } }); }
在 HTML 正文中:
<div> <strong>Start: </strong> <select id="start" onchange="calcRoute();"> <option value="chicago, il">Chicago</option> <option value="st louis, mo">St Louis</option> <option value="joplin, mo">Joplin, MO</option> <option value="oklahoma city, ok">Oklahoma City</option> <option value="amarillo, tx">Amarillo</option> <option value="gallup, nm">Gallup, NM</option> <option value="flagstaff, az">Flagstaff, AZ</option> <option value="winona, az">Winona</option> <option value="kingman, az">Kingman</option> <option value="barstow, ca">Barstow</option> <option value="san bernardino, ca">San Bernardino</option> <option value="los angeles, ca">Los Angeles</option> </select> <strong>End: </strong> <select id="end" onchange="calcRoute();"> <option value="chicago, il">Chicago</option> <option value="st louis, mo">St Louis</option> <option value="joplin, mo">Joplin, MO</option> <option value="oklahoma city, ok">Oklahoma City</option> <option value="amarillo, tx">Amarillo</option> <option value="gallup, nm">Gallup, NM</option> <option value="flagstaff, az">Flagstaff, AZ</option> <option value="winona, az">Winona</option> <option value="kingman, az">Kingman</option> <option value="barstow, ca">Barstow</option> <option value="san bernardino, ca">San Bernardino</option> <option value="los angeles, ca">Los Angeles</option> </select> </div>
以下示例展示了从加利福尼亚旧金山的海特-阿什伯里区到欧申比奇区使用不同出行方式的路线:
function initMap() { var directionsService = new google.maps.DirectionsService(); var directionsRenderer = new google.maps.DirectionsRenderer(); var haight = new google.maps.LatLng(37.7699298, -122.4469157); var oceanBeach = new google.maps.LatLng(37.7683909618184, -122.51089453697205); var mapOptions = { zoom: 14, center: haight } var map = new google.maps.Map(document.getElementById('map'), mapOptions); directionsRenderer.setMap(map); } function calcRoute() { var selectedMode = document.getElementById('mode').value; var request = { origin: haight, destination: oceanBeach, // Note that JavaScript allows us to access the constant // using square brackets and a string value as its // "property." travelMode: google.maps.TravelMode[selectedMode] }; directionsService.route(request, function(response, status) { if (status == 'OK') { directionsRenderer.setDirections(response); } }); }
在 HTML 正文中:
<div> <strong>Mode of Travel: </strong> <select id="mode" onchange="calcRoute();"> <option value="DRIVING">Driving</option> <option value="WALKING">Walking</option> <option value="BICYCLING">Bicycling</option> <option value="TRANSIT">Transit</option> </select> </div>
DirectionsRenderer
不仅负责显示多段线及任何关联标记,还负责以文本形式将路线显示为一系列路段。为此,请对 DirectionsRenderer
调用 setPanel()
,并向其传递用于显示这些信息的 <div>
。这样做还可确保您显示相应的版权信息,以及任何可能与结果相关的警告。
以文本形式表示的路线将使用浏览器的首选语言设置或加载 API JavaScript 时使用 language
参数指定的语言提供(如需了解详情,请参阅本地化)。对于公交路线,时间将按照相应公交站所在的时区来显示。
以下示例与上一示例完全相同,但包含了一个用于显示路线的 <div>
面板:
function initMap() { var directionsService = new google.maps.DirectionsService(); var directionsRenderer = new google.maps.DirectionsRenderer(); var chicago = new google.maps.LatLng(41.850033, -87.6500523); var mapOptions = { zoom:7, center: chicago } var map = new google.maps.Map(document.getElementById('map'), mapOptions); directionsRenderer.setMap(map); directionsRenderer.setPanel(document.getElementById('directionsPanel')); } function calcRoute() { var start = document.getElementById('start').value; var end = document.getElementById('end').value; var request = { origin:start, destination:end, travelMode: 'DRIVING' }; directionsService.route(request, function(response, status) { if (status == 'OK') { directionsRenderer.setDirections(response); } }); }
在 HTML 正文中:
<div id="map" style="float:left;width:70%;height:100%"></div> <div id="directionsPanel" style="float:right;width:30%;height:100%"></div>
DirectionsResult 对象
向 DirectionsService
发送路线请求后,您会收到一个包含状态代码和结果(即 DirectionsResult
对象)的响应。DirectionsResult
是一个包含以下字段的对象字面量:
geocoded_waypoints[]
包含DirectionsGeocodedWaypoint
对象数组,其中每个对象都包含有关出发地、目的地和航点的地理编码的详细信息。routes[]
包含DirectionsRoute
对象数组。每条路线表示一种从DirectionsRequest
中所提供的出发地到目的地的方式。对于任何给定请求,系统通常只会返回一条路线,除非请求的provideRouteAlternatives
字段设置为true
(在这种情况下,可能会返回多条路线)。
注意:备选路线中已弃用 via_waypoint
属性。版本 3.27 是最后一版可在备选路线中通过航点添加额外内容的 API。对于 API 3.28 版及更高版本,您可以继续使用路线服务来实现可拖动路线,只需停用备选路线的拖动功能即可。只有主路线应该是可拖动的。用户可以拖动主路线,直到它与备选路线一致为止。
经过地理编码的路线航点
DirectionsGeocodedWaypoint
包含有关出发地、目的地和航点的地理编码的详细信息。
DirectionsGeocodedWaypoint
是一个包含以下字段的对象字面量:
geocoder_status
表示地理编码操作生成的状态代码。此字段可能包含以下值。"OK"
表示未出现任何错误;已成功解析地址,并且至少返回了一个地理编码。"ZERO_RESULTS"
表示地理编码成功,但未返回任何结果。如果向地理编码器传递了不存在的address
,就可能会发生这种情况。
-
partial_match
表示地理编码器无法返回与原始请求完全匹配的结果,尽管它能够匹配所请求地址的一部分内容。建议您检查一下原始请求中是否存在拼写错误和/或地址不完整的情况。部分匹配的最常见原因是请求中所传递的市行政区内不存在相关街道地址。当请求与同一市行政区中的两个或更多位置相匹配时,也可能会返回部分匹配。例如,无论是 Henry Street 还是 Henrietta Street,“Hillpar St, Bristol, UK”都会返回部分匹配。请注意,如果请求中包含拼写错误的地址组成部分,地理编码服务可能会推荐备选地址。通过这种方式触发的建议也将标记为部分匹配。
place_id
是地点的唯一标识符,可以与其他 Google API 搭配使用。例如,您可以将place_id
与 Google Places API 库搭配使用,以获取本地商家的详细信息(例如电话号码、营业时间、用户评价等)。请参阅地点 ID 概览。types[]
是一个数组,表示所返回结果的类型。此数组包含零个或多个标记,用于标识结果中所返回的地图项的类型。例如,“Chicago”的地理编码会返回“locality”,表示“Chicago”是一个城市;同时返回“political”,表示它是一个政治实体。
路线
注意:旧版 DirectionsTrip
对象已重命名为 DirectionsRoute
。请注意,路线现在是指从开始到结束的整个行程,而不是仅指整个行程中的一段路程。
DirectionsRoute
包含从指定出发地到目的地的单个结果。该路线可包含一段或多段路程(类型为 DirectionsLeg
),具体取决于是否指定了任何航点。此外,除了路线安排信息之外,该路线还包含必须向用户显示的版权和警告信息。
DirectionsRoute
是一个包含以下字段的对象字面量:
legs[]
包含DirectionsLeg
对象数组,其中每个对象都包含有关路线的一段路程(介于给定路线中两个位置之间)的信息。系统会针对指定的每个航点或目的地显示一段单独的路程(没有任何航点的路线将仅包含一个DirectionsLeg
)。每段路程都由一系列DirectionStep
组成。waypoint_order
包含一个数组,用于表示计算出的路线中任意航点的顺序。如果已向DirectionsRequest
传递optimizeWaypoints: true
,此数组可能包含更改后的顺序。overview_path
包含LatLng
数组,用于表示所生成路线的近似(平滑)路径。overview_polyline
包含一个points
对象,用于保存路线的编码多段线表示法。此多段线是所生成路线的近似(平滑)路径。bounds
包含一个LatLngBounds
,用于表示沿着此给定路线的多段线的边界。copyrights
包含要为此路线显示的版权文本。warnings[]
包含一系列要在显示这些路线时显示的警告。如果您不使用所提供的DirectionsRenderer
对象,则必须自行处理和显示这些警告。fare
包含该路线的总交通费用(即总票价)。此属性仅针对公交请求返回,并且仅适用于所有公交路程均有票价信息的路线。这些信息包括:currency
:ISO 4217 货币代码,表示金额所采用的货币。value
:总票价(以上面指定的货币为单位)。
路线路程
注意:旧版 DirectionsRoute
对象已重命名为 DirectionsLeg
。
DirectionsLeg
定义计算出的路线中从出发地到目的地的一段行程。如果路线不包含任何航点,则由一段“路程”组成;但如果路线定义了一个或多个航点,则由一段或多段路程(与相关行程的特定路程相对应)组成。
DirectionsLeg
是一个包含以下字段的对象字面量:
steps[]
包含DirectionsStep
对象数组,用于表示行程路程的每个单独路段的相关信息。distance
以Distance
对象的形式表示这段路程所涵盖的总距离,该对象的格式如下:value
表示距离(以米为单位)text
包含距离的字符串表示法,默认情况下以出发地所使用的单位显示(例如,对于美国境内的任何出发地,都将使用英里)。您可以通过在原始查询中明确设置UnitSystem
来替换此单位制。请注意,无论您使用哪种单位制,distance.value
字段包含的值始终以米为单位。
如果距离未知,那么这些字段可能未定义。
duration
以Duration
对象的形式表示这段路程所需的总时长,该对象的格式如下:value
表示时长(以秒为单位)。text
包含时长的字符串表示法。
如果时长未知,那么这些字段可能未定义。
duration_in_traffic
表示在考虑当前路况信息的情况下这段路程所需的总时长。只有在满足以下所有条件时,系统才会返回duration_in_traffic
:- 请求不包含停靠航点。也就是说,请求不包含
stopover
为true
的航点。 - 请求专门用于行车路线,即
mode
设置为driving
。 - 请求的
drivingOptions
字段中包含departureTime
。 - 所请求路线的路况信息可用。
duration_in_traffic
包含以下字段:value
表示时长(以秒为单位)。text
包含简单易懂的时长表示法。
- 请求不包含停靠航点。也就是说,请求不包含
arrival_time
包含这段路程的预计到达时间。系统只针对公交路线返回该属性。结果以Time
对象的形式返回,该对象包含以下三个属性:value
是指以 JavaScriptDate
对象的形式指定的时间。text
是指以字符串形式指定的时间。时间按照公交站所在的时区显示。time_zone
包含该公交站所在的时区。该属性的值是时区的名称(如 IANA 时区数据库中所定义),例如“America/New_York”。
departure_time
包含这段路程的预计出发时间,以Time
对象的形式指定。departure_time
仅适用于公交路线。start_location
包含这段路程出发地的LatLng
。由于路线网络服务根据距离起点和终点最近的交通方式(通常为道路)来计算不同位置之间的路线,因此start_location
可能会与所提供的这段路程出发地不同,例如道路不在出发地附近时。end_location
包含这段路程目的地的LatLng
。由于DirectionsService
根据距离起点和终点最近的交通方式(通常为道路)来计算不同位置之间的路线,因此end_location
可能会与所提供的这段路程目的地不同,例如道路不在目的地附近时。start_address
包含这段路程起点的简单易懂的地址(通常为街道地址)。
此内容应按原样读取。请勿以程序化方式解析设置了格式的地址。end_address
包含这段路程终点的简单易懂的地址(通常为街道地址)。
此内容应按原样读取。请勿以程序化方式解析设置了格式的地址。
路线路段
DirectionsStep
是路线的最小单位,其中包含用于描述行程中某条具体指示的单个路段。例如“在西四街左转”。该路段不仅可用于描述指示,同时也包含与该路段和下一路段之间关系有关的距离和时长信息。例如,一个以“并入 80 号公路西段”表示的路段可能包含距离“37 英里”和时长“40 分钟”这些信息,指示从此路段到下一路段还有 37 英里/需要 40 分钟。
使用路线服务搜索公交路线时,路段数组会包含其他公交专属信息(以 transit
对象的形式)。如果路线包括多种交通方式,系统会在 steps[]
数组中提供步行或行车路段的详细路线。例如,步行路段将包含从起始位置到终点位置的路线:“步行至 Innes Ave & Fitch St”。该路段会在 steps[]
数组中提供该路线的详细步行路线,例如:“朝西北方向走”“左转进入 Arelious Walker”和“左转进入 Innes Ave”。
DirectionsStep
是一个包含以下字段的对象字面量:
instructions
包含该路段的相关指示(以文本字符串表示)。distance
包含该路段与下一路段之间的距离,以Distance
对象表示(请参阅上述DirectionsLeg
中的说明)。如果距离未知,那么此字段可能未定义。duration
包含走完此路段到达下一路段预计所需的时间,以Duration
对象表示(请参阅上述DirectionsLeg
中的说明)。如果时长未知,那么此字段可能未定义。start_location
包含此路段出发地的LatLng
(已经过地理编码)。end_location
包含此路段终点的LatLng
。polyline
包含一个points
对象,用于保存路段的编码多段线表示法。此多段线是路段的近似(平滑)路径。steps[]
是DirectionsStep
对象字面量,其中包含公交路线中步行或行车路段的详细路线。子路段只适用于公交路线。travel_mode
包含此路段中使用的TravelMode
。公交路线可能包含步行路线与公交路线的组合。path
包含LatLngs
数组,用于描述此路段的路径。transit
包含公交专属信息,例如到达时间和出发时间以及公交线路的名称。
公交专属信息
公交路线会返回与其他交通方式无关的额外信息。这些额外属性通过 TransitDetails
对象公开,并作为 DirectionsStep
的属性返回。通过 TransitDetails
对象,您可以访问 TransitStop
、TransitLine
、TransitAgency
和 VehicleType
对象的额外信息,如下所述。
公交详细信息
TransitDetails
对象公开了以下属性:
arrival_stop
包含一个表示到达站的TransitStop
对象,该对象包含以下属性:name
是指公交站的名称。例如“联合广场”。location
是指公交站的位置,以LatLng
表示。
departure_stop
包含一个表示出发站的TransitStop
对象。arrival_time
包含以Time
对象的形式指定的到达时间,该对象包含以下属性:value
是指以 JavaScriptDate
对象的形式指定的时间。text
是指以字符串形式指定的时间。时间按照公交站所在的时区显示。time_zone
包含该公交站所在的时区。该属性的值是时区的名称(如 IANA 时区数据库中所定义),例如“America/New_York”。
departure_time
包含以Time
对象的形式指定的出发时间。headsign
指定该线路的行进方向,如车辆或出发站所标示的方向(通常为终点站)。headway
指定目前同一车站各次发车的预计间隔秒数(如有)。例如,headway
值为 600 时,如果您错过了一班公交,那么预计需要 10 分钟才能等到下一班。line
包含一个TransitLine
对象字面量,其中包含该路段中所用公交线路的相关信息。TransitLine
提供该线路的名称和运营商,以及TransitLine
参考文档中所述的其他属性。num_stops
包含该路段中的公交站数量。该属性包含到达站,但不含出发站。例如,如果您的路线是从 A 站出发,途经 B 站和 C 站,最终到达 D 站,那么num_stops
会返回 3。
公交线路
TransitLine
对象公开了以下属性:
name
包含该公交线路的全名。例如,“7 号大道快线”或“14 路跨市区线”short_name
包含该公交线路的简称。这通常是线路编号,例如“2”或“M14”。agencies
是一个包含单个TransitAgency
对象的数组。TransitAgency
对象会提供该线路运营商的相关信息,其中包含以下属性:name
包含公交公司的名称。phone
包含公交公司的电话号码。url
包含公交公司的网址。
注意:如果您要手动渲染公交路线,而不是使用
DirectionsRenderer
对象,则必须显示提供行程结果的公交公司的名称和网址。url
包含该公交线路的网址(由公交公司提供)。icon
包含与该线路相关联的图标的网址。大多数城市都会使用因交通工具类型而异的通用图标。某些公交线路(例如纽约市地铁网络)有专用的图标。color
包含该公交站牌常用的颜色。颜色以十六进制字符串形式指定,例如:#FF0033。text_color
包含该线路站牌常用的文本颜色。颜色以十六进制字符串形式指定。vehicle
包含具有以下属性的Vehicle
对象:name
包含该线路上交通工具的名称。例如“地铁”。type
包含该线路所用交通工具的类型。如需查看支持的值的完整列表,请参阅交通工具类型文档。icon
包含通常与该交通工具类型相关联的图标的网址。local_icon
包含与该交通工具类型相关联的图标的网址(取决于当地交通标志)。
交通工具类型
VehicleType
对象公开了以下属性:
值 | 定义 |
---|---|
VehicleType.RAIL |
铁路。 |
VehicleType.METRO_RAIL |
轻轨交通。 |
VehicleType.SUBWAY |
地下轻轨。 |
VehicleType.TRAM |
地上轻轨。 |
VehicleType.MONORAIL |
单轨。 |
VehicleType.HEAVY_RAIL |
重轨。 |
VehicleType.COMMUTER_TRAIN |
通勤铁路。 |
VehicleType.HIGH_SPEED_TRAIN |
高速列车。 |
VehicleType.BUS |
公交车。 |
VehicleType.INTERCITY_BUS |
长途客车。 |
VehicleType.TROLLEYBUS |
无轨电车。 |
VehicleType.SHARE_TAXI |
共享出租车是一种公交车,可供乘客在其路线中的任意位置上下车。 |
VehicleType.FERRY |
轮渡。 |
VehicleType.CABLE_CAR |
一种靠电缆运行的交通工具,通常在地面上行驶。空中缆车可以算作 VehicleType.GONDOLA_LIFT 类型。 |
VehicleType.GONDOLA_LIFT |
空中缆车 |
VehicleType.FUNICULAR |
一种由缆线拉上陡坡的交通工具。索道缆车通常由两个车体组成,彼此作为对方的平衡重物。 |
VehicleType.OTHER |
所有其他交通工具都将返回此类型。 |
检查 DirectionsResults
您可在解析任何路线响应时检查和使用 DirectionsResults
组成部分(DirectionsRoute
、DirectionsLeg
、DirectionsStep
和 TransitDetails
)。
重要提示:如果您要手动渲染公交路线,而不是使用 DirectionsRenderer
对象,则必须显示提供行程结果的公交公司的名称和网址。
以下示例绘制了前往纽约市某些旅游景点的步行路线。我们会检查路线的 DirectionsStep
,以便为各个路段添加标记,然后将相关信息及相应路段的指示文本附加到 InfoWindow
中。
注意:由于我们要计算的是步行路线,因此还会在单独的 <div>
面板中向用户显示任何警告。
var map; var directionsRenderer; var directionsService; var stepDisplay; var markerArray = []; function initMap() { // Instantiate a directions service. directionsService = new google.maps.DirectionsService(); // Create a map and center it on Manhattan. var manhattan = new google.maps.LatLng(40.7711329, -73.9741874); var mapOptions = { zoom: 13, center: manhattan } map = new google.maps.Map(document.getElementById('map'), mapOptions); // Create a renderer for directions and bind it to the map. var rendererOptions = { map: map } directionsRenderer = new google.maps.DirectionsRenderer(rendererOptions) // Instantiate an info window to hold step text. stepDisplay = new google.maps.InfoWindow(); } function calcRoute() { // First, clear out any existing markerArray // from previous calculations. for (i = 0; i < markerArray.length; i++) { markerArray[i].setMap(null); } // Retrieve the start and end locations and create // a DirectionsRequest using WALKING directions. var start = document.getElementById('start').value; var end = document.getElementById('end').value; var request = { origin: start, destination: end, travelMode: 'WALKING' }; // Route the directions and pass the response to a // function to create markers for each step. directionsService.route(request, function(response, status) { if (status == "OK") { var warnings = document.getElementById("warnings_panel"); warnings.innerHTML = "" + response.routes[0].warnings + ""; directionsRenderer.setDirections(response); showSteps(response); } }); } function showSteps(directionResult) { // For each step, place a marker, and add the text to the marker's // info window. Also attach the marker to an array so we // can keep track of it and remove it when calculating new // routes. var myRoute = directionResult.routes[0].legs[0]; for (var i = 0; i < myRoute.steps.length; i++) { var marker = new google.maps.Marker({ position: myRoute.steps[i].start_point, map: map }); attachInstructionText(marker, myRoute.steps[i].instructions); markerArray[i] = marker; } } function attachInstructionText(marker, text) { google.maps.event.addListener(marker, 'click', function() { stepDisplay.setContent(text); stepDisplay.open(map, marker); }); }
在 HTML 正文中:
<div>
<strong>Start: </strong>
<select id="start">
<option value="penn station, new york, ny">Penn Station</option>
<option value="grand central station, new york, ny">Grand Central Station</option>
<option value="625 8th Avenue New York NY 10018">Port Authority Bus Terminal</option>
<option value="staten island ferry terminal, new york, ny">Staten Island Ferry Terminal</option>
<option value="101 E 125th Street, New York, NY">Harlem - 125th St Station</option>
</select>
<strong>End: </strong>
<select id="end" onchange="calcRoute();">
<option value="260 Broadway New York NY 10007">City Hall</option>
<option value="W 49th St & 5th Ave, New York, NY 10020">Rockefeller Center</option>
<option value="moma, New York, NY">MOMA</option>
<option value="350 5th Ave, New York, NY, 10118">Empire State Building</option>
<option value="253 West 125th Street, New York, NY">Apollo Theatre</option>
<option value="1 Wall St, New York, NY">Wall St</option>
</select>
<div>
在路线中使用航点
如 DirectionsRequest 中所述,您也可以在使用路线服务计算步行、骑车或行车路线时指定航点(类型为 DirectionsWaypoint
)。航点不适用于公交路线。您可以利用航点计算途经其他位置的路线,在这种情况下,返回的路线会经过给定航点。
waypoint
包含以下字段:
location
(必需)指定航点的地址。stopover
(可选)指示该航点是路线上的实际经停点 (true
),还是只是途经指定位置的首选路线 (false
)。经停点默认为true
。
默认情况下,路线服务会按所提供航点的指定顺序计算途经这些航点的路线。或者,您也可以在
DirectionsRequest
中传递 optimizeWaypoints: true
,以便路线服务按照更高效的顺序重新排列这些航点,从而对提供的路线进行优化(这种优化用于解决旅行推销员问题)。行程时间是主要因素且进行了优化,但在确定哪条路线最高效时,可以将距离、转弯次数及许多其他因素考虑在内。所有航点都必须是停靠点,以便路线服务优化路线。
如果您指示路线服务对航点顺序进行优化,那么系统将在 DirectionsResult
对象的 waypoint_order
字段中返回这些航点的顺序。
以下示例使用各种出发地、终点和航点计算横跨美国的越野路线(若要选择多个航点,请在列表中选择项目时,按住 Ctrl 键同时点击一下)。请注意,我们会检查 routes.start_address
和 routes.end_address
,以获取每条路线的出发地和终点的相关文本。
TypeScript
function initMap(): void { const directionsService = new google.maps.DirectionsService(); const directionsRenderer = new google.maps.DirectionsRenderer(); const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 6, center: { lat: 41.85, lng: -87.65 }, } ); directionsRenderer.setMap(map); (document.getElementById("submit") as HTMLElement).addEventListener( "click", () => { calculateAndDisplayRoute(directionsService, directionsRenderer); } ); } function calculateAndDisplayRoute( directionsService: google.maps.DirectionsService, directionsRenderer: google.maps.DirectionsRenderer ) { const waypts: google.maps.DirectionsWaypoint[] = []; const checkboxArray = document.getElementById( "waypoints" ) as HTMLSelectElement; for (let i = 0; i < checkboxArray.length; i++) { if (checkboxArray.options[i].selected) { waypts.push({ location: (checkboxArray[i] as HTMLOptionElement).value, stopover: true, }); } } directionsService .route({ origin: (document.getElementById("start") as HTMLInputElement).value, destination: (document.getElementById("end") as HTMLInputElement).value, waypoints: waypts, optimizeWaypoints: true, travelMode: google.maps.TravelMode.DRIVING, }) .then((response) => { directionsRenderer.setDirections(response); const route = response.routes[0]; const summaryPanel = document.getElementById( "directions-panel" ) as HTMLElement; summaryPanel.innerHTML = ""; // For each route, display summary information. for (let i = 0; i < route.legs.length; i++) { const routeSegment = i + 1; summaryPanel.innerHTML += "<b>Route Segment: " + routeSegment + "</b><br>"; summaryPanel.innerHTML += route.legs[i].start_address + " to "; summaryPanel.innerHTML += route.legs[i].end_address + "<br>"; summaryPanel.innerHTML += route.legs[i].distance!.text + "<br><br>"; } }) .catch((e) => window.alert("Directions request failed due to " + status)); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const directionsService = new google.maps.DirectionsService(); const directionsRenderer = new google.maps.DirectionsRenderer(); const map = new google.maps.Map(document.getElementById("map"), { zoom: 6, center: { lat: 41.85, lng: -87.65 }, }); directionsRenderer.setMap(map); document.getElementById("submit").addEventListener("click", () => { calculateAndDisplayRoute(directionsService, directionsRenderer); }); } function calculateAndDisplayRoute(directionsService, directionsRenderer) { const waypts = []; const checkboxArray = document.getElementById("waypoints"); for (let i = 0; i < checkboxArray.length; i++) { if (checkboxArray.options[i].selected) { waypts.push({ location: checkboxArray[i].value, stopover: true, }); } } directionsService .route({ origin: document.getElementById("start").value, destination: document.getElementById("end").value, waypoints: waypts, optimizeWaypoints: true, travelMode: google.maps.TravelMode.DRIVING, }) .then((response) => { directionsRenderer.setDirections(response); const route = response.routes[0]; const summaryPanel = document.getElementById("directions-panel"); summaryPanel.innerHTML = ""; // For each route, display summary information. for (let i = 0; i < route.legs.length; i++) { const routeSegment = i + 1; summaryPanel.innerHTML += "<b>Route Segment: " + routeSegment + "</b><br>"; summaryPanel.innerHTML += route.legs[i].start_address + " to "; summaryPanel.innerHTML += route.legs[i].end_address + "<br>"; summaryPanel.innerHTML += route.legs[i].distance.text + "<br><br>"; } }) .catch((e) => window.alert("Directions request failed due to " + status)); } window.initMap = initMap;
针对航点的限额和限制
您需要遵循以下用量限额和限制:
- 使用 Maps JavaScript API 中的路线服务时,所允许的航点数上限为 25 个,再加上出发地和目的地。这一限制同样适用于 Directions API 网络服务。
- 对于 Directions API 网络服务,客户可以使用 25 个航点,以及出发地和目的地。
- Google Maps Platform 专业版方案客户可以使用 25 个航点,以及出发地和目的地。
- 公交路线不支持航点。
可拖动路线
如果显示的骑车、步行或行车路线是可拖动的,那么用户便可使用 DirectionsRenderer
动态修改这些路线,这样一来,用户就可以通过点击并拖动地图上生成的路径来选择和更改路线。若要指示渲染程序允许显示可拖动路线,请将其 draggable
属性设置为 true
。公交路线无法设为可拖动。
如果路线可拖动,用户可以选择所呈现结果的路径上的任意点(或航点),然后将指示的部分移动到新位置。DirectionsRenderer
会以动态方式进行更新,以显示修改后的路径。修改后的路径显示后,系统会向地图添加过渡航点(以白色小标记表示)。选择并移动某段路径会更改路线的路程,而选择并移动航点标记(包括出发地和终点)则会更改途经相应航点的路线的路程。
由于可拖动路线是在客户端进行修改和渲染的,因此您可能需要监控并处理 DirectionsRenderer
上的 directions_changed
事件,以便在用户修改了所显示的路线时收到通知。
以下代码显示的行程起点为澳大利亚西海岸的珀斯,终点为东海岸的悉尼。它会监控 directions_changed
事件,以便更新该行程所有路程的总距离。
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: -24.345, lng: 134.46 }, // Australia. } ); const directionsService = new google.maps.DirectionsService(); const directionsRenderer = new google.maps.DirectionsRenderer({ draggable: true, map, panel: document.getElementById("panel") as HTMLElement, }); directionsRenderer.addListener("directions_changed", () => { const directions = directionsRenderer.getDirections(); if (directions) { computeTotalDistance(directions); } }); displayRoute( "Perth, WA", "Sydney, NSW", directionsService, directionsRenderer ); } function displayRoute( origin: string, destination: string, service: google.maps.DirectionsService, display: google.maps.DirectionsRenderer ) { service .route({ origin: origin, destination: destination, waypoints: [ { location: "Adelaide, SA" }, { location: "Broken Hill, NSW" }, ], travelMode: google.maps.TravelMode.DRIVING, avoidTolls: true, }) .then((result: google.maps.DirectionsResult) => { display.setDirections(result); }) .catch((e) => { alert("Could not display directions due to: " + e); }); } function computeTotalDistance(result: google.maps.DirectionsResult) { let total = 0; const myroute = result.routes[0]; if (!myroute) { return; } for (let i = 0; i < myroute.legs.length; i++) { total += myroute.legs[i]!.distance!.value; } total = total / 1000; (document.getElementById("total") as HTMLElement).innerHTML = total + " km"; } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: -24.345, lng: 134.46 }, // Australia. }); const directionsService = new google.maps.DirectionsService(); const directionsRenderer = new google.maps.DirectionsRenderer({ draggable: true, map, panel: document.getElementById("panel"), }); directionsRenderer.addListener("directions_changed", () => { const directions = directionsRenderer.getDirections(); if (directions) { computeTotalDistance(directions); } }); displayRoute( "Perth, WA", "Sydney, NSW", directionsService, directionsRenderer, ); } function displayRoute(origin, destination, service, display) { service .route({ origin: origin, destination: destination, waypoints: [ { location: "Adelaide, SA" }, { location: "Broken Hill, NSW" }, ], travelMode: google.maps.TravelMode.DRIVING, avoidTolls: true, }) .then((result) => { display.setDirections(result); }) .catch((e) => { alert("Could not display directions due to: " + e); }); } function computeTotalDistance(result) { let total = 0; const myroute = result.routes[0]; if (!myroute) { return; } for (let i = 0; i < myroute.legs.length; i++) { total += myroute.legs[i].distance.value; } total = total / 1000; document.getElementById("total").innerHTML = total + " km"; } window.initMap = initMap;