路线服务

概览

您可以使用 DirectionsService 对象来计算(使用各种交通方式时的)路线。此对象会与 Google Maps API 路线服务通信,后者可接收路线请求并返回高效路径。行程时间是主要因素且进行了优化,但也可以将距离、转弯次数及许多其他因素考虑在内。您可以自行处理这些路线查询结果,也可以使用 DirectionsRenderer 对象呈现这些结果。

在路线请求中指定出发地或目的地时,您可以指定查询字符串(例如,“伊利诺伊州芝加哥市”或“澳大利亚新南威尔士州达尔文市”)、LatLng 值或 Place 对象。

路线服务可使用一系列航点返回多段式路线。路线可在地图上显示为多段线(用于绘制路线),此外也可在 <div> 元素内显示为一系列文本说明(例如“右转上威廉斯堡大桥匝道”)。

开始使用

在使用 Maps JavaScript API 中的路线服务之前,请先确保在 Google Cloud 控制台中针对您为 Maps JavaScript API 设置的同一项目启用了 Directions API。

若要查看已启用的 API 列表,请按以下步骤操作:

  1. 前往 Google Cloud 控制台
  2. 点击选择项目按钮,选择您为 Maps JavaScript API 设置的同一项目,然后点击打开
  3. 信息中心上的 API 列表中,查找 Directions API
  4. 如果您在列表中看到该 API,就说明一切就绪。如果其中未列出该 API,请执行以下操作将其启用:
    1. 在页面顶部,选择启用 API 以显示标签页。或者,您也可以从左侧菜单中选择
    2. 搜索 Directions API,然后从结果列表中选择它。
    3. 选择启用。该过程完成后,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(可选)- 此字段指定的值仅适用于 travelModeTRANSIT 的请求。下文的公交选项部分介绍了有效值。
  • drivingOptions(可选)- 此字段指定的值仅适用于 travelModeDRIVING 的请求。下文的行车选项部分介绍了有效值。
  • unitSystem(可选)指定显示结果时要使用的单位制。下文的单位制部分指定了有效值。

  • waypoints[](可选)指定 DirectionsWaypoint 数组。航点通过使路线经过指定位置来改变路线。航点可指定为对象字面量,后者包含的字段如下所示:

    • location 将航点的位置指定为 LatLngPlace 对象或要进行地理编码的 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"。

注意:步行路线可能不包含畅通无阻的步道,因此如果您没有使用默认的 DirectionsRenderer,步行路线将在您必须显示的 DirectionsResult 中返回警告。

公交选项

路线请求的可用选项因出行方式而异。请求公交路线时,系统将忽略 avoidHighwaysavoidTollswaypoints[]optimizeWaypoints 选项。您可以通过 TransitOptions 对象字面量指定公交专属的路线安排选项。

公交路线具有时效性。系统仅针对未来的时间返回路线。

TransitOptions 对象字面量包含以下字段:

{
  arrivalTime: Date,
  departureTime: Date,
  modes[]: TransitMode,
  routingPreference: TransitRoutePreference
}

这些字段的说明如下:

  • arrivalTime(可选)以 Date 对象的形式指定预期到达时间。如果到达时间已指定,系统会忽略出发时间。
  • departureTime(可选)以 Date 对象的形式指定预期出发时间。如果 arrivalTime 已指定,系统会忽略 departureTime。如果没有为 departureTimearrivalTime 指定任何值,则默认采用当前时间。
  • 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 发起路线请求,则需要传递一个在该服务请求完成后执行的回调。此回调将在响应中返回 DirectionsResultDirectionsStatus 代码。

路线查询状态

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,您需要执行以下操作:

  1. 创建 DirectionsRenderer 对象。
  2. 对渲染程序调用 setMap(),以将其绑定到所传递的地图。
  3. 对渲染程序调用 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_idGoogle Places API 库搭配使用,以获取本地商家的详细信息(例如电话号码、营业时间、用户评价等)。请参阅地点 ID 概览
  • types[] 是一个数组,表示所返回结果的类型。此数组包含一个标记集(零个或多个标记),用于标识结果中所返回地图项的类型。例如,“芝加哥”的地理编码会返回“市行政区”,表示“芝加哥”是一个城市;同时返回“政治”,表示这是一个政治实体。

路线

注意:旧版 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 包含该路线的总交通费用(即总票价)。此属性仅针对公交请求返回,并且仅适用于所有公交路程均有票价信息的路线。这些信息包括:
    • currencyISO 4217 货币代码,表示金额所采用的货币。
    • value:总票价(以上面指定的货币为单位)。

路线路程

注意:旧版 DirectionsRoute 对象已重命名为 DirectionsLeg

DirectionsLeg 定义计算出的路线中从出发地到目的地的一段行程。如果路线不包含任何航点,则由一段“路程”组成;但如果路线定义了一个或多个航点,则由一段或多段路程(与相关行程的特定路程相对应)组成。

DirectionsLeg 是一个包含以下字段的对象字面量:

  • steps[] 包含 DirectionsStep 对象数组,用于表示行程路程的每个单独路段的相关信息。
  • distanceDistance 对象的形式表示这段路程所涵盖的总距离,该对象的格式如下:

    • value 表示距离(以米为单位)
    • text 包含距离的字符串表示法,默认情况下以出发地所使用的单位显示(例如,对于美国境内的任何出发地,都将使用英里)。您可以通过在原始查询中明确设置 UnitSystem 来替换此单位制。请注意,无论您使用哪种单位制,distance.value 字段包含的值始终以米为单位。

    如果距离未知,那么这些字段可能未定义。

  • durationDuration 对象的形式表示这段路程所需的总时长,该对象的格式如下:

    • value 表示时长(以秒为单位)。
    • text 包含时长的字符串表示法。

    如果时长未知,那么这些字段可能未定义。

  • duration_in_traffic 表示在考虑当前路况信息的情况下这段路程所需的总时长。只有在满足以下所有条件时,系统才会返回 duration_in_traffic

    • 请求不包含停靠航点。也就是说,请求不包含 stopovertrue 的航点。
    • 请求专门用于行车路线,即 mode 设置为 driving
    • 请求的 drivingOptions 字段中包含 departureTime
    • 所请求路线的路况信息可用。

    duration_in_traffic 包含以下字段:

    • value 表示时长(以秒为单位)。
    • text 包含简单易懂的时长表示法。
  • arrival_time 包含这段路程的预计到达时间。系统只针对公交路线返回该属性。结果以 Time 对象的形式返回,该对象包含以下三个属性:
    • value 是指以 JavaScript Date 对象的形式指定的时间。
    • 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 对象,您可以访问 TransitStopTransitLineTransitAgencyVehicleType 对象的额外信息,如下所述。

公交详细信息

TransitDetails 对象公开了以下属性:

  • arrival_stop 包含一个表示到达站的 TransitStop 对象,该对象包含以下属性:
    • name 是指公交站的名称。例如“联合广场”。
    • location 是指公交站的位置,以 LatLng 表示。
  • departure_stop 包含一个表示出发站的 TransitStop 对象。
  • arrival_time 包含以 Time 对象的形式指定的到达时间,该对象包含以下属性:
    • value 是指以 JavaScript Date 对象的形式指定的时间。
    • 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 包含该公交线路的全名。例如,“第七大道快车”或“14th St Crosstown”。
  • 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 组成部分(DirectionsRouteDirectionsLegDirectionsStepTransitDetails)。

重要提示:如果您要手动渲染公交路线,而不是使用 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_addressroutes.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;
查看示例

试用示例