距離矩陣服務

總覽

Google 的距離矩陣服務會計算在使用特定交通方式的情況下,多個起點與目的地之間的移動距離和旅途所需時間。

這項服務不會傳回詳細的路線資訊。您只要將所需的單一起點與目的地傳遞至路線規劃服務,就可以取得包括折線和文字導航在內的路線資訊。

開始使用

請先在 Google Cloud 控制台中,確認您為 Maps JavaScript API 設定的專案已啟用 Distance Matrix API,然後再開始使用 Maps JavaScript API 距離矩陣服務。

如要查看已啟用的 API 清單,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台
  2. 按一下「選取專案」按鈕,選取您為 Maps JavaScript API 設定的專案,然後點選「開啟」
  3. 在「資訊主頁」的 API 清單中,找出 Distance Matrix API
  4. 如果在清單中看到該 API,就表示一切就緒。如果「沒有」看到這個 API,請按照下列步驟進行啟用:
    1. 選取頁面頂端的「啟用 API」,即會顯示「程式庫」分頁。或者,您也可以從左側選單中選取「程式庫」
    2. 搜尋「Distance Matrix API」,然後從結果清單中選取該 API。
    3. 選取「啟用」。這個程序完成後,「資訊主頁」的 API 清單就會顯示「Distance Matrix API」

定價和政策

定價

自 2018 年 7 月 16 日起,地圖介面集、路徑介面集和地點介面集採用新的「即付即用」定價方案,如要進一步瞭解新的 JavaScript 距離矩陣服務使用費和用量限制,請參閱 Distance Matrix API 的「用量與計費」一文。

注意:傳送至距離矩陣服務的每筆查詢都有可用元素數量上限,其中「起點」數量乘以「目的地」數量就等於元素數量。

政策

使用距離矩陣服務時,必須遵循 Distance Matrix API 的既定政策

距離矩陣要求

Google Maps API 必須呼叫外部伺服器,因此距離矩陣服務是以非同步的方式存取。基於這個理由,您必須傳遞在完成要求後執行的「回呼」方法,才能處理結果。

您可以透過 google.maps.DistanceMatrixService 建構函式物件,在程式碼內存取距離矩陣服務。DistanceMatrixService.getDistanceMatrix() 方法會向距離矩陣服務發出要求,並將含有起點、目的地和交通方式的 DistanceMatrixRequest 物件常值,以及收到回應後要執行的回呼方法傳遞至該服務。

var origin1 = new google.maps.LatLng(55.930385, -3.118425);
var origin2 = 'Greenwich, England';
var destinationA = 'Stockholm, Sweden';
var destinationB = new google.maps.LatLng(50.087692, 14.421150);

var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
  {
    origins: [origin1, origin2],
    destinations: [destinationA, destinationB],
    travelMode: 'DRIVING',
    transitOptions: TransitOptions,
    drivingOptions: DrivingOptions,
    unitSystem: UnitSystem,
    avoidHighways: Boolean,
    avoidTolls: Boolean,
  }, callback);

function callback(response, status) {
  // See Parsing the Results for
  // the basics of a callback function.
}

查看範例

DistanceMatrixRequest 包含下列欄位:

  • origins (必要):計算距離和時間時要做為起點的陣列,內含一或多個地址字串、google.maps.LatLng 物件或 Place 物件。
  • destinations (必要):計算距離和時間時要做為目的地的陣列,內含一或多個地址字串、google.maps.LatLng 物件或 Place 物件。
  • travelMode (自選):計算路線時要使用的交通方式。請參閱「交通方式」一節。
  • transitOptions (自選):這些選項僅適用於 travelModeTRANSIT 的要求。如需有效值的說明,請參閱「大眾運輸選項」一節。
  • drivingOptions (自選):指定的值只適用於 travelModeDRIVING 的要求。如需有效值的說明,請參閱「行車選項」一節。
  • unitSystem (自選):顯示距離時要使用的單位系統。可接受的值如下:
    • google.maps.UnitSystem.METRIC (預設)
    • google.maps.UnitSystem.IMPERIAL
  • avoidHighways (自選):如為 true,系統計算起點與目的地之間的路線時,會盡量避開高速公路。
  • avoidTolls (自選):如為 true,系統計算點與點之間的路線時,會盡量避開收費路段。

交通方式

計算時間和距離時,您可以指定要使用的交通方式。目前支援下列交通方式︰

  • BICYCLING 會要求沿途設有單車道與專用道路的單車路線 (目前只適用於美國和部分加拿大城市)。
  • DRIVING (預設) 表示使用路網的標準行車路線。
  • TRANSIT 會要求使用大眾運輸的路線。這個選項只有在要求包含 API 金鑰時才能指定。請參閱「大眾運輸選項」一節,瞭解這類要求的可用選項。
  • WALKING 會要求沿途設有人行道和騎樓 (如有) 的步行路線。

