1. 程式人生 > >Google Maps V3 之 路線服務

Google Maps V3 之 路線服務

概述

您可以使用 DirectionsService 物件計算路線(使用各種交通方式)。此物件與 Google Maps API 路線服務進行通訊,該服務會接收路線請求並返回計算的結果。您可以自行處理這些路線結果,也可以使用 DirectionsRenderer 物件呈現這些結果。

您可以通過文字字串(例如,“伊利諾斯州芝加哥市”或“澳大利亞新南威爾士州達爾文市”)或 LatLng 值的形式來指定路線的起點和終點。路線服務可以使用一系列路標返回多段路線。路線可以顯示為一條在地圖上繪製路線的折線,此外,也可以顯示為 <div> 元素中的一些文字說明(例如,“右轉上中山南路”)。

路線請求

由於 Google Maps API 需要呼叫外部伺服器,因此對路線服務的訪問是非同步進行的。為此,您需要傳遞一個回撥方法,以便在請求完成時執行。此回撥方法將會對結果進行處理。請注意,路線服務可能會以單個 routes[] 陣列的形式返回多個可能的行程。

要在 V3 中使用路線,請建立一個型別為 DirectionsService 的物件,並呼叫 DirectionsService.route() 向路線服務發起請求,同時向其傳遞一個 DirectionsRequest 物件常量(其中包含輸入字詞和一個用於在收到響應後執行的回撥方法)。

DirectionsRequest 物件常量包含以下欄位:

{
  origin: LatLng | String,
  destination: LatLng | String,
  travelMode: TravelMode,
  transitOptions: TransitOptions,
  unitSystem: UnitSystem,
  waypoints[]: DirectionsWaypoint,
  optimizeWaypoints: Boolean,
  provideRouteAlternatives: Boolean,
  avoidHighways: Boolean,
  avoidTolls: Boolean
  region: String
}

下面對這些欄位進行了說明:

  • origin(必填),用於指定計算路線時所用的起始地點。該值可以指定為 String(例如“伊利諾斯州芝加哥市”),也可以指定為 LatLng 值。
  • destination(必填),用於指定計算路線時所用的結束地點。該值可以指定為 String(例如“伊利諾斯州芝加哥市”),也可以指定為 LatLng 值。
  • travelMode(必填),用於指定計算路線時所用的交通方式。下面的出行方式中指明瞭有效值。
  • transitOptions(可選),用於指定僅適用於其中 travelMode 為 google.maps.TravelMode.TRANSIT 的請求的值。下面的公交選項中說明了有效值。
  • unitSystem(可選),用於指定顯示結果時所用的單位制。您可在下面的單位制中指定有效的值。

  • waypoints[](可選),用於指定 DirectionsWaypoint 陣列。路標可使路線經過指定地點,從而更改路線。您可將路標指定為帶有如下欄位的一個物件常量:

    • location,用於以 LatLng 或要進行地理編碼的 String 的形式指定路標的位置。
    • stopover(布林值),用於表示路標是否為路線上的車站(可將該路線一分為二)。

    (有關路標的詳情,請參閱下面的在路線中使用路標。)

  • optimizeWaypoints(可選),用於指定可對使用提供的 waypoints 的路線進行優化,以提供儘可能最短的路線。如果該值為 true,那麼路線服務將在 waypoints 欄位中返回重新排序的 waypoint_order。(有關詳情,請參閱下面的在路線中使用路標。)
  • provideRouteAlternatives(可選),用於在設為 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: TravelMode.DRIVING,
  unitSystem: UnitSystem.IMPERIAL
}

出行方式

計算路線時,您需要指定要使用的交通方式。目前支援以下出行方式:

  • google.maps.TravelMode.DRIVING預設),用於表示使用道路網路的標準行車路線。
  • google.maps.TravelMode.BICYCLING,用於請求經過騎行道和優先街道的騎行路線。
  • google.maps.TravelMode.TRANSIT,用於請求經過公交路線的路線。
  • google.maps.TravelMode.WALKING,用於請求經過步行街和人行道的步行路線。

請查閱 Google 地圖覆蓋範圍電子表格,確定某個國家/地址支援的路線範圍。如果您對該路線型別不適用的區域請求路線,響應將會返回DirectionsStatus="ZERO_RESULTS"。

步行路線有時可能不包含暢通無阻的步行街,因此,如果您未使用預設的 DirectionsRenderer,那麼步行路線將會在您應顯示的 DirectionsResult 中返回警告。

公交選項

