The JavaScript Fleet Tracking Library lets you visualize the locations
of vehicles in their fleets in near real time. The library uses the
Deliveries API
to allow visualization of delivery vehicles as well as tasks. Like the
JavaScript Shipment Tracking Library,
it contains a JavaScript map component that is a drop-in replacement
for a standard google.maps.Map
entity and data components to connect
with Fleet Engine.
Components
The JavaScript Fleet Tracking Library provides components for visualization of delivery vehicles and stops, as well as raw data feeds for ETA or remaining distance to a delivery.
Fleet Tracking map view
The Fleet Tracking map view component visualizes the location of vehicles and tasks. If the route for a vehicle is known, the map view component animates that vehicle as it moves along its predicted path.
Location providers
Location providers work with information stored in Fleet Engine to send location information for tracked objects into the journey sharing map.
Delivery vehicle location provider
The delivery vehicle location provider displays a single delivery vehicle's location information. It has information on the vehicle location as well as the tasks that were completed by the delivery vehicle.
Delivery fleet location provider
The delivery fleet location provider displays multiple vehicles' location information. You can filter for specific vehicles or locations, or you can show the whole fleet.
Control the visibility of tracked locations
This section describes the visibility rules for tracked location objects on the map for the Fleet Engine predefined location provider. Custom or derived location providers may change the visibility rules.
Delivery vehicles
A delivery vehicle is visible as soon as it is created in Fleet Engine, and is visible throughout its route regardless of its tasks.
Task location markers
Planned vehicle stops are shown on the map as vehicle stop markers. Markers for completed tasks are displayed with a different style than a vehicle's planned stops.
The location of task outcomes are displayed with task outcome markers. Tasks with a SUCCEEDED outcome are displayed with successful task markers, while all other tasks are displayed with unsuccessful task markers.
Get started with the JavaScript Fleet Tracking Library
Before using the JavaScript Fleet Tracking Library make sure you are familiar with Fleet Engine and with getting an API key. Then create a task ID and delivery vehicle ID claim.
Create a task ID and delivery vehicle ID claim
To track delivery vehicles using the delivery vehicle location provider, create a JSON Web Token (JWT) with a task ID and delivery vehicle ID claim.
To create the JWT payload, add an additional claim in the authorization section with the keys taskid and deliveryvehicleid and set the value of each key to *. The token should be created using the Fleet Engine Service Super User Cloud IAM role. Note that this grants broad access to create, read, and modify Fleet Engine entities, and should only be shared with trusted users.
The following example shows how to create a token for tracking by vehicle and task:
{
"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": "*",
}
}
Create an authentication token fetcher
You can create an authentication token fetcher to retrieve a token minted with the appropriate claims on your servers using a service account certificate for your project. It is important to only mint tokens on your servers and never share your certificates on any clients. Otherwise, you will compromise the security of your system.
The fetcher must return a data structure with two fields, wrapped in a Promise:
- A string
token
. - A number
expiresInSeconds
. A token expires in this amount of time after fetching.
The JavaScript Fleet Tracking Library requests a token via the authentication token fetcher when any of the following is true:
- It does not have a valid token, such as when it hasn't called the fetcher on a fresh page load, or when the fetcher hasn't returned with a token.
- The token it fetched previously has expired.
- The token it fetched previously is within one minute of expiring.
Otherwise, the library uses the previously issued, still valid token and does not call the fetcher.
The following example shows how to create an authentication token fetcher:
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(),
};
}
When implementing the server-side endpoint for minting the tokens, keep the following in mind:
- The endpoint must return an expiry time for the token; in the example
above, it is given as
data.ExpiresInSeconds
. - The authentication token fetcher must pass the expiry time (in seconds, from time of fetching) to the library, as shown in the example.
- The SERVER_TOKEN_URL depends on your backend implementation, these are the URLs for the sample app backend:
- https://
SERVER_URL
/token/delivery_driver/DELIVERY_VEHICLE_ID
- https://
SERVER_URL
/token/delivery_consumer/TRACKING_ID
- https://
SERVER_URL
/token/fleet_reader
- https://
Loading a map from HTML
The following example shows how to load the JavaScript Journey Sharing
library from a specified URL. The callback parameter executes the initMap
function after the API loads. The defer attribute lets the browser
continue rendering the rest of your page while the API loads.
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=journeySharing" defer></script>
Follow a delivery vehicle
This section shows how to use the JavaScript Fleet Tracking Library to follow a delivery vehicle. Make sure to load the library from the callback function specified in the script tag before running your code.
Instantiate a delivery vehicle location provider
The JavaScript Fleet Tracking Library predefines a location provider for the Fleet Engine Deliveries API. Use your project ID and a reference to your token factory to instantiate it.
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',
});
Initialize the map view
After loading the JavaScript Journey Sharing library, initialize the map view and add it to the HTML page. Your page should contain a <div> element that holds the map view. The <div> element is named map_canvas in the example below.
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);
Listen to change events
You can retrieve meta information about a task from the deliveryVehicle
object
using the location provider. The meta information includes the ETA and
remaining distance before the vehicle's next pickup or dropoff. Changes
to the meta information trigger an update event. The following example
shows how to listen to these change events.
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);
}
});
Listen for errors
Errors that arise asynchronously from requesting delivery vehicle information trigger error events. The following example shows how to listen for these events in order to handle errors.
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);
});
Stop tracking
To stop the location provider from tracking the delivery vehicle, remove the delivery vehicle ID from the location provider.
JavaScript
locationProvider.deliveryVehicleId = '';
TypeScript
locationProvider.deliveryVehicleId = '';
Remove the location provider from the map view
The following example shows how to remove a location provider from the map view.
JavaScript
mapView.removeLocationProvider(locationProvider);
TypeScript
mapView.removeLocationProvider(locationProvider);
View a delivery fleet
This section shows how to use the JavaScript Journey Sharing library to view a delivery fleet. Make sure to load the library from the callback function specified in the script tag before running your code.
Instantiate a delivery fleet location provider
The JavaScript Fleet Tracking Library predefines a location provider that fetches multiple vehicles from the FleetEngine Deliveries API. Use your project ID as well as as a reference to your token fetcher to instantiate it.
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
specifies a query used to filter vehicles displayed on
the map. This filter is passed directly to Fleet Engine. See
ListDeliveryVehiclesRequest.filter
for supported formats.
locationRestriction
limits the area in which to display vehicles on the map.
It also controls whether location tracking is active or not. Location tracking
will not start until this is set.
Once the location provider is constructed, initialize the map view.
Set location restriction using the map viewport
The locationRestriction
bounds can be configured to match the area currently
visible in the map view.
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;
}
});
Listen to change events
You can retrieve meta information about the fleet from the deliveryVehicles
object using the location provider. The meta information includes vehicle
properties such as navigation state, remaining distance and custom attributes;
see
reference documentation
for more details. Change to the meta information trigger an update event. The
following example shows how to listen to these change events.
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);
}
}
});
Listen for errors
Errors that arise asynchronously from requesting delivery fleet information trigger error events. For examples showing how to listen for these events, refer to Listen for errors.
Stop tracking
To stop the location provider from tracking the delivery fleet, set the bounds of the location provider to null.
JavaScript
locationProvider.locationRestriction = null;
TypeScript
locationProvider.locationRestriction = null;
Remove the location provider from the map view
The following example shows how to remove a location provider from the map view.
JavaScript
mapView.removeLocationProvider(locationProvider);
TypeScript
mapView.removeLocationProvider(locationProvider);
Track a delivery vehicle while viewing a delivery fleet
While viewing a fleet, you can show the route and upcoming tasks for a specific delivery vehicle. To do this, instantiate both a Delivery Fleet Location Provider and a Delivery Vehicle Location Provider, and add them both to the map view:
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
});
The delivery fleet location provider starts to show delivery vehicles on the map. Use marker customization to enable the delivery vehicle location provider to track a delivery vehicle when its fleet marker has been clicked:
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();
});
}
};
Hide the marker from the delivery vehicle location provider to prevent rendering two markers for the same vehicle:
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);
}
};
Customize the look and feel of the base map
To customize the look and feel of the maps component, style your map using cloud-based tooling or by setting options directly in code.
Use cloud-based map styling
Cloud-based maps styling
lets you create and edit map styles for any of your apps that use Google Maps
from the Google Cloud console without requiring any changes to your code.
The map styles are saved as map IDs in your Cloud project. To
apply a style to your JavaScript Fleet Tracking map, specify a
mapId
when you create the JourneySharingMapView
. The mapId
field cannot be changed
or added after the JourneySharingMapView
has been instantiated. The following
example shows how to enable a previously created map style with a
map 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'
}
});
Use code-based map styling
Another way of customizing map styling is to set
mapOptions
when you
create the JourneySharingMapView
.
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" }
]
}
]
}
});
Change the styling and visibility of routes
To configure the styling and visibility of taken and anticipated routes, use custom styling options. For more information, see PolylineOptions interface.
The following example shows how to configure the styling and visibility
of anticipated routes. To configure the styling and visibility of taken routes,
use takenRoutePolylineSetup
instead of anticipatedRoutePolylineSetup
.
JavaScript
// This function is specified in the
// JourneySharingMapView constructor's options
// parameter.
function anticipatedRoutePolylineSetup({
defaultPolylineOptions, defaultVisible}) {
// If this function is not specified, the
// PolylineOptions object contained in
// defaultPolylineOptions is used to render the
// anticipated route polyline. visible property sets the
// polyline's visibility. Modify this object and
// pass it back to customize the style of the map.
defaultPolylineOptions.strokeOpacity = 0.5;
defaultPolylineOptions.strokeColor = 'red';
return {
polylineOptions: defaultPolylineOptions,
visible: true
};
}
// As an alternative, set static PolylineOptions to
// use for the anticipated route.
const anticipatedRoutePolylineOptionsSetup = {
polylineOptions: {
strokeOpacity: 0.5,
strokeColor: 'red',
…
},
visible: true,
};
TypeScript
// This function is specified in the
// JourneySharingMapView constructor's options
// parameter.
function anticipatedRoutePolylineSetup(options: {
defaultPolylineOptions: google.maps.PolylineOptions,
visible: boolean,
}): {
polylineOptions: google.maps.PolylineOptions,
visible: boolean,
} {
// If this function is not specified, the
// PolylineOptions object contained in
// defaultPolylineOptions is used to render the
// anticipated route polyline. visible property sets the
// polyline's visibility. Modify this object and
// pass it back to customize the style of the map.
options.defaultPolylineOptions.strokeOpacity = 0.5;
options.defaultPolylineOptions.strokeColor = 'red';
return {
polylineOptions: options.defaultPolylineOptions,
visible: true
};
}
// As an alternative, set static PolylineOptions to
// use for the anticipated route.
const anticipatedRoutePolylineSetup = {
polylineOptions: {
strokeOpacity: 0.5,
strokeColor: 'red',
…
},
visible: true,
};
Use marker customizations
With the JavaScript Fleet Tracking Library, you can customize the look and feel of markers added to the map. You do this by specifying marker customizations, which the Fleet Tracking Library then applies before adding markers to the map and with every marker update.
The simplest customization is to specify a
MarkerOptions
object that will be applied to all markers of the same type. The changes
specified in the object are applied after each marker has been created,
overwriting any default options.
A more advanced option is to specify a customization function. Customization functions allow for styling of the markers based on data, as well as adding interactivity to markers, such as click handling. Specifically, Fleet Tracking passes data to the customization function about the type of object the marker represents: vehicle, stop, or task. This then allows marker styling to change based on the current state of the marker element itself; for example, the number of remaining stops or type of task. You can even join against data from sources outside Fleet Engine and style the marker based on that information.
Additionally, you can use customization functions to filter marker visibility.
To do this, call
setVisible(false)
on the marker.
However, for performance reasons, we recommend filtering with the native
filtering in the location provider, such as
FleetEngineDeliveryFleetLocationProvider.deliveryVehicleFilter
.
That said, when you need additional filtering functionality, you can apply
filtering using the customization function.
The Fleet Tracking library provides the following customization parameters:
Change the styling of markers using MarkerOptions
The following example shows how to configure a vehicle marker's styling with
a MarkerOptions
object. Follow this pattern to customize the styling of any
marker using any of the marker customization parameters listed above.
JavaScript
deliveryVehicleMarkerCustomization = {
cursor: 'grab'
};
TypeScript
deliveryVehicleMarkerCustomization = {
cursor: 'grab'
};
Change the styling of markers using customization functions
The following example shows how to configure a vehicle marker's styling. Follow this pattern to customize the styling of any marker using any of the marker customization parameters listed above.
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}`);
};
Add click handling to markers
The following example shows how to add click handling to a vehicle marker. Follow this pattern to add click handling to any marker using any of the marker customization parameters listed above.
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.
});
}
};
Filter visible markers
The following example shows how to filter which vehicle markers are visible. Follow this pattern to filter any markers using any of the marker customization parameters listed above.
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);
}
};
Display an InfoWindow
for a vehicle or location marker
You can use an InfoWindow
to display additional information about a vehicle or location marker.
The following example shows how to create an InfoWindow
and attach it
to a vehicle marker.
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();
Disable automatic fitting
You can stop the map from automatically fitting the viewport to the vehicle and anticipated route by disabling automatic fitting. The following example shows how to disable automatic fitting when you configure the journey sharing map view.
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,
...
});
Replace an existing map
You can replace an existing map that includes markers or other customizations without losing those customizations.
For example, suppose you have a web page with a standard google.maps.Map
entity on which a marker is shown:
<!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>
To add the JavaScript Journey Sharing library, which includes Fleet Tracking:
- Add code for the authentication token factory.
- Initialize a location provider in the
initMap()
function. - Initialize the map view in the
initMap()
function. The view contains the map. - Move your customization into the callback function for the map view initialization.
- Add the location library to the API loader.
The following example shows the changes to be made:
<!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>
If you operate a delivery vehicle with the specified ID near Uluru, it will now be rendered on the map.