Züge springen nicht mehr zurück bei steigender Verspätung; Ausfälle und Teilausfälle (SKIPPED) berücksichtigt; POI-Symbole ausgeblendet
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X48pE4bzjHej8w9HyZXCjb
This commit is contained in:
+13
-9
@@ -283,7 +283,7 @@ class Feed:
|
||||
for j in range(bisect_right(cum, d0), bisect_right(cum, d1)):
|
||||
if d0 < cum[j] < d1:
|
||||
out.append((cum[j], (k + (cum[j] - d0) / (d1 - d0)) * step))
|
||||
res = [[*self.point_at((pts, cum, None), d), round(t, 2)] for d, t in out]
|
||||
res = [[*self.point_at((pts, cum, None), d), round(t, 2), round(d)] for d, t in out] # d: m ab Fahrtbeginn
|
||||
return simplify(res, tolerance, fixed)
|
||||
|
||||
@staticmethod
|
||||
@@ -299,11 +299,12 @@ class Feed:
|
||||
|
||||
def times(self, ti: int, ds: float, upd):
|
||||
"""Ankunft/Abfahrt je Halt (Sekunden ab Betriebstag), mit Verspätungen aus GTFS-RT.
|
||||
Eine Verspätung gilt für alle folgenden Halte, bis eine neue gemeldet wird."""
|
||||
Eine Verspätung gilt für alle folgenden Halte, bis eine neue gemeldet wird.
|
||||
Dazu die Nummern (0 …) der ausfallenden Halte."""
|
||||
o0, o1 = self.off[ti], self.off[ti + 1]
|
||||
arr, dep = list(self.st_arr[o0:o1]), list(self.st_dep[o0:o1])
|
||||
if not upd:
|
||||
return arr, dep
|
||||
return arr, dep, set()
|
||||
seqs, stops = self.st_seq[o0:o1], self.st_stop[o0:o1]
|
||||
by_i, j = {}, 0
|
||||
for u in upd:
|
||||
@@ -339,7 +340,7 @@ class Feed:
|
||||
a = max(a, prev)
|
||||
d = max(d, a)
|
||||
arr[i], dep[i], prev = a, d, d
|
||||
return arr, dep
|
||||
return arr, dep, {i for i, u in by_i.items() if u[6]}
|
||||
|
||||
# ---------- Positionen ----------
|
||||
|
||||
@@ -357,8 +358,11 @@ class Feed:
|
||||
r = rt.get((self.trip_ids[ti], dstr))
|
||||
if r and r[0]:
|
||||
continue # ausgefallen
|
||||
arr, dep = self.times(ti, ds, r[1] if r else None)
|
||||
if not (dep[0] <= t <= arr[-1]):
|
||||
arr, dep, skip = self.times(ti, ds, r[1] if r else None)
|
||||
# Teilausfall: fährt nur zwischen erstem und letztem bedienten Halt; Deutschland meldet
|
||||
# auch ganze Ausfälle so (alle Halte fallen aus)
|
||||
live = [k for k in range(len(arr)) if k not in skip]
|
||||
if not live or not (dep[live[0]] <= t <= arr[live[-1]]):
|
||||
continue
|
||||
pa, pd = with_min_dwell(arr, dep) # nur für die Position; Zeiten/Verspätung bleiben echt
|
||||
i = min(bisect_right(pd, t), len(pd) - 1) # Zug ist zwischen Halt i-1 und i (oder steht an Halt i)
|
||||
@@ -394,7 +398,7 @@ class Feed:
|
||||
d = dt.datetime.strptime(date, "%Y%m%d").date()
|
||||
ds = day_start(d)
|
||||
r = rt.get((self.trip_ids[ti], date))
|
||||
arr, dep = self.times(ti, ds, r[1] if r else None)
|
||||
arr, dep, skip = self.times(ti, ds, r[1] if r else None)
|
||||
o0, o1 = self.off[ti], self.off[ti + 1]
|
||||
|
||||
def hhmm(sec):
|
||||
@@ -410,10 +414,10 @@ class Feed:
|
||||
"dep": hhmm(self.st_dep[i]) if i < o1 - 1 else None,
|
||||
"arr_delay": arr[k] - self.st_arr[i] if r else None,
|
||||
"dep_delay": dep[k] - self.st_dep[i] if r else None,
|
||||
"passed": now - ds > dep[k],
|
||||
"passed": now - ds > dep[k], "skipped": k in skip,
|
||||
})
|
||||
route = self.routes[self.trip_route[ti]]
|
||||
return {"line": route["line"], "cat": route["cat"], "agency": route["agency"],
|
||||
"nr": self.trip_number[ti], "to": self.trip_headsign[ti],
|
||||
"realtime": bool(r), "canceled": bool(r and r[0]),
|
||||
"realtime": bool(r), "canceled": bool(r and r[0]) or len(skip) == len(stops),
|
||||
"stops": stops, "shape": self.geometry(ti)[0]}
|
||||
|
||||
@@ -5,10 +5,11 @@ from google.transit import gtfs_realtime_pb2 as pb
|
||||
from . import config as C
|
||||
|
||||
CANCELED = pb.TripDescriptor.CANCELED
|
||||
SKIPPED = pb.TripUpdate.StopTimeUpdate.SKIPPED
|
||||
|
||||
|
||||
def parse(data: bytes, known_trips: dict):
|
||||
"""-> (feed_version, {(trip_id, start_date): (ausgefallen, [(seq, stop_id, ank, ank_absolut, abf, abf_absolut), ...])})
|
||||
"""-> (feed_version, {(trip_id, start_date): (ausgefallen, [(seq, stop_id, ank, ank_absolut, abf, abf_absolut, fällt_aus), ...])})
|
||||
seq ist None, wenn die Quelle nur die Haltestellen-ID liefert (Frankreich, Niederlande).
|
||||
ank/abf sind Verspätung in s, oder Unix-Zeit wenn *_absolut; None = keine Angabe."""
|
||||
feed = pb.FeedMessage()
|
||||
@@ -29,7 +30,8 @@ def parse(data: bytes, known_trips: dict):
|
||||
ev += [x.time, True] if x.HasField("time") else [x.delay, False] if x.HasField("delay") else [None, False]
|
||||
else:
|
||||
ev += [None, False]
|
||||
upd.append((s.stop_sequence if s.HasField("stop_sequence") else None, s.stop_id, *ev))
|
||||
upd.append((s.stop_sequence if s.HasField("stop_sequence") else None, s.stop_id, *ev,
|
||||
s.schedule_relationship == SKIPPED))
|
||||
out[(tu.trip.trip_id, tu.trip.start_date)] = (tu.trip.schedule_relationship == CANCELED, upd)
|
||||
version = feed.header.feed_version if feed.header.HasField("feed_version") else None
|
||||
return version, out
|
||||
|
||||
Reference in New Issue
Block a user