公交服務目前屬於“實驗性”服務。在此階段中,我們會設定速率限制以防止 API 濫用。我們最終會基於 API 的公平使用對每次載入地圖的總查詢次數設定上限。

適用於某一路線請求的選項會根據出行方式的不同而有所區別。在請求公交路線時,將會忽略 avoidHighwaysavoidTollswaypoints[] 和 optimizeWaypoints 選項。您可以通過 TransitOptions 物件常量指定專門針對公交的路線選項。

公交路線具有時效性。只有對於未來的時間才會返回路線。

TransitOptions 物件常量包含以下欄位:

{
  departureTime: Date,
  arrivalTime: Date
}

下面對這些欄位進行了說明:

  • departureTime(可選),用於以 Date 物件的形式指定期望出發時間。如果指定了 arrivalTime,就會忽略 departureTime。如果未對 departureTime 或 arrivalTime 指定任何值,則預設採用當前時間。
  • arrivalTime(可選),用於以 Date 物件的形式指定期望到達時間。如果指定了到達時間,就會忽略出發時間。

公交 DirectionsRequest 的示例如下所示:


{
  origin: "Hoboken NJ",
  destination: "Carroll Gardens, Brooklyn",
  travelMode: google.maps.TravelMode.TRANSIT,
  transitOptions: {
    departureTime: new Date(1337675679473)
  },
  unitSystem: google.maps.UnitSystem.IMPERIAL
}

單位制

預設情況下,使用起點所在國家或地區的單位制計算和顯示路線。(注意:以緯度/經度座標而不是地址表示的起點始終預設採用公制單位。)例如,將以英里顯示從“伊利諾斯州芝加哥市”到“安大略省多倫多市”的路線結果,而以公里顯示反向路線結果。您可以使用以下某個 UnitSystem 值在請求中顯式設定一個單位制,從而覆蓋此單位制:

  • UnitSystem.METRIC,用於指定使用公制。以公里為單位顯示距離。
  • UnitSystem.IMPERIAL,用於指定使用英制。以英里為單位顯示距離。

注意:此單位制設定僅會影響向用戶顯示的文字。路線結果也包括始終以米為單位表示的距離值,但這些值不向使用者顯示。

路線的區域偏向

Google Maps API Directions Service 將返回受到您從中載入 JavaScript 啟動的域(區域或國家/地區)影響的地址結果。(由於大多數使用者都會載入http://maps.google.com/,因此對於美國使用者而言,這就設定了一個隱式域。)如果您是從其他的支援域載入該載入程式的,那麼所獲得的結果將會受到該域的影響。例如,當載入 http://maps.google.com/(美國)與載入 http://maps.google.es/(西班牙)時,搜尋“San Francisco”可能會從應用返回不同的結果。

您還可以使用 region 引數,從而將路線服務設為返回偏向特定區域的結果。此引數採用一個已指定為 IANA 語言 region 子標記的區域程式碼。在大多數情況下,這些標記會直接對映到 ccTLD(“頂級域”)雙字元值,例如“co.uk”中的“uk”。而在某些情況下,region 標記也支援 ISO-3166-1 程式碼,該程式碼有時會與 ccTLD 值有所不同(例如,“GB”表示“Great Britain”)。

呈現路線

如果使用 route() 方法向 DirectionsService 發起路線請求,那麼必須傳遞在該服務請求完成後執行的回撥。此回撥將在響應中返回 DirectionsResult 和 DirectionsStatus 程式碼。

路線查詢狀態

DirectionsStatus 可能會返回以下值:

  • OK,用於表示相關響應包含一個有效的 DirectionsResult
  • NOT_FOUND,用於表示請求的起點、終點或路標中指定的至少一個位置無法進行地理編碼。
  • ZERO_RESULTS,用於表示在起點和終點之間找不到路線。
  • MAX_WAYPOINTS_EXCEEDED,用於表示 DirectionsRequest 中提供的 DirectionsWaypoint 過多。允許的路標數目上限為 8 個,此外還包括起點和終點。Maps API for Business 客戶可使用 23 個路標,此外還包括起點和終點。公交路線不支援路標。
  • 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 處理了指定地點之間折線的顯示方式,並將標記放在起點、終點和所有路標(如果有)上。

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  var chicago = new google.maps.LatLng(41.850033, -87.6500523);
  var mapOptions = {
    zoom:7,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: chicago
  }
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  directionsDisplay.setMap(map);
}

function calcRoute() {
  var start = document.getElementById("start").value;
  var end = document.getElementById("end").value;
  var request = {
    origin:start,
    destination:end,
    travelMode: google.maps.TravelMode.DRIVING
  };
  directionsService.route(request, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.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>