@@ -17,15 +17,60 @@ namespace nigiri::rt {
1717std::pair<date::days, duration_t > split (duration_t );
1818
1919template <typename Fn>
20- void resolve_static (date::sys_days const today,
21- timetable const & tt,
22- source_idx_t const src,
23- transit_realtime::TripDescriptor const & td,
24- Fn&& fn) {
25- using loader::gtfs::hhmm_to_min;
26- using loader::gtfs::parse_date;
20+ void resolve_trip (date::sys_days const today,
21+ timetable const & tt,
22+ trip_idx_t const trip,
23+ std::optional<date::sys_days> const & start_date,
24+ std::optional<duration_t > const & start_time,
25+ Fn&& fn) {
26+ for (auto const [t, stop_range] : tt.trip_transport_ranges_ [trip]) {
27+ auto const [first_dep_offset, tz_offset] =
28+ tt.transport_first_dep_offset_ [t].to_offset ();
29+ auto const utc_dep =
30+ tt.event_mam (t, stop_range.from_ , event_type::kDep ).as_duration ();
31+ auto const gtfs_static_dep = utc_dep + first_dep_offset + tz_offset;
32+ auto const [gtfs_static_dep_day, gtfs_static_dep_time] =
33+ split (gtfs_static_dep);
34+ auto const [start_time_day, start_time_time] =
35+ start_time.has_value () ? split (*start_time)
36+ : std::pair{date::days{0U }, duration_t {0U }};
37+
38+ if (start_time.has_value () && gtfs_static_dep_time != start_time_time) {
39+ continue ;
40+ }
41+
42+ auto const start_time_day_offset =
43+ start_time.has_value () ? gtfs_static_dep_day - start_time_day
44+ : date::days{0U };
2745
28- auto const & trip_id = td.trip_id ();
46+ auto const day_idx =
47+ ((start_date.has_value () ? *start_date : today) + first_dep_offset -
48+ start_time_day_offset - tt.internal_interval_days ().from_ )
49+ .count ();
50+
51+ if (day_idx > kMaxDays || day_idx < 0 ) {
52+ continue ;
53+ }
54+
55+ auto const & traffic_days = tt.bitfields_ [tt.transport_traffic_days_ [t]];
56+ if (traffic_days.test (static_cast <std::size_t >(day_idx))) {
57+ auto const r = run{.t_ = transport{t, day_idx_t {day_idx}},
58+ .stop_range_ = stop_range};
59+ if (fn (r, trip) == utl::continue_t ::kBreak ) {
60+ return ;
61+ }
62+ }
63+ }
64+ }
65+
66+ template <typename Fn>
67+ void resolve_static_trip_id (date::sys_days const today,
68+ timetable const & tt,
69+ source_idx_t const src,
70+ std::string const & trip_id,
71+ std::optional<date::sys_days> const & start_date,
72+ std::optional<duration_t > const & start_time,
73+ Fn&& fn) {
2974 auto const lb = std::lower_bound (
3075 begin (tt.trip_id_to_idx_ ), end (tt.trip_id_to_idx_ ), trip_id,
3176 [&](pair<trip_id_idx_t , trip_idx_t > const & a, auto && b) {
@@ -34,58 +79,65 @@ void resolve_static(date::sys_days const today,
3479 std::tuple{src, static_cast <std::string_view>(b)};
3580 });
3681
37- auto const start_date = td.has_start_date ()
38- ? std::make_optional (parse_date (
39- utl::parse<unsigned >(td.start_date ())))
40- : std::nullopt ;
41- auto const start_time = td.has_start_time ()
42- ? std::make_optional (hhmm_to_min (td.start_time ()))
43- : std::nullopt ;
44-
4582 auto const id_matches = [&](trip_id_idx_t const t_id_idx) {
4683 return tt.trip_id_src_ [t_id_idx] == src &&
4784 tt.trip_id_strings_ [t_id_idx].view () == trip_id;
4885 };
4986
5087 for (auto i = lb; i != end (tt.trip_id_to_idx_ ) && id_matches (i->first ); ++i) {
51- for (auto const [t, stop_range] : tt.trip_transport_ranges_ [i->second ]) {
52- auto const [first_dep_offset, tz_offset] =
53- tt.transport_first_dep_offset_ [t].to_offset ();
54- auto const utc_dep =
55- tt.event_mam (t, stop_range.from_ , event_type::kDep ).as_duration ();
56- auto const gtfs_static_dep = utc_dep + first_dep_offset + tz_offset;
57- auto const [gtfs_static_dep_day, gtfs_static_dep_time] =
58- split (gtfs_static_dep);
59- auto const [start_time_day, start_time_time] =
60- start_time.has_value () ? split (*start_time)
61- : std::pair{date::days{0U }, duration_t {0U }};
62-
63- if (start_time.has_value () && gtfs_static_dep_time != start_time_time) {
64- continue ;
65- }
88+ resolve_trip (today, tt, i->second , start_date, start_time, fn);
89+ }
90+ }
6691
67- auto const start_time_day_offset =
68- start_time.has_value () ? gtfs_static_dep_day - start_time_day
69- : date::days{0U };
92+ template <typename Fn>
93+ void resolve_static_route (date::sys_days const today,
94+ timetable const & tt,
95+ source_idx_t const src,
96+ std::string const & route_id,
97+ direction_id_t const direction,
98+ date::sys_days const start_date,
99+ duration_t const start_time,
100+ Fn&& fn) {
101+ auto const route = tt.route_ids_ [src].ids_ .find (route_id);
102+ if (!route.has_value ()) {
103+ return ;
104+ }
70105
71- auto const day_idx =
72- ((start_date.has_value () ? *start_date : today) + first_dep_offset -
73- start_time_day_offset - tt.internal_interval_days ().from_ )
74- .count ();
106+ for (auto const trip : tt.route_ids_ [src].route_id_trips_ [*route]) {
107+ if (tt.trip_direction_id_ .test (trip) == (direction != 0U )) {
108+ resolve_trip (today, tt, trip, start_date, start_time, fn);
109+ }
110+ }
111+ }
75112
76- if (day_idx > kMaxDays || day_idx < 0 ) {
77- continue ;
78- }
113+ template <typename Fn>
114+ void resolve_static (date::sys_days const today,
115+ timetable const & tt,
116+ source_idx_t const src,
117+ transit_realtime::TripDescriptor const & td,
118+ Fn&& fn) {
119+ using loader::gtfs::hhmm_to_min;
120+ using loader::gtfs::parse_date;
79121
80- auto const & traffic_days = tt.bitfields_ [tt.transport_traffic_days_ [t]];
81- if (traffic_days.test (static_cast <std::size_t >(day_idx))) {
82- auto const r = run{.t_ = transport{t, day_idx_t {day_idx}},
83- .stop_range_ = stop_range};
84- if (fn (r, i->second ) == utl::continue_t ::kBreak ) {
85- return ;
86- }
87- }
88- }
122+ auto const start_date = td.has_start_date ()
123+ ? std::make_optional (parse_date (
124+ utl::parse<unsigned >(td.start_date ())))
125+ : std::nullopt ;
126+ auto const start_time = td.has_start_time ()
127+ ? std::make_optional (hhmm_to_min (td.start_time ()))
128+ : std::nullopt ;
129+
130+ if (td.has_trip_id ()) {
131+ resolve_static_trip_id (today, tt, src, td.trip_id (), start_date, start_time,
132+ std::forward<Fn>(fn));
133+ } else {
134+ utl_verify (td.has_route_id () && td.has_direction_id () &&
135+ start_time.has_value () && start_date.has_value (),
136+ " bad trip descriptor {}" , td.DebugString ());
137+ resolve_static_route (
138+ today, tt, src, td.route_id (),
139+ td.direction_id () == 0U ? direction_id_t {0U } : direction_id_t {1U },
140+ start_date.value (), start_time.value (), std::forward<Fn>(fn));
89141 }
90142}
91143
0 commit comments