aboutsummaryrefslogtreecommitdiffstats
path: root/src/querykv1/journeys.cpp
diff options
context:
space:
mode:
authorLibravatar Rutger Broekhoff2024-05-02 20:27:40 +0200
committerLibravatar Rutger Broekhoff2024-05-02 20:27:40 +0200
commit17a3ea880402338420699e03bcb24181e4ff3924 (patch)
treeda666ef91e0b60d20aa0b01529644c136fd1f4ab /src/querykv1/journeys.cpp
downloadoeuf-17a3ea880402338420699e03bcb24181e4ff3924.tar.gz
oeuf-17a3ea880402338420699e03bcb24181e4ff3924.zip
Initial commit
Based on dc4ba6a
Diffstat (limited to 'src/querykv1/journeys.cpp')
-rw-r--r--src/querykv1/journeys.cpp95
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
10using namespace std::string_view_literals;
11
12void 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}