mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 15:36:33 +00:00
aea37d9914
The hiking costing moves to shared, so the planner and the server ask the router the same way. The road trip router learns to plan a hike on foot with that costing (Valhalla only: OSRM knows no trail difficulty), to read heights along a line in chunks and to read the OSM ways a line follows, all through its one paced queue. A hike router builds on it: the way, its heights, distance, climb and DIN walking time, and the SAC grades of its stretches from the trail grade service, each part best effort. New MCP tools in HikePlanMcp, in the assistant's tours group: - propose_hike plans a hike without saving it. - create_hike saves a confirmed hike through the planner's own creation; a router that does not answer leaves it pending for the planner, a way that cannot be planned is refused and nothing is saved. - update_tour changes a saved hike against its revision, keeping linked stations and refusing what would silently drop drawn legs or stages. - import_tour_gpx takes a GPX file's text in as tours, like the import. Same permission checks as REST, broadcasts from the services. In the assistant a new hike or city walk is an "Add tour" card with its route and difficulty, undone through delete_place while the tour is untouched, and a hike being planned shows as a live step.
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
/**
|
|
* Valhalla's answers as the router reads them, for suites that stub the
|
|
* routing host behind safeFetchAdminConfigured.
|
|
*/
|
|
|
|
function encodeValue(value: number): string {
|
|
let remaining = value < 0 ? ~(value << 1) : value << 1;
|
|
let encoded = '';
|
|
while (remaining >= 32) {
|
|
encoded += String.fromCharCode((32 | (remaining & 31)) + 63);
|
|
remaining >>>= 5;
|
|
}
|
|
return encoded + String.fromCharCode(remaining + 63);
|
|
}
|
|
|
|
/** A line as Valhalla encodes a leg's shape: a polyline at six decimals. */
|
|
export function valhallaPolyline(line: ReadonlyArray<readonly [number, number]>): string {
|
|
let lat = 0;
|
|
let lng = 0;
|
|
return line
|
|
.map(([nextLat, nextLng]) => {
|
|
const [y, x] = [Math.round(nextLat * 1e6), Math.round(nextLng * 1e6)];
|
|
const step = encodeValue(y - lat) + encodeValue(x - lng);
|
|
[lat, lng] = [y, x];
|
|
return step;
|
|
})
|
|
.join('');
|
|
}
|
|
|
|
/** Valhalla's /route answer: one leg per line, each with its length in kilometres and its time in seconds. */
|
|
export function valhallaRoute(legs: ReadonlyArray<{ line: Array<[number, number]>; km: number; seconds: number }>) {
|
|
return {
|
|
trip: {
|
|
legs: legs.map(({ line, km, seconds }) => ({
|
|
shape: valhallaPolyline(line),
|
|
summary: { length: km, time: seconds },
|
|
})),
|
|
},
|
|
};
|
|
}
|