fifteen/apps/web/lib/valhalla.ts
2026-03-01 21:59:44 +01:00

53 lines
1.3 KiB
TypeScript

const VALHALLA_BASE = process.env.VALHALLA_URL ?? "http://valhalla:8002";
export type ValhallaCosting = "pedestrian" | "bicycle" | "auto";
const COSTING_MAP: Record<string, ValhallaCosting> = {
walking: "pedestrian",
cycling: "bicycle",
driving: "auto",
};
export interface IsochroneOpts {
lng: number;
lat: number;
travelMode: string;
contourMinutes: number[];
polygons?: boolean;
}
export async function fetchIsochrone(opts: IsochroneOpts): Promise<object> {
const costing = COSTING_MAP[opts.travelMode] ?? "pedestrian";
const body = {
locations: [{ lon: opts.lng, lat: opts.lat }],
costing,
contours: opts.contourMinutes.map((time) => ({ time })),
polygons: opts.polygons ?? true,
show_locations: false,
};
const res = await fetch(`${VALHALLA_BASE}/isochrone`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
signal: AbortSignal.timeout(30_000),
});
if (!res.ok) {
const text = await res.text();
throw new Error(`Valhalla error ${res.status}: ${text}`);
}
return res.json();
}
export async function checkValhalla(): Promise<boolean> {
try {
const res = await fetch(`${VALHALLA_BASE}/status`, {
signal: AbortSignal.timeout(3000),
});
return res.ok;
} catch {
return false;
}
}