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