使用 JavaScript 舰队跟踪库跟踪舰队

借助 JavaScript 舰队跟踪库,您可以近乎实时地直观呈现车辆在车队中的位置。该库使用 Deliveries API 来直观呈现送货车辆以及任务。与 JavaScript 物流跟踪库一样,它包含一个 JavaScript 地图组件,可轻松替换标准 google.maps.Map 实体和数据组件,以便与 Fleet Engine 连接。

组件

JavaScript 舰队跟踪库提供了用于直观呈现送货车辆和停靠点的组件,以及有关预计到达时间或到送货的剩余距离的原始数据 Feed。

Fleet Tracking 地图视图

Fleet Tracking 地图视图组件可直观呈现车辆和任务的位置。如果车辆的路线已知,地图视图组件会在车辆沿着预测路径移动时以动画形式呈现车辆。

Fleet Tracking 地图视图示例

位置信息提供程序

位置信息提供程序使用存储在 Fleet Engine 中的信息,将所跟踪对象的位置信息发送到行程共享地图。

送货车辆位置信息提供程序

送货车辆位置信息提供程序会显示单个送货车辆的位置信息。其中包含有关车辆位置以及送货车辆已完成的任务的信息。

交付舰队位置信息提供程序

交付车队位置信息提供程序会显示多辆车的位置信息。您可以过滤出特定车辆或位置,也可以显示整个车队。

控制所跟踪位置的可见性

本部分介绍了 Fleet Engine 预定义位置信息提供程序在地图上跟踪的位置对象的可见性规则。自定义或派生的位置信息提供程序可能会更改公开范围规则。

送货车辆

在 Fleet Engine 中创建送货车辆后,它会立即显示;无论它执行什么任务,它在整个路线中都会显示。

任务地点标记

计划的车辆停靠点在地图上显示为车辆停靠站标记。已完成任务的标记以与车辆计划的停靠点不同的样式显示。

任务结果的位置与任务结果标记一起显示。结果显示成功的任务会显示成功任务标记,而所有其他任务会显示失败任务标记。

开始使用 JavaScript 舰队跟踪库

在使用 JavaScript 舰队跟踪库之前,请确保您已熟悉 Fleet Engine 以及获取 API 密钥。然后创建任务 ID 和送货车辆 ID 版权主张。

创建任务 ID 和送货车辆 ID 声明

如需使用送货车辆位置信息提供程序跟踪送货车辆,请创建带有任务 ID 和送货车辆 ID 声明的 JSON Web 令牌 (JWT)。

要创建 JWT 载荷,请在授权部分添加一个包含键 taskiddeliveryvehicleid 的额外声明,并将每个键的值设置为 *。应使用 Fleet Engine Service Super User 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_网址 取决于您的后端实现,下面是示例应用后端的网址:
    • 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
        .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);
    }
  }
});

监听错误

因请求传送舰队信息而异步发生的错误会触发错误事件。如需查看有关如何监听这些事件的示例,请参阅监听错误

停止跟踪

如需阻止位置信息提供程序跟踪交付舰队,请将位置信息提供程序的边界设置为 null。

JavaScript

locationProvider.locationRestriction = null;

TypeScript

locationProvider.locationRestriction = null;

从地图视图中移除位置信息提供程序

以下示例展示了如何从地图视图中移除位置信息提供程序。

JavaScript

mapView.removeLocationProvider(locationProvider);

TypeScript

mapView.removeLocationProvider(locationProvider);

跟踪送货车辆,还可查看送货车队

查看车队时,您可以显示特定送货车辆的路线和即将完成的任务。为此,请将配送车队位置信息提供程序和送货车辆位置信息提供程序都实例化,并将它们都添加到地图视图中:

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 地图的任何应用创建和修改地图样式,而无需更改代码。地图样式会以地图 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'
  }
});

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)进行过滤。也就是说,如果您需要其他过滤功能,可以使用自定义函数应用过滤。

Fleet Tracking 库提供以下自定义参数:

使用 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>

如果您在乌鲁鲁附近运营具有指定 ID 的送货车辆,则该车辆现在会渲染在地图上。