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>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Reichert App/assets/data/lg-roadnet.json an: ersetzt die hand-kuratierte
|
||||
Polyline jeder Kante durch die echte OSRM-Routengeometrie entlang echter
|
||||
Autobahnen. Die bisherigen Wegpunkte dienen als Stuetzstellen, damit OSRM
|
||||
den gewuenschten Korridor waehlt (z.B. Brenner statt Mont Blanc).
|
||||
|
||||
Nutzt den freien OSRM-Demo-Server (router.project-osrm.org). Nur fuer
|
||||
Dev-Zeit — die fertige Polyline landet im JSON, die Produktion ruft
|
||||
OSRM nie auf (DSGVO, Rate-Limit, Verfuegbarkeit).
|
||||
|
||||
Aufruf:
|
||||
python App/sims/logistik/scripts/enrich-roadnet-osrm.py
|
||||
"""
|
||||
import json
|
||||
import ssl
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import time
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# SSL-Cert-Verify aus — Windows-Python findet den CA-Store oft nicht. Das
|
||||
# ist fuer ein Dev-Tool (einmaliger Run, Ergebnis landet im JSON) akzeptabel.
|
||||
# Produktiv wird OSRM nie aufgerufen.
|
||||
SSL_CTX = ssl.create_default_context()
|
||||
SSL_CTX.check_hostname = False
|
||||
SSL_CTX.verify_mode = ssl.CERT_NONE
|
||||
|
||||
ROADNET = Path(__file__).resolve().parents[3] / "assets" / "data" / "lg-roadnet.json"
|
||||
OSRM = "https://router.project-osrm.org/route/v1/driving/{coords}?overview=full&geometries=geojson"
|
||||
|
||||
|
||||
def fetch_route(waypoints):
|
||||
# waypoints = [[lat, lon], ...] -> OSRM erwartet "lon,lat;lon,lat;..."
|
||||
coords = ";".join(f"{w[1]},{w[0]}" for w in waypoints)
|
||||
url = OSRM.format(coords=coords)
|
||||
with urllib.request.urlopen(url, timeout=30, context=SSL_CTX) as resp:
|
||||
data = json.load(resp)
|
||||
if data.get("code") != "Ok" or not data.get("routes"):
|
||||
raise RuntimeError(f"OSRM-Fehler: {data.get('code')} / {data.get('message')}")
|
||||
route = data["routes"][0]
|
||||
geo = route["geometry"]["coordinates"] # [[lon, lat], ...]
|
||||
polyline = [[round(c[1], 5), round(c[0], 5)] for c in geo]
|
||||
distance_km = route["distance"] / 1000.0
|
||||
return polyline, distance_km
|
||||
|
||||
|
||||
def main():
|
||||
net = json.loads(ROADNET.read_text(encoding="utf-8"))
|
||||
total = len(net["edges"])
|
||||
for i, edge in enumerate(net["edges"], 1):
|
||||
print(f"[{i}/{total}] {edge['id']}: ", end="", flush=True)
|
||||
waypoints = edge.get("polyline") or []
|
||||
if len(waypoints) < 2:
|
||||
print("skip (keine Wegpunkte)")
|
||||
continue
|
||||
try:
|
||||
poly, dist_km = fetch_route(waypoints)
|
||||
except Exception as e:
|
||||
print(f"FEHLER — {e}")
|
||||
continue
|
||||
edge["polyline"] = poly
|
||||
# OSRM-Distanz in die Kante schreiben als Diagnose, Original beibehalten
|
||||
edge["distanceKmOsrm"] = round(dist_km, 1)
|
||||
print(f"{len(poly)} Punkte, {dist_km:.0f} km (hand: {edge.get('distanceKm')})")
|
||||
time.sleep(1.1) # OSRM-Demo: ~1 req/s, nicht mehr
|
||||
|
||||
ROADNET.write_text(
|
||||
json.dumps(net, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(f"\nFertig — {ROADNET} aktualisiert.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user