透過 JavaScript 運送追蹤程式庫追蹤運送進度

JavaScript 運送追蹤程式庫能以視覺化方式呈現 Fleet Engine 中追蹤的車輛位置和感興趣的地點。程式庫包含 JavaScript 對應元件,可直接取代標準 google.maps.Map 實體和資料元件,將其與 Fleet Engine 連結。透過 JavaScript 運送追蹤程式庫,您可以從網頁應用程式提供可自訂的動畫運送追蹤體驗。

元件

JavaScript 運送追蹤程式庫提供元件,可視覺化呈現車輛和抵達目的地的路線,而原始資料動態饋給則可用來顯示司機的預計到達時間或剩餘的行駛距離。

運送追蹤地圖檢視

地圖檢視元件能以視覺化方式呈現車輛和目的地的位置。如果已知車輛路線,地圖檢視元件會在車輛沿著預測路徑移動時以動畫方式呈現該車輛。

出貨地點供應商

運送地點供應商會將追蹤物件的位置資訊寫入運送追蹤地圖,以便進行首次和最後一里運送追蹤。

你可以使用運送地點供應商追蹤以下資訊:

  • 商品的取貨或送貨地點。
  • 交車的位置和路線。

已追蹤的位置物件

位置提供者會追蹤車輛和目的地等物件的位置。

目的地位置

目的地位置是指旅程的終點。運送追蹤則是預定的工作地點。

車輛位置

車輛位置是指車輛追蹤的地點。也可以視需要加入車輛路線。

驗證權杖擷取工具

如要控管儲存在 Fleet Engine 中的位置資料存取權,您必須在伺服器上實作 Fleet Engine 適用的 JSON Web Token (JWT) 擷取服務。接著,使用 JavaScript 歷程共用資料庫驗證位置資料的存取權,做為網頁應用程式的一部分實作驗證權杖擷取工具

樣式選項

標記和折線樣式會決定地圖上追蹤的地點物件的外觀和風格。您可以使用自訂樣式選項來變更預設樣式,以符合網頁應用程式的樣式。

控管追蹤位置的瀏覽權限

本節說明地圖上追蹤物件的瀏覽權限控制項。這些規則適用於兩種物件類別:

  • 地點標記
  • 工作資料

位置標記顯示設定

出發地和目的地的所有地點標記一律會顯示在地圖上。舉例來說,無論運送狀態如何,運送地點一律會在地圖上顯示。

工作資料顯示設定

本節說明工作資料適用的預設瀏覽權限規則,例如車輛位置和其餘路線。您可以自訂許多工作,但無法自訂所有工作:

  • 無法使用的工作 - 您無法自訂這些工作的顯示設定。
  • 進行中的車輛工作 - 您可以自訂這些類型的任務。
  • 非使用中的車輛工作 -- 您無法自訂這些工作的顯示設定。

無法使用的工作

如果追蹤任務的路徑中至少有一項無法使用的工作 (例如駕駛人休息或車輛停飛),系統就不會顯示車輛。不過,您還是可以提供預估抵達時間和預估工作完成時間。

進行中的車輛任務

TaskTrackingInfo 物件提供多項資料元素,可在運送追蹤程式庫中顯示。根據預設,當工作指派給車輛,且車輛位於工作停靠站的 5 個以內時,系統就會顯示這些欄位。工作完成或取消時,瀏覽權限就會結束。這些欄位如下:

  • 路線折線
  • 預計到達時間
  • 預估工作完成時間
  • 與工作相關的剩餘行車距離
  • 剩餘停靠站數量
  • 車輛位置

您可以在 Fleet Engine 內建立或更新工作時,在任務上設定 TaskTrackingViewConfig,以自訂每項工作的瀏覽權限設定。這樣即可根據下列條件建立可用個別資料元素時機的規則 (以下稱為瀏覽權限選項):

  • 剩餘停靠站數量
  • 距離預估抵達時間還有
  • 剩餘行車距離
  • 一律顯示
  • 一律不顯示

請注意,每個資料元素都只能與一個瀏覽權限選項建立關聯。您無法使用 OR 或 AND 來結合條件。

