Skip to main content

Route Alarms

|

This example demonstrates how to calculate a route with overlay items, simulate navigation along it, and receive real-time alarm notifications when approaching hazards or points of interest.

Overview

The example demonstrates the following features:

  • Calculating routes containing social reports or overlay items
  • Setting up alarm listeners to track proximity to overlay items
  • Simulating navigation with alarm notifications
  • Displaying alarm information with distance and images
  • Managing alarm service with configurable alarm distance

Code Implementation

Importing SDK Components

index.ts
import {
GemKit,
GemMap,
Landmark,
RoutePreferences,
RoutingService,
NavigationService,
SearchService,
AlarmService,
AlarmListener,
GemError,
Route,
Coordinates,
RectangleGeographicArea,
SearchPreferences,
RouteRenderOptions,
TaskHandler,
RouteRenderSettings
} from '@magiclane/maps-sdk';

Setting Up Alarm Listener

index.ts
function startSimulation() {
const routes = map?.preferences.routes;
map?.preferences.routes.clearAllButMainRoute();

if (!routes?.mainRoute) {
showMessage('No main route available');
return;
}

alarmListener = new AlarmListener({
onOverlayItemAlarmsUpdated: (alarmsList: OverlayItemAlarmsList) => {
if (alarmsList.items && alarmsList.items.length > 0) {
closestOverlayItem = alarmsList.items.reduce((closest, current) =>
current.distance < closest.distance ? current : closest
);
updateUI();
} else {
closestOverlayItem = null;
updateUI();
}
},
onOverlayItemAlarmsPassedOver: () => {
closestOverlayItem = null;
updateUI();
},
});

try {
alarmService = new AlarmService(alarmListener);
alarmService.alarmDistance = 500;
}

Starting Navigation Simulation

index.ts
navigationHandler = NavigationService.startSimulation(
routes.mainRoute,
undefined,
{
onNavigationInstruction: (instruction: any, events: any) => {
isSimulationActive = true;
updateUI();
},
onDestinationReached: (landmark: any) => {
stopSimulation();
cancelRoute();
showMessage("Destination reached");
},
onError: (error: any) => {
isSimulationActive = false;
closestOverlayItem = null;
cancelRoute();
updateUI();
if (error !== GemError.cancel) stopSimulation();
},
}
);

map?.startFollowingPosition();

Searching for Overlay Items

index.ts
async function getReportFromMap(): Promise<Landmark | null> {
return new Promise((resolve) => {
const area = new RectangleGeographicArea({
topLeft: Coordinates.fromLatLong(52.59310690528571, 7.524257524882292),
bottomRight: Coordinates.fromLatLong(48.544623829072655, 12.815748995947535),
});

const searchPreferences = SearchPreferences.create({
searchAddresses: false,
searchMapPOIs: false,
});

try {
SearchService.searchInArea({
area: area,
referenceCoordinates: Coordinates.fromLatLong(51.02858483954893, 10.29982567727901),
onCompleteCallback: (err: GemError, results: Landmark[]) => {
if (err === GemError.success && results && results.length > 0) {
resolve(results[0]);
} else {
resolve(null);
}
},
preferences: searchPreferences
});
} catch (error) {
resolve(null);
}
});

Calculating Route with Reports

index.ts
async function getRouteWithReport(): Promise<Route | null> {
const initialStart = Landmark.withCoordinates(
Coordinates.fromLatLong(51.48345483353617, 6.851883736746337)
);
const initialEnd = Landmark.withCoordinates(
Coordinates.fromLatLong(49.01867442442069, 12.061988113314802)
);

const report = await getReportFromMap();

if (!report) {
// Fallback to simple route
const start = Landmark.withCoordinates(
Coordinates.fromLatLong(51.48345483353617, 6.851883736746337)
);
const end = Landmark.withCoordinates(
Coordinates.fromLatLong(50.1109221, 8.6821267)
);
return await calculateRoute([start, end]);
}

const initialRoute = await calculateRoute([initialStart, report, initialEnd]);
if (!initialRoute) return null;

// Crop route to area around the report
const reportDistanceInInitialRoute = initialRoute.getDistanceOnRoute(
report.coordinates,
true
);
const newStartCoords = initialRoute.getCoordinateOnRoute(
reportDistanceInInitialRoute - 600
);
const newEndCoords = initialRoute.getCoordinateOnRoute(
reportDistanceInInitialRoute + 200
);

const newStart = Landmark.withCoordinates(newStartCoords);
const newEnd = Landmark.withCoordinates(newEndCoords);

return await calculateRoute([newStart, report, newEnd, report, newStart]);
}

async function calculateRoute(waypoints: Landmark[]): Promise<Route | null> {
return new Promise((resolve) => {
RoutingService.calculateRoute(
waypoints,
new RoutePreferences({}),
(err: GemError, routes: Route[]) => {
if (err === GemError.success && routes && routes.length > 0) {
resolve(routes[0]);
} else {
resolve(null);
}
}
);
});
}

Rendering Route on Map

index.ts
const routesMap = map?.preferences.routes;
const routeRenderSettings = new RouteRenderSettings({
options: new Set([
RouteRenderOptions.showTraffic,
RouteRenderOptions.showHighlights,
])
});

routesMap?.add(route, true, {
routeRenderSettings: routeRenderSettings
});

map?.centerOnRoute(route);

Live Demo

Key Features

  • Alarm Listener: Monitor proximity to overlay items during navigation with customizable callbacks
  • Alarm Service: Configure alarm distance threshold and track multiple overlay types
  • Overlay Item Search: Search for social reports and other overlay items within geographic areas
  • Route Calculation: Calculate routes that include overlay items as waypoints
  • Navigation Simulation: Simulate navigation along routes with real-time alarm updates
  • Visual Feedback: Display alarm information including distance and overlay item images

Explanation of Key Components

  • AlarmListener: Interface for receiving notifications when approaching or passing overlay items during navigation
  • AlarmService: Service that monitors position relative to overlay items and triggers alarms based on distance threshold
  • alarmDistance: Configurable property defining the distance (in meters) at which alarms are triggered
  • onOverlayItemAlarmsUpdated: Callback invoked when alarm list is updated, providing sorted list of nearby overlay items
  • onOverlayItemAlarmsPassedOver: Callback triggered when all active alarms have been passed
  • SearchService.searchInArea(): Search for landmarks and overlay items within a defined geographic area
  • RouteRenderSettings: Configures route visualization options including traffic and highlights
  • NavigationService.startSimulation(): Begins simulated navigation with navigation instruction callbacks

Next Steps