利用 JavaScript 機群追蹤程式庫追蹤您的車隊

JavaScript 機群追蹤程式庫可讓您以近乎即時的方式,以視覺化的方式呈現車輛車隊的位置。這個程式庫使用 Deliveries API,允許以視覺化方式呈現運送車輛和工作。和 JavaScript 運送追蹤程式庫一樣包含 JavaScript 地圖元件,可直接取代標準 google.maps.Map 實體和資料元件,以便與 Fleet Engine 連結。

元件

JavaScript 機群追蹤程式庫提供元件,以視覺化方式呈現外送車輛和停靠站,以及用於預計到達時間或與交付時間的其餘距離原始資料動態饋給。

機群追蹤地圖檢視

「機群追蹤」地圖檢視元件會以視覺化方式呈現車輛和工作的位置。如果知道車輛路線,地圖檢視元件就會在車輛沿著預測路徑移動時,建立動畫效果。

機群追蹤地圖檢視範例

定位服務供應商

位置提供者會使用 Fleet Engine 中儲存的資訊,將追蹤的物件位置資訊傳送至旅程分享地圖。

交車地點供應商

外送車輛位置資訊服務供應商會顯示單一外送車輛的位置資訊。其中包含車輛位置和運送車輛完成的工作資訊。

配送機群位置供應商

運送車隊定位服務供應商會顯示多輛車輛的位置資訊。您可以篩選特定車輛或位置,也可以顯示整個機群。

控管追蹤位置的顯示設定

本節說明 Fleet Engine 預先定義位置提供者在地圖上追蹤的位置物件的瀏覽權限規則。自訂或衍生位置供應商可能會變更瀏覽權限規則。

交車

在 Fleet Engine 建立運輸車輛後就會立即顯示,且無論其任務為何,車輛在整個路線中都會顯示該車輛。

工作位置標記

規劃過的車輛停靠站會以車輛停靠站標記的形式顯示在地圖上。已完成工作的標記會以與車輛預定停靠站不同的樣式顯示。

工作結果的位置會與工作結果標記一起顯示。含有 SUCCEEDED 結果的工作會顯示成功的工作標記,而所有其他工作則會顯示失敗的工作標記。

開始使用 JavaScript 機群追蹤程式庫

使用 JavaScript 機群追蹤程式庫前,請務必熟悉 Fleet Engine 並取得 API 金鑰。然後建立工作 ID 及提交車輛 ID 聲明。

建立工作 ID 及提交車輛 ID 聲明

如要透過運送車輛位置供應商追蹤運送車輛,請建立含有工作 ID 和交車 ID 憑證附加資訊的 JSON Web Token (JWT)。

如要建立 JWT 酬載,請在授權區段中使用金鑰 taskiddeliveryvehicleid 新增額外憑證附加資訊,並將每個金鑰的值設為 *。憑證應使用 Fleet Engine 服務超級使用者 Cloud IAM 角色建立。請注意,這個角色授予廣泛的存取權,可用於建立、讀取及修改 Fleet Engine 實體,而且只應與信任的使用者共用。

以下範例說明如何建立權杖,以便進行車輛和工作追蹤:

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

建立驗證權杖擷取工具

您可以建立驗證權杖擷取工具,以使用專案的服務帳戶憑證,在伺服器上擷取具有適當憑證附加資訊的憑證。請務必只在伺服器上建立權杖,並且絕不會在用戶端分享您的憑證。否則將破壞系統的安全性。

擷取器必須傳回具有兩個欄位的資料結構,並納入 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 旅程共享程式庫。回呼參數會在 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
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher,

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

TypeScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher,

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

初始化地圖檢視

載入 JavaScript 旅程共用資料庫後,請初始化地圖檢視並加進 HTML 網頁。網頁應包含存放地圖檢視的 <div> 元素。在下方範例中,<div> 元素的名稱是 map_canvas

JavaScript

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