自訂範例如下:自訂的規則如下:

  • 如果車輛位於 3 站內,顯示路線折線。
  • 如果剩餘行車距離短於 5000 公尺,則顯示預計到達時間。
  • 一律不顯示剩餘的停靠站計數。
  • 其他欄位保留車輛於任務停靠站 5 個停靠站時顯示的預設顯示設定。
"taskTrackingViewConfig": {
  "routePolylinePointsVisibility": {
    "remainingStopCountThreshold": 3
  },
  "estimatedArrivalTimeVisibility": {
    "remainingDrivingDistanceMetersThreshold": 5000
  },
  "remainingStopCountVisibility": {
    "never": true
  }
}

您也可以與支援團隊聯絡,自訂專案的預設瀏覽權限設定。

路線折線和車輛位置顯示規則:

如果路線折線可顯示,您也必須顯示車輛位置,否則車輛位置則是由折線的末端指定。因此,路線折線不能有較寬鬆的顯示設定選項。

您必須遵循這些規則,才能提供有效的路線折線 / 車輛位置顯示設定組合:

  • 如果路線折線和車輛位置有相同瀏覽權限選項類型:

    • 如果顯示設定選項是剩餘的停靠站數量、抵達預計到達時間,或剩餘的行車距離,路線折線必須提供小於或等於該車輛位置針對這個瀏覽權限選項設定的值。範例如下:
    "taskTrackingViewConfig": {
      "routePolylinePointsVisibility": {
        "remainingStopCountThreshold": 3
      },
      "vehicleLocationVisibility": {
        "remainingStopCountThreshold": 5
      },
    }
    
    • 如果路線折線具有一律可見的顯示選項,車輛位置也必須提供一律可見的顯示選項。
    • 如果車輛位置設有一律不可見的顯示選項,路線折線也必須提供一律不可見的顯示選項。
  • 如果路線折線和車輛位置具有「不同」瀏覽權限選項類型,只有當「同時」同時滿足兩者的顯示設定選項時,系統才會顯示車輛位置。

    範例如下:

    "taskTrackingViewConfig": {
      "routePolylinePointsVisibility": {
        "remainingStopCountThreshold": 3
      },
      "vehicleLocationVisibility": {
        "remainingDrivingDistanceMetersThreshold": 3000
      },
    }
    

    在本範例中,其餘停靠站數量至少為 3 個剩餘行車距離至少 3, 000 公尺時,系統才會顯示車輛位置。

開始使用 JavaScript 歷程共用資料庫

使用 JavaScript 歷程共用資料庫前,請確認您已熟悉 Fleet Engine,並已取得 API 金鑰

如要追蹤商品運送狀態,請先建立追蹤 ID 聲明。

建立追蹤 ID 聲明

如要透過出貨地點提供者追蹤運送狀態,請建立含有追蹤 ID 憑證附加資訊的 JSON Web Token (JWT)。

如要建立 JWT 酬載,請在授權區段中使用鍵 trackingid 新增額外憑證附加資訊。將值設為運送追蹤 ID。

下例說明如何透過追蹤 ID 建立用於追蹤的權杖:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "private_key_id_of_consumer_service_account"
}
.
{
  "iss": "consumer@yourgcpproject.iam.gserviceaccount.com",
  "sub": "consumer@yourgcpproject.iam.gserviceaccount.com",
  "aud": "https://fleetengine.googleapis.com/",
  "iat": 1511900000,
  "exp": 1511903600,
  "scope": "https://www.googleapis.com/auth/xapi",
  "authorization": {
     "trackingid": "tid_54321",
   }
}

建立驗證權杖擷取工具

您可以建立驗證權杖擷取程式,使用專案的服務帳戶憑證在伺服器上擷取以適當憑證附加的資訊。請務必只在伺服器上建立權杖,且絕不在任何用戶端上分享您的憑證。否則會損害系統的安全性。

擷取器必須傳回資料結構,其中包含兩個欄位,這些欄位包裝在 Promise 中:

  • 字串 token
  • 數字 expiresInSeconds。憑證會在擷取後的這段時間到期。

如果發生下列任一情況,JavaScript 運送追蹤程式庫會透過驗證權杖擷取器要求權杖:

  • 權杖沒有有效權杖,例如瀏覽器未在新載入網頁時呼叫擷取器,或是擷取器未傳回權杖。
  • 它先前擷取的權杖已過期。
  • 先前擷取的權杖會在到期後的一分鐘內。

