MSI Navigation & Entities
Turn-by-turn navigation and real-time entity tracking on the map.
Navigation & Entities Overview
This API enables:
- Turn-by-turn navigation with voice guidance
- Real-time position updates during navigation
- Fleet tracking and nearby entity management
- Navigation events and lifecycle management
- External navigation data casting
Navigation Operations
Complete navigation lifecycle from mounting to dismissal.
mountNavigation()
Prepare a route for navigation (required before starting).
Mount Navigation
Prepare the route and UI
await controls.mountNavigation({
route: routeId, // Route to navigate
simulateLocation: false, // Use real GPS (false) or simulation (true)
voiceGuidance: true, // Enable voice instructions
speedLimit: true, // Show speed limit warnings
alternatives: true // Show alternative routes during nav
})
console.log('Navigation mounted and ready')2
3
4
5
6
7
8
9
Parameters:
{
route?: string // Route ID (uses current if omitted)
simulateLocation?: boolean // Simulate movement (for testing)
voiceGuidance?: boolean // Turn-by-turn voice
speedLimit?: boolean // Speed limit display
alternatives?: boolean // Alternative route suggestions
units?: 'metric' | 'imperial'
}2
3
4
5
6
7
8
loadNavigation()
Start the navigation session.
Load Navigation
Begin turn-by-turn guidance
await controls.loadNavigation()
console.log('Navigation started')
// User will now see turn-by-turn instructions2
3
4
This displays the navigation UI with:
- Current instruction
- Distance to next turn
- Estimated time of arrival
- Remaining distance
setInitialNavigationPosition()
Set starting position for navigation (useful when user is not at route origin).
Set Starting Position
Begin from specific location
await controls.setInitialNavigationPosition({
lng: -74.0060,
lat: 40.7128
}, {
snapToRoute: true, // Snap to nearest route point
heading: 45 // Initial heading (degrees)
})2
3
4
5
6
7
navigate()
Provide real-time position updates during navigation.
Real-time Position Updates
Update position as user moves
// Get location updates from GPS
navigator.geolocation.watchPosition(async (position) => {
await controls.navigate({
lng: position.coords.longitude,
lat: position.coords.latitude,
heading: position.coords.heading,
speed: position.coords.speed,
accuracy: position.coords.accuracy
})
}, {
enableHighAccuracy: true,
maximumAge: 0
})2
3
4
5
6
7
8
9
10
11
12
13
Navigation State Updates:
controls.on('navigation:instruction', (instruction) => {
console.log('Next:', instruction.text)
console.log('Distance:', instruction.distance, 'meters')
console.log('Duration:', instruction.duration, 'seconds')
})
controls.on('navigation:progress', (progress) => {
console.log('Completed:', progress.percentage, '%')
console.log('Remaining:', progress.distanceRemaining, 'meters')
console.log('ETA:', progress.eta)
})2
3
4
5
6
7
8
9
10
11
casting()
Feed external navigation data (e.g., from Google Maps, Apple Maps).
Cast External Navigation
Use navigation from other sources
// Receive navigation updates from external source
externalNavigationService.on('update', async (navData) => {
await controls.casting({
position: {
lng: navData.longitude,
lat: navData.latitude,
heading: navData.bearing
},
instruction: {
text: navData.currentInstruction,
distance: navData.distanceToNextManeuver,
maneuver: navData.maneuverType
},
route: {
distanceRemaining: navData.remainingDistance,
durationRemaining: navData.remainingTime,
eta: navData.estimatedArrival
}
})
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Use Cases:
- Integrate with third-party navigation
- Display navigation from native apps
- Sync with external routing services
dismissNavigation()
End the navigation session.
Dismiss Navigation
Stop navigation and hide UI
await controls.dismissNavigation()
console.log('Navigation ended')2
3
This removes the navigation UI but keeps the route visible.
unmountNavigation()
Complete cleanup of navigation session.
Unmount Navigation
Full navigation cleanup
await controls.unmountNavigation()
console.log('Navigation fully unmounted')2
3
This removes all navigation state and UI elements.
Navigation Events
Listen to navigation lifecycle and state changes.
Navigation Lifecycle Events
controls.on('navigation:started', (data) => {
console.log('Navigation started:', data)
showNavigationUI()
})
controls.on('navigation:stopped', () => {
console.log('Navigation stopped')
hideNavigationUI()
})
controls.on('navigation:paused', () => {
console.log('Navigation paused')
})
controls.on('navigation:resumed', () => {
console.log('Navigation resumed')
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Navigation Progress Events
controls.on('navigation:instruction', (instruction) => {
// Next maneuver instruction
console.log('Instruction:', instruction.text)
console.log('Distance:', instruction.distance)
// Speak instruction
if (voiceEnabled) {
speak(instruction.text)
}
})
controls.on('navigation:maneuver', (maneuver) => {
// Upcoming maneuver details
console.log('Maneuver type:', maneuver.type)
console.log('Modifier:', maneuver.modifier)
console.log('In:', maneuver.distance, 'meters')
})
controls.on('navigation:progress', (progress) => {
// Overall progress
console.log('Progress:', progress.percentage, '%')
console.log('Distance remaining:', progress.distanceRemaining)
console.log('Time remaining:', progress.durationRemaining)
console.log('ETA:', progress.eta)
updateProgressBar(progress.percentage)
updateETA(progress.eta)
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Navigation Status Events
controls.on('navigation:rerouting', (reason) => {
console.log('Rerouting because:', reason)
showRerouteNotification()
})
controls.on('navigation:reroute', (newRoute) => {
console.log('New route calculated:', newRoute)
updateRoute(newRoute)
})
controls.on('navigation:offroute', (deviation) => {
console.log('Off route by:', deviation, 'meters')
showOffRouteWarning()
})
controls.on('navigation:nearby', (data) => {
console.log('Approaching waypoint:', data.waypoint)
console.log('Distance:', data.distance)
})
controls.on('navigation:arrived', (waypoint) => {
console.log('Arrived at:', waypoint)
playArrivalSound()
})
controls.on('navigation:complete', () => {
console.log('Journey complete!')
showCompletionScreen()
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Speed & Traffic Events
controls.on('navigation:speeding', (data) => {
console.log('Speed limit:', data.limit, 'km/h')
console.log('Current speed:', data.current, 'km/h')
showSpeedWarning()
})
controls.on('navigation:traffic', (traffic) => {
console.log('Traffic level:', traffic.severity)
console.log('Delay:', traffic.delay, 'seconds')
if (traffic.severity === 'high') {
suggestAlternativeRoute()
}
})2
3
4
5
6
7
8
9
10
11
12
13
14
Nearby Entities
Display and manage multiple entities (vehicles, drivers, points of interest) on the map.
showNearby()
Display multiple entities at once.
Show Multiple Entities
Display fleet or POIs
await controls.showNearby([
{
id: 'vehicle-1',
type: 'vehicle',
grade: 'primary',
position: { lng: -74.0060, lat: 40.7128 },
label: 'Truck 101',
heading: 45,
metadata: {
driver: 'John Doe',
status: 'available'
}
},
{
id: 'vehicle-2',
type: 'vehicle',
grade: 'secondary',
position: { lng: -73.9951, lat: 40.7489 },
label: 'Van 202',
heading: 180,
metadata: {
driver: 'Jane Smith',
status: 'busy'
}
},
{
id: 'warehouse-1',
type: 'warehouse',
grade: 'primary',
position: { lng: -74.0100, lat: 40.7100 },
label: 'Main Warehouse',
icon: 'warehouse'
}
])2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Entity Types:
vehicle- Cars, trucks, vansdriver- Delivery personnelwarehouse- Distribution centershub- Collection pointscustomer- Delivery locationspoi- Points of interestcustom- Custom entity types
Entity Grades:
primary- Main/active entities (larger, more prominent)secondary- Supporting entities (smaller, less prominent)tertiary- Background entities (minimal display)
addNearbyEntity()
Add a single entity to the map.
Add Single Entity
Add one entity
const entityId = await controls.addNearbyEntity({
id: 'driver-123',
type: 'driver',
grade: 'primary',
position: { lng: -74.0060, lat: 40.7128 },
label: 'Driver: Mike',
sublabel: 'En route',
heading: 90,
icon: 'delivery-person',
color: '#0ea5e9',
// Interactive
clickable: true,
onClick: (entity) => {
showDriverDetails(entity)
}
})
console.log('Entity added:', entityId)2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
moveNearbyEntity()
Update an entity's position (for live tracking).
Move Entity
Update position in real-time
// Update vehicle position from GPS/API
socket.on('vehicle:location', async (update) => {
await controls.moveNearbyEntity(update.vehicleId, {
position: {
lng: update.longitude,
lat: update.latitude
},
heading: update.bearing,
speed: update.speed,
// Optional: smooth animation
animate: true,
duration: 1000
})
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
updateNearbyEntity()
Update entity properties (label, color, metadata).
await controls.updateNearbyEntity('vehicle-1', {
label: 'Truck 101 - Delivering',
color: '#10b981',
metadata: {
status: 'busy',
currentOrder: 'ORD-123'
}
})2
3
4
5
6
7
8
removeNearbyEntity()
Remove a single entity from the map.
await controls.removeNearbyEntity('vehicle-1')removeNearby()
Remove all nearby entities.
await controls.removeNearby()getNearbyEntities()
Get all current entities on the map.
const entities = await controls.getNearbyEntities()
console.log('Active entities:', entities.length)
entities.forEach(entity => {
console.log(`${entity.label} at ${entity.position.lat}, ${entity.position.lng}`)
})2
3
4
5
6
7
Event Listeners
Manage event subscriptions.
on()
Subscribe to map and navigation events.
const handler = (data) => {
console.log('Event data:', data)
}
controls.on('navigation:started', handler)
controls.on('entity:clicked', handler)
controls.on('route:created', handler)2
3
4
5
6
7
Available Events:
- Navigation:
navigation:*(started, stopped, instruction, progress, etc.) - Route:
route:*(created, updated, cleared) - Entity:
entity:*(added, moved, removed, clicked) - Map:
map:*(clicked, moved, zoomed) - Location:
location:*(updated, error)
off()
Unsubscribe from specific event.
controls.off('navigation:started', handler)removeListeners()
Remove all event listeners (cleanup).
controls.removeListeners()once()
Listen to event only once.
controls.once('navigation:complete', () => {
console.log('Journey finished - this will only run once')
showCompletionScreen()
})2
3
4
Complete Examples
Full Navigation Flow
import De from '@de./sdk'
const msi = new De.MSI({
element: 'map',
accessToken: token
})
const { controls } = await msi.load()
// Create route
const route = await controls.setRoute({
origin: pickupLocation,
destination: deliveryLocation,
options: {
profile: 'driving-traffic'
}
})
// Setup navigation
await controls.mountNavigation({
voiceGuidance: true,
speedLimit: true
})
// Listen to events
controls.on('navigation:instruction', (instruction) => {
updateInstructionUI(instruction.text)
speakInstruction(instruction.text)
})
controls.on('navigation:progress', (progress) => {
updateProgressBar(progress.percentage)
updateETA(progress.eta)
})
controls.on('navigation:arrived', async () => {
await controls.dismissNavigation()
showArrivalScreen()
})
// Start navigation
await controls.loadNavigation()
// Track real-time position
navigator.geolocation.watchPosition(async (pos) => {
await controls.navigate({
lng: pos.coords.longitude,
lat: pos.coords.latitude,
heading: pos.coords.heading,
speed: pos.coords.speed
})
}, {
enableHighAccuracy: true,
maximumAge: 0
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Fleet Tracking Dashboard
class FleetTracker {
private controls: MSIControls
private vehicles = new Map()
constructor(controls: MSIControls) {
this.controls = controls
}
async initialize(vehicleList: Vehicle[]) {
// Display all vehicles
await this.controls.showNearby(
vehicleList.map(v => ({
id: v.id,
type: 'vehicle',
grade: v.status === 'active' ? 'primary' : 'secondary',
position: v.location,
label: v.name,
heading: v.heading,
metadata: v
}))
)
vehicleList.forEach(v => this.vehicles.set(v.id, v))
}
async updateVehicle(vehicleId: string, update: LocationUpdate) {
await this.controls.moveNearbyEntity(vehicleId, {
position: update.location,
heading: update.heading,
animate: true,
duration: 1000
})
const vehicle = this.vehicles.get(vehicleId)
if (vehicle) {
vehicle.location = update.location
vehicle.heading = update.heading
}
}
async setVehicleStatus(vehicleId: string, status: string) {
const color = {
'available': '#10b981',
'busy': '#0ea5e9',
'offline': '#6b7280'
}[status]
await this.controls.updateNearbyEntity(vehicleId, {
color,
metadata: { status }
})
}
getVehiclesInArea(bounds: Bounds): Vehicle[] {
return Array.from(this.vehicles.values()).filter(v =>
this.isInBounds(v.location, bounds)
)
}
private isInBounds(location: Location, bounds: Bounds): boolean {
return (
location.lng >= bounds.southwest.lng &&
location.lng <= bounds.northeast.lng &&
location.lat >= bounds.southwest.lat &&
location.lat <= bounds.northeast.lat
)
}
}
// Usage
const fleet = new FleetTracker(controls)
await fleet.initialize(vehicles)
// Real-time updates
socket.on('vehicle:location', (update) => {
fleet.updateVehicle(update.vehicleId, update)
})
socket.on('vehicle:status', (update) => {
fleet.setVehicleStatus(update.vehicleId, update.status)
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Navigation with Delivery Stops
async function startDeliveryRoute(stops: DeliveryStop[]) {
// Create multi-stop route
const route = await controls.setRoute({
origin: depot,
waypoints: stops.map(s => ({
...s.location,
id: s.orderId
})),
destination: depot,
options: {
profile: 'driving-traffic',
optimizeWaypoints: true
}
})
let currentStopIndex = 0
// Mount navigation
await controls.mountNavigation({
voiceGuidance: true
})
// Handle waypoint arrival
controls.on('navigation:arrived', async (waypoint) => {
const stop = stops[currentStopIndex]
// Mark stop as arrived
await controls.updateWaypointCaption(waypoint.id, {
status: 'arrived',
color: '#10b981'
})
// Show delivery UI
showDeliveryScreen(stop)
// Pause navigation
await controls.dismissNavigation()
// Wait for delivery completion
await waitForDeliveryComplete(stop)
// Mark as complete
await controls.updateWaypointCaption(waypoint.id, {
status: 'completed'
})
currentStopIndex++
// Continue to next stop or complete
if (currentStopIndex < stops.length) {
await controls.loadNavigation()
} else {
console.log('All deliveries complete!')
await controls.unmountNavigation()
showCompletionScreen()
}
})
// Start navigation
await controls.loadNavigation()
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Type Definitions
interface NavigationOptions {
route?: string
simulateLocation?: boolean
voiceGuidance?: boolean
speedLimit?: boolean
alternatives?: boolean
units?: 'metric' | 'imperial'
}
interface NavigationInstruction {
text: string
distance: number
duration: number
maneuver: {
type: string
modifier?: string
location: Location
}
}
interface NavigationProgress {
percentage: number
distanceRemaining: number
durationRemaining: number
distanceTraveled: number
eta: string
}
interface NearbyEntity {
id: string
type: 'vehicle' | 'driver' | 'warehouse' | 'hub' | 'customer' | 'poi' | 'custom'
grade: 'primary' | 'secondary' | 'tertiary'
position: Location
label?: string
sublabel?: string
heading?: number
icon?: string
color?: string
clickable?: boolean
onClick?: (entity: NearbyEntity) => void
metadata?: any
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

