tracktracker/src/data/routing.js

68 lines
2.0 KiB
JavaScript

import * as turfHelpers from "@turf/helpers";
import dijkstra from "dijkstrajs";
import network from "./network.json";
// Transform the navigation graph to be in the format expected by dijkstrajs
const graph = {};
for (const [beginId, begin] of Object.entries(network.navigation)) {
const neighbors = {};
for (const [endId, end] of Object.entries(begin)) {
neighbors[endId] = end.properties.length;
}
graph[beginId] = neighbors;
}
/**
* Get the OSM ID of a stop.
* @param {string} stopId Network ID of the stop.
* @return {string} OSM ID of the stop.
*/
export const stopToOSM = stopId => network.stops[stopId].properties.node;
/**
* Find the shortest path of nodes linking two stops.
* @param {string} fromStop Network ID of the starting stop.
* @param {string} toStop Network ID of the ending stop.
* @return {Array.<string>} If it exists, a path of nodes joining the two stops.
*/
export const findPath = (fromStop, toStop) => {
try {
return dijkstra.find_path(
graph, stopToOSM(fromStop), stopToOSM(toStop)
);
} catch (err) {
return null;
}
};
/**
* Find the shortest segment linking two nodes or stops.
* @param {string} fromStop Network ID of the starting stop.
* @param {string} toStop Network ID of the ending stop.
* @return {LineString?} If it exists, a segment joining the two stops.
*/
export const findSegment = (fromStop, toStop) => {
const path = findPath(fromStop, toStop);
if (path === null) {
return null;
}
const initial = network.navigation[path[0]][path[1]];
let points = [...initial.geometry.coordinates];
let length = initial.properties.length;
for (let i = 1; i + 1 < path.length; ++i) {
const current = network.navigation[path[i]][path[i + 1]];
points = points.concat(current.geometry.coordinates.slice(1));
length += current.properties.length;
}
const route = turfHelpers.lineString(points);
route.properties.length = length;
return route;
};