否則,程式庫會使用先前核發且仍然有效的憑證,不會呼叫擷取程式。

以下範例說明如何建立驗證權杖擷取程式:

JavaScript

function authTokenFetcher(options) {
  // options is a record containing two keys called
  // serviceType and context. The developer should
  // generate the correct SERVER_TOKEN_URL and request
  // based on the values of these fields.
  const response = await fetch(SERVER_TOKEN_URL);
  if (!response.ok) {
    throw new Error(response.statusText);
  }
  const data = await response.json();
  return {
    token: data.Token,
    expiresInSeconds: data.ExpiresInSeconds
  };
}

TypeScript

function authTokenFetcher(options: {
  serviceType: google.maps.journeySharing.FleetEngineServiceType,
  context: google.maps.journeySharing.AuthTokenContext,
}): Promise<google.maps.journeySharing.AuthToken> {
  // The developer should generate the correct
  // SERVER_TOKEN_URL based on options.
  const response = await fetch(SERVER_TOKEN_URL);
  if (!response.ok) {
    throw new Error(response.statusText);
  }
  const data = await response.json();
  return {
    token: data.token,
    expiresInSeconds: data.expiration_timestamp_ms - Date.now(),
  };
}

實作擷取權杖的伺服器端端點時,請注意下列事項:

  • 端點必須傳回權杖的到期時間;在上述範例中,該符記指定為 data.ExpiresInSeconds
  • 驗證權杖擷取工具必須將到期時間 (以秒為單位,從擷取時間) 傳遞至程式庫,如範例所示。
  • SERVER_TOKEN_URL 取決於您的後端實作項目,以下是範例應用程式後端的網址:
    • https://SERVER_URL/token/delivery_driver/DELIVERY_VEHICLE_ID
    • https://SERVER_URL/token/delivery_consumer/TRACKING_ID
    • https://SERVER_URL/token/fleet_reader

從 HTML 載入地圖

以下範例說明如何從指定網址載入 JavaScript 運送追蹤程式庫。「callback」參數會在 API 載入後執行 initMap 函式。defer 屬性可讓瀏覽器在 API 載入時繼續轉譯網頁的其他部分。

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=journeySharing" defer></script>

追蹤出貨資訊

本節說明如何使用 JavaScript 運送追蹤程式庫,追蹤出貨或貨品交付。執行程式碼前,請務必透過指令碼標記中指定的回呼函式載入程式庫

將出貨地點供應商例項化

JavaScript 運送追蹤程式庫為 Fleet Engine Deliveries API 預先定義位置提供者。請使用專案 ID 和權杖工廠參照來執行個體化權杖工廠。

JavaScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineShipmentLocationProvider({
          projectId: 'your-project-id',
          authTokenFetcher: authTokenFetcher, // the token fetcher defined in the previous step

          // Optionally, you may specify tracking ID to
          // immediately start tracking.
          trackingId: 'your-tracking-id',
});

TypeScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineShipmentLocationProvider({
          projectId: 'your-project-id',
          authTokenFetcher: authTokenFetcher, // the token fetcher defined in the previous step

          // Optionally, you may specify tracking ID to
          // immediately start tracking.
          trackingId: 'your-tracking-id',
});

初始化地圖檢視

載入 JavaScript 歷程共用資料庫後,請初始化地圖檢視並加進 HTML 網頁。您的網頁應包含保留地圖檢視的 <div> 元素。在以下範例中,<div> 元素命名為 map_canvas

為避免競爭狀況,請在地圖初始化後所叫用的回呼中設定位置提供者的追蹤 ID。

JavaScript

const mapView = new 
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'), 
  locationProviders: [locationProvider],
  vehicleMarkerSetup: vehicleMarkerSetup,
  anticipatedRoutePolylineSetup:
      anticipatedRoutePolylineSetup,
  // Any undefined styling options will use defaults.
});

// If you did not specify a tracking ID in the location
// provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.trackingId = 'your-tracking-id';

// Give the map an initial viewport to allow it to 
// initialize; otherwise the 'ready' event above may 
// not fire. The user also has access to the mapView
// object to customize as they wish.
mapView.map.setCenter({lat: 37.2, lng: -121.9});
mapView.map.setZoom(14);

TypeScript

