Files
geograsim/App/sims/logistik/scripts/enrich-railnet-osrm.py
T
Adminator 79ac9dad84 Atlas: Deploy-Buendel vor Staustufen-Sprint
- Logistik: Musik-Player Playlist-Modus (5 Gruppen, 20 Tracks)
- Heli: End-Screen auf .ggs-endscreen, Mission-Bilder, Voice-Lines, Briefing-Audio
- Logistik: Layout-Tausch Auftraege+Fahrzeuge links, Karte rechts
- Logistik: Tier-1-Staedte ausgebaut, Auto-Timescale-Badge
- Logistik: Roadnet/Railnet Dijkstra-Routing, Balance-Updates
- Atlas: 5 Atlas-Inbox-Nachrichten (Cards-Pattern, DALL-E-Key, Musik-Playlists)
- Status-Updates Heli + Logistik

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 01:05:13 +02:00

89 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""
Reichert lg-railnet.json mit OSRM-Polylines an. Nutzt das Auto-Profil als
Approximation fuer Bahnstrecken — die echten Bahnkorridore folgen oft
den Autobahnen (Wien-Muenchen via Salzburg, Hamburg-Rotterdam via Bremen-
Osnabrueck etc.), das ist auf Europa-Zoom visuell sauberer als Luftlinie.
Aufruf:
python App/sims/logistik/scripts/enrich-railnet-osrm.py
"""
import json
import math
import ssl
import time
import urllib.request
from pathlib import Path
RAILNET = Path(__file__).resolve().parents[3] / "assets" / "data" / "lg-railnet.json"
LOCATIONS = Path(__file__).resolve().parents[3] / "assets" / "data" / "lg-locations.json"
TOLERANCE_DEG = 0.001
SSL_CTX = ssl.create_default_context()
SSL_CTX.check_hostname = False
SSL_CTX.verify_mode = ssl.CERT_NONE
OSRM = "https://router.project-osrm.org/route/v1/driving/{coords}?overview=full&geometries=geojson"
def perp(pt, a, b):
dx, dy = b[0]-a[0], b[1]-a[1]
if dx == 0 and dy == 0:
return math.hypot(pt[0]-a[0], pt[1]-a[1])
t = max(0.0, min(1.0, ((pt[0]-a[0])*dx + (pt[1]-a[1])*dy)/(dx*dx+dy*dy)))
return math.hypot(pt[0]-(a[0]+t*dx), pt[1]-(a[1]+t*dy))
def rdp(points, eps):
if len(points) < 3:
return list(points)
md, idx = 0.0, 0
for i in range(1, len(points)-1):
d = perp(points[i], points[0], points[-1])
if d > md:
md, idx = d, i
if md <= eps:
return [points[0], points[-1]]
return rdp(points[:idx+1], eps)[:-1] + rdp(points[idx:], eps)
def fetch(waypoints):
coords = ";".join(f"{w[1]},{w[0]}" for w in waypoints)
with urllib.request.urlopen(OSRM.format(coords=coords), timeout=30, context=SSL_CTX) as r:
data = json.load(r)
route = data["routes"][0]
poly = [[round(c[1], 5), round(c[0], 5)] for c in route["geometry"]["coordinates"]]
return poly, route["distance"]/1000.0
def main():
net = json.loads(RAILNET.read_text(encoding="utf-8"))
locs = {l["id"]: l for l in json.loads(LOCATIONS.read_text(encoding="utf-8"))}
nodes = {n["id"]: n for n in net["nodes"]}
for i, edge in enumerate(net["edges"], 1):
fl = locs[nodes[edge["from"]]["locationId"]]
tl = locs[nodes[edge["to"]]["locationId"]]
start = [fl["lat"], fl["lon"]]
end = [tl["lat"], tl["lon"]]
print(f"[{i}/{len(net['edges'])}] {edge['id']}: ", end="", flush=True)
try:
poly, km = fetch([start, end])
poly = rdp(poly, TOLERANCE_DEG)
edge["polyline"] = poly
edge["distanceKmOsrm"] = round(km, 1)
print(f"{km:.0f} km, {len(poly)} Punkte")
except Exception as e:
print(f"FEHLER: {e}")
time.sleep(1.1)
RAILNET.write_text(
json.dumps(net, ensure_ascii=False, separators=(",", ":")),
encoding="utf-8",
)
sz = RAILNET.stat().st_size / 1024
print(f"\nFertig: {sz:.1f} KB")
if __name__ == "__main__":
main()