// If you did not specify a delivery vehicle ID in the 
// location provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.deliveryVehicleId 
                        = 'your-delivery-vehicle-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('Times Square, New York, NY');
mapView.map.setZoom(14);

TypeScript

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

// If you did not specify a delivery vehicle ID in the 
// location provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.deliveryVehicleId 
                        = 'your-delivery-vehicle-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('Times Square, New York, NY');
mapView.map.setZoom(14);

監聽變更事件

您可以使用位置提供工具,從 deliveryVehicle 物件擷取工作的相關中繼資訊。中繼資訊包括預計到達時間,以及車輛下次上車或下車前的剩餘距離。變更中繼資料會觸發 update 事件。以下範例說明如何監聽這些變更事件。

JavaScript

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

TypeScript

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

監聽錯誤

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

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);
});

停止追蹤

如要讓位置供應商停止追蹤送貨車輛,請從位置供應商移除車輛運送 ID。

JavaScript

locationProvider.deliveryVehicleId = '';

TypeScript

locationProvider.deliveryVehicleId = '';

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

下例顯示如何從地圖檢視中移除位置提供者。

JavaScript

mapView.removeLocationProvider(locationProvider);

TypeScript

mapView.removeLocationProvider(locationProvider);

查看運送機群

本節說明如何使用 JavaScript 歷程共用資料庫查看運送機群。執行程式碼之前,請務必從指令碼標記中指定的回呼函式載入程式庫

將運送機群定位服務供應商執行個體化

JavaScript 機群追蹤程式庫預先定義了位置提供者,該供應器可從 FleetEngine Deliveries API 擷取多輛車輛。使用專案 ID 和權杖擷取器的參照,即可將其例項化。

JavaScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

TypeScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

deliveryVehicleFilter 會指定用於篩選地圖上顯示車輛的查詢。這個篩選器會直接傳送至 Fleet Engine。如要瞭解支援的格式,請參閱 ListDeliveryVehiclesRequest.filter

locationRestriction 會限制在地圖上顯示車輛的區域。以及是否啟用位置追蹤功能。設定完成之後,裝置才會開始追蹤位置。

建構位置提供者後,請初始化地圖檢視

使用地圖可視區域設定地點限制

您可以設定 locationRestriction 邊界,以符合地圖檢視中目前顯示的區域。

JavaScript

google.maps.event.addListenerOnce(
  mapView.map, 'bounds_changed', () => {
    const bounds = mapView.map.getBounds();
    if (bounds) {
      // If you did not specify a location restriction in the
      // location provider constructor, you may do so here.
      // Location tracking will start as soon as this is set.
      locationProvider.locationRestriction = bounds;
    }
  });

TypeScript

google.maps.event.addListenerOnce(
  mapView.map, 'bounds_changed', () => {
    const bounds = mapView.map.getBounds();
    if (bounds) {
      // If you did not specify a location restriction in the
      // location provider constructor, you may do so here.
      // Location tracking will start as soon as this is set.
      locationProvider.locationRestriction = bounds;
    }
  });

監聽變更事件

您可以使用位置提供者從 deliveryVehicles 物件擷取機群的中繼資料。中繼資料包含車輛屬性,例如導航狀態、剩餘距離和自訂屬性;詳情請參閱參考說明文件。變更中繼資料會觸發 update 事件。以下範例說明如何監聽這些變更事件。

JavaScript

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

TypeScript

locationProvider.addListener('update',
    (e: google.maps.journeySharing.FleetEngineDeliveryFleetLocationProviderUpdateEvent) => {
  // e.deliveryVehicles contains data that may be
  // useful to the rest of the UI.
  if (e.deliveryVehicles) {
    for (vehicle of e.deliveryVehicles) {
      console.log(vehicle.remainingDistanceMeters);
    }
  }
});

監聽錯誤

因要求配送機群資訊而非同步產生的錯誤會觸發錯誤事件。如需瞭解如何監聽這些事件的範例,請參閱「監聽錯誤」。

