Skip to main content

Calculate Route

|

This example demonstrates how to create a web application that calculates a route between two locations and displays it on a map using Maps SDK for TypeScript.

How it works

The example app demonstrates the following features:

  • Calculate a route between two landmarks (Paris to Brussels).
  • Display the route on a map and allow user interaction with the route.
  • Provide options to cancel route calculation or clear the routes from the map.
  • Select alternative routes by clicking on them.

Live Demo

Try the interactive demo below. Click "Build Route" to calculate a route between Paris and Brussels:

Code Implementation

Route Calculation and Map Integration

This code handles the calculation of routes between two landmarks, displays the routes on the map, and provides options to cancel or clear the routes. The map is centered on the calculated routes, and a label showing the distance and duration is displayed.

index.ts
import {
GemKit,
GemMap,
Landmark,
RoutePreferences,
RoutingService,
GemError,
Route
} from '@magiclane/maps-sdk';

let map: GemMap | null = null;
let routingHandler: any = null;
let routes: Route[] | null = null;

function onBuildRouteButtonPressed() {
// Define the departure (Paris)
const departureLandmark = Landmark.withLatLng({
latitude: 48.85682,
longitude: 2.34375
});

// Define the destination (Brussels)
const destinationLandmark = Landmark.withLatLng({
latitude: 50.84644,
longitude: 4.34587
});

// Define the route preferences
const routePreferences = new RoutePreferences({});
showMessage('The route is calculating.');

// Calculate route
routingHandler = RoutingService.calculateRoute(
[departureLandmark, destinationLandmark],
routePreferences,
(err: GemError, calculatedRoutes: Route[]) => {
routingHandler = null;

if (err === GemError.success) {
const routesMap = map?.preferences.routes;

// Display the routes on map
calculatedRoutes.forEach((route, index) => {
// Add route with label
const label = getRouteLabel(route);
routesMap?.add(route, index === 0, { label });
});

// Center the camera on routes
map?.centerOnRoutes({ routes: calculatedRoutes });
showMessage('Route calculated successfully!');

routes = calculatedRoutes;
} else {
showMessage('Route calculation failed.');
}

updateUI();
}
);

updateUI();
}

Clear and Cancel Functionality

Handle clearing routes from the map and canceling ongoing calculations:

index.ts
// Clear routes functionality
function onClearRoutesButtonPressed() {
// Remove the routes from map
map?.preferences.routes.clear();
routes = null;
updateUI();
}

// Cancel route calculation
function onCancelRouteButtonPressed() {
if (routingHandler) {
RoutingService.cancelRoute(routingHandler);
routingHandler = null;
showMessage('Route calculation cancelled.');
}
updateUI();
}

Route Selection

Enable the user to select a specific route on the map by clicking on it. The selected route becomes the main route displayed:

index.ts
// Register route tap callback for selecting alternative routes
function registerRouteTapCallback() {
if (!map) return;

map.registerTouchCallback(async (pos: any) => {
// Select the map objects at given position
await map.setCursorScreenPosition(pos);

// Get the selected routes
const selectedRoutes = map.cursorSelectionRoutes();

// If there is a route at position, select it as the main one
if (selectedRoutes.length > 0) {
const routesMap = map.preferences.routes;
if (routesMap) {
routesMap.mainRoute = selectedRoutes[0];
}
}
});
}

Displaying Route Information

Utility functions to format and display route information:

index.ts
// Utility function to get route label (distance and duration)
function getRouteLabel(route: Route): string {
const timeDistance = route.getTimeDistance();
const totalDistance = timeDistance.unrestrictedDistanceM +
timeDistance.restrictedDistanceM;
const totalDuration = timeDistance.unrestrictedTimeS +
timeDistance.restrictedTimeS;

return `${convertDistance(totalDistance)}\n${convertDuration(totalDuration)}`;
}

// Convert meters distance into a suitable format
function convertDistance(meters: number): string {
if (meters >= 1000) {
const kilometers = meters / 1000;
return `${kilometers.toFixed(1)} km`;
} else {
return `${meters.toString()} m`;
}
}

// Convert seconds duration into a suitable format
function convertDuration(seconds: number): string {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);

const hoursText = hours > 0 ? `${hours} h ` : '';
const minutesText = `${minutes} min`;

return hoursText + minutesText;
}

Key Features

  • Route Calculation: Calculates the best route between two points
  • Visual Feedback: Routes are displayed on the map with distance and time labels
  • Interactive Selection: Click on alternative routes to make them the main route
  • Cancellation: Cancel route calculation while it's in progress
  • Clean UI: Clear all routes from the map with one click

Next Steps