- Implemented StopsMap component to display bus stops on a map using MapLibre GL. - Integrated walking directions feature in WalkingDirections component to calculate routes from user location to selected bus stop. - Added geo utility functions for coordinate validation and distance calculation. - Created route grouping and stop filtering logic in routeGroups module. - Developed custom hooks for managing stop routes with React Query. - Added tests for routing and stop functionalities to ensure reliability.
24 lines
1.0 KiB
TypeScript
24 lines
1.0 KiB
TypeScript
import type { Route, RouteStops, Stop } from '../types';
|
|
|
|
export const routeNumberKey = (number: string) => number.trim().replace(/^№\s*/, '').normalize('NFKC').toLocaleUpperCase('ru');
|
|
|
|
export function groupRoutes(routes: Route[]) {
|
|
const groups = new Map<string, { key: string; number: string; routes: Route[] }>();
|
|
for (const route of routes) {
|
|
const key = routeNumberKey(route.number);
|
|
const group = groups.get(key) ?? { key, number: route.number, routes: [] };
|
|
if (!group.routes.some(value => value.id === route.id)) group.routes.push(route);
|
|
groups.set(key, group);
|
|
}
|
|
return [...groups.values()].sort((a, b) => a.key.localeCompare(b.key, 'ru', { numeric: true }));
|
|
}
|
|
|
|
export function stopsForRoutes(catalog: Stop[], routes: RouteStops[]): Stop[] {
|
|
const stops = new Map<number, Stop>();
|
|
const known = new Map(catalog.map(stop => [stop.id, stop]));
|
|
for (const route of routes) for (const stop of route.stops) {
|
|
if (!stops.has(stop.id)) stops.set(stop.id, { ...stop, ...known.get(stop.id) });
|
|
}
|
|
return [...stops.values()];
|
|
}
|