adds modes of transportation to routing

This commit is contained in:
Christian Beutel
2024-05-02 14:23:32 +02:00
parent b3ed2b1098
commit 2a771b195e
7 changed files with 183 additions and 83 deletions

View File

@@ -3,6 +3,7 @@ import type Track from "$lib/models/gpx/track";
import TrackSegment from "$lib/models/gpx/track-segment";
import Waypoint from "$lib/models/gpx/waypoint";
import { type ValhallaAnchor, type ValhallaHeightResponse, type ValhallaRouteResponse } from "$lib/models/valhalla";
import { decodePolyline, encodePolyline } from "$lib/util/polyline_util";
import { ClientResponseError } from "pocketbase";
@@ -19,26 +20,45 @@ export function setRoute(newRoute: GPX) {
route = newRoute
}
export async function calculateRouteBetween(startLat: number, startLon: number, endLat: number, endLon: number) {
const requestBody = {
"directions_type": "none",
"locations": [{ "lat": startLat, "lon": startLon }, { "lat": endLat, "lon": endLon }],
"costing": "pedestrian", "costing_options": { "pedestrian": { "max_hiking_difficulty": 6, "use_ferry": 0 } }
}
let r = await fetch("/api/v1/valhalla/route", { method: "POST", body: JSON.stringify(requestBody) })
export async function calculateRouteBetween(startLat: number, startLon: number, endLat: number, endLon: number, costing: string = "pedestrian", autoRoute: boolean = true) {
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
const routeResponse: ValhallaRouteResponse = await r.json();
const shape = routeResponse.trip.legs[0].shape
r = await fetch("/api/v1/valhalla/height", { method: "POST", body: JSON.stringify({ encoded_polyline: shape }) })
let shape;
if (autoRoute) {
let costingBody;
switch (costing) {
case "bicycle":
costingBody = { "costing": "bicycle", "costing_options": { "bicycle": { "bicycle_type": "Hybrid", "use_roads": 0.5, "use_hills": 0.5, "avoid_bad_surfaces": 0.5, "use_ferry": 0 } } }
break;
case "auto":
costingBody = { "costing": "auto", "costing_options": { "auto": { "use_ferry": 0 } } }
default:
costingBody = { "costing": costing, "costing_options": { costing: { "max_hiking_difficulty": 6, "use_ferry": 0 } } }
break;
}
const requestBody = {
"directions_type": "none",
"locations": [{ "lat": startLat, "lon": startLon }, { "lat": endLat, "lon": endLon }],
...costingBody
}
if (!r.ok) {
throw new ClientResponseError(await r.json())
let r = await fetch("/api/v1/valhalla/route", { method: "POST", body: JSON.stringify(requestBody) })
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
const routeResponse: ValhallaRouteResponse = await r.json();
shape = routeResponse.trip.legs[0].shape
} else {
shape = encodePolyline([[startLat, startLon], [endLat, endLon]])
}
const heightResponse: ValhallaHeightResponse = await r.json()
const points = decodeShape(shape);
const r2 = await fetch("/api/v1/valhalla/height", { method: "POST", body: JSON.stringify({ encoded_polyline: shape }) })
if (!r2.ok) {
throw new ClientResponseError(await r2.json())
}
const heightResponse: ValhallaHeightResponse = await r2.json()
const points = decodePolyline(shape);
const waypoints = points.map((p, i) => new Waypoint({ $: { lat: p[0], lon: p[1] }, ele: heightResponse.height[i] }))
return waypoints
@@ -62,49 +82,4 @@ export async function editRoute(index: number, waypoints: Waypoint[]) {
export function deleteFromRoute(index: number) {
route.trk?.at(0)?.trkseg?.splice(index, 1);
}
function decodeShape(shape: string, precision: number = 6) {
var index = 0,
lat = 0,
lng = 0,
coordinates = [],
shift = 0,
result = 0,
byte = null,
latitude_change,
longitude_change,
factor = Math.pow(10, precision);
while (index < shape.length) {
byte = null;
shift = 0;
result = 0;
do {
byte = shape.charCodeAt(index++) - 63;
result |= (byte & 0x1f) << shift;
shift += 5;
} while (byte >= 0x20);
latitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));
shift = result = 0;
do {
byte = shape.charCodeAt(index++) - 63;
result |= (byte & 0x1f) << shift;
shift += 5;
} while (byte >= 0x20);
longitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += latitude_change;
lng += longitude_change;
coordinates.push([lat / factor, lng / factor]);
}
return coordinates;
};
}