diff options
author | Rutger Broekhoff | 2024-05-02 20:27:40 +0200 |
---|---|---|
committer | Rutger Broekhoff | 2024-05-02 20:27:40 +0200 |
commit | 17a3ea880402338420699e03bcb24181e4ff3924 (patch) | |
tree | da666ef91e0b60d20aa0b01529644c136fd1f4ab /src/querykv1/journeys.cpp | |
download | oeuf-17a3ea880402338420699e03bcb24181e4ff3924.tar.gz oeuf-17a3ea880402338420699e03bcb24181e4ff3924.zip |
Initial commit
Based on dc4ba6a
Diffstat (limited to 'src/querykv1/journeys.cpp')
-rw-r--r-- | src/querykv1/journeys.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/querykv1/journeys.cpp b/src/querykv1/journeys.cpp new file mode 100644 index 0000000..96566b2 --- /dev/null +++ b/src/querykv1/journeys.cpp | |||
@@ -0,0 +1,95 @@ | |||
1 | // vim:set sw=2 ts=2 sts et: | ||
2 | |||
3 | #include <iostream> | ||
4 | #include <map> | ||
5 | #include <string_view> | ||
6 | #include <unordered_set> | ||
7 | |||
8 | #include "journeys.hpp" | ||
9 | |||
10 | using namespace std::string_view_literals; | ||
11 | |||
12 | void journeys(const Options &options, Kv1Records &records, Kv1Index &index) { | ||
13 | const std::string_view want_begin_stop_code(options.begin_stop_code); | ||
14 | const std::string_view want_end_stop_code(options.end_stop_code); | ||
15 | |||
16 | FILE *out = stdout; | ||
17 | if (options.output_file_path != "-"sv) | ||
18 | out = fopen(options.output_file_path, "wb"); | ||
19 | if (!out) { | ||
20 | fprintf(stderr, "Open %s: %s\n", options.output_file_path, strerrordesc_np(errno)); | ||
21 | exit(EXIT_FAILURE); | ||
22 | } | ||
23 | |||
24 | std::cerr << "Generating journeys for " << options.line_planning_number << ", going from stop " | ||
25 | << options.begin_stop_code << " to " << options.end_stop_code << std::endl; | ||
26 | |||
27 | std::unordered_map<std::string, const Kv1UserStopPoint *> usrstops; | ||
28 | for (size_t i = 0; i < records.user_stop_points.size(); i++) { | ||
29 | const Kv1UserStopPoint *usrstop = &records.user_stop_points[i]; | ||
30 | usrstops[usrstop->key.user_stop_code] = usrstop; | ||
31 | } | ||
32 | |||
33 | std::unordered_set<std::string> journey_pattern_codes; | ||
34 | for (const auto &jopa : records.journey_patterns) { | ||
35 | if (jopa.key.line_planning_number != options.line_planning_number) | ||
36 | continue; | ||
37 | journey_pattern_codes.insert(jopa.key.journey_pattern_code); | ||
38 | } | ||
39 | |||
40 | std::unordered_map<std::string, std::vector<const Kv1JourneyPatternTimingLink *>> jopatilis; | ||
41 | for (size_t i = 0; i < records.journey_pattern_timing_links.size(); i++) { | ||
42 | const Kv1JourneyPatternTimingLink *jopatili = &records.journey_pattern_timing_links[i]; | ||
43 | if (jopatili->key.line_planning_number != options.line_planning_number | ||
44 | || !journey_pattern_codes.contains(jopatili->key.journey_pattern_code)) | ||
45 | continue; | ||
46 | jopatilis[jopatili->key.journey_pattern_code].push_back(jopatili); | ||
47 | } | ||
48 | |||
49 | std::unordered_set<std::string> valid_jopas; | ||
50 | for (auto &[journey_pattern_code, timing_links] : jopatilis) { | ||
51 | std::sort(timing_links.begin(), timing_links.end(), [](auto a, auto b) -> bool { | ||
52 | return a->key.timing_link_order < b->key.timing_link_order; | ||
53 | }); | ||
54 | auto begin_stop = timing_links.front()->user_stop_code_begin; | ||
55 | auto end_stop = timing_links.back()->user_stop_code_end; | ||
56 | |||
57 | const auto *begin = usrstops[begin_stop]; | ||
58 | const auto *end = usrstops[end_stop]; | ||
59 | |||
60 | bool begin_stop_ok = false; | ||
61 | if (want_begin_stop_code.starts_with("stop:")) | ||
62 | begin_stop_ok = want_begin_stop_code.substr(5) == begin_stop; | ||
63 | else if (want_begin_stop_code.starts_with("star:")) | ||
64 | begin_stop_ok = want_begin_stop_code.substr(5) == begin->user_stop_area_code; | ||
65 | |||
66 | bool end_stop_ok = false; | ||
67 | if (want_end_stop_code.starts_with("stop:")) | ||
68 | end_stop_ok = want_end_stop_code.substr(5) == end_stop; | ||
69 | else if (want_end_stop_code.starts_with("star:")) | ||
70 | end_stop_ok = want_end_stop_code.substr(5) == end->user_stop_area_code; | ||
71 | |||
72 | if (begin_stop_ok && end_stop_ok) { | ||
73 | valid_jopas.insert(journey_pattern_code); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | std::map<int, std::pair<std::string, std::string>> valid_journeys; | ||
78 | for (const auto &pujo : records.public_journeys) { | ||
79 | if (pujo.key.line_planning_number == options.line_planning_number | ||
80 | && valid_jopas.contains(pujo.journey_pattern_code)) { | ||
81 | valid_journeys[pujo.key.journey_number] = { | ||
82 | pujo.time_demand_group_code, | ||
83 | pujo.journey_pattern_code, | ||
84 | }; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | fputs("journey_number,time_demand_group_code,journey_pattern_code\n", out); | ||
89 | for (const auto &[journey_number, timdemgrp_jopa] : valid_journeys) { | ||
90 | const auto &[time_demand_group_code, journey_pattern_code] = timdemgrp_jopa; | ||
91 | fprintf(out, "%d,%s,%s\n", journey_number, time_demand_group_code.c_str(), journey_pattern_code.c_str()); | ||
92 | } | ||
93 | |||
94 | if (options.output_file_path != "-"sv) fclose(out); | ||
95 | } | ||