const mapView = new 
    google.maps.journeySharing.JourneySharingMapView({
  document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  vehicleMarkerSetup: vehicleMarkerSetup,
  anticipatedRoutePolylineSetup:
      anticipatedRoutePolylineSetup,
 // Any undefined styling options will use defaults.
});

// If you did not specify a tracking ID in the location
// provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.trackingId = 'your-tracking-id';

// Give the map an initial viewport to allow it to
// initialize; otherwise the 'ready' event above may 
// not fire. The user also has access to the mapView
// object to customize as they wish.
mapView.map.setCenter({lat: 37.2, lng: -121.9});
mapView.map.setZoom(14);

追蹤 ID

提供給位置提供者的追蹤 ID 可能會對應至多項工作,例如同一包裹的上車和貨件交付工作,或多次傳送失敗。已選取一項工作顯示在運送追蹤地圖上。決定顯示的工作如下:

  1. 如果只有一項待處理的取貨工作,系統會顯示這個項目。如有多項待處理的取貨工作,就會產生錯誤。
  2. 如果目前有一項待處理的放送工作,系統會顯示這個項目。如有多個開放式交付工作,就會發生錯誤。
  3. 如果已完成的送貨工作:
    • 如果目前已有一項已停業的運送工作,系統會顯示該工作。
    • 如有多項已關閉的傳送工作,系統會顯示最晚傳送時間的工作。
    • 如果有多個已關閉的傳送工作,全都沒有結果時間,系統就會產生錯誤。
  4. 如果已關閉的上車工作:
    • 如果只有一個停靠的上車工作,系統就會顯示該工作。
    • 如有多項已關閉的上車工作,系統會顯示結果時間最近期的工作。
    • 如果有多個已關閉的取貨工作,都沒有結果時間,系統就會產生錯誤。
  5. 否則就不會顯示工作。

監聽變更事件

您可以使用位置提供程式,從工作追蹤資訊物件擷取工作的相關中繼資訊。中繼資訊包括預計到達時間、剩餘停靠站數量,以及上車或外送服務前的剩餘距離。變更中繼資訊會觸發 update 事件。以下範例說明如何監聽這些變更事件。

JavaScript

locationProvider.addListener('update', e => {
  // e.taskTrackingInfo contains data that may be useful
  // to the rest of the UI.
  console.log(e.taskTrackingInfo.remainingStopCount);
});

TypeScript

locationProvider.addListener('update',
    (e: google.maps.journeySharing.FleetEngineShipmentLocationProviderUpdateEvent) => {
  // e.taskTrackingInfo contains data that may be useful
  // to the rest of the UI.
  console.log(e.taskTrackingInfo.remainingStopCount);
});

處理錯誤

因要求運送資訊而以非同步方式發生的錯誤,會觸發 error 事件。以下範例說明如何監聽這些事件以處理錯誤。

JavaScript

locationProvider.addListener('error', e => {
  // e.error is the error that triggered the event.
  console.error(e.error);
});

TypeScript

locationProvider.addListener('error', (e: google.maps.ErrorEvent) => {
  // e.error is the error that triggered the event.
  console.error(e.error);
});

注意:請務必將程式庫呼叫包裝在 try...catch 區塊中,以便處理非預期的錯誤。

停止追蹤

如要停止地點提供者追蹤運送狀態,請從位置供應商中移除追蹤 ID。

JavaScript

locationProvider.trackingId = '';

TypeScript

locationProvider.trackingId = '';

從地圖檢視中移除這個位置提供者

下例說明如何從地圖檢視中移除地點提供者。

JavaScript

mapView.removeLocationProvider(locationProvider);

TypeScript

mapView.removeLocationProvider(locationProvider);

自訂基本地圖的外觀與風格

如要自訂地圖元件的外觀和風格,請使用雲端工具設定地圖樣式,或直接在程式碼中設定選項。

使用雲端式地圖樣式設定

您可以透過 Google Cloud 控制台,使用雲端式地圖樣式設定,為使用 Google 地圖的任何應用程式建立及編輯地圖樣式,無須修改程式碼。地圖樣式會儲存為地圖 ID,並儲存在 Cloud 專案中。如要將樣式套用至 JavaScript 運送追蹤地圖,請在建立 JourneySharingMapView 時指定 mapId。將 JourneySharingMapView 執行個體化後,就無法變更或新增 mapId 欄位。下例說明如何啟用先前建立且具有地圖 ID 的地圖樣式。

JavaScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    mapId: 'YOUR_MAP_ID'
  }
  // Any other styling options.
});

TypeScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    mapId: 'YOUR_MAP_ID'
  }
  // Any other styling options.
});

使用程式碼式地圖樣式設定

另一種自訂地圖樣式設定的方法,是在建立 JourneySharingMapView 時設定 mapOptions

JavaScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    styles: [
      {
        "featureType": "road.arterial",
        "elementType": "geometry",
        "stylers": [
          { "color": "#CCFFFF" }
        ]
      }
    ]
  }
});

TypeScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    styles: [
      {
        "featureType": "road.arterial",
        "elementType": "geometry",
        "stylers": [
          { "color": "#CCFFFF" }
        ]
      }
    ]
  }
});

使用標記自訂功能

使用 JavaScript 運送追蹤程式庫,即可自訂新增至地圖標記的外觀和樣式。方法是指定標記自訂項目,運送追蹤程式庫之後,系統就會先套用這個程式庫,再為地圖和每次標記更新新增標記。

最簡單的自訂方式就是指定 MarkerOptions 物件,並套用至所有相同類型標記。建立每個標記後都會套用物件中指定的變更,並覆寫任何預設選項。

更進階的選項是指定自訂函式。自訂函式可讓您根據資料設定標記樣式,以及在標記中加入點擊處理等互動功能。具體來說,運送追蹤會將資料傳送至標記所代表物件類型 (車輛或目的地) 的自訂函式。如此一來,標記樣式就能根據標記元素本身的目前狀態變更標記樣式;例如,在目的地之前剩餘的預定停靠站數量。您甚至可以彙整 Fleet Engine 以外來源的資料,並根據該資訊設定標記樣式。

運送追蹤程式庫在 FleetEngineShipmentLocationProviderOptions 中提供下列自訂參數:

使用 MarkerOptions 變更標記樣式

下例說明如何使用 MarkerOptions 物件設定車輛標記樣式。請按照這個模式,使用上述任一標記自訂項目自訂任何標記的樣式。

JavaScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

TypeScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

使用自訂函式變更標記樣式

以下範例說明如何設定車輛標記樣式。請按照這個模式使用上述任一標記自訂參數,自訂任何標記的樣式。

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    var stopsLeft = params.taskTrackingInfo.remainingStopCount;
    params.marker.setLabel(`${stopsLeft}`);
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: ShipmentMarkerCustomizationFunctionParams) => {
    const stopsLeft = params.taskTrackingInfo.remainingStopCount;
    params.marker.setLabel(`${stopsLeft}`);
  };

在標記中加入點擊處理方式

以下範例說明如何在車輛標記中新增點擊處理方式。請按照這個模式,使用上述任一標記自訂參數,為任何標記新增點擊處理機制。

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // Perform desired action.
      });
    }
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: ShipmentMarkerCustomizationFunctionParams) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // Perform desired action.
      });
    }
  };

使用折線自訂功能

透過運送追蹤程式庫,您還可以自訂地圖上運送路線的外觀和風格。程式庫會為運送有效或其餘路徑中的每組座標建立 google.maps.Polyline 物件。您可以指定折線自訂項目來設定 Polyline 物件的樣式。接著,程式庫會在以下兩種情況下套用這些自訂項目:將物件加入地圖之前,以及用於物件的資料已變更。

與標記自訂作業類似,您可以指定一組 PolylineOptions,並在建立或更新所有相符的 Polyline 物件時套用。

同樣地,您也可以指定自訂函式。自訂函式可讓您根據 Fleet Engine 傳送的資料,為物件設定個別樣式。此函式可根據運送狀態變更每個物件的樣式。舉例來說,將 Polyline 物件上色較深,或在車輛移動速度較慢時加粗。您甚至可以和 Fleet Engine 以外的來源進行彙整,並根據該資訊設定 Polyline 物件的樣式。

您可以使用 FleetEngineShipmentLocationProviderOptions 中提供的參數指定自訂項目。您可以為車輛歷程中的不同路徑狀態 (已行經、正在積極旅遊或尚未旅遊) 設定自訂項目。參數如下:

