Skip to main content

Getting started with Routing

|

The Routing module provides powerful route calculation capabilities, enabling you to compute routes between multiple waypoints with various transportation modes and preferences. Whether you need the fastest route, the shortest distance, or an eco-friendly path, the SDK offers comprehensive routing functionality.

Basic route calculation

The simplest way to calculate a route is by providing start and destination coordinates:

import {
GemError,
RoutingService,
RoutePreferences,
Landmark,
Route,
RouteTransportMode,
RouteType,
TrafficAvoidance,
RouteAlternativesSchema
} from '@magiclane/maps-sdk';

// Define waypoints
const start = Landmark.withLatLng ({ latitude: 48.858844, longitude: 2.294351 }); // Eiffel Tower
const destination = Landmark.withLatLng({ latitude: 48.853409, longitude: 2.349014 }); // Notre-Dame


// Create route preferences
const preferences = new RoutePreferences({
transportMode: RouteTransportMode.car,
routeType: RouteType.fastest
});

// Calculate the route
const taskHandler = RoutingService.calculateRoute(
[start, destination],
preferences,
(err, routes) => {
if (err === GemError.success && routes.length > 0) {
const route = routes[0];
const timeDistance = route.getTimeDistance();
const totalDistance = timeDistance.unrestrictedDistanceM + timeDistance.restrictedDistanceM;
const totalDuration = timeDistance.unrestrictedTimeS + timeDistance.restrictedTimeS;

console.log(`Route distance: ${totalDistance / 1000} km`);
console.log(`Estimated time: ${totalDuration / 60} minutes`);

// Display route on map
displayRoutesOnMap(gemMap, routes);
} else {
console.error(`Routing error: ${err}`);
}
}
);

Transport modes

The SDK supports different transportation modes:

enum RouteTransportMode {
car,
lorry,
pedestrian,
bicycle,
public,
sharedVehicles
}

// Example: Pedestrian route
const preferences = new RoutePreferences({
transportMode: RouteTransportMode.pedestrian,
routeType: RouteType.shortest
});

Route types

Choose the type of route based on your needs:

enum RouteType {
fastest, // Minimize travel time
shortest, // Minimize distance
economic, // Fuel-efficient route
scenic // Fast route with scenic preference
}

Multiple waypoints

Calculate routes with intermediate stops:

const waypoints = [
Landmark.withLatLng({ latitude: 48.858844, longitude: 2.294351 }), // Start: Eiffel Tower
Landmark.withLatLng({ latitude: 48.865717, longitude: 2.321906 }), // Via: Arc de Triomphe
Landmark.withLatLng({ latitude: 48.853409, longitude: 2.349014 }) // End: Notre-Dame
];

const taskHandler = RoutingService.calculateRoute(
waypoints,
preferences,
(err, routes) => {
if (err === GemError.success) {
console.log(`Route with ${waypoints.length - 2} intermediate stops calculated`);
}
}
);

Route preferences

Customize routing behavior with detailed preferences:

const preferences = new RoutePreferences({
transportMode: RouteTransportMode.car,
routeType: RouteType.fastest,
avoidMotorways: false,
avoidTollRoads: false,
avoidFerries: false,
avoidUnpavedRoads: true,
avoidTraffic: TrafficAvoidance.none
});

Handling route alternatives

Request multiple route options:

const preferences = new RoutePreferences({
transportMode: RouteTransportMode.car,
routeType: RouteType.fastest,
alternativesSchema: RouteAlternativesSchema.always // Explicitly request alternatives
});

const taskHandler = RoutingService.calculateRoute(
[start, destination],
preferences,
(err, routes) => {
if (err === GemError.success) {
console.log(`Found ${routes.length} alternative routes:`);
routes.forEach((route, index) => {
const timeDistance = route.getTimeDistance();
const totalDistance = timeDistance.unrestrictedDistanceM + timeDistance.restrictedDistanceM;
const totalDuration = timeDistance.unrestrictedTimeS + timeDistance.restrictedTimeS;

console.log(`Route ${index + 1}:`);
console.log(` Distance: ${totalDistance / 1000} km`);
console.log(` Time: ${totalDuration / 60} min`);
});
}
}
);

Displaying routes on the map

Once you have calculated a route, display it on the map:

import { GemMap, Route } from '@magiclane/maps-sdk';

function displayRoutesOnMap(gemMap: GemMap, routes: Route[]) {
const routesMap = gemMap.preferences.routes;
routesMap.clear();

// Add all routes and mark the first one as main route
routes.forEach((route, index) => {
routesMap.add(route, index === 0);
});

gemMap.centerOnRoutes({ routes });
}

Route information

Access detailed route information:

function displayRouteInfo(route: Route) {
const timeDistance = route.getTimeDistance();
const totalDistance = timeDistance.unrestrictedDistanceM + timeDistance.restrictedDistanceM;
const totalDuration = timeDistance.unrestrictedTimeS + timeDistance.restrictedTimeS;
const instructions = route.segments.flatMap((segment) => segment.instructions);

console.log('Route Information:');
console.log(`Total distance: ${(totalDistance / 1000).toFixed(2)} km`);
console.log(`Estimated time: ${Math.round(totalDuration / 60)} minutes`);
console.log(`Number of instructions: ${instructions.length}`);

// Display turn-by-turn instructions
instructions.forEach((instruction, index) => {
console.log(`${index + 1}. ${instruction.text} (${instruction.distance}m)`);
});
}

Canceling a route calculation

If you need to cancel an ongoing route calculation:

if (taskHandler) {
RoutingService.cancelRoute(taskHandler);
console.log('Route calculation cancelled');
}

Using Promises (Alternative Pattern)

Wrap routing in a Promise for async/await usage:

function calculateRouteAsync(
waypoints: Landmark[],
preferences: RoutePreferences
): Promise<Route[]> {
return new Promise((resolve, reject) => {
const taskHandler = RoutingService.calculateRoute(
waypoints,
preferences,
(err, routes) => {
if (err === GemError.success) {
resolve(routes);
} else {
reject(new Error(`Route calculation failed: ${err}`));
}
}
);

if (!taskHandler) {
reject(new Error('Failed to initialize route calculation'));
}
});
}

// Usage
try {
const routes = await calculateRouteAsync([start, destination], preferences);
console.log(`Calculated ${routes.length} routes`);
displayRoutesOnMap(gemMap, routes);
} catch (error) {
console.error('Routing error:', error);
}

Traffic-aware routing

Enable real-time traffic consideration:

const preferences = new RoutePreferences({
transportMode: RouteTransportMode.car,
routeType: RouteType.fastest,
avoidTraffic: TrafficAvoidance.all,
timestamp: new Date() // Current local time
});

// Or schedule for future departure
const futureTime = new Date(Date.now() + (2 * 60 * 60 * 1000)); // 2 hours from now
preferences.timestamp = futureTime;

Next Steps

Now that you understand basic routing, you can explore:

  • Advanced route preferences and constraints
  • Turn-by-turn navigation
  • Route optimization for multiple destinations
  • Real-time route recalculation