停止追蹤

如要讓位置提供者停止追蹤運送車隊,請將位置提供者的邊界設為空值。

JavaScript

locationProvider.locationRestriction = null;

TypeScript

locationProvider.locationRestriction = null;

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

下例顯示如何從地圖檢視中移除位置提供者。

JavaScript

mapView.removeLocationProvider(locationProvider);

TypeScript

mapView.removeLocationProvider(locationProvider);

查看運送途中的車輛追蹤運送進度

查看車隊時,您可以顯示特定運送車輛的路線和即將完成的工作。方法是將「運送 Fleet Location 提供者」和「 Delivery 車輛位置提供者」例項化,然後同時新增至地圖檢視中:

JavaScript

deliveryFleetLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

deliveryVehicleLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher
        });

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

TypeScript

deliveryFleetLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

deliveryVehicleLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher
        });

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

運送車隊定位服務供應商開始在地圖上顯示運送車輛。運用標記自訂功能,讓運送車輛地點提供者在使用者點擊車隊標記時追蹤配送車輛:

JavaScript

// Specify the customization function either separately, or as a field in
// the options for the delivery fleet location provider constructor.
deliveryFleetLocationProvider.deliveryVehicleMarkerCustomization =
  (params) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // params.vehicle.name follows the format
        // "providers/{provider}/deliveryVehicles/{vehicleId}".
        // Only the vehicleId portion is used for the delivery vehicle
        // location provider.
        deliveryVehicleLocationProvider.deliveryVehicleId =
            params.vehicle.name.split('/').pop();
      });
    }
  };

TypeScript

// Specify the customization function either separately, or as a field in
// the options for the delivery fleet location provider constructor.
deliveryFleetLocationProvider.deliveryVehicleMarkerCustomization =
  (params: google.maps.journeySharing.DeliveryVehicleMarkerCustomizationFunctionParams) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // params.vehicle.name follows the format
        // "providers/{provider}/deliveryVehicles/{vehicleId}".
        // Only the vehicleId portion is used for the delivery vehicle
        // location provider.
        deliveryVehicleLocationProvider.deliveryVehicleId =
            params.vehicle.name.split('/').pop();
      });
    }
  };

向外送車輛地點提供者隱藏標記,以免同一輛車算繪兩個標記:

JavaScript

// Specify the customization function either separately, or as a field in 
// the options for the delivery vehicle location provider constructor.
deliveryVehicleLocationProvider.deliveryVehicleMarkerCustomization =
  (params) => {
    if (params.isNew) {
      params.marker.setVisible(false);
    }
  };

TypeScript

// Specify the customization function either separately, or as a field in
// the options for the delivery vehicle location provider constructor.
deliveryVehicleLocationProvider.deliveryVehicleMarkerCustomization =
  (params: deliveryVehicleMarkerCustomizationFunctionParams) => {
    if (params.isNew) {
      params.marker.setVisible(false);
    }
  };

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

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

使用雲端式地圖樣式設定

雲端式地圖樣式設定可讓您透過 Google Cloud 控制台,為使用 Google 地圖的任何應用程式建立及編輯地圖樣式,無須修改程式碼。地圖樣式會在 Cloud 專案中以地圖 ID 的形式儲存。如要將樣式套用至 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'
  }
});

TypeScript

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

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

另一種自訂地圖樣式的方法,是在建立 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 外部來源的資料,並根據該資訊設定標記樣式。

此外,您也可以使用自訂函式來篩選標記瀏覽權限。如要執行此操作,請對標記呼叫 setVisible(false)

不過,基於效能考量,建議您使用位置供應器中的原生篩選功能,例如 FleetEngineDeliveryFleetLocationProvider.deliveryVehicleFilter。也就是說,當您需要額外的篩選功能時,可以使用自訂函式套用篩選功能。

機群追蹤程式庫提供下列自訂參數:

使用 MarkerOptions 變更標記的樣式

以下範例說明如何使用 MarkerOptions 物件設定車輛標記的樣式。請遵照這個模式,然後使用上述任何標記自訂參數來自訂任何標記的樣式。

JavaScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

TypeScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

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

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

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    params.marker.setLabel(`${stopsLeft}`);
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: DeliveryVehicleMarkerCustomizationFunctionParams) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    params.marker.setLabel(`${stopsLeft}`);
  };

為標記新增點擊處理

下例說明如何在車輛標記中新增點擊處理。遵照此模式,即可使用上述任何標記自訂參數,在任何標記中加入點擊處理方式。

JavaScript

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

TypeScript

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

篩選可見的標記

以下範例說明如何篩選可見的車輛標記。遵照此模式,即可使用上述任何標記自訂參數篩選任何標記。

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    if (stopsLeft > 10) {
      params.marker.setVisible(false);
    }
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: DeliveryVehicleMarkerCustomizationFunctionParams) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    if (stopsLeft > 10) {
      params.marker.setVisible(false);
    }
  };

在跟隨運輸車輛的指示使用折線自訂功能

您也可以使用 JavaScript 機群追蹤程式庫,在地圖上自訂下方車輛路線的外觀和風格。程式庫會為車輛使用中或其餘路徑中的每個座標配對建立 google.maps.Polyline 物件。指定折線自訂項目,即可設定 Polyline 物件的樣式。接著,程式庫會在以下兩種情況套用這些自訂項目:將物件加入地圖之前,以及用於物件的資料有所變更。

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

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

您可以使用 FleetEngineDeliveryVehicleLocationProviderOptions 中提供的參數指定自訂項目。您可以針對車輛旅程中的不同路徑狀態 (已旅行、正在旅行或尚未外出) 設定自訂項目。參數如下:

使用 PolylineOptions 變更 Polyline 物件的樣式

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

JavaScript

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

TypeScript

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

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

以下範例說明如何使用自訂函式,為使用中的折線物件設定樣式。按照這個模式,即可使用先前列出的任何折線自訂參數自訂任何 Polyline 物件的樣式。

JavaScript

// Color the Polyline objects in green if the vehicle is nearby.
activePolylineCustomization =
  (params) => {
    const distance = params.deliveryVehicle.remainingDistanceMeters;
    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: DeliveryVehiclePolylineCustomizationFunctionParams) => {
    const distance = params.deliveryVehicle.remainingDistanceMeters;
    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});

// (Assumes a delivery vehicle location provider.)
locationProvider.addListener('update', e => {
  if (e.deliveryVehicle) {
    const distance = 
           e.deliveryVehicle.remainingDistanceMeters;
    infoWindow.setContent(
        `Your vehicle is ${distance}m away from the next task.`);

    // 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});

// (Assumes a delivery vehicle location provider.)
locationProvider.addListener('update', (e: google.maps.journeySharing.FleetEngineDeliveryVehicleLocationProviderUpdateEvent) => {
  if (e.deliveryVehicle) {
    const distance = 
           e.deliveryVehicle.remainingDistanceMeters;
    infoWindow.setContent(
        `Your vehicle is ${distance}m away from the next task.`);

    // 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

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

取代現有地圖

您可以取代包含標記或其他自訂內容的現有地圖,而不會失去這些自訂設定。

舉例來說,假設有一個網頁具有標準 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. Use FleetEngineDeliveryVehicleLocationProvider
  // as appropriate.
  locationProvider = new google.maps.journeySharing.FleetEngineDeliveryVehicleLocationProvider({
    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
  });

mapView.addListener('ready', () => {
  locationProvider.deliveryVehicleId = DELIVERY_VEHICLE_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, which includes Fleet Tracking functionality.
    -->
    <script defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=journeySharing">
    </script>
  </body>
</html>

如果您操作的車輛在 Uluru 附近,該車輛的車輛現在會顯示在地圖上,