使用 PolylineOptions 變更 Polyline 物件的樣式

以下範例說明如何使用 PolylineOptions 設定 Polyline 物件的樣式。請按照這個模式,使用前述的任一折線自訂設定自訂任何 Polyline 物件的樣式。

JavaScript

activePolylineCustomization = {
  strokeWidth: 5,
  strokeColor: 'black',
};

TypeScript

activePolylineCustomization = {
  strokeWidth: 5,
  strokeColor: 'black',
};

使用自訂函式變更 Polyline 物件的樣式

以下範例說明如何設定有效 Polyline 物件的樣式。請按照這個模式,使用前述的任一折線自訂參數來自訂任何 Polyline 物件的樣式。

JavaScript

// Color the Polyline objects in green if the vehicle is nearby.
activePolylineCustomization =
  (params) => {
    const distance = params.taskTrackingInfo.remainingDrivingDistanceMeters;
    if (distance < 1000) {

      // params.polylines contains an ordered list of Polyline objects for
      // the path.
      for (const polylineObject of params.polylines) {
        polylineObject.setOptions({strokeColor: 'green'});
      }
    }
  };

TypeScript

// Color the Polyline objects in green if the vehicle is nearby.
activePolylineCustomization =
  (params: ShipmentPolylineCustomizationFunctionParams) => {
    const distance = params.taskTrackingInfo.remainingDrivingDistanceMeters;
    if (distance < 1000) {

      // params.polylines contains an ordered list of Polyline objects for
      // the path.
      for (const polylineObject of params.polylines) {
        polylineObject.setOptions({strokeColor: 'green'});
      }
    }
  };

控制 Polyline 物件的瀏覽權限

根據預設,系統會顯示所有 Polyline 物件。如要隱藏 Polyline 物件,請設定其 visible 屬性:

JavaScript

remainingPolylineCustomization = {visible: false};

TypeScript

remainingPolylineCustomization = {visible: false};

為車輛或位置標記顯示 InfoWindow

您可以使用 InfoWindow 顯示車輛或位置標記的其他資訊。

下例說明如何建立 InfoWindow 並附加至車輛標記:

JavaScript

// 1. Create an info window.
const infoWindow = new google.maps.InfoWindow(
    {disableAutoPan: true});

locationProvider.addListener('update', e => {
  const stopsCount =
      e.taskTrackingInfo.remainingStopCount;
  infoWindow.setContent(
      `Your vehicle is ${stopsCount} stops away.`);

  // 2. Attach the info window to a vehicle marker.
  // This property can return multiple markers.
  const marker = mapView.vehicleMarkers[0];
  infoWindow.open(mapView.map, marker);
});

// 3. Close the info window.
infoWindow.close();

TypeScript

// 1. Create an info window.
const infoWindow = new google.maps.InfoWindow(
    {disableAutoPan: true});

locationProvider.addListener('update', (e: google.maps.journeySharing.FleetEngineShipmentLocationProviderUpdateEvent) => {
  const stopsCount =
      e.taskTrackingInfo.remainingStopCount;
  infoWindow.setContent(
      `Your vehicle is ${stopsCount} stops away.`);

  // 2. Attach the info window to a vehicle marker.
  // This property can return multiple markers.
  const marker = mapView.vehicleMarkers[0];
  infoWindow.open(mapView.map, marker);
});

// 3. Close the info window.
infoWindow.close();

停用自動合框功能

您可以停用自動合框功能,避免地圖自動根據可視區域調整到車輛大小,並停止自動調整預測路徑。以下範例說明如何在設定旅程共用地圖檢視時,停用自動合框功能。

JavaScript

const mapView = new
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  automaticViewportMode:
      google.maps.journeySharing
          .AutomaticViewportMode.NONE,
  ...
});

TypeScript

// 1. Create an info window.
const infoWindow = new google.maps.InfoWindow(
    {disableAutoPan: true});

locationProvider.addListener('update', (e: google.maps.journeySharing.FleetEngineShipmentLocationProviderUpdateEvent) => {
  const stopsCount =
      e.taskTrackingInfo.remainingStopCount;
  infoWindow.setContent(
      `Your vehicle is ${stopsCount} stops away.`);

  // 2. Attach the info window to a vehicle marker.   
  // This property can return multiple markers.
  const marker = mapView.vehicleMarkers[0];
  infoWindow.open(mapView.map, marker);
});

