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,115 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Erweitert lg-roadnet.json um die wichtigsten Hafen-Knoten + Edges. So
|
||||
zeichnen Routes zu Häfen echte Polylines statt Luftlinie.
|
||||
|
||||
Neu: hamburg_hafen, rotterdam_hafen, triest_hafen, genua_hafen,
|
||||
goeteborg_hafen, gdansk_hafen — jeweils mit Edge zur naechsten Stadt
|
||||
und ggf. direkt zu wichtigen Hub-Staedten.
|
||||
"""
|
||||
import json
|
||||
import math
|
||||
import ssl
|
||||
import time
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
ROADNET = Path(__file__).resolve().parents[3] / "assets" / "data" / "lg-roadnet.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(ROADNET.read_text(encoding="utf-8"))
|
||||
locs = {l["id"]: l for l in json.loads(LOCATIONS.read_text(encoding="utf-8"))}
|
||||
existing_node_ids = {n["id"] for n in net["nodes"]}
|
||||
existing_edge_ids = {e["id"] for e in net["edges"]}
|
||||
|
||||
NEW_NODES = ['hamburg_hafen', 'rotterdam_hafen', 'triest_hafen',
|
||||
'genua_hafen', 'goeteborg_hafen', 'gdansk_hafen']
|
||||
for nid in NEW_NODES:
|
||||
if nid in existing_node_ids:
|
||||
continue
|
||||
loc = locs[nid]
|
||||
net["nodes"].append({"id": nid, "locationId": nid, "name": loc["name"]})
|
||||
|
||||
# Edges: jeweils Stadt -> Hafen + ev. weitere
|
||||
NEW_EDGES = [
|
||||
('hamburg-hamburg_hafen', 'hamburg', 'hamburg_hafen', 6, 'A7-Anbindung'),
|
||||
('rotterdam-rotterdam_hafen', 'rotterdam', 'rotterdam_hafen', 30, 'A15-Maasvlakte'),
|
||||
('mailand-genua_hafen', 'mailand', 'genua_hafen', 145, 'A7'),
|
||||
('muenchen-genua_hafen', 'muenchen', 'genua_hafen', 640, 'A22 + A7'),
|
||||
('wien-triest_hafen', 'wien', 'triest_hafen', 480, 'A2 + A1 + A4 SLO'),
|
||||
('muenchen-triest_hafen', 'muenchen', 'triest_hafen', 500, 'A8 + A23'),
|
||||
('hamburg-goeteborg_hafen', 'hamburg', 'goeteborg_hafen', 500, 'A7 + Faehre Kiel-Goeteborg'),
|
||||
('warschau-gdansk_hafen', 'warschau', 'gdansk_hafen', 340, 'S7'),
|
||||
]
|
||||
|
||||
for eid, fnode, tnode, dist, code in NEW_EDGES:
|
||||
if eid in existing_edge_ids:
|
||||
print(f"skip {eid}")
|
||||
continue
|
||||
fl = locs[fnode]
|
||||
tl = locs[tnode]
|
||||
start = [fl["lat"], fl["lon"]]
|
||||
end = [tl["lat"], tl["lon"]]
|
||||
print(f"-> {eid}: ", end="", flush=True)
|
||||
try:
|
||||
poly, km = fetch([start, end])
|
||||
poly = rdp(poly, TOLERANCE_DEG)
|
||||
net["edges"].append({
|
||||
"id": eid, "from": fnode, "to": tnode,
|
||||
"distanceKm": dist, "routeCode": code,
|
||||
"polyline": poly,
|
||||
"distanceKmOsrm": round(km, 1),
|
||||
})
|
||||
print(f"{km:.0f} km, {len(poly)} pts")
|
||||
except Exception as e:
|
||||
print(f"FEHLER: {e}")
|
||||
time.sleep(1.1)
|
||||
|
||||
ROADNET.write_text(
|
||||
json.dumps(net, ensure_ascii=False, separators=(",", ":")),
|
||||
encoding="utf-8",
|
||||
)
|
||||
sz = ROADNET.stat().st_size / 1024
|
||||
print(f"\nFertig: {len(net['edges'])} Kanten total, {sz:.1f} KB")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user