使用 JavaScript 物流跟踪库跟踪运单

借助 JavaScript 物流跟踪库,您可以直观呈现在 Fleet Engine 中跟踪的车辆位置和感兴趣的位置。该库包含一个 JavaScript 地图组件,可轻松替换标准 google.maps.Map 实体和数据组件,以便与 Fleet Engine 连接。使用 JavaScript 物流跟踪库,您可以在 Web 应用中提供可定制的动画式货运跟踪体验。

组件

JavaScript 物流跟踪库提供用于直观呈现车辆和路线前往目的地时的组件,以及有关驾驶员预计到达时间或剩余行驶距离的原始数据 Feed。

物流跟踪地图视图

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

运送地点提供商

配送位置提供程序会将所跟踪对象的位置信息馈送到配送跟踪地图,以进行第一英里和最后一公里货运跟踪。

您可以使用配送地点提供商来跟踪:

  • 货物的取货或送货地点。
  • 送货车辆的位置和路线。

已跟踪的位置对象

位置信息提供程序会跟踪车辆和目的地等对象的位置。

目标位置

目的地是旅程的结束位置。对于货物跟踪,这是计划的任务位置。

车辆位置

车辆位置是指跟踪到的车辆位置。它可以选择性地包含车辆的路线。

身份验证令牌提取器

如需控制对存储在 Fleet Engine 中的位置数据的访问权限,您必须在服务器上为 Fleet Engine 实现 JSON 网络令牌 (JWT) 创建服务。然后,在您的 Web 应用中实现身份验证令牌提取器,使用 JavaScript 历程共享库来验证对位置数据的访问。

样式选项

标记和多段线样式决定了地图上所跟踪的位置对象的外观和风格。您可以使用自定义样式选项来更改默认样式,使其与您的 Web 应用的样式一致。

控制所跟踪位置的可见性

本部分介绍了地图上被跟踪对象的可见性控制。这些规则适用于两类对象:

  • 地点标记
  • 任务数据

位置标记可见性

地图上会始终显示出发地和目的地的所有位置标记。例如,无论配送状态如何,地图上始终会显示配送地点。

任务数据可见性

本部分介绍适用于任务数据(例如车辆位置和剩余路线)的默认可见性规则。您可以自定义许多任务,但并非所有任务:

  • 不可用任务 - 您无法自定义这些任务的显示设置。
  • 活跃车辆任务 - 您可以自定义这些类型的任务。
  • 车辆任务 - 您无法自定义这些任务的显示设置。

不可用任务

如果前往所跟踪任务的路线上至少有一个不可用任务(例如,驾驶员正在休息或给车辆加油),车辆将不可见。但仍会提供预计到达时间和预计任务完成时间。

正在进行的车辆任务

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 且剩余行驶距离至少为 3000 米时,车辆位置才会显示。

开始使用 JavaScript 历程共享库

在使用 JavaScript 历程共享库之前,请确保您已熟悉 Fleet Engine 以及获取 API 密钥

要跟踪送货情况,请先创建跟踪 ID 版权主张。

创建跟踪 ID 版权主张

如需使用发货位置提供商跟踪运送情况,请创建带有跟踪 ID 声明的 JSON 网络令牌 (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_网址 取决于您的后端实现,下面是示例应用后端的网址:
    • 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.
      });
    }
  };

使用多段线自定义选项

借助 Shipment Tracking Library,您还可以在地图上自定义配送路线的外观和风格。该库会为运单的有效或剩余路径中的每对坐标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>

如果您在乌鲁鲁附近有带指定 ID 的受跟踪包裹,它现在会渲染在地图上。