From abe5000544f857031fd894c2b6b70ae5f8d7bb55 Mon Sep 17 00:00:00 2001 From: Pablo Hoch Date: Thu, 10 Aug 2023 15:43:54 +0200 Subject: [PATCH 01/23] rename /paxmon/get_interchanges -> /paxmon/interchanges_at_station --- docs/api/paths.yaml | 6 +++--- docs/api/schemas/motis/paxmon.yaml | 4 ++-- ...et_interchanges.h => interchanges_at_station.h} | 4 ++-- ..._interchanges.cc => interchanges_at_station.cc} | 14 +++++++------- modules/paxmon/src/paxmon.cc | 6 +++--- protocol/Message.fbs | 8 ++++---- ....fbs => PaxMonInterchangesAtStationRequest.fbs} | 2 +- ...fbs => PaxMonInterchangesAtStationResponse.fbs} | 2 +- ui/rsl/src/api/protocol/motis/paxmon.ts | 12 ++++++------ 9 files changed, 29 insertions(+), 29 deletions(-) rename modules/paxmon/include/motis/paxmon/api/{get_interchanges.h => interchanges_at_station.h} (53%) rename modules/paxmon/src/api/{get_interchanges.cc => interchanges_at_station.cc} (92%) rename protocol/paxmon/{PaxMonGetInterchangesRequest.fbs => PaxMonInterchangesAtStationRequest.fbs} (86%) rename protocol/paxmon/{PaxMonGetInterchangesResponse.fbs => PaxMonInterchangesAtStationResponse.fbs} (92%) diff --git a/docs/api/paths.yaml b/docs/api/paths.yaml index 3ccc857a4..03a8f731b 100644 --- a/docs/api/paths.yaml +++ b/docs/api/paths.yaml @@ -352,13 +352,13 @@ type: motis.paxmon.PaxMonGetGroupsResponse description: Information about the requested passenger groups -/paxmon/get_interchanges: +/paxmon/interchanges_at_station: summary: List monitored interchanges at a station tags: - rsl - input: motis.paxmon.PaxMonGetInterchangesRequest + input: motis.paxmon.PaxMonInterchangesAtStationRequest output: - type: motis.paxmon.PaxMonGetInterchangesResponse + type: motis.paxmon.PaxMonInterchangesAtStationResponse description: Information about the requested interchanges /paxmon/group_statistics: diff --git a/docs/api/schemas/motis/paxmon.yaml b/docs/api/schemas/motis/paxmon.yaml index cc78d06bc..b641e1dd8 100644 --- a/docs/api/schemas/motis/paxmon.yaml +++ b/docs/api/schemas/motis/paxmon.yaml @@ -875,7 +875,7 @@ PaxMonUniverseDestroyed: fields: universe: description: TODO -PaxMonGetInterchangesRequest: +PaxMonInterchangesAtStationRequest: description: TODO fields: universe: @@ -924,7 +924,7 @@ PaxMonInterchangeInfo: description: TODO broken: description: TODO -PaxMonGetInterchangesResponse: +PaxMonInterchangesAtStationResponse: description: TODO fields: station: diff --git a/modules/paxmon/include/motis/paxmon/api/get_interchanges.h b/modules/paxmon/include/motis/paxmon/api/interchanges_at_station.h similarity index 53% rename from modules/paxmon/include/motis/paxmon/api/get_interchanges.h rename to modules/paxmon/include/motis/paxmon/api/interchanges_at_station.h index af7375276..9f782e939 100644 --- a/modules/paxmon/include/motis/paxmon/api/get_interchanges.h +++ b/modules/paxmon/include/motis/paxmon/api/interchanges_at_station.h @@ -6,7 +6,7 @@ namespace motis::paxmon::api { -motis::module::msg_ptr get_interchanges(paxmon_data& data, - motis::module::msg_ptr const& msg); +motis::module::msg_ptr interchanges_at_station( + paxmon_data& data, motis::module::msg_ptr const& msg); } // namespace motis::paxmon::api diff --git a/modules/paxmon/src/api/get_interchanges.cc b/modules/paxmon/src/api/interchanges_at_station.cc similarity index 92% rename from modules/paxmon/src/api/get_interchanges.cc rename to modules/paxmon/src/api/interchanges_at_station.cc index 80dc5edbc..b8b2c9b8a 100644 --- a/modules/paxmon/src/api/get_interchanges.cc +++ b/modules/paxmon/src/api/interchanges_at_station.cc @@ -1,4 +1,4 @@ -#include "motis/paxmon/api/get_interchanges.h" +#include "motis/paxmon/api/interchanges_at_station.h" #include #include @@ -16,8 +16,8 @@ using namespace motis::paxmon; namespace motis::paxmon::api { -msg_ptr get_interchanges(paxmon_data& data, msg_ptr const& msg) { - auto const req = motis_content(PaxMonGetInterchangesRequest, msg); +msg_ptr interchanges_at_station(paxmon_data& data, msg_ptr const& msg) { + auto const req = motis_content(PaxMonInterchangesAtStationRequest, msg); auto const uv_access = get_universe_and_schedule(data, req->universe()); auto const& sched = uv_access.sched_; auto& uv = uv_access.uv_; @@ -145,10 +145,10 @@ msg_ptr get_interchanges(paxmon_data& data, msg_ptr const& msg) { } mc.create_and_finish( - MsgContent_PaxMonGetInterchangesResponse, - CreatePaxMonGetInterchangesResponse(mc, to_fbs(mc, ic_station), - mc.CreateVector(interchange_infos), - max_count_reached) + MsgContent_PaxMonInterchangesAtStationResponse, + CreatePaxMonInterchangesAtStationResponse( + mc, to_fbs(mc, ic_station), mc.CreateVector(interchange_infos), + max_count_reached) .Union()); return make_msg(mc); } diff --git a/modules/paxmon/src/paxmon.cc b/modules/paxmon/src/paxmon.cc index 57916a6bc..ba6e87f58 100644 --- a/modules/paxmon/src/paxmon.cc +++ b/modules/paxmon/src/paxmon.cc @@ -34,12 +34,12 @@ #include "motis/paxmon/api/get_addressable_groups.h" #include "motis/paxmon/api/get_groups.h" #include "motis/paxmon/api/get_groups_in_trip.h" -#include "motis/paxmon/api/get_interchanges.h" #include "motis/paxmon/api/get_status.h" #include "motis/paxmon/api/get_trip_capacity.h" #include "motis/paxmon/api/get_trip_load_info.h" #include "motis/paxmon/api/get_universes.h" #include "motis/paxmon/api/group_statistics.h" +#include "motis/paxmon/api/interchanges_at_station.h" #include "motis/paxmon/api/keep_alive.h" #include "motis/paxmon/api/metrics.h" #include "motis/paxmon/api/remove_groups.h" @@ -401,9 +401,9 @@ void paxmon::init(motis::module::registry& reg) { }, {}); - reg.register_op("/paxmon/get_interchanges", + reg.register_op("/paxmon/interchanges_at_station", [&](msg_ptr const& msg) -> msg_ptr { - return api::get_interchanges(data_, msg); + return api::interchanges_at_station(data_, msg); }, {}); diff --git a/protocol/Message.fbs b/protocol/Message.fbs index 69a15ca26..b4dddea0c 100644 --- a/protocol/Message.fbs +++ b/protocol/Message.fbs @@ -111,8 +111,8 @@ include "paxmon/PaxMonGetGroupsInTripRequest.fbs"; include "paxmon/PaxMonGetGroupsInTripResponse.fbs"; include "paxmon/PaxMonUniverseForked.fbs"; include "paxmon/PaxMonUniverseDestroyed.fbs"; -include "paxmon/PaxMonGetInterchangesRequest.fbs"; -include "paxmon/PaxMonGetInterchangesResponse.fbs"; +include "paxmon/PaxMonInterchangesAtStationRequest.fbs"; +include "paxmon/PaxMonInterchangesAtStationResponse.fbs"; include "paxmon/PaxMonGetAddressableGroupsRequest.fbs"; include "paxmon/PaxMonGetAddressableGroupsResponse.fbs"; include "paxmon/PaxMonKeepAliveRequest.fbs"; @@ -300,8 +300,8 @@ union MsgContent { motis.paxforecast.PaxForecastApplyMeasuresRequest = 118, motis.paxmon.PaxMonUniverseForked = 119, motis.paxmon.PaxMonUniverseDestroyed = 120, - motis.paxmon.PaxMonGetInterchangesRequest = 121, - motis.paxmon.PaxMonGetInterchangesResponse = 122, + motis.paxmon.PaxMonInterchangesAtStationRequest = 121, + motis.paxmon.PaxMonInterchangesAtStationResponse = 122, motis.paxmon.PaxMonStatusRequest = 123, motis.ris.RISApplyRequest = 124, motis.ris.RISSystemTimeChanged = 125, diff --git a/protocol/paxmon/PaxMonGetInterchangesRequest.fbs b/protocol/paxmon/PaxMonInterchangesAtStationRequest.fbs similarity index 86% rename from protocol/paxmon/PaxMonGetInterchangesRequest.fbs rename to protocol/paxmon/PaxMonInterchangesAtStationRequest.fbs index 89cd93ba9..e12ea4345 100644 --- a/protocol/paxmon/PaxMonGetInterchangesRequest.fbs +++ b/protocol/paxmon/PaxMonInterchangesAtStationRequest.fbs @@ -1,6 +1,6 @@ namespace motis.paxmon; -table PaxMonGetInterchangesRequest { +table PaxMonInterchangesAtStationRequest { universe: uint; station: string; // station id diff --git a/protocol/paxmon/PaxMonGetInterchangesResponse.fbs b/protocol/paxmon/PaxMonInterchangesAtStationResponse.fbs similarity index 92% rename from protocol/paxmon/PaxMonGetInterchangesResponse.fbs rename to protocol/paxmon/PaxMonInterchangesAtStationResponse.fbs index 7651600e4..ba6fa92e4 100644 --- a/protocol/paxmon/PaxMonGetInterchangesResponse.fbs +++ b/protocol/paxmon/PaxMonInterchangesAtStationResponse.fbs @@ -21,7 +21,7 @@ table PaxMonInterchangeInfo { broken: bool; } -table PaxMonGetInterchangesResponse { +table PaxMonInterchangesAtStationResponse { station: motis.Station; interchanges: [PaxMonInterchangeInfo]; max_count_reached: bool; diff --git a/ui/rsl/src/api/protocol/motis/paxmon.ts b/ui/rsl/src/api/protocol/motis/paxmon.ts index 291a3f89e..34d6b08c5 100644 --- a/ui/rsl/src/api/protocol/motis/paxmon.ts +++ b/ui/rsl/src/api/protocol/motis/paxmon.ts @@ -583,8 +583,8 @@ export interface PaxMonUniverseDestroyed { universe: number; } -// paxmon/PaxMonGetInterchangesRequest.fbs -export interface PaxMonGetInterchangesRequest { +// paxmon/PaxMonInterchangesAtStationRequest.fbs +export interface PaxMonInterchangesAtStationRequest { universe: number; station: string; start_time: number; @@ -596,7 +596,7 @@ export interface PaxMonGetInterchangesRequest { include_disabled_group_routes: boolean; } -// paxmon/PaxMonGetInterchangesResponse.fbs +// paxmon/PaxMonInterchangesAtStationResponse.fbs export interface PaxMonTripStopInfo { schedule_time: number; current_time: number; @@ -604,7 +604,7 @@ export interface PaxMonTripStopInfo { station: Station; } -// paxmon/PaxMonGetInterchangesResponse.fbs +// paxmon/PaxMonInterchangesAtStationResponse.fbs export interface PaxMonInterchangeInfo { arrival: PaxMonTripStopInfo[]; departure: PaxMonTripStopInfo[]; @@ -615,8 +615,8 @@ export interface PaxMonInterchangeInfo { broken: boolean; } -// paxmon/PaxMonGetInterchangesResponse.fbs -export interface PaxMonGetInterchangesResponse { +// paxmon/PaxMonInterchangesAtStationResponse.fbs +export interface PaxMonInterchangesAtStationResponse { station: Station; interchanges: PaxMonInterchangeInfo[]; max_count_reached: boolean; From fb0472ea3c43b2933216a977fa451e5e0a46987f Mon Sep 17 00:00:00 2001 From: Pablo Hoch Date: Mon, 21 Aug 2023 17:19:17 +0200 Subject: [PATCH 02/23] rsl: new /paxmon/critical_interchanges + /paxmon/interchange_details apis --- .../motis/paxmon/api/critical_interchanges.h | 12 ++ .../motis/paxmon/api/interchange_details.h | 12 ++ .../paxmon/include/motis/paxmon/universe.h | 4 +- .../include/motis/paxmon/util/group_delay.h | 57 +++++ .../motis/paxmon/util/interchange_info.h | 195 +++++++++++++++++ .../paxmon/src/api/critical_interchanges.cc | 202 ++++++++++++++++++ modules/paxmon/src/api/get_groups_in_trip.cc | 2 +- modules/paxmon/src/api/interchange_details.cc | 49 +++++ .../paxmon/src/api/interchanges_at_station.cc | 75 ++----- modules/paxmon/src/paxmon.cc | 14 ++ protocol/Message.fbs | 10 +- .../PaxMonCriticalInterchangesRequest.fbs | 30 +++ .../PaxMonCriticalInterchangesResponse.fbs | 12 ++ .../PaxMonInterchangeDetailsRequest.fbs | 8 + .../PaxMonInterchangeDetailsResponse.fbs | 10 + protocol/paxmon/PaxMonInterchangeId.fbs | 6 + protocol/paxmon/PaxMonInterchangeInfo.fbs | 40 ++++ .../PaxMonInterchangesAtStationResponse.fbs | 20 +- .../interchanges/CriticalInterchangeList.tsx | 62 ++++++ .../interchanges/InterchangesMainSection.tsx | 18 ++ 20 files changed, 753 insertions(+), 85 deletions(-) create mode 100644 modules/paxmon/include/motis/paxmon/api/critical_interchanges.h create mode 100644 modules/paxmon/include/motis/paxmon/api/interchange_details.h create mode 100644 modules/paxmon/include/motis/paxmon/util/group_delay.h create mode 100644 modules/paxmon/include/motis/paxmon/util/interchange_info.h create mode 100644 modules/paxmon/src/api/critical_interchanges.cc create mode 100644 modules/paxmon/src/api/interchange_details.cc create mode 100644 protocol/paxmon/PaxMonCriticalInterchangesRequest.fbs create mode 100644 protocol/paxmon/PaxMonCriticalInterchangesResponse.fbs create mode 100644 protocol/paxmon/PaxMonInterchangeDetailsRequest.fbs create mode 100644 protocol/paxmon/PaxMonInterchangeDetailsResponse.fbs create mode 100644 protocol/paxmon/PaxMonInterchangeId.fbs create mode 100644 protocol/paxmon/PaxMonInterchangeInfo.fbs create mode 100644 ui/rsl/src/components/interchanges/CriticalInterchangeList.tsx create mode 100644 ui/rsl/src/components/interchanges/InterchangesMainSection.tsx diff --git a/modules/paxmon/include/motis/paxmon/api/critical_interchanges.h b/modules/paxmon/include/motis/paxmon/api/critical_interchanges.h new file mode 100644 index 000000000..a8e8d2ea9 --- /dev/null +++ b/modules/paxmon/include/motis/paxmon/api/critical_interchanges.h @@ -0,0 +1,12 @@ +#pragma once + +#include "motis/module/message.h" + +#include "motis/paxmon/paxmon_data.h" + +namespace motis::paxmon::api { + +motis::module::msg_ptr critical_interchanges(paxmon_data& data, + motis::module::msg_ptr const& msg); + +} // namespace motis::paxmon::api diff --git a/modules/paxmon/include/motis/paxmon/api/interchange_details.h b/modules/paxmon/include/motis/paxmon/api/interchange_details.h new file mode 100644 index 000000000..4cfe5737f --- /dev/null +++ b/modules/paxmon/include/motis/paxmon/api/interchange_details.h @@ -0,0 +1,12 @@ +#pragma once + +#include "motis/module/message.h" + +#include "motis/paxmon/paxmon_data.h" + +namespace motis::paxmon::api { + +motis::module::msg_ptr interchange_details(paxmon_data& data, + motis::module::msg_ptr const& msg); + +} // namespace motis::paxmon::api diff --git a/modules/paxmon/include/motis/paxmon/universe.h b/modules/paxmon/include/motis/paxmon/universe.h index 250f9e781..2f2de33b5 100644 --- a/modules/paxmon/include/motis/paxmon/universe.h +++ b/modules/paxmon/include/motis/paxmon/universe.h @@ -65,7 +65,9 @@ struct edge { inline edge_type type() const { return type_; } - inline bool has_trips() const { return is_trip() || is_wait(); } + inline bool has_trips() const { + return is_trip() || is_wait() || is_disabled(); + } inline merged_trips_idx get_merged_trips_idx() const { return trips_; } diff --git a/modules/paxmon/include/motis/paxmon/util/group_delay.h b/modules/paxmon/include/motis/paxmon/util/group_delay.h new file mode 100644 index 000000000..526814bd5 --- /dev/null +++ b/modules/paxmon/include/motis/paxmon/util/group_delay.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include "motis/paxmon/universe.h" + +namespace motis::paxmon::util { + +struct group_delay_info { + float estimated_delay_{}; + bool possibly_unreachable_{}; +}; + +inline group_delay_info get_current_estimated_delay( + universe const& uv, passenger_group_index const pgi, + std::int16_t const unreachable_delay = 24 * 60) { + auto info = group_delay_info{}; + auto at_least_one_active_route = false; + for (auto const& gr : uv.passenger_groups_.routes(pgi)) { + if (gr.probability_ != 0) { + auto const route_est_delay = + gr.destination_unreachable_ ? unreachable_delay : gr.estimated_delay_; + info.estimated_delay_ += gr.probability_ * route_est_delay; + at_least_one_active_route = true; + if (gr.destination_unreachable_) { + info.possibly_unreachable_ = true; + } + } + } + if (!at_least_one_active_route) { + info.estimated_delay_ = unreachable_delay; + info.possibly_unreachable_ = true; + } + return info; +} + +inline std::int16_t get_scheduled_delay(universe const& uv, + passenger_group_with_route const pgwr, + std::int16_t const invalid_delay = 24 * + 60) { + // assumption in this function: route 0 is the (only) planned route + if (pgwr.route_ == 0) { + return 0; + } + auto const this_planned_arrival = + uv.passenger_groups_.route(pgwr).planned_arrival_time_; + if (this_planned_arrival == INVALID_TIME) { + return invalid_delay; + } + auto const original_planned_arrival = + uv.passenger_groups_.route(passenger_group_with_route{pgwr.pg_, 0}) + .planned_arrival_time_; + return static_cast(static_cast(this_planned_arrival) - + static_cast(original_planned_arrival)); +} + +} // namespace motis::paxmon::util diff --git a/modules/paxmon/include/motis/paxmon/util/interchange_info.h b/modules/paxmon/include/motis/paxmon/util/interchange_info.h new file mode 100644 index 000000000..5a423d19d --- /dev/null +++ b/modules/paxmon/include/motis/paxmon/util/interchange_info.h @@ -0,0 +1,195 @@ +#pragma once + +#include +#include + +#include "flatbuffers/flatbuffers.h" + +#include "motis/core/schedule/schedule.h" +#include "motis/core/conv/station_conv.h" + +#include "motis/paxmon/get_load.h" +#include "motis/paxmon/messages.h" +#include "motis/paxmon/universe.h" +#include "motis/paxmon/util/group_delay.h" + +namespace motis::paxmon::util { + +struct interchange_info { + flatbuffers::Offset to_fbs_interchange_info( + flatbuffers::FlatBufferBuilder& fbb, universe const& uv, + schedule const& sched, bool const include_delay_info) const { + auto const id = PaxMonInterchangeId{ei_.node_, ei_.out_edge_idx_}; + auto const* e = ei_.get(uv); + + auto const make_fbs_event = [&](event_node const* ev, bool const arrival) { + std::vector> res; + if (!ev->is_enter_exit_node()) { + std::vector> fbs_trips; + // TODO(pablo): service infos only for arriving trip section + if (arrival) { + for (auto const& trp_edge : ev->incoming_edges(uv)) { + if (trp_edge.is_trip() || trp_edge.is_disabled()) { + for (auto const& trp : trp_edge.get_trips(sched)) { + fbs_trips.emplace_back( + to_fbs_trip_service_info(fbb, sched, trp)); + } + } + } + } else { + for (auto const& trp_edge : ev->outgoing_edges(uv)) { + if (trp_edge.is_trip() || trp_edge.is_disabled()) { + for (auto const& trp : trp_edge.get_trips(sched)) { + fbs_trips.emplace_back( + to_fbs_trip_service_info(fbb, sched, trp)); + } + } + } + } + res.emplace_back(CreatePaxMonTripStopInfo( + fbb, motis_to_unixtime(sched, ev->schedule_time()), + motis_to_unixtime(sched, ev->current_time()), ev->is_canceled(), + fbb.CreateVector(fbs_trips), + to_fbs(fbb, *sched.stations_.at(ev->station_idx())))); + } + return fbb.CreateVector(res); + }; + + return CreatePaxMonInterchangeInfo( + fbb, &id, make_fbs_event(from_, true), make_fbs_event(to_, false), + groups_, group_count_, pax_count_, e->transfer_time(), e->is_valid(uv), + e->is_disabled(), e->is_broken(), e->is_canceled(uv), + include_delay_info + ? CreatePaxMonInterchangeDelayInfo( + fbb, min_delay_increase_, max_delay_increase_, + total_delay_increase_, squared_total_delay_increase_, + unreachable_pax_) + : 0); + } + + edge_index ei_; + + event_node const* from_{}; + event_node const* to_{}; + + std::int32_t group_count_{}; + std::int32_t pax_count_{}; + + std::int16_t min_delay_increase_{std::numeric_limits::max()}; + std::int16_t max_delay_increase_{}; + std::int64_t total_delay_increase_{}; + std::uint64_t squared_total_delay_increase_{}; + std::int32_t unreachable_pax_{}; + + std::uint32_t normal_routes_{}; + std::uint32_t broken_routes_{}; + + flatbuffers::Offset groups_{}; +}; + +struct get_interchange_info_options { + bool include_group_infos_{}; + bool include_disabled_group_routes_{}; + bool include_delay_info_{}; + bool only_planned_routes_{}; +}; + +inline interchange_info get_interchange_info( + universe const& uv, schedule const& sched, edge_index const ei, + flatbuffers::FlatBufferBuilder& fbb, + get_interchange_info_options const& options) { + auto const* ic_edge = ei.get(uv); + auto info = interchange_info{ + .ei_ = ei, .from_ = ic_edge->from(uv), .to_ = ic_edge->to(uv)}; + + auto group_route_infos = std::vector{}; + auto last_pg = std::numeric_limits::max(); + + auto const handle_pgwr = [&](auto const& pgwr) { + if (options.only_planned_routes_ && pgwr.route_ != 0) { + return; + } + auto const& pg = uv.passenger_groups_.at(pgwr.pg_); + auto const& gr = uv.passenger_groups_.route(pgwr); + + auto const is_new_group = last_pg != pgwr.pg_; + + if (is_new_group) { + last_pg = pgwr.pg_; + ++info.group_count_; + info.pax_count_ += pg->passengers_; + } + + if (options.include_delay_info_) { + auto const current_group_delay_info = + get_current_estimated_delay(uv, pgwr.pg_); + auto const current_group_est_delay = + static_cast(current_group_delay_info.estimated_delay_); + + auto const sched_delay = get_scheduled_delay(uv, pgwr); + + auto const delay_increase = + static_cast(current_group_est_delay - sched_delay); + + if (!current_group_delay_info.possibly_unreachable_) { + info.min_delay_increase_ = + std::min(info.min_delay_increase_, delay_increase); + info.max_delay_increase_ = + std::max(info.max_delay_increase_, delay_increase); + } + + if (delay_increase > 0) { + info.total_delay_increase_ += delay_increase; + info.squared_total_delay_increase_ += + static_cast(delay_increase) * + static_cast(delay_increase); + } + + if (is_new_group && current_group_delay_info.possibly_unreachable_) { + info.unreachable_pax_ += pg->passengers_; + } + } + + if (options.include_group_infos_) { + if (options.include_disabled_group_routes_ || gr.probability_ != 0.0F) { + group_route_infos.emplace_back(to_fbs_base_info(fbb, *pg, gr)); + } + } + }; + + auto const normal_routes = + uv.pax_connection_info_.group_routes(ic_edge->pci_); + auto const broken_routes = + uv.pax_connection_info_.broken_group_routes(ic_edge->pci_); + + info.normal_routes_ = normal_routes.size(); + info.broken_routes_ = broken_routes.size(); + + for (auto const& pgwr : normal_routes) { + handle_pgwr(pgwr); + } + + for (auto const& pgwr : broken_routes) { + handle_pgwr(pgwr); + } + + if (options.include_group_infos_) { + std::sort(begin(group_route_infos), end(group_route_infos), + [](PaxMonGroupRouteBaseInfo const& a, + PaxMonGroupRouteBaseInfo const& b) { + return std::make_pair(a.g(), a.r()) < + std::make_pair(b.g(), b.r()); + }); + auto const pdf = + get_load_pdf(uv.passenger_groups_, + uv.pax_connection_info_.group_routes(ic_edge->pci_)); + auto const cdf = get_cdf(pdf); + info.groups_ = CreatePaxMonCombinedGroupRoutes( + fbb, fbb.CreateVectorOfStructs(group_route_infos), + to_fbs_distribution(fbb, pdf, cdf)); + } + + return info; +} + +} // namespace motis::paxmon::util diff --git a/modules/paxmon/src/api/critical_interchanges.cc b/modules/paxmon/src/api/critical_interchanges.cc new file mode 100644 index 000000000..38e1dc31d --- /dev/null +++ b/modules/paxmon/src/api/critical_interchanges.cc @@ -0,0 +1,202 @@ +#include "motis/paxmon/api/critical_interchanges.h" + +#include +#include +#include +#include + +#include "utl/to_vec.h" + +#include "motis/core/access/time_access.h" + +#include "motis/paxmon/get_universe.h" +#include "motis/paxmon/messages.h" +#include "motis/paxmon/util/interchange_info.h" + +using namespace motis::module; +using namespace motis::paxmon; +using namespace motis::paxmon::util; +using namespace flatbuffers; + +namespace motis::paxmon::api { + +msg_ptr critical_interchanges(paxmon_data& data, msg_ptr const& msg) { + auto const req = motis_content(PaxMonCriticalInterchangesRequest, msg); + auto const uv_access = get_universe_and_schedule(data, req->universe()); + auto const& sched = uv_access.sched_; + auto const& uv = uv_access.uv_; + + auto const max_results = req->max_results(); + auto const skip_first = req->skip_first(); + + auto const filter_interval_begin = + req->filter_interval()->begin() != 0 + ? unix_to_motistime(sched.schedule_begin_, + req->filter_interval()->begin()) + : 0; + auto const filter_interval_end = + req->filter_interval()->end() != 0 + ? unix_to_motistime(sched.schedule_begin_, + req->filter_interval()->end()) + : std::numeric_limits