// 3. Close the info window.
infoWindow.close();

取代現有地圖

您可以使用 JavaScript 運送追蹤程式庫來取代含有標記或其他自訂項目的現有地圖,但不會保留這些自訂項目。

舉例來說,假設您有一個網頁內含標準 google.maps.Map 實體,並在其中顯示標記:

<!DOCTYPE html>
<html>
  <head>
    <style>
       /* Set the size of the div element that contains the map */
      #map {
        height: 400px;  /* The height is 400 pixels */
        width: 100%;  /* The width is the width of the web page */
       }
    </style>
  </head>
  <body>
    <h3>My Google Maps Demo</h3>
    <!--The div element for the map -->
    <div id="map"></div>
    <script>
// Initialize and add the map
function initMap() {
  // The location of Uluru
  var uluru = {lat: -25.344, lng: 131.036};
  // The map, initially centered at Mountain View, CA.
  var map = new google.maps.Map(document.getElementById('map'));
  map.setOptions({center: {lat: 37.424069, lng: -122.0916944}, zoom: 14});

  // The marker, now positioned at Uluru
  var marker = new google.maps.Marker({position: uluru, map: map});
}
    </script>
    <!-- Load the API from the specified URL.
       * The async attribute allows the browser to render the page while the API loads.
       * The key parameter will contain your own API key (which is not needed for this tutorial).
       * The callback parameter executes the initMap() function.
    -->
    <script defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
  </body>
</html>

如何新增「JavaScript 歷程共用」程式庫:

  1. 新增驗證權杖工廠程式碼。
  2. initMap() 函式中初始化位置提供者。
  3. initMap() 函式中初始化地圖檢視。檢視畫麵包含地圖。
  4. 將自訂內容移至地圖檢視初始化的回呼函式。
  5. 將位置程式庫加入 API 載入器。

以下範例顯示需要進行的變更:

<!DOCTYPE html>
<html>
  <head>
    <style>
       /* Set the size of the div element that contains the map */
      #map {
        height: 400px;  /* The height is 400 pixels */
        width: 100%;  /* The width is the width of the web page */
       }
    </style>
  </head>
  <body>
    <h3>My Google Maps Demo</h3>
    <!--The div element for the map -->
    <div id="map"></div>
    <script>
let locationProvider;

// (1) Authentication Token Fetcher
function authTokenFetcher(options) {
  // options is a record containing two keys called 
  // serviceType and context. The developer should
  // generate the correct SERVER_TOKEN_URL and request
  // based on the values of these fields.
  const response = await fetch(SERVER_TOKEN_URL);
      if (!response.ok) {
        throw new Error(response.statusText);
      }
      const data = await response.json();
      return {
        token: data.Token,
        expiresInSeconds: data.ExpiresInSeconds
      };
}

// Initialize and add the map
function initMap() {
  // (2) Initialize location provider.
  locationProvider = new google.maps.journeySharing.FleetEngineShipmentLocationProvider({
    YOUR_PROVIDER_ID,
    authTokenFetcher,
  });

  // (3) Initialize map view (which contains the map).
  const mapView = new google.maps.journeySharing.JourneySharingMapView({
    element: document.getElementById('map'),
    locationProviders: [locationProvider],
    // any styling options
  });

  locationProvider.trackingId = TRACKING_ID;

    // (4) Add customizations like before.

    // The location of Uluru
    var uluru = {lat: -25.344, lng: 131.036};
    // The map, initially centered at Mountain View, CA.
    var map = mapView.map;
    map.setOptions({center: {lat: 37.424069, lng: -122.0916944}, zoom: 14});
    // The marker, now positioned at Uluru
    var marker = new google.maps.Marker({position: uluru, map: map});
  };

    </script>
    <!-- Load the API from the specified URL
      * The async attribute allows the browser to render the page while the API loads
      * The key parameter will contain your own API key (which is not needed for this tutorial)
      * The callback parameter executes the initMap() function
      *
      * (5) Add the journey sharing library to the API loader.
    -->
    <script defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=journeySharing">
    </script>
  </body>
</html>

如果您在 Uluru 附近如有包含指定 ID 的追蹤套件,則該套件現在會顯示在地圖上。