Skip to main content

Public Transit

|

This example demonstrates how to calculate public transit routes, display route segments with transit types, and handle alternative route selection.

Overview

The example demonstrates the following features:

  • Calculating routes using public transportation mode
  • Converting routes to public transit routes (PTRoute)
  • Extracting and displaying route segments with transit information
  • Showing route details including departure/arrival times and walking distances
  • Handling alternative routes with tap selection
  • Displaying wheelchair accessibility information

Code Implementation

Importing SDK Components

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

Calculating Public Transit Routes

index.ts
function onBuildRouteButtonPressed() {
// Define the departure
const departureLandmark = Landmark.withLatLng({
latitude: 51.505929,
longitude: -0.097579,
});

// Define the destination
const destinationLandmark = Landmark.withLatLng({
latitude: 51.507616,
longitude: -0.105036,
});

// Define the route preferences with public transport mode
const routePreferences = new RoutePreferences({
transportMode: RouteTransportMode.public,
});

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

if (err === GemError.success && routes.length > 0) {
const routesMap = map?.preferences.routes;
routes.forEach((route, idx) => {
routesMap?.add(route, idx === 0, {
label: idx === 0 ? getRouteLabel(route) : undefined
});
});
map?.centerOnRoutes({ routes });

// Convert normal route to PTRoute and extract segments
const ptRoute: PTRoute | null = routes[0].toPTRoute() ?
routes[0].toPTRoute() : null;
if (ptRoute) {
const segments: PTRouteSegment[] = ptRoute.segments
.map((seg: any) => seg.toPTRouteSegment && seg.toPTRouteSegment())
.filter((seg: any) => !!seg);
ptSegments = segments;
}
}
updateUI();
}
);
}

Converting Routes to Public Transit Format

index.ts
function getRouteLabel(route: Route): string {
const td = route.getTimeDistance();
const totalDistance = td.unrestrictedDistanceM + td.restrictedDistanceM;
const totalDuration = td.unrestrictedTimeS + td.restrictedTimeS;

// Convert the route to a public transit route (PTRoute)
const publicTransitRoute: PTRoute | null = route.toPTRoute ?
route.toPTRoute() : null;
if (!publicTransitRoute) return "";

// Get the first and last segments of the route
const firstSegment = publicTransitRoute.segments[0]?.toPTRouteSegment?.();
const lastSegment = publicTransitRoute.segments[
publicTransitRoute.segments.length - 1
]?.toPTRouteSegment?.();

if (!firstSegment || !lastSegment) return "";

// Get departure and arrival times from the segments
const departureTime = firstSegment.departureTime;
const arrivalTime = lastSegment.arrivalTime;

// Calculate total walking distance
const totalWalkingDistance = firstSegment.timeDistance.totalDistanceM +
lastSegment.timeDistance.totalDistanceM;

let formattedDepartureTime = "";
let formattedArrivalTime = "";

if (departureTime && arrivalTime) {
formattedDepartureTime = `${departureTime.getHours()}:${
departureTime.getMinutes().toString().padStart(2, '0')
}`;
formattedArrivalTime = `${arrivalTime.getHours()}:${
arrivalTime.getMinutes().toString().padStart(2, '0')
}`;
}

// Build the label string with the route's details
return `${convertDuration(totalDuration)}\n` +
`${formattedDepartureTime} - ${formattedArrivalTime}\n` +
`${convertDistance(totalDistance)} (${convertDistance(totalWalkingDistance)} walking)\n` +
`${publicTransitRoute.publicTransportFare || ''}`;
}

Handling Route Selection

index.ts
// Register route tap callback for selecting alternative routes
function registerRouteTapCallback() {
if (!map) return;
map.registerTouchCallback(async (pos: any) => {
await map!.setCursorScreenPosition(pos);
const selectedRoutes = map!.cursorSelectionRoutes();
if (selectedRoutes.length > 0) {
map!.preferences.routes.mainRoute = selectedRoutes[0];
}
});
}

Canceling Route Calculation

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

Live Demo

Key Features

  • Public Transport Routing: Calculate routes optimized for public transportation including buses, trains, and walking segments
  • PTRoute Conversion: Convert standard routes to public transit format for detailed segment information
  • Route Segments: Access individual transit segments with type, duration, and accessibility details
  • Time Information: Retrieve departure and arrival times for transit segments
  • Alternative Routes: Display and select from multiple route options
  • Wheelchair Support: Check wheelchair accessibility for each transit segment

Explanation of Key Components

  • RouteTransportMode.public: Route calculation mode optimized for public transportation networks
  • PTRoute: Public transit route representation containing detailed segment information
  • PTRouteSegment: Individual segment of a public transit route with transit type, times, and accessibility
  • toPTRoute(): Method to convert a standard Route object to PTRoute format
  • TransitType: Enumeration of transit types (walk, bus, train, etc.)
  • departureTime/arrivalTime: Timestamp properties indicating when transit segments begin and end
  • hasWheelchairSupport: Boolean property indicating wheelchair accessibility for transit segments
  • publicTransportFare: Property containing fare information for the route
  • registerTouchCallback(): Register callback for map touch events to enable route selection

Next Steps