Richtung aus dem Gleisverlauf statt aus der Bewegung, sanftes Bremsen/Anfahren an Halten
- Server berechnet den Kurs aus der Strecke (±25 m) an der Zugposition; stimmt dadurch auch im Stillstand (vorher blieb der Pfeil verdreht stehen) - Trapezprofil: ~150 m vor/nach jedem Halt bremst bzw. beschleunigt der Zug, Ankunfts- und Abfahrtszeiten bleiben gleich Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X48pE4bzjHej8w9HyZXCjb
This commit is contained in:
+8
-11
@@ -122,7 +122,7 @@ async function refreshTrains() {
|
||||
if (now) clockOffset = Date.now() / 1000 - now;
|
||||
const old = new Map(trains.features.map((f) => [f.properties.id, f.properties.bearing]));
|
||||
for (const f of d.features) {
|
||||
f.pts = [f.geometry.coordinates, ...(f.path || [])];
|
||||
f.pts = [[...f.geometry.coordinates, f.properties.heading], ...(f.path || [])];
|
||||
const b = old.get(f.properties.id);
|
||||
if (b !== undefined) f.properties.bearing = b;
|
||||
}
|
||||
@@ -132,13 +132,8 @@ async function refreshTrains() {
|
||||
} catch (e) { /* nächster Versuch in ein paar Sekunden */ }
|
||||
}
|
||||
|
||||
// Fahrtrichtung in Grad (0 = Norden, im Uhrzeigersinn), in Mercator gerechnet wie die Karte
|
||||
function bearing(a, b) {
|
||||
const y = (lat) => Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360));
|
||||
const dx = ((b[0] - a[0]) * Math.PI) / 180, dy = y(b[1]) - y(a[1]);
|
||||
if (Math.hypot(dx, dy) < 3e-7) return null; // unter ~2 m: steht (Rundungsrauschen würde die Spitze umklappen)
|
||||
return (Math.atan2(dx, dy) * 180) / Math.PI;
|
||||
}
|
||||
// kürzester Drehwinkel von a nach b in Grad (-180..180)
|
||||
const turn = (a, b) => ((((b - a) % 360) + 540) % 360) - 180;
|
||||
|
||||
// SDF-Icons, damit MapLibre sie nach Verspätung einfärben und mit Rand zeichnen kann
|
||||
const S = 64, R = 8;
|
||||
@@ -207,10 +202,12 @@ function render() {
|
||||
const i = Math.min(Math.floor(x), p.length - 1);
|
||||
const a = p[i], b = p[Math.min(i + 1, p.length - 1)], k = i + 1 < p.length ? x - i : 0;
|
||||
f.geometry.coordinates = [a[0] + (b[0] - a[0]) * k, a[1] + (b[1] - a[1]) * k];
|
||||
const target = bearing(a, b);
|
||||
if (target === null) continue; // steht: Richtung behalten
|
||||
// Richtung kommt vom Server (Gleisverlauf an der Position); dazwischen interpolieren und weich nachdrehen
|
||||
const ha = a[2] ?? b[2], hb = b[2] ?? a[2];
|
||||
if (ha === null || ha === undefined) continue;
|
||||
const target = ha + turn(ha, hb) * k;
|
||||
const cur = f.properties.bearing;
|
||||
f.properties.bearing = cur === undefined ? target : cur + (((((target - cur) % 360) + 540) % 360) - 180) * ease;
|
||||
f.properties.bearing = cur === undefined ? target : cur + turn(cur, target) * ease;
|
||||
}
|
||||
map.getSource("trains").setData(trains);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user