大眾運輸選項

大眾運輸服務目前處於「實驗」階段。在這個階段中,我們會實施頻率限制來防止 API 遭到濫用。我們最終會根據 API 的公平使用原則,設定每次地圖上傳的總查詢次數上限。

距離矩陣要求的可用選項會因交通方式而異。在大眾運輸要求中,系統會略過 avoidHighwaysavoidTolls 選項。您可以透過 TransitOptions 物件常值,指定大眾運輸專屬的路線選項。

大眾運輸要求具有時效性。系統只會傳回未來時間的計算結果。

TransitOptions 物件常值包含下列欄位:

{
  arrivalTime: Date,
  departureTime: Date,
  modes: [transitMode1, transitMode2]
  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 表示計算出的路線應優先選擇步行距離較短的選項。

行車選項

請使用 drivingOptions 物件來指定出發時間,以便根據預期的路況計算前往目的地的最佳路線。此外,您也可以指定系統是否要根據歷來路況和即時車流量,保守、大膽或精準預估交通時間。

drivingOptions 物件包含下列欄位:

{
  departureTime: Date,
  trafficModel: TrafficModel
}

這些欄位的說明如下:

  • departureTime (讓 drivingOptions 物件常值有效的必要欄位) 會將所需的出發時間指定為 Date 物件。這個值必須設為目前時間或未來時間,不得設為過去的時間 (API 會將所有日期轉換為世界標準時間,確保不同時區的資料能以一致的方式處理)。如果您在要求中加入 departureTime,API 就會根據當時的預期路況傳回最佳路線,並在回應中附上預估交通時間 (duration_in_traffic)。如未指定出發時間 (也就是如果要求不包含 drivingOptions),系統傳回的路線通常是不考慮路況的最佳路線。

    注意:如未指定出發時間,路線和所需時間的選擇將取決於路網,以及不考慮時間的平均路況。受到路網變動、平均路況更新,以及這項服務的分散性質影響,特定要求的結果可能會隨時間而改變。此外,在時間或頻率都沒有限制的情況下,即使兩條路線幾乎相同,結果還是有可能不同。

  • trafficModel (自選) 會指定計算交通時間時要採用的假設。這項設定會影響回應中 duration_in_traffic 欄位傳回的值,其中包含根據歷來平均值預估的交通時間。預設值為 best_guess。可使用的值如下:
    • bestguess (預設) 表示傳回的 duration_in_traffic 應是最準確的預估交通時間 (根據歷來路況和即時車流量兩者的已知相關資訊計算而得)。departureTime 距離現在的時間越近,即時車流量的影響力就越大。
    • pessimistic 表示傳回的 duration_in_traffic 在大多數日子應該都會比實際交通時間長,但偶爾路況特別差時,實際交通時間可能會超過這個值。
    • optimistic 表示傳回的 duration_in_traffic 在大多數日子應該都會比實際交通時間短,但偶爾路況特別好時,實際交通時間可能會短於這個值。

以下是行車路線的 DistanceMatrixRequest 範例,包括出發時間和車流量模型:

{
  origins: [{lat: 55.93, lng: -3.118}, 'Greenwich, England'],
  destinations: ['Stockholm, Sweden', {lat: 50.087, lng: 14.421}],
  travelMode: 'DRIVING',
  drivingOptions: {
    departureTime: new Date(Date.now() + N),  // for the time N milliseconds from now.
    trafficModel: 'optimistic'
  }
}

距離矩陣回應

如果距離矩陣服務呼叫成功,就會傳回 DistanceMatrixResponseDistanceMatrixStatus 物件,這些物件會傳遞至要求中指定的回呼函式。

DistanceMatrixResponse 物件會針對可計算路線的每個起點/目的地組合,提供距離和所需時間資訊。

{
  "originAddresses": [ "Greenwich, Greater London, UK", "13 Great Carleton Square, Edinburgh, City of Edinburgh EH16 4, UK" ],
  "destinationAddresses": [ "Stockholm County, Sweden", "Dlouhá 609/2, 110 00 Praha-Staré Město, Česká republika" ],
  "rows": [ {
    "elements": [ {
      "status": "OK",
      "duration": {
        "value": 70778,
        "text": "19 hours 40 mins"
      },
      "distance": {
        "value": 1887508,
        "text": "1173 mi"
      }
    }, {
      "status": "OK",
      "duration": {
        "value": 44476,
        "text": "12 hours 21 mins"
      },
      "distance": {
        "value": 1262780,
        "text": "785 mi"
      }
    } ]
  }, {
    "elements": [ {
      "status": "OK",
      "duration": {
        "value": 96000,
        "text": "1 day 3 hours"
      },
      "distance": {
        "value": 2566737,
        "text": "1595 mi"
      }
    }, {
      "status": "OK",
      "duration": {
        "value": 69698,
        "text": "19 hours 22 mins"
      },
      "distance": {
        "value": 1942009,
        "text": "1207 mi"
      }
    } ]
  } ]
}

距離矩陣結果

以下說明回應中支援的欄位。

  • originAddresses 陣列包含距離矩陣要求 origins 欄位中所傳遞的地點。地址會由地理編碼器進行格式化,然後傳回。
  • destinationAddresses 陣列包含 destinations 欄位中所傳遞的地點,並採用地理編碼器傳回的格式。
  • rowsDistanceMatrixResponseRow 物件的陣列,其中每一列都對應一個起點。
  • elementsrows 的子項,會對應該列中起點與每個目的地的組合,且包含每個起點/目的地組合的狀態、時間長度、距離和車資資訊 (如有)。
  • 每個 element 都包含下列欄位:
    • status:如需狀態碼清單,請參閱「狀態碼」一節。
    • duration:行經這條路線所需的時間,以秒為單位 (value 欄位),格式為 text。文字值的格式取決於要求中指定的 unitSystem (如未提供偏好設定,則採用公制)。
    • duration_in_traffic:將目前路況列入考量,行經這條路線所需的時間,以秒 (value 欄位) 為單位,格式為 text。文字值的格式取決於要求中指定的 unitSystem (如未提供偏好設定,則採用公制)。只有在有車流量資料可用、mode 已設為 driving,且 departureTime 包含在要求的 distanceMatrixOptions 欄位中的情況下,才會向 Google 地圖平台付費方案客戶傳回 duration_in_traffic
    • distance:這條路線的總距離,以公尺 (value) 為單位,格式為 text。文字值的格式取決於要求中指定的 unitSystem (如未提供偏好設定,則採用公制)。
    • fare:包含這條路線的總車資 (也就是總票價)。這個屬性只會針對大眾運輸要求傳回,且僅適用於提供車資資訊的大眾運輸服務供應商。這些資訊包括:
      • currencyISO 4217 貨幣代碼,表示金額採用的貨幣。
      • value:總車資金額,以上方指定的貨幣為單位。

狀態碼

距離矩陣回應包含整個回應的狀態碼,以及各項元素的狀態。

回應狀態碼

適用於 DistanceMatrixResponse 的狀態碼會在 DistanceMatrixStatus 物件中傳遞,其中包括:

  • OK:要求有效。即使找不到任何起點與目的地之間的路線,也可能會傳回這個狀態。如要瞭解元素層級的狀態,請參閱「元素狀態碼」一節。
  • INVALID_REQUEST:提供的要求無效。這通常是缺少必要欄位所致。請參閱上方的支援欄位清單
  • MAX_ELEMENTS_EXCEEDED:起點與目的地產生的結果超過每項查詢的限制
  • MAX_DIMENSIONS_EXCEEDED:要求包含超過 25 個起點或目的地。
  • OVER_QUERY_LIMIT:應用程式在允許的時間範圍內要求過多元素。如果您在適當的時間過後再試一次,要求應該就會成功。
  • REQUEST_DENIED:服務拒絕您的網頁使用距離矩陣服務。
  • UNKNOWN_ERROR:伺服器發生錯誤,無法處理距離矩陣要求。如果您再試一次,要求可能會成功。

元素狀態碼

下列狀態碼適用於特定的 DistanceMatrixElement物件:

  • NOT_FOUND:無法針對這個起點和/或目的地組合進行地理編碼。
  • OK:回應包含有效的結果。
  • ZERO_RESULTS:找不到起點與目的地之間的路線。

剖析結果

DistanceMatrixResponse 物件中包含的 row 會各自對應到要求中傳遞的各個起點,而每一列包含的 element 欄位,又會對應到該起點與所提供目的地的每個組合。

function callback(response, status) {
  if (status == 'OK') {
    var origins = response.originAddresses;
    var destinations = response.destinationAddresses;

    for (var i = 0; i < origins.length; i++) {
      var results = response.rows[i].elements;
      for (var j = 0; j < results.length; j++) {
        var element = results[j];
        var distance = element.distance.text;
        var duration = element.duration.text;
        var from = origins[i];
        var to = destinations[j];
      }
    }
  }
}