aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libtmi8/include
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 /lib/libtmi8/include
downloadoeuf-17a3ea880402338420699e03bcb24181e4ff3924.tar.gz
oeuf-17a3ea880402338420699e03bcb24181e4ff3924.zip
Initial commit
Based on dc4ba6a
Diffstat (limited to 'lib/libtmi8/include')
-rw-r--r--lib/libtmi8/include/tmi8/kv1_index.hpp135
-rw-r--r--lib/libtmi8/include/tmi8/kv1_lexer.hpp46
-rw-r--r--lib/libtmi8/include/tmi8/kv1_parser.hpp87
-rw-r--r--lib/libtmi8/include/tmi8/kv1_types.hpp1528
-rw-r--r--lib/libtmi8/include/tmi8/kv6_parquet.hpp46
5 files changed, 1842 insertions, 0 deletions
diff --git a/lib/libtmi8/include/tmi8/kv1_index.hpp b/lib/libtmi8/include/tmi8/kv1_index.hpp
new file mode 100644
index 0000000..621acf6
--- /dev/null
+++ b/lib/libtmi8/include/tmi8/kv1_index.hpp
@@ -0,0 +1,135 @@
1// vim:set sw=2 ts=2 sts et:
2
3#ifndef OEUF_LIBTMI8_KV1_INDEX_HPP
4#define OEUF_LIBTMI8_KV1_INDEX_HPP
5
6#include <unordered_map>
7
8#include <boost/container_hash/hash.hpp>
9
10#include <tmi8/kv1_types.hpp>
11
12struct Kv1Index {
13 Kv1Records *records;
14
15 explicit Kv1Index(Kv1Records *records);
16
17 std::unordered_map<
18 Kv1OrganizationalUnit::Key,
19 Kv1OrganizationalUnit *,
20 boost::hash<Kv1OrganizationalUnit::Key>> organizational_units;
21 std::unordered_map<
22 Kv1HigherOrganizationalUnit::Key,
23 Kv1HigherOrganizationalUnit *,
24 boost::hash<Kv1HigherOrganizationalUnit::Key>> higher_organizational_units;
25 std::unordered_map<
26 Kv1UserStopPoint::Key,
27 Kv1UserStopPoint *,
28 boost::hash<Kv1UserStopPoint::Key>> user_stop_points;
29 std::unordered_map<
30 Kv1UserStopArea::Key,
31 Kv1UserStopArea *,
32 boost::hash<Kv1UserStopArea::Key>> user_stop_areas;
33 std::unordered_map<
34 Kv1TimingLink::Key,
35 Kv1TimingLink *,
36 boost::hash<Kv1TimingLink::Key>> timing_links;
37 std::unordered_map<
38 Kv1Link::Key,
39 Kv1Link *,
40 boost::hash<Kv1Link::Key>> links;
41 std::unordered_map<
42 Kv1Line::Key,
43 Kv1Line *,
44 boost::hash<Kv1Line::Key>> lines;
45 std::unordered_map<
46 Kv1Destination::Key,
47 Kv1Destination *,
48 boost::hash<Kv1Destination::Key>> destinations;
49 std::unordered_map<
50 Kv1JourneyPattern::Key,
51 Kv1JourneyPattern *,
52 boost::hash<Kv1JourneyPattern::Key>> journey_patterns;
53 std::unordered_map<
54 Kv1ConcessionFinancerRelation::Key,
55 Kv1ConcessionFinancerRelation *,
56 boost::hash<Kv1ConcessionFinancerRelation::Key>> concession_financer_relations;
57 std::unordered_map<
58 Kv1ConcessionArea::Key,
59 Kv1ConcessionArea *,
60 boost::hash<Kv1ConcessionArea::Key>> concession_areas;
61 std::unordered_map<
62 Kv1Financer::Key,
63 Kv1Financer *,
64 boost::hash<Kv1Financer::Key>> financers;
65 std::unordered_map<
66 Kv1JourneyPatternTimingLink::Key,
67 Kv1JourneyPatternTimingLink *,
68 boost::hash<Kv1JourneyPatternTimingLink::Key>> journey_pattern_timing_links;
69 std::unordered_map<
70 Kv1Point::Key,
71 Kv1Point *,
72 boost::hash<Kv1Point::Key>> points;
73 std::unordered_map<
74 Kv1PointOnLink::Key,
75 Kv1PointOnLink *,
76 boost::hash<Kv1PointOnLink::Key>> point_on_links;
77 std::unordered_map<
78 Kv1Icon::Key,
79 Kv1Icon *,
80 boost::hash<Kv1Icon::Key>> icons;
81 std::unordered_map<
82 Kv1Notice::Key,
83 Kv1Notice *,
84 boost::hash<Kv1Notice::Key>> notices;
85 std::unordered_map<
86 Kv1TimeDemandGroup::Key,
87 Kv1TimeDemandGroup *,
88 boost::hash<Kv1TimeDemandGroup::Key>> time_demand_groups;
89 std::unordered_map<
90 Kv1TimeDemandGroupRunTime::Key,
91 Kv1TimeDemandGroupRunTime *,
92 boost::hash<Kv1TimeDemandGroupRunTime::Key>> time_demand_group_run_times;
93 std::unordered_map<
94 Kv1PeriodGroup::Key,
95 Kv1PeriodGroup *,
96 boost::hash<Kv1PeriodGroup::Key>> period_groups;
97 std::unordered_map<
98 Kv1SpecificDay::Key,
99 Kv1SpecificDay *,
100 boost::hash<Kv1SpecificDay::Key>> specific_days;
101 std::unordered_map<
102 Kv1TimetableVersion::Key,
103 Kv1TimetableVersion *,
104 boost::hash<Kv1TimetableVersion::Key>> timetable_versions;
105 std::unordered_map<
106 Kv1PublicJourney::Key,
107 Kv1PublicJourney *,
108 boost::hash<Kv1PublicJourney::Key>> public_journeys;
109 std::unordered_map<
110 Kv1PeriodGroupValidity::Key,
111 Kv1PeriodGroupValidity *,
112 boost::hash<Kv1PeriodGroupValidity::Key>> period_group_validities;
113 std::unordered_map<
114 Kv1ExceptionalOperatingDay::Key,
115 Kv1ExceptionalOperatingDay *,
116 boost::hash<Kv1ExceptionalOperatingDay::Key>> exceptional_operating_days;
117 std::unordered_map<
118 Kv1ScheduleVersion::Key,
119 Kv1ScheduleVersion *,
120 boost::hash<Kv1ScheduleVersion::Key>> schedule_versions;
121 std::unordered_map<
122 Kv1PublicJourneyPassingTimes::Key,
123 Kv1PublicJourneyPassingTimes *,
124 boost::hash<Kv1PublicJourneyPassingTimes::Key>> public_journey_passing_times;
125 std::unordered_map<
126 Kv1OperatingDay::Key,
127 Kv1OperatingDay *,
128 boost::hash<Kv1OperatingDay::Key>> operating_days;
129
130 size_t size() const;
131};
132
133void kv1LinkRecords(Kv1Index &index);
134
135#endif // OEUF_LIBTMI8_KV1_INDEX_HPP
diff --git a/lib/libtmi8/include/tmi8/kv1_lexer.hpp b/lib/libtmi8/include/tmi8/kv1_lexer.hpp
new file mode 100644
index 0000000..df6a57c
--- /dev/null
+++ b/lib/libtmi8/include/tmi8/kv1_lexer.hpp
@@ -0,0 +1,46 @@
1// vim:set sw=2 ts=2 sts et:
2
3#ifndef OEUF_LIBTMI8_KV1_LEXER_HPP
4#define OEUF_LIBTMI8_KV1_LEXER_HPP
5
6#include <cstdint>
7#include <cstring>
8#include <iostream>
9#include <string>
10#include <vector>
11#include <variant>
12
13enum Kv1TokenType {
14 KV1_TOKEN_CELL,
15 KV1_TOKEN_ROW_END,
16};
17struct Kv1Token { Kv1TokenType type; std::string data; };
18
19struct Kv1Lexer {
20 std::vector<std::string> errors;
21 std::vector<Kv1Token> tokens;
22
23 explicit Kv1Lexer(std::string_view input);
24
25 void lex();
26
27 private:
28 // Does not eat newline character.
29 void eatRestOfLine();
30 void lexOptionalHeader();
31 void lexOptionalComment();
32
33 static bool isWhitespace(int c);
34
35 void readQuotedColumn();
36 void readUnquotedColumn();
37 void lexRow();
38 // Returns true when a line ending was consumed.
39 bool eatWhitespace();
40
41 std::string_view input;
42 std::string_view slice;
43 std::string colbuf;
44};
45
46#endif // OEUF_LIBTMI8_KV1_LEXER_HPP
diff --git a/lib/libtmi8/include/tmi8/kv1_parser.hpp b/lib/libtmi8/include/tmi8/kv1_parser.hpp
new file mode 100644
index 0000000..ccd8ec6
--- /dev/null
+++ b/lib/libtmi8/include/tmi8/kv1_parser.hpp
@@ -0,0 +1,87 @@
1// vim:set sw=2 ts=2 sts et:
2
3#ifndef OEUF_LIBTMI8_KV1_PARSER_HPP
4#define OEUF_LIBTMI8_KV1_PARSER_HPP
5
6#include <optional>
7#include <string>
8#include <string_view>
9#include <unordered_map>
10#include <vector>
11
12#include <tmi8/kv1_lexer.hpp>
13#include <tmi8/kv1_types.hpp>
14
15struct Kv1Parser {
16 explicit Kv1Parser(std::vector<Kv1Token> tokens, Kv1Records &parse_into);
17
18 void parse();
19
20 private:
21 // Method pointer to a method of Kv1Parser (i.e. a function that takes
22 // 'this'; is not static) that takes no arguments and also does not return
23 // anything.
24 using ParseFunc = void (Kv1Parser::*)();
25 static const std::unordered_map<std::string_view, ParseFunc> type_parsers;
26
27 bool atEnd() const;
28 void eatRowEnds();
29 const Kv1Token *cur() const;
30 const std::string *eatCell(std::string_view parsing_what);
31 std::string parseHeader();
32 void eatRestOfRow();
33
34 void requireString(std::string_view field, bool mandatory, size_t max_length, std::string_view value);
35 std::optional<bool> requireBoolean(std::string_view field, bool mandatory, std::string_view value);
36 std::optional<double> requireNumber(std::string_view field, bool mandatory, size_t max_digits, std::string_view value);
37 std::optional<RgbColor> requireRgbColor(std::string_view field, bool mandatory, std::string_view value);
38 std::optional<double> requireRdCoord(std::string_view field, bool mandatory, size_t min_digits, std::string_view value);
39
40 std::string eatString(std::string_view field, bool mandatory, size_t max_length);
41 std::optional<bool> eatBoolean(std::string_view field, bool mandatory);
42 std::optional<double> eatNumber(std::string_view field, bool mandatory, size_t max_digits);
43 std::optional<RgbColor> eatRgbColor(std::string_view field, bool mandatory);
44 std::optional<double> eatRdCoord(std::string_view field, bool mandatory, size_t min_digits);
45
46 void parseOrganizationalUnit();
47 void parseHigherOrganizationalUnit();
48 void parseUserStopPoint();
49 void parseUserStopArea();
50 void parseTimingLink();
51 void parseLink();
52 void parseLine();
53 void parseDestination();
54 void parseJourneyPattern();
55 void parseConcessionFinancerRelation();
56 void parseConcessionArea();
57 void parseFinancer();
58 void parseJourneyPatternTimingLink();
59 void parsePoint();
60 void parsePointOnLink();
61 void parseIcon();
62 void parseNotice();
63 void parseNoticeAssignment();
64 void parseTimeDemandGroup();
65 void parseTimeDemandGroupRunTime();
66 void parsePeriodGroup();
67 void parseSpecificDay();
68 void parseTimetableVersion();
69 void parsePublicJourney();
70 void parsePeriodGroupValidity();
71 void parseExceptionalOperatingDay();
72 void parseScheduleVersion();
73 void parsePublicJourneyPassingTimes();
74 void parseOperatingDay();
75
76 size_t pos = 0;
77 std::vector<Kv1Token> tokens;
78 const std::chrono::time_zone *amsterdam = std::chrono::locate_zone("Europe/Amsterdam");
79
80 public:
81 std::vector<std::string> warns;
82 std::vector<std::string> global_errors;
83 std::vector<std::string> record_errors;
84 Kv1Records &records;
85};
86
87#endif // OEUF_LIBTMI8_KV1_PARSER_HPP
diff --git a/lib/libtmi8/include/tmi8/kv1_types.hpp b/lib/libtmi8/include/tmi8/kv1_types.hpp
new file mode 100644
index 0000000..d4a0760
--- /dev/null
+++ b/lib/libtmi8/include/tmi8/kv1_types.hpp
@@ -0,0 +1,1528 @@
1// vim:set sw=2 ts=2 sts et:
2
3#ifndef OEUF_LIBTMI8_KV1_TYPES_HPP
4#define OEUF_LIBTMI8_KV1_TYPES_HPP
5
6#include <chrono>
7#include <cstdint>
8#include <optional>
9#include <string>
10#include <variant>
11
12struct Kv1OrganizationalUnit;
13struct Kv1HigherOrganizationalUnit;
14struct Kv1UserStopPoint;
15struct Kv1UserStopArea;
16struct Kv1TimingLink;
17struct Kv1Link;
18struct Kv1Line;
19struct Kv1Destination;
20struct Kv1JourneyPattern;
21struct Kv1ConcessionFinancerRelation;
22struct Kv1ConcessionArea;
23struct Kv1Financer;
24struct Kv1JourneyPatternTimingLink;
25struct Kv1Point;
26struct Kv1PointOnLink;
27struct Kv1Icon;
28struct Kv1Notice;
29struct Kv1NoticeAssignment;
30struct Kv1TimeDemandGroup;
31struct Kv1TimeDemandGroupRunTime;
32struct Kv1PeriodGroup;
33struct Kv1SpecificDay;
34struct Kv1TimetableVersion;
35struct Kv1PublicJourney;
36struct Kv1PeriodGroupValidity;
37struct Kv1ExceptionalOperatingDay;
38struct Kv1ScheduleVersion;
39struct Kv1PublicJourneyPassingTimes;
40struct Kv1OperatingDay;
41
42struct Kv1Records {
43 std::vector<Kv1OrganizationalUnit> organizational_units;
44 std::vector<Kv1HigherOrganizationalUnit> higher_organizational_units;
45 std::vector<Kv1UserStopPoint> user_stop_points;
46 std::vector<Kv1UserStopArea> user_stop_areas;
47 std::vector<Kv1TimingLink> timing_links;
48 std::vector<Kv1Link> links;
49 std::vector<Kv1Line> lines;
50 std::vector<Kv1Destination> destinations;
51 std::vector<Kv1JourneyPattern> journey_patterns;
52 std::vector<Kv1ConcessionFinancerRelation> concession_financer_relations;
53 std::vector<Kv1ConcessionArea> concession_areas;
54 std::vector<Kv1Financer> financers;
55 std::vector<Kv1JourneyPatternTimingLink> journey_pattern_timing_links;
56 std::vector<Kv1Point> points;
57 std::vector<Kv1PointOnLink> point_on_links;
58 std::vector<Kv1Icon> icons;
59 std::vector<Kv1Notice> notices;
60 std::vector<Kv1NoticeAssignment> notice_assignments;
61 std::vector<Kv1TimeDemandGroup> time_demand_groups;
62 std::vector<Kv1TimeDemandGroupRunTime> time_demand_group_run_times;
63 std::vector<Kv1PeriodGroup> period_groups;
64 std::vector<Kv1SpecificDay> specific_days;
65 std::vector<Kv1TimetableVersion> timetable_versions;
66 std::vector<Kv1PublicJourney> public_journeys;
67 std::vector<Kv1PeriodGroupValidity> period_group_validities;
68 std::vector<Kv1ExceptionalOperatingDay> exceptional_operating_days;
69 std::vector<Kv1ScheduleVersion> schedule_versions;
70 std::vector<Kv1PublicJourneyPassingTimes> public_journey_passing_times;
71 std::vector<Kv1OperatingDay> operating_days;
72
73 size_t size() const;
74};
75
76// These definitions implement TMI8, KV1 Dienstregeling (Timetable) version
77// 8.3.0.2 (release), published by BISON on January 8, 2020.
78// (Filename: tmi8 dienstregeling (kv 1) v8.3.0.2, release.docx)
79//
80// This specification and other BISON specifications, as well as other
81// supplementary information, can be found on BISON's website:
82// https://bison.dova.nu/
83//
84// The specification that was used to create these definitions was downloaded
85// from the following address:
86// https://bison.dova.nu/sites/default/files/bestanden/tmi8_dienstregeling_kv_1_v8.3.0.2_release.pdf
87//
88// The KV1 table structure and the corresponding documentation describing the
89// relevant tables and fields, as presented here, is derived from the original
90// specification. Most documentation is a manually translated version of the
91// documentation as present in the specification. The specification is licensed
92// under CC BY-ND 3.0. The exact text of this license can be found on
93// https://creativecommons.org/licenses/by-nd/3.0/nl/.
94
95// KV1 Table 1: Organizational Unit [ORUN] (MANDATORY)
96//
97// A collection of trips with the same validity features. An organizational
98// unit can be part of a 'higher' unit.
99//
100// An organizational unit is defined as a unity vor which the planning of trips
101// is compiled. When defining the organizational units, it is important that
102// all trips within the package have a homogeneous validity (school holidays,
103// shopping Sundays, foreign bank holidays).
104//
105// This table is part of the core data tables, which are common for all KV1
106// variants.
107struct Kv1OrganizationalUnit {
108 struct Key {
109 // Mandatory (key), at most 10 characters. Transport operator (from list as
110 // defined in BISON enumeration E1).
111 std::string data_owner_code;
112 // Mandatory (key), at most 10 characters.
113 std::string organizational_unit_code;
114
115 explicit Key(std::string data_owner_code,
116 std::string organizational_unit_code);
117 };
118
119 Key key;
120 // Mandatory, at most 50 characters.
121 std::string name;
122 // Mandatory, at most 10 characters.
123 std::string organizational_unit_type;
124 // Optional, at most 255 characters.
125 std::string description;
126};
127
128// KV1 Table 2: Higher Organizational Unit [ORUNORUN] (OPTIONAL)
129//
130// An in the hierarchy higher-ordered organizational unit for the purpose of
131// (among others) recording of (deviating) validities on the high level.
132//
133// This table is part of the core data tables, which are common for all KV1
134// variants.
135struct Kv1HigherOrganizationalUnit {
136 struct Key {
137 // Mandatory (key), at most 10 characters. Transport operator (from list as
138 // defined in BISON enumeration E1).
139 std::string data_owner_code;
140 // Mandatory (key), at most 10 characters. Parent, higher organizational unit
141 // that is referred to.
142 std::string organizational_unit_code_parent;
143 // Mandatory (key), at most 10 characters. Child, lower organizational unit.
144 std::string organizational_unit_code_child;
145 // Mandatory (key), at most 10 characters. [YYYY-MM-DD] Starting date of the
146 // hierarchical relation (can be a fixed value, e.g. 2006-12-31).
147 std::chrono::year_month_day valid_from;
148
149 explicit Key(std::string data_owner_code,
150 std::string organizational_unit_code_parent,
151 std::string organizational_unit_code_child,
152 std::chrono::year_month_day valid_from);
153 };
154
155 Key key;
156
157 Kv1OrganizationalUnit *p_organizational_unit_parent = nullptr;
158 Kv1OrganizationalUnit *p_organizational_unit_child = nullptr;
159};
160
161// KV1 Table 3: User Stop Point [USRSTOP]
162//
163// Stop or other point (e.g. Bridge, functioning as info for the bridge keeper)
164// for which times are recorded in the planning system of the transit operator.
165//
166// Coordinates of a UserStopPoint are recorded as Point. When defining
167// UserStopPoints, it is important that the coordinates can be unambiguously
168// and verifiably recorded. For a stop, the coordinates of the stop sign are
169// recorded. If there is no stop sign, the end of the bus stop (where the bus
170// normally halts) is recorded as the coordinate of the stop.
171//
172// This table is part of the core data tables, which are common for all KV1
173// variants.
174struct Kv1UserStopPoint {
175 struct Key {
176 // Mandatory (key), at most 10 characters. Transport operator (from list as
177 // defined in BISON enumeration E1).
178 std::string data_owner_code;
179 // Mandatory (key), at most 10 characters. Stop number in domain of operator.
180 std::string user_stop_code;
181
182 explicit Key(std::string data_owner_code,
183 std::string user_stop_code);
184 };
185
186 Key key;
187 // Optional, at most 10 characters. Stop number in domain of integrator,
188 // (initially) equal to UserStopCode.
189 std::string timing_point_code;
190 // Mandatory, at most 5 characters. Boolean indicator whether USRSTOP is used
191 // as boarding stop, true by default. False for e.g. dummy stop for bridge
192 // keeper.
193 bool get_in = true;
194 // Mandatory, at most 5 characters. Boolean indicator whether USRSTOP is used
195 // as alighting stop.
196 bool get_out = false;
197 // Mandatory, at most 50 characters. Stop name.
198 std::string name;
199 // Mandatory, at most 50 characters. Town name.
200 std::string town;
201 // Optional, at most 10 characters. Reference to StopArea of which the
202 // UserStop is part.
203 std::string user_stop_area_code;
204 // Mandatory, at most 10 characters. Platform indication/letter. The '-'
205 // value is used to indication that this is not applicable.
206 std::string stop_side_code;
207 // Mandatory, at most 5 digits. Minimal stop duration for boarding and
208 // alighting, zero by default. In seconds.
209 double minimal_stop_time_s = 0;
210 // Optional, at most 3 digits. Length of stop platform.
211 std::optional<double> stop_side_length;
212 // Optional, at most 255 characters.
213 std::string description;
214 // Mandatory, at most 10 characters. USRSTOPTYPE. Indicates the stop kind.
215 std::string user_stop_type;
216 // Optional, at most 30 characters. Nationally unique stop number.
217 std::string quay_code;
218
219 Kv1UserStopArea *p_user_stop_area = nullptr;
220 Kv1Point *p_point = nullptr;
221};
222
223// KV1 Table 4: User Stop Area [USRSTAR]
224//
225// A StopArea is a collection of stops, which have the same name for passengers
226// and logically belong together. (E.g. a bus station of transfer point.) Stops
227// lying opposite each other can also form a StopArea.
228//
229// Used for display of all stops in a stop area on an overview display and for
230// announcement of stop names (stops on both sides of the street share the same
231// name).
232//
233// This table is part of the core data tables, which are common for all KV1
234// variants.
235struct Kv1UserStopArea {
236 struct Key {
237 // Mandatory (key), at most 10 characters. Transport operator (from list as
238 // defined in BISON enumeration E1).
239 std::string data_owner_code;
240 // Mandatory (key), at most 10 characters. Code of StopArea following coding
241 // of operator, e.g. PlaceCode.
242 std::string user_stop_area_code;
243
244 explicit Key(std::string data_owner_code,
245 std::string user_stop_area_code);
246 };
247
248 Key key;
249 // Mandatory, at most 50 characters.
250 std::string name;
251 // Mandatory, at most 50 characters.
252 std::string town;
253 // Mandatory, at most 255 characters.
254 std::string description;
255};
256
257// KV1 Table 5: Timing Link [TILI]
258//
259// Link between two points which have the feature 'stop' or 'timing point'. A
260// Timing Link is set between all stops and other timing points (e.g. for the
261// bridge) which make part of a journey pattern.
262//
263// This table is part of the core data tables, which are common for all KV1
264// variants.
265struct Kv1TimingLink {
266 struct Key {
267 // Mandatory (key), at most 10 characters. Transport operator (from list as
268 // defined in BISON enumeration E1).
269 std::string data_owner_code;
270 // Mandatory (key), at most 10 characters. Stop number in the domain of
271 // DataOwner (here: the operator).
272 std::string user_stop_code_begin;
273 // Mandatory (key), at most 10 characters. Stop number in the domain of
274 // DataOwner (here: the operator).
275 std::string user_stop_code_end;
276
277 explicit Key(std::string data_owner_code,
278 std::string user_stop_code_begin,
279 std::string user_stop_code_end);
280 };
281
282 Key key;
283 // Optional, at most 5 digits. Minimal trip time (in seconds).
284 std::optional<double> minimal_drive_time_s;
285 // Optional, at most 255 characters.
286 std::string description;
287
288 Kv1UserStopPoint *p_user_stop_begin = nullptr;
289 Kv1UserStopPoint *p_user_stop_end = nullptr;
290};
291
292// KV1 Table 6: Link [LINK]
293//
294// A route link describes the connection between to points on the physical path
295// of a route.
296//
297// This table is part of the core data tables, which are common for all KV1
298// variants.
299struct Kv1Link {
300 struct Key {
301 // Mandatory (key), at most 10 characters. Transport operator (from list as
302 // defined in BISON enumeration E1).
303 std::string data_owner_code;
304 // Mandatory (key), at most 10 characters. Stop code in the domain of
305 // DataOwner (here: the operator).
306 std::string user_stop_code_begin;
307 // Mandatory (key), at most 10 characters. Stop code in the domain of
308 // DataOwner (here: the operator).
309 std::string user_stop_code_end;
310 // Mandatory (key), at most 5 characters. Modality for which the distance
311 // applies, see BISON enumeration E9.
312 // TODO: Check if BISON enumeration E9 can be put into an enum.
313 std::string transport_type;
314
315 explicit Key(std::string data_owner_code,
316 std::string user_stop_code_begin,
317 std::string user_stop_code_end,
318 std::string transport_type);
319 };
320
321 Key key;
322 // Mandatory, at most 6 digits. Length of the link (in meters).
323 double distance = 0;
324 // Optional, at most 255 characters.
325 std::string description;
326
327 Kv1UserStopPoint *p_user_stop_begin = nullptr;
328 Kv1UserStopPoint *p_user_stop_end = nullptr;
329};
330
331struct RgbColor {
332 uint8_t r, g, b = 0;
333};
334
335// KV1 Table 7: Line [LINE]
336//
337// A line is a collection of routes/journey patterns which is publically known
338// under a shared number.
339//
340// This table is part of the core data tables, which are common for all KV1
341// variants.
342struct Kv1Line {
343 struct Key {
344 // Mandatory (key), at most 10 characters. Transport operator (from list as
345 // defined in BISON enumeration E1).
346 std::string data_owner_code;
347 // Mandatory (key), at most 10 characters. Unique system line number in the
348 // domain of DataOwner.
349 std::string line_planning_number;
350
351 explicit Key(std::string data_owner_code,
352 std::string line_planning_number);
353 };
354
355 Key key;
356 // Mandatory, at most 4 characters. Line number for the public, incl. S/N
357 // indications.
358 std::string line_public_number;
359 // Mandatory, at most 50 characters.
360 std::string line_name;
361 // Mandatory, at most three digits. Should be in the range [0, 400).
362 // Only processing Connexxion's KV1 export, however, shows us that this range
363 // constrained is not honored in practice. That is why we also don't care.
364 short line_ve_tag_number = 0;
365 // Optional, at most 255 characters.
366 std::string description;
367 // Mandatory, at most 5 characters. Modality, see BISON enumeration E9.
368 // TODO: Check if BISON enumeration E9 can be put into an enum.
369 std::string transport_type;
370 // Optional, at most 4 digits. Symbol / image for the line. Reference to ICON
371 // table.
372 std::optional<short> line_icon;
373 // Optional, at most four characters. Background color for the line.
374 // Hexadecimal representation following RGB coding. Always six characters
375 // (RRGGBB), only numbers and/or capital letters.
376 std::optional<RgbColor> line_color;
377 // Optional, at most four characters. Foreground color for the line.
378 // Hexadecimal representation following RGB coding. Always six characters
379 // (RRGGBB), only numbers and/or capital letters.
380 std::optional<RgbColor> line_text_color;
381
382 Kv1Icon *p_line_icon = nullptr;
383};
384
385// KV1 Table 8: Destination [DEST]
386//
387// A destination shows the place/district/description of the route for the
388// passenger. Intermediate and detail destinations of a journey pattern are
389// shown under a single desination code, together with the primary destination.
390//
391// This table is part of the core data tables, which are common for all KV1
392// variants.
393struct Kv1Destination {
394 struct Key {
395 // Mandatory (key), at most 10 characters. Transport operator (from list as
396 // defined in BISON enumeration E1).
397 std::string data_owner_code;
398 // Mandatory (key), at most 10 characters.
399 std::string dest_code;
400
401 explicit Key(std::string data_owner_code,
402 std::string dest_code);
403 };
404
405 Key key;
406 // Mandatory, at most 50 characters. Full destination (e.g. compiled from
407 // primary, detail or intermediate destination).
408 std::string dest_name_full;
409 // Mandatory, at most 24 characters. Primary / intermediate destination in
410 // enumeration / final destination if 1 line is used.
411 std::string dest_name_main;
412 // Optional, at most 24 characters. Detail/secondary or intermediate
413 // destination for primary desination, final destination (for intermediate
414 // destination on line 1).
415 std::string dest_name_detail;
416 // Mandatory, at most 5 characters. Boolean which indcates whether
417 // DestNameDetail must always be shown (e.g. because this contains an
418 // important intermediate destination.)
419 bool relevant_dest_name_detail = false;
420 // Mandatory, at most 21 characters. Primary destination in 21 characters.
421 std::string dest_name_main_21;
422 // Optional, at most 21 characters. Detail/secondary/intermediate destination
423 // in 21 characters.
424 std::string dest_name_detail_21;
425 // Mandatory, at most 19 characters. Primary destination in 19 characters.
426 std::string dest_name_main_19;
427 // Optional, at most 19 characters. Detail/secondary/intermediate destination
428 // in 19 characters.
429 std::string dest_name_detail_19;
430 // Mandatory, at most 16 characters. Primary destination in 16 characters.
431 std::string dest_name_main_16;
432 // Optional, at most 16 characters. Detail/secondary/intermediate destination
433 // in 16 characters.
434 std::string dest_name_detail_16;
435 // Optional, at most 4 digits. Symbol/image for the destination. Reference to
436 // the ICON table.
437 std::optional<short> dest_icon;
438 // Optional, at most 6 characters. Background color for the destination.
439 // Hexadecimal representation following RGB coding. Always six characters
440 // (RRGGBB), only six digits and/or capital letters.
441 std::optional<RgbColor> dest_color;
442 // Optional, at most 30 characters (WTF?). Foreground color for the
443 // destination. Hexadecimal representation following RGB coding. Always six
444 // characters (RRGGBB), only six digits and/or capital letters.
445 std::optional<RgbColor> dest_text_color;
446};
447
448// KV1 Table 9: Journey Pattern [JOPA]
449//
450// The journey pattern describes the route from start to end point as a ordered
451// list of stops and links between stops/timing points.
452//
453// This table is part of the core data tables, which are common for all KV1
454// variants.
455struct Kv1JourneyPattern {
456 struct Key {
457 // Mandatory (key), at most 10 characters. Transport operator (from list as
458 // defined in BISON enumeration E1).
459 std::string data_owner_code;
460 // Mandatory (key), at most 10 characters.
461 std::string line_planning_number;
462 // Mandatory (key), at most 10 characters.
463 std::string journey_pattern_code;
464
465 explicit Key(std::string data_owner_code,
466 std::string line_planning_number,
467 std::string journey_pattern_code);
468 };
469
470 Key key;
471 // Mandatory, at most 10 characters. Refers to a journey pattern type
472 // (JOPATYPE).
473 std::string journey_pattern_type;
474 // Mandatory, at most 1 character. One of [1, 2, A, B].
475 char direction = 0;
476 // Optional, at most 255 characters.
477 std::string description;
478
479 Kv1Line *p_line = nullptr;
480};
481
482// KV1 Table 10: Concession Financer Relation [CONFINREL]
483//
484// Concession financer relation (mainly parcel). Smallest unit for which data
485// about a concession can be captured in relation to a financer and/or
486// concession.
487//
488// This table is part of the core data tables, which are common for all KV1
489// variants.
490struct Kv1ConcessionFinancerRelation {
491 struct Key {
492 // Mandatory (key), at most 10 characters. Transport operator (from list as
493 // defined in BISON enumeration E1).
494 std::string data_owner_code;
495 // Mandatory (key), at most 10 characters. Parcel code.
496 std::string con_fin_rel_code;
497
498 explicit Key(std::string data_owner_code,
499 std::string con_fin_rel_code);
500 };
501
502 Key key;
503 // Mandatory, at most 10 characters. Concession code.
504 std::string concession_area_code;
505 // Optional, at most 10 characters. Code of financer/client of the parcel.
506 std::string financer_code;
507
508 Kv1ConcessionArea *p_concession_area = nullptr;
509 Kv1Financer *p_financer = nullptr;
510};
511
512// KV1 Table 11: Concession Area [CONAREA]
513//
514// Concession (area).
515//
516// This table is part of the core data tables, which are common for all KV1
517// variants.
518struct Kv1ConcessionArea {
519 struct Key {
520 // Mandatory (key), at most 10 characters. Transport operator (from list as
521 // defined in BISON enumeration E1).
522 std::string data_owner_code;
523 // Mandatory (key), at most 10 characters. Code of the concession.
524 std::string concession_area_code;
525
526 explicit Key(std::string data_owner_code,
527 std::string concession_area_code);
528 };
529
530 Key key;
531 // Mandatory, at most 255 characters.
532 std::string description;
533};
534
535// KV1 Table 12: Financer [FINANCER] (OPTIONAL)
536//
537// Financer of a parcel.
538//
539// This table is part of the core data tables, which are common for all KV1
540// variants.
541struct Kv1Financer {
542 struct Key {
543 // Mandatory (key), at most 10 characters. Transport operator (from list as
544 // defined in BISON enumeration E1).
545 std::string data_owner_code;
546 // Mandatory (key), at most 10 characters.
547 std::string financer_code;
548
549 explicit Key(std::string data_owner_code,
550 std::string financer_code);
551 };
552
553 Key key;
554 // Mandatory, at most 255 characters.
555 std::string description;
556};
557
558// KV1 Table 13: Journey Pattern Timing Link [JOPATILI]
559//
560// Compilation of journey pattern from logical links (between pairs of
561// stops/timing points). Features such as the destination code, the public line
562// number, the concession financer relation (parcel) and product formula are
563// set per connection. Moreover, a color and/or image linked to the line
564// destination and the use of the (first) stop as boarding/alighting stop can
565// be set per link.
566//
567// Timing Link: A timing link is a stop, set by the transit operator, where a
568// bus / public transit vehicle may never depart earlier than set in the
569// timetable.
570//
571// A logical link may never occur more than once in a journey pattern.
572// Therefore, the combination of LinePlanningNumber, JourneyPatternCode,
573// UserStopCodeBegin and UserStopCodeEnd must be unique in JOPATILI.
574//
575// The value of GetIn and GetOut are normally copied from the corresponding
576// stop in the USRSTOP table, but can be overruled per journey pattern if so
577// desired.
578//
579// A Icon or (Text)Color set here overrules the general value of the
580// corresponding line (Line) or destination (Destination).
581//
582// A value of ShowFlexibleTrip or ProductFormulaType in PUJO or PUJOPASS
583// overrules the value in JOPATILI.
584//
585// This table is part of the core data tables, which are common for all KV1
586// variants.
587struct Kv1JourneyPatternTimingLink {
588 struct Key {
589 // Mandatory (key), at most 10 characters. Transport operator (from list as
590 // defined in BISON enumeration E1).
591 std::string data_owner_code;
592 // Mandatory (key), at most 10 characters.
593 std::string line_planning_number;
594 // Mandatory (key), at most 10 characters.
595 std::string journey_pattern_code;
596 // Mandatory (key), at most 3 digits.
597 short timing_link_order = 0;
598
599 explicit Key(std::string data_owner_code,
600 std::string line_planning_number,
601 std::string journey_pattern_code,
602 short timing_link_order);
603 };
604
605 Key key;
606 // Mandatory, at most 10 characters. Stop number in the domain of the
607 // DataOwner (here: the transit operator).
608 std::string user_stop_code_begin;
609 // Mandatory, at most 10 characters. Stop number in the domain of the
610 // DataOwner (here: the transit operator).
611 std::string user_stop_code_end;
612 // Mandatory, at most 10 characters. Concession financer relation / parcel
613 // (smallest unit).
614 std::string con_fin_rel_code;
615 // Mandatory, at most 10 characters. The destination (incl. intermediat
616 // destinations) as these are shown at the first stop of the journey pattern
617 // link.
618 std::string dest_code;
619 // Mandatory, at most 5 characters. Boolean which indicates whether the first
620 // stop of the connection is a timing stop. Indicator is at least "true" at
621 // first stop of a line and at waiting stops.
622 bool is_timing_stop = false;
623 // Optional, at most 4 characters. Public line number which must be shown on
624 // displays from the first stop of the journey pattern link (e.g. Line number
625 // + S). This is important when a deviating public line number applies from a
626 // certain point on forward. Normally, the public line number of the
627 // corresponding line is shown.
628 std::string display_public_line;
629 // Optional, at most 4 digits. Enumeration E10 (see section 2.5). A public
630 // transit service which distinguishes itself by a set of unique features,
631 // that is offered to the passenger as distinct (a marketing aspect).
632 // TODO: Check if we can turn BISON enumeration E10 into an enum
633 std::optional<short> product_formula_type;
634 // Mandatory, at most 5 characters. Boolean indicator whether UserStopBegin
635 // is used as a boarding stop in this journey pattern. Usually equal to the
636 // value of the corresponding USRSTOP.
637 bool get_in = false;
638 // Mandatory, at most 5 characters. Boolean indicator whether UserStopBegin
639 // is used as an alighting stop in this journey pattern. Usually equal to the
640 // value of the corresponding USRSTOP.
641 bool get_out = false;
642 // Optional, at most 8 characters. Indicates whether the transit operator
643 // wants a not explicitly planned trip (i.e. a trip that only operates after
644 // reservation such as a 'call bus' (belbus), 'line taxi' (lijntaxi) etc.) to
645 // be shown on displays. Values according enumeration E21: TRUE (always),
646 // FALSE (never), REALTIME (only when tracking trip).
647 // TODO: Check if we can turn BISON enumeration E21 into an enum
648 std::string show_flexible_trip;
649 // Optional, at most 4 digits. Symbol / image for display of the line
650 // destination at the journey stop passing. Reference to the ICON table.
651 std::optional<short> line_dest_icon;
652 // Optional, at most 6 characters. Background color for display of the line
653 // destination at a journey stop passing. Hexadecimal representation
654 // following RGB coding. Always six characters (RRGGBB), only numbers and/or
655 // capital letters.
656 std::optional<RgbColor> line_dest_color;
657 // Optional, at most 6 characters. Foreground color for display of the line
658 // destination at a journey stop passing. Hexadecimal representation
659 // following RGB coding. Always six characters (RRGGBB), only numbers and/or
660 // capital letters.
661 std::optional<RgbColor> line_dest_text_color;
662
663 Kv1Line *p_line = nullptr;
664 Kv1JourneyPattern *p_journey_pattern = nullptr;
665 Kv1UserStopPoint *p_user_stop_begin = nullptr;
666 Kv1UserStopPoint *p_user_stop_end = nullptr;
667 Kv1ConcessionFinancerRelation *p_con_fin_rel = nullptr;
668 Kv1Destination *p_dest = nullptr;
669 Kv1Icon *p_line_dest_icon = nullptr;
670};
671
672// KV1 Table 14: Point [POINT]
673//
674// A point is the smallest location which can be reffered to within the public
675// transit network. Every stop (USRSTOP) is a point.
676//
677// This table is part of the core data tables, which are common for all KV1
678// variants.
679struct Kv1Point {
680 struct Key {
681 // Mandatory (key), at most 10 characters. Transport operator (from list as
682 // defined in BISON enumeration E1).
683 std::string data_owner_code;
684 // Mandatory (key), at most 10 characters.
685 std::string point_code;
686
687 explicit Key(std::string data_owner_code,
688 std::string point_code);
689 };
690
691 Key key;
692 // Mandatory, at most 10 characters. Refers to the POINTTYPE table.
693 std::string point_type;
694 // Mandatory, at most 10 characters. Refers to the GEOSYSTYPE table. Only
695 // allowed to have the value "RD" (rijkdsdriehoekstelsel; the national Dutch
696 // coordinate system).
697 std::string coordinate_system_type;
698 // Mandatory, at most 15 characters. X position in the RD coordinate system,
699 // in meters (at least 6 digits).
700 double location_x_ew = 0;
701 // Mandatory, at most 15 characters. Y position in the RD coordinate system,
702 // in meters (at least 6 digits).
703 double location_y_ns = 0;
704 // Optional, at most 15 characters.
705 // NOTE: the standart (presumeably wrongly) indicates this field as having
706 // alphanumeric contents.
707 std::optional<double> location_z;
708 // Optional, at most 255 characters.
709 std::string description;
710};
711
712// KV1 Table 15: Point on Link [POOL]
713//
714// A point that is used to geographically describe the trajectory between two
715// stops.
716//
717// This table is part of the core data tables, which are common for all KV1
718// variants.
719struct Kv1PointOnLink {
720 struct Key {
721 // Mandatory (key), at most 10 characters. Transport operator (from list as
722 // defined in BISON enumeration E1).
723 std::string data_owner_code;
724 // Mandatory (key), at most 10 characters. Stop number in the domain of the
725 // DataOwner (here: transit operator).
726 std::string user_stop_code_begin;
727 // Mandatory (key), at most 10 characters. Stop number in the domain of the
728 // DataOwner (here: transit operator).
729 std::string user_stop_code_end;
730 // Mandatory (key), at most 10 characters. Code from the road manager for KAR
731 // points. For curve points of the DataOwner (often the transit operator).
732 std::string point_data_owner_code;
733 // Mandatory (key), at most 10 charcters.
734 std::string point_code;
735 // Mandatory (key), at most 5 characters. Modality for which the distance
736 // applies, see BISON enumeration E9.
737 std::string transport_type;
738
739 explicit Key(std::string data_owner_code,
740 std::string user_stop_code_begin,
741 std::string user_stop_code_end,
742 std::string point_data_owner_code,
743 std::string point_code,
744 std::string transport_type);
745 };
746
747 Key key;
748 // Mandatory, at most 5 digits. Distance in meters relative to the start of
749 // the link.
750 double distance_since_start_of_link = 0;
751 // Optional, at most 4 digits. Crossing speed for a public transit vehicle
752 // from the previous point (on a link) in m/s.
753 std::optional<double> segment_speed_mps = 0;
754 // Optional, at most 4 digits. Comfort speed for a public transit vehicle on
755 // the curve point.
756 std::optional<double> local_point_speed_mps = 0;
757 // Optional, at most 255 characters.
758 std::string description;
759
760 Kv1UserStopPoint *p_user_stop_begin = nullptr;
761 Kv1UserStopPoint *p_user_stop_end = nullptr;
762 Kv1Point *p_point = nullptr;
763};
764
765// KV1 Table 16: Icon [ICON]
766//
767// Table with images which can be referred to from DEST.DestIcon, LINE.LineIcon
768// and JOPATILI.LineDestIcon to load the correct image.
769//
770// This table is part of the core data tables, which are common for all KV1
771// variants.
772struct Kv1Icon {
773 struct Key {
774 // Mandatory (key), at most 10 characters. Transport operator (from list as
775 // defined in BISON enumeration E1).
776 std::string data_owner_code;
777 // Mandatory (key), at most 4 digits. Reference from other tables for the
778 // requested image.
779 short icon_number = 0;
780
781 explicit Key(std::string data_owner_code,
782 short icon_number);
783 };
784
785 Key key;
786 // Mandatory, at most 1024 characters. Absolute URI to a publically available
787 // location from which the image can be loaded. The extension of the file
788 // indicates the image type.
789 // Supported file types are: GIF (.gif), JPEG (.jpg, .jpeg),
790 // PNG (.png), SVG (.svg)
791 // Supported protocols are: HTTP, HTTPS, FTP
792 // Prefer to not use any capital letters. Examples:
793 // - http://bison.dova.nu/images/logo.png
794 // - https://bison.dova.nu/images/logo.png
795 // - ftp://ftp.dova.nu/images/logo.png
796 std::string icon_uri;
797};
798
799// KV1 Table 17: Notice [NOTICE] (OPTIONAL)
800//
801// A (reusable) text with supplementary information about exceptions /
802// clarifications for a line, journey pattern etc.
803//
804// Usage is optional; when there are no clarifying texts, the NOTICE table does
805// not need to be provided in a KV1 set.
806//
807// This table is part of the core data tables, which are common for all KV1
808// variants.
809struct Kv1Notice {
810 struct Key {
811 // Mandatory (key), at most 10 characters. Transport operator (from list as
812 // defined in BISON enumeration E1).
813 std::string data_owner_code;
814 // Mandatory (key), at most 20 characters. Identification of Notice (remark,
815 // clarifying text).
816 std::string notice_code;
817
818 explicit Key(std::string data_owner_code,
819 std::string notice_code);
820 };
821
822 Key key;
823 // Mandatory, at most 1024 characters. Content, text. Contains contact
824 // information such as telephone number, web address and reservation time for
825 // 'call buses' (belbussen) and other demand-based transit.
826 std::string notice_content;
827};
828
829// KV1 Table 18: Notice Assignment [NTCASSGNM] (OPTIONAL)
830//
831// Linking table in which Notice (remark, clarfiying text) is assigned to a
832// line, journey pattern, stops within a journey pattern, journey etc. Notice
833// Assignment contains all logical key elements of the corresponding objects to
834// which a Notice can be assigned.
835//
836// Different attributes are required for the Notice Assignment, depending on
837// the type object to which the Notice is assigned. In the following table
838// structure, this is indicated as 'Only relevant for ...'. This means that
839// fields for other object types in the Notice Assignment can be ignored.
840//
841// Moreover, it can also occur that not all key fields of the linked table are
842// of interest (content-wise) for recording the Notice.
843//
844// Both matters are summarised in this overview:
845//
846// --------------------------------------------------------
847// AssignedObject PUJO PUJOPASS LINE JOPATILI
848// --------------------------------------------------------
849// DataOwnerCode........... x ...... x ...... x ..... x ...
850// TimetableVersionCode ... o .............................
851// OrganizationalUnitCode . o ...... o ....................
852// ScheduleCode .................... o ....................
853// ScheduleTypeCode ................ o ....................
854// PeriodGroupCode ........ o .............................
855// SpecificDayCode ........ o .............................
856// DayType ................ o .............................
857// LinePlanningNumber ..... x ...... x ...... x ..... x ...
858// JourneyNumber .......... x ...... x ....................
859// StopOrder ....................... o .............. o ...
860// JourneyPatternCode ............................... x ...
861// TimingLinkOrder .................................. o ...
862// UserStopCode .................... o .............. o ...
863// --------------------------------------------------------
864//
865// Legend:
866// x - Mandatory. The Notice for this object type is always depndent on the
867// value of the attribute.
868// o - Optional. The Notice can be independent of the value of this
869// attribute for this object type.
870// <empty> - Attribute is no key field for this object type and can be
871// ignored when processed.
872//
873// Usage of Notice Assignment is optional in KV1. If there are no clarifying
874// texts, then the Notice Assignment table is not required to be present in the
875// provided KV1 set.
876//
877// This table is part of the core data tables, which are common for all KV1
878// variants.
879struct Kv1NoticeAssignment {
880 // Mandatory, at most 10 characters. Transport operator (from list as
881 // defined in BISON enumeration E1).
882 std::string data_owner_code;
883 // Mandatory, at most 20 characters. Notice that is assigned.
884 std::string notice_code;
885 // Mandatory, at most 8 characters. Object type to which Notice is assigned.
886 std::string assigned_object;
887 // Optional, at most 10 characters. Only relevant for PUJO.
888 std::string timetable_version_code;
889 // Optional, at most 10 characters. Only relevant for PUJO and PUJOPASS.
890 std::string organizational_unit_code;
891 // Optional, at most 10 characters. Only relevant for PUJOPASS.
892 std::string schedule_code;
893 // Optional, at most 10 characters. Only relevant for PUJOPASS.
894 std::string schedule_type_code;
895 // Optional, at most 10 characters. Only relevant for PUJO.
896 std::string period_group_code;
897 // Optional, at most 10 characters. Only relevant for PUJO.
898 std::string specific_day_code;
899 // Optional, at most 10 characters. Only relevant for PUJO.
900 // [0|1][0|2][0|3][0|4][0|5][0|6][0|7] for Mon, Tue, Wed, Thu, Fri, Sat, Sun.
901 // E.g. 1234500 means Mon, Tue, Wed, Thu, Fri but not Sat, Sun.
902 std::string day_type;
903 // Mandatory, at most 10 characters. Mandatory for all object types.
904 std::string line_planning_number;
905 // Optional (for all object types except PUJO and PUJOPASS), at most 6
906 // digits. Only relevant for PUJO and PUJOPASS. Must be in the range
907 // [0-1000000).
908 std::optional<int> journey_number;
909 // Optional, at most 4 digits. Only relevant for PUJOPASS and JOPATILI.
910 std::optional<int> stop_order;
911 // Optional (for all object types except JOPATILI), at most 4 digits. Only
912 // relevant for JOPATILI.
913 std::string journey_pattern_code;
914 // Optional (at most 3 digits). Only relevant for JOPATILI.
915 std::optional<short> timing_link_order;
916 // Optional (at most 10 characters). Only relevant for PUJOPASS and JOPATILI.
917 // For JOPATILI, this correspond to the first stop of the link.
918 std::string user_stop_code;
919
920 Kv1Notice *p_notice = nullptr;
921};
922
923// KV1 Table 19: Time Demand Group [TIMDEMGRP]
924//
925// A time demand group is a grouping of the run time distribution from stop to
926// stop, for a journey pattern (from start to end point).
927//
928// This table is part of the KV1 variant "validities and time demand groups".
929struct Kv1TimeDemandGroup {
930 struct Key {
931 // Mandatory (key), at most 10 characters. Transport operator (from list as
932 // defined in BISON enumeration E1).
933 std::string data_owner_code;
934 // Mandatory (key), at most 10 characters.
935 std::string line_planning_number;
936 // Mandatory (key), at most 10 characters. Refers to the JOPATILI table.
937 std::string journey_pattern_code;
938 // Mandatory (key), at most 10 characters. Defines the code for the time
939 // demand group. (NOTE: this is not entirely made clear by the specification.
940 // This claim must be verified.)
941 std::string time_demand_group_code;
942
943 explicit Key(std::string data_owner_code,
944 std::string line_planning_number,
945 std::string journey_pattern_code,
946 std::string time_demand_group_code);
947 };
948
949 Key key;
950
951 Kv1Line *p_line = nullptr;
952 Kv1JourneyPattern *p_journey_pattern = nullptr;
953};
954
955// KV1 Table 20: Time Demand Group Run Time [TIMDEMRNT]
956//
957// The run time structure/distribution for all timing links of a journey
958// pattern or a time demand group.
959//
960// Optional run time elements are, when these are present, used to more
961// accurately calculate expected departure times based on punctuality
962// deviations.
963//
964// This table is part of the KV1 variant "validities and time demand groups".
965struct Kv1TimeDemandGroupRunTime {
966 struct Key {
967 // Mandatory (key), at most 10 characters. Transport operator (from list as
968 // defined in BISON enumeration E1).
969 std::string data_owner_code;
970 // Mandatory (key), at most 10 characters.
971 std::string line_planning_number;
972 // Mandatory (key), at most 10 characters. Refers to the JOPATILI table.
973 std::string journey_pattern_code;
974 // Mandatory (key), at most 10 characters. Refers to the TIMDEMGRP table.
975 std::string time_demand_group_code;
976 // Mandatory (key), at most 3 digits. Reference number of a link within the
977 // journey pattern (a link can occur more than once within a journey
978 // pattern).
979 short timing_link_order = 0;
980
981 explicit Key(std::string data_owner_code,
982 std::string line_planning_number,
983 std::string journey_pattern_code,
984 std::string time_demand_group_code,
985 short timing_link_order);
986 };
987
988 Key key;
989 // Mandatory, at most 10 characters. Refers to the first stop of the link.
990 std::string user_stop_code_begin;
991 // Mandatory, at most 10 characters. Refers to the last stop of the link.
992 std::string user_stop_code_end;
993 // Mandatory, at most 5 digits. Planned total run time on link for time
994 // demand group: (Departure time end stop - departure time begin stop)
995 // corresponding to the time demand group. In seconds.
996 double total_drive_time_s = 0;
997 // Mandatory, at most 5 digits. Planned minimal run time on link for time
998 // demand group. Often calculated as: (Arrival time end stop - arrival time
999 // begin stop) corresponding to the time demand group. In seconds.
1000 double drive_time_s = 0;
1001 // Optional, at most 5 digits. Expected/planned delay/congestion on link for
1002 // time demand group. In seconds.
1003 std::optional<double> expected_delay_s;
1004 // Optional, at most 5 digits. Layover/catch-up time. Gives play in the
1005 // timetable. In seconds.
1006 // LayOverTime = TotDriveTime - DriveTime + ExpectedDelay - StopWaitTime.
1007 std::optional<double> layover_time;
1008 // Mandatory, at most 5 digits. Planned stop waiting time at the final stop
1009 // of the link for the time demand group. Determined based on the difference
1010 // between the departure time and arrival time at this stop. Is zero when no
1011 // waiting time is planned for this stop. In seconds.
1012 double stop_wait_time = 0;
1013 // Optional, at most 5 digits. Planned minimal stop time for
1014 // boarding/alighting of passengers at the final stop of the link for the
1015 // time demand group. Application: at hub stops with a planned waiting time,
1016 // the difference between the planned waiting time and the minimum stop time
1017 // is the layover/catch-up time. In seconds.
1018 std::optional<double> minimum_stop_time;
1019
1020 Kv1Line *p_line = nullptr;
1021 Kv1UserStopPoint *p_user_stop_begin = nullptr;
1022 Kv1UserStopPoint *p_user_stop_end = nullptr;
1023 Kv1JourneyPattern *p_journey_pattern = nullptr;
1024 Kv1TimeDemandGroup *p_time_demand_group = nullptr;
1025 Kv1JourneyPatternTimingLink *p_journey_pattern_timing_link = nullptr;
1026};
1027
1028// KV1 Table 21: Period Group [PEGR]
1029//
1030// Period group is an indication of a 'homogeneous period' during the year,
1031// i.e. a period in which the schedule has the same composition w.r.t.
1032// frequencies and run times.
1033//
1034// This table is part of the KV1 variant "validities and time demand groups".
1035struct Kv1PeriodGroup {
1036 struct Key {
1037 // Mandatory (key), at most 10 characters. Transport operator (from list as
1038 // defined in BISON enumeration E1).
1039 std::string data_owner_code;
1040 // Mandatory (key), at most 10 characters.
1041 std::string period_group_code;
1042
1043 explicit Key(std::string data_owner_code,
1044 std::string period_group_code);
1045 };
1046
1047 Key key;
1048 // Optional, at most 255 characters.
1049 std::string description;
1050};
1051
1052// KV1 Table 22: Specific Day [SPECDAY]
1053//
1054// A specific day is a feature of a day for which a deviating service level is
1055// provided, respective to a normal day of the week.
1056//
1057// E.g. shopping Sundays (koopzondagen, if not every Sunday), New Year's Eve
1058// (oudejaarsdag), foreign bank holidays (as applicable).
1059//
1060// This table is part of the KV1 variant "validities and time demand groups".
1061struct Kv1SpecificDay {
1062 struct Key {
1063 // Mandatory (key), at most 10 characters. Transport operator (from list as
1064 // defined in BISON enumeration E1).
1065 std::string data_owner_code;
1066 // Mandatory (key), at most 10 characters. Default: "NORMAL".
1067 std::string specific_day_code;
1068
1069 explicit Key(std::string data_owner_code,
1070 std::string specific_day_code);
1071 };
1072
1073 Key key;
1074 // Mandatory, at most 50 characters.
1075 std::string name;
1076 // Optional, at most 255 characters.
1077 std::string description;
1078};
1079
1080// KV1 Table 23: Timetable Version [TIVE]
1081//
1082// A timetable version budles all planned activities for an organizational
1083// unit. For the public schedule, these are trips, routes, run times etc.
1084//
1085// When processing a new Timetable Version, it is checked if another TIVE with
1086// the same key has already been processed. If this is the case, ValidFrom must
1087// be equal to the starting date of the previously provided set. The new set
1088// replaces the older one. A package with a new starting date is only processed
1089// if another TimetableVersionCode is used.
1090//
1091// This table is part of the KV1 variant "validities and time demand groups".
1092struct Kv1TimetableVersion {
1093 struct Key {
1094 // Mandatory (key), at most 10 characters. Transport operator (from list as
1095 // defined in BISON enumeration E1).
1096 std::string data_owner_code;
1097 // Mandatory (key), at most 10 characters.
1098 std::string organizational_unit_code;
1099 // Mandatory (key), at most 10 characters.
1100 std::string timetable_version_code;
1101 // Mandatory (key), at most 10 charactes.
1102 std::string period_group_code;
1103 // Mandatory (key), at most 10 characters. Default: "NORMAL".
1104 std::string specific_day_code;
1105
1106 explicit Key(std::string data_owner_code,
1107 std::string organizational_unit_code,
1108 std::string timetable_version_code,
1109 std::string period_group_code,
1110 std::string specific_day_code);
1111 };
1112
1113 Key key;
1114 // Mandatory, at most 10 characters. Datum on which the timetable goes into
1115 // effect, following the YYYY-MM-DD format.
1116 std::chrono::year_month_day valid_from;
1117 // Mandatory, at most 10 characters. Value: "PUBT".
1118 std::string timetable_version_type;
1119 // Optional, at most 10 characters. Datum on which the timetable goes out of
1120 // effect, following the YYYY-MM-DD format.
1121 std::optional<std::chrono::year_month_day> valid_thru;
1122 // Optional, at most 255 characters. Should be null/empty.
1123 std::string description;
1124
1125 Kv1OrganizationalUnit *p_organizational_unit = nullptr;
1126 Kv1PeriodGroup *p_period_group = nullptr;
1127 Kv1SpecificDay *p_specific_day = nullptr;
1128};
1129
1130// KV1 Table 24: Public Journey [PUJO]
1131//
1132// Public journeys are journeys that are operated by a public transit
1133// organization and are accessible to the passenger.
1134//
1135// Business rules:
1136// - If ShowFlexibleTrip or ProductFormulaType is set in a record of this
1137// table, this takes precedence over the value as in the corresponding
1138// JOPATILI entry.
1139//
1140// This table is part of the KV1 variant "validities and time demand groups".
1141struct Kv1PublicJourney {
1142 struct Key {
1143 // Mandatory (key), at most 10 characters. Transport operator (from list as
1144 // defined in BISON enumeration E1).
1145 std::string data_owner_code;
1146 // Mandatory (key), at most 10 characters.
1147 std::string timetable_version_code;
1148 // Mandatory (key), at most 10 characters.
1149 std::string organizational_unit_code;
1150 // Mandatory (key), at most 10 characters.
1151 std::string period_group_code;
1152 // Mandatory (key), at most 10 characters.
1153 std::string specific_day_code;
1154 // Mandatory (key), at most 7 characters.
1155 // [0|1][0|2][0|3][0|4][0|5][0|6][0|7] for Mon, Tue, Wed, Thu, Fri, Sat, Sun.
1156 // E.g. 1234500 means Mon, Tue, Wed, Thu, Fri but not Sat, Sun.
1157 // TODO: See if we can make this into a more concrete type
1158 std::string day_type;
1159 // Mandatory (key), at most 10 characters.
1160 std::string line_planning_number;
1161 // Mandatory (key), at most 6 digits. Must be in the range [0-1000000).
1162 int journey_number = 0;
1163
1164 explicit Key(std::string data_owner_code,
1165 std::string timetable_version_code,
1166 std::string organizational_unit_code,
1167 std::string period_group_code,
1168 std::string specific_day_code,
1169 std::string day_type,
1170 std::string line_planning_number,
1171 int journey_number);
1172 };
1173
1174 Key key;
1175 // Mandatory, at most 10 characters.
1176 std::string time_demand_group_code;
1177 // Mandatory, at most 10 characters.
1178 std::string journey_pattern_code;
1179 // Mandatory, at most 8 characters. Format: "HH:MM:SS".
1180 std::chrono::hh_mm_ss<std::chrono::seconds> departure_time;
1181 // Mandatory, at most 13 characters. Values as in BISON enumeration E3.
1182 // Allowed are: "ACCESSIBLE", "NOTACCESSIBLE" and "UNKNOWN".
1183 // TODO: See if we can fit BISON enumeration E3 into an enum
1184 std::string wheelchair_accessible;
1185 // Mandatory, at most 5 characters. Boolean. Value "true": journey is
1186 // operator by DataOwner. Value "false": journey is operator by a different
1187 // DataOwner. Indicator is meant for a line that is operated jointly by
1188 // multiple transit operators. The indicator is used to be able to match the
1189 // journey operation (KV6, KV19 etc.); only journeys for which the indicator
1190 // is "true" can be expected to have corresponding current/real-time
1191 // information, although "true" doesn't necessarily mean that this
1192 // current/real-time information will (always) become available.
1193 bool data_owner_is_operator = false;
1194 // Mandatory, at most 5 characters. Boolean. Indicates whether
1195 // current/real-time journey information may be expected for the
1196 // corresponding journey ("true" or "false").
1197 bool planned_monitored = false;
1198 // Optional, at most 4 digits. BISON enumeration E10. Intended to allow
1199 // capturing transit mode features at the journey level.
1200 // TODO: See if we can make BISON enumeration E10 into an enum
1201 std::optional<short> product_formula_type;
1202 // Optional, at most 8 characters. Indicates whether the transit operator
1203 // wants that a not-explicitly planned trip (i.e. a journey that only runs on
1204 // reservation, e.g. 'call bus' (belbus), 'line taxi' (lijntaxi) etc.) to be
1205 // shown on displays. Values following BISON enumeration E21: TRUE (always),
1206 // FALSE (never), REALTIME (only when journey is tracked).
1207 // TODO: See if we can make BISON enumeration E21 into an enum
1208 std::string show_flexible_trip;
1209
1210 Kv1TimetableVersion *p_timetable_version = nullptr;
1211 Kv1OrganizationalUnit *p_organizational_unit = nullptr;
1212 Kv1PeriodGroup *p_period_group = nullptr;
1213 Kv1SpecificDay *p_specific_day = nullptr;
1214 Kv1Line *p_line = nullptr;
1215 Kv1TimeDemandGroup *p_time_demand_group = nullptr;
1216 Kv1JourneyPattern *p_journey_pattern = nullptr;
1217};
1218
1219// KV1 Table 25: Period Group Validity [PEGRVAL]
1220//
1221// Validities (multiple from-thru data) of a period group.
1222//
1223// This table is part of the KV1 variant "validities and time demand groups".
1224struct Kv1PeriodGroupValidity {
1225 struct Key {
1226 // Mandatory (key), at most 10 characters. Transport operator (from list as
1227 // defined in BISON enumeration E1).
1228 std::string data_owner_code;
1229 // Mandatory (key), at most 10 characters.
1230 std::string organizational_unit_code;
1231 // Mandatory (key), at most 10 characters.
1232 std::string period_group_code;
1233 // Mandatory (key), at most 10 characters. Date of the start of the validity
1234 // period. Format: "YYYY-MM-DD".
1235 std::chrono::year_month_day valid_from;
1236
1237 explicit Key(std::string data_owner_code,
1238 std::string organizational_unit_code,
1239 std::string period_group_code,
1240 std::chrono::year_month_day valid_from);
1241 };
1242
1243 Key key;
1244 // Mandatory, at most 10 characters. Date of the end of the validity period.
1245 // Format: "YYYY-MM-DD".
1246 std::chrono::year_month_day valid_thru;
1247
1248 Kv1OrganizationalUnit *p_organizational_unit = nullptr;
1249 Kv1PeriodGroup *p_period_group = nullptr;
1250};
1251
1252// KV1 Table 26: Exceptional Operating Day [EXCOPDAY]
1253//
1254// Contains exceptional validity dates, for which the service runs following a
1255// different day type (such as another day of the week or a different period).
1256//
1257// This table is part of the KV1 variant "validities and time demand groups".
1258struct Kv1ExceptionalOperatingDay {
1259 struct Key {
1260 // Mandatory (key), at most 10 characters. Transport operator (from list as
1261 // defined in BISON enumeration E1).
1262 std::string data_owner_code;
1263 // Mandatory (key), at most 10 characters. Organization unit for which an
1264 // exceptional day validity applies.
1265 std::string organizational_unit_code;
1266 // Mandatory (key), at most 23 characters. Date (+ time) for which the
1267 // exceptional validity applies. Format: "YYYYMMDDThh:mm:ssTZD".
1268 std::chrono::sys_seconds valid_date;
1269
1270 explicit Key(std::string data_owner_code,
1271 std::string organizational_unit_code,
1272 std::chrono::sys_seconds valid_date);
1273 };
1274
1275 Key key;
1276 // Mandatory, at most 7 characters. The exceptional day type that applies on
1277 // a calendar day: [0|1][0|2][0|3][0|4][0|5][0|6][0|7] for Mon, Tue, Wed,
1278 // Thu, Fri, Sat.
1279 // E.g. 1234500 means Mon, Tue, Wed, Thu, Fri but not Sat, Sun.
1280 // TODO: See if we can make this into a more concrete type
1281 std::string day_type_as_on;
1282 // Mandatory, at most 10 characters. Specific day service level to which the
1283 // exceptional day validity refers.
1284 std::string specific_day_code;
1285 // Optional, at most 10 characters. An exceptional day validity can be
1286 // related to the service level of another period (e.g. the school holiday
1287 // schedule). This exceptional period reference is set here.
1288 //
1289 // E.g. on Good Friday or the day after Ascension day, transit runs according
1290 // to the holiday season schedule, while transit runs following the winter
1291 // package in the surrounding days.
1292 std::string period_group_code;
1293 // Optional, at most 255 characters.
1294 std::string description;
1295
1296 Kv1OrganizationalUnit *p_organizational_unit = nullptr;
1297 Kv1SpecificDay *p_specific_day = nullptr;
1298 Kv1PeriodGroup *p_period_group = nullptr;
1299};
1300
1301// KV1 Table 27: Schedule Version [SCHEDVERS]
1302//
1303// A schedule version bundles the planned activities for an organisation unit
1304// per day type. The journeys with passing times and corresponding routes are
1305// for the public timetable.
1306//
1307// When processing a new Schedule Version, it is checked if another SCHEDVERS
1308// with the same key has already been processed. If this is the case, ValidFrom
1309// must be equal to the starting date of the previously provided set. The new
1310// set replaces the older one. A package with a new starting date is only
1311// processed if another Schedule Code is used.
1312//
1313// This table is part of the KV1 variant "schedules and passing times".
1314struct Kv1ScheduleVersion {
1315 struct Key {
1316 // Mandatory (key), at most 10 characters. Transport operator (from list as
1317 // defined in BISON enumeration E1).
1318 std::string data_owner_code;
1319 // Mandatory (key), at most 10 characters.
1320 std::string organizational_unit_code;
1321 // Mandatory (key), at most 10 characters. A unique code in combination with
1322 // the ScheduleTypeCode of the package within the ORUN.
1323 std::string schedule_code;
1324 // Mandatory (key), at most 10 characters. Code for the Schedule Type (Day Type).
1325 std::string schedule_type_code;
1326
1327 explicit Key(std::string data_owner_code,
1328 std::string organizational_unit_code,
1329 std::string schedule_code,
1330 std::string schedule_type_code);
1331 };
1332
1333 Key key;
1334 // Mandatory, at most 10 characters. Date on which the schedule goes into
1335 // effect. Format: "YYYY-MM-DD".
1336 std::chrono::year_month_day valid_from;
1337 // Optional, at most 10 characters. Date on which the schedule goes out of
1338 // effect. Format: "YYYY-MM-DD".
1339 std::optional<std::chrono::year_month_day> valid_thru;
1340 // Optional, at most 255 characters. Should be empty/null.
1341 std::string description;
1342
1343 Kv1OrganizationalUnit *p_organizational_unit = nullptr;
1344};
1345
1346// KV1 Table 28: Public Journey Passing Times [PUJOPASS]
1347//
1348// Public journey with arrival and departure times at all stops (and other
1349// timing points).
1350//
1351// Business rules:
1352// - If ShowFlexibleTrip or ProductFormulaType is set here, then this takes
1353// precedence over the value in the corresponding JOPATILI record.
1354// - All stop passings of a public journey refer to the same journey pattern
1355// (JOPA)!
1356//
1357// This table is part of the KV1 variant "schedules and passing times".
1358struct Kv1PublicJourneyPassingTimes {
1359 struct Key {
1360 // Mandatory (key), at most 10 characters. Transport operator (from list as
1361 // defined in BISON enumeration E1).
1362 std::string data_owner_code;
1363 // Mandatory (key), at most 10 characters.
1364 std::string organizational_unit_code;
1365 // Mandatory (key), at most 10 characters. A unique code in combination with
1366 // the ScheduleTypeCode of the package within the ORUN.
1367 std::string schedule_code;
1368 // Mandatory (key), at most 10 characters. Code for the Schedule Type (e.g.
1369 // Day Type).
1370 std::string schedule_type_code;
1371 // Mandatory (key), at most 10 characters.
1372 std::string line_planning_number;
1373 // Mandatory (key), at most 6 digits. Must be in the range [0-1000000).
1374 int journey_number = 0;
1375 // Mandatory (key), at most 4 digits.
1376 short stop_order = 0;
1377
1378 explicit Key(std::string data_owner_code,
1379 std::string organizational_unit_code,
1380 std::string schedule_code,
1381 std::string schedule_type_code,
1382 std::string line_planning_number,
1383 int journey_number,
1384 short stop_order);
1385 };
1386
1387 Key key;
1388 // Mandatory, at most 10 characters.
1389 std::string journey_pattern_code;
1390 // Mandatory, at most 10 characters.
1391 std::string user_stop_code;
1392 // Mandatory (except for the first stop of a journey), at most 8 digits. Not
1393 // compulsory for the first stop of a journey. Format: "HH:MM:SS".
1394 std::optional<std::chrono::hh_mm_ss<std::chrono::seconds>> target_arrival_time;
1395 // Mandatory (expect for the last stop of a journey), at most 8 digits. Not
1396 // compulsory for the last stop of a journey. Format: "HH:MM:SS".
1397 std::optional<std::chrono::hh_mm_ss<std::chrono::seconds>> target_departure_time;
1398 // Mandatory, at most 13 characters. Values as in BISON enumeration E3.
1399 // Allowed are: "ACCESSIBLE", "NOTACCESSIBLE" and "UNKNOWN".
1400 // TODO: See if we can fit BISON enumeration E3 into an enum
1401 std::string wheelchair_accessible;
1402 // Mandatory, at most 5 characters. Boolean. Value "true": journey is
1403 // operator by DataOwner. Value "false": journey is operator by a different
1404 // DataOwner. Indicator is meant for a line that is operated jointly by
1405 // multiple transit operators. The indicator is used to be able to match the
1406 // journey operation (KV6, KV19 etc.); only journeys for which the indicator
1407 // is "true" can be expected to have corresponding current/real-time
1408 // information, although "true" doesn't necessarily mean that this
1409 // current/real-time information will (always) become available.
1410 bool data_owner_is_operator = false;
1411 // Mandatory, at most 5 characters. Boolean. Indicates whether
1412 // current/real-time journey information may be expected for the
1413 // corresponding journey ("true" or "false").
1414 bool planned_monitored = false;
1415 // Optional, at most 4 digits. BISON enumeration E10. Intended to allow
1416 // capturing transit mode features at the journey level.
1417 // TODO: See if we can make BISON enumeration E10 into an enum
1418 std::optional<short> product_formula_type;
1419 // Optional, at most 8 characters. Indicates whether the transit operator
1420 // wants that a not-explicitly planned trip (i.e. a journey that only runs on
1421 // reservation, e.g. 'call bus' (belbus), 'line taxi' (lijntaxi) etc.) to be
1422 // shown on displays. Values following BISON enumeration E21: TRUE (always),
1423 // FALSE (never), REALTIME (only when journey is tracked).
1424 // TODO: See if we can make BISON enumeration E21 into an enum
1425 std::string show_flexible_trip;
1426
1427 Kv1OrganizationalUnit *p_organizational_unit = nullptr;
1428 Kv1ScheduleVersion *p_schedule_version = nullptr;
1429 Kv1Line *p_line = nullptr;
1430 Kv1JourneyPattern *p_journey_pattern = nullptr;
1431 Kv1UserStopPoint *p_user_stop = nullptr;
1432};
1433
1434// KV1 Table 29: Operating Day [OPERDAY]
1435//
1436// Contains the operational calendar. Which package (schedule version) applies
1437// is specified per day, per organisation unit.
1438//
1439// This table is part of the KV1 variant "schedules and passing times".
1440struct Kv1OperatingDay {
1441 struct Key {
1442 // Mandatory (key), at most 10 characters. Transport operator (from list as
1443 // defined in BISON enumeration E1).
1444 std::string data_owner_code;
1445 // Mandatory (key), at most 10 characters.
1446 std::string organizational_unit_code;
1447 // Mandatory (key), at most 10 characters.
1448 std::string schedule_code;
1449 // Mandatory (key), at most 10 characters.
1450 std::string schedule_type_code;
1451 // Mandatory (key), at most 10 characters. Date on which the package
1452 // (schedule version) applies. Format: "YYYY-MM-DD".
1453 std::chrono::year_month_day valid_date;
1454
1455 explicit Key(std::string data_owner_code,
1456 std::string organizational_unit_code,
1457 std::string schedule_code,
1458 std::string schedule_type_code,
1459 std::chrono::year_month_day valid_date);
1460 };
1461
1462 Key key;
1463 // Optional, at most 255 characters.
1464 std::string description;
1465
1466 Kv1OrganizationalUnit *p_organizational_unit = nullptr;
1467 Kv1ScheduleVersion *p_schedule_version = nullptr;
1468};
1469
1470bool operator==(const Kv1OrganizationalUnit::Key &a, const Kv1OrganizationalUnit::Key &b);
1471bool operator==(const Kv1HigherOrganizationalUnit::Key &a, const Kv1HigherOrganizationalUnit::Key &b);
1472bool operator==(const Kv1UserStopPoint::Key &a, const Kv1UserStopPoint::Key &b);
1473bool operator==(const Kv1UserStopArea::Key &a, const Kv1UserStopArea::Key &b);
1474bool operator==(const Kv1TimingLink::Key &a, const Kv1TimingLink::Key &b);
1475bool operator==(const Kv1Link::Key &a, const Kv1Link::Key &b);
1476bool operator==(const Kv1Line::Key &a, const Kv1Line::Key &b);
1477bool operator==(const Kv1Destination::Key &a, const Kv1Destination::Key &b);
1478bool operator==(const Kv1JourneyPattern::Key &a, const Kv1JourneyPattern::Key &b);
1479bool operator==(const Kv1ConcessionFinancerRelation::Key &a, const Kv1ConcessionFinancerRelation::Key &b);
1480bool operator==(const Kv1ConcessionArea::Key &a, const Kv1ConcessionArea::Key &b);
1481bool operator==(const Kv1Financer::Key &a, const Kv1Financer::Key &b);
1482bool operator==(const Kv1JourneyPatternTimingLink::Key &a, const Kv1JourneyPatternTimingLink::Key &b);
1483bool operator==(const Kv1Point::Key &a, const Kv1Point::Key &b);
1484bool operator==(const Kv1PointOnLink::Key &a, const Kv1PointOnLink::Key &b);
1485bool operator==(const Kv1Icon::Key &a, const Kv1Icon::Key &b);
1486bool operator==(const Kv1Notice::Key &a, const Kv1Notice::Key &b);
1487bool operator==(const Kv1TimeDemandGroup::Key &a, const Kv1TimeDemandGroup::Key &b);
1488bool operator==(const Kv1TimeDemandGroupRunTime::Key &a, const Kv1TimeDemandGroupRunTime::Key &b);
1489bool operator==(const Kv1PeriodGroup::Key &a, const Kv1PeriodGroup::Key &b);
1490bool operator==(const Kv1SpecificDay::Key &a, const Kv1SpecificDay::Key &b);
1491bool operator==(const Kv1TimetableVersion::Key &a, const Kv1TimetableVersion::Key &b);
1492bool operator==(const Kv1PublicJourney::Key &a, const Kv1PublicJourney::Key &b);
1493bool operator==(const Kv1PeriodGroupValidity::Key &a, const Kv1PeriodGroupValidity::Key &b);
1494bool operator==(const Kv1ExceptionalOperatingDay::Key &a, const Kv1ExceptionalOperatingDay::Key &b);
1495bool operator==(const Kv1ScheduleVersion::Key &a, const Kv1ScheduleVersion::Key &b);
1496bool operator==(const Kv1PublicJourneyPassingTimes::Key &a, const Kv1PublicJourneyPassingTimes::Key &b);
1497bool operator==(const Kv1OperatingDay::Key &a, const Kv1OperatingDay::Key &b);
1498
1499size_t hash_value(const Kv1OrganizationalUnit::Key &k);
1500size_t hash_value(const Kv1HigherOrganizationalUnit::Key &k);
1501size_t hash_value(const Kv1UserStopPoint::Key &k);
1502size_t hash_value(const Kv1UserStopArea::Key &k);
1503size_t hash_value(const Kv1TimingLink::Key &k);
1504size_t hash_value(const Kv1Link::Key &k);
1505size_t hash_value(const Kv1Line::Key &k);
1506size_t hash_value(const Kv1Destination::Key &k);
1507size_t hash_value(const Kv1JourneyPattern::Key &k);
1508size_t hash_value(const Kv1ConcessionFinancerRelation::Key &k);
1509size_t hash_value(const Kv1ConcessionArea::Key &k);
1510size_t hash_value(const Kv1Financer::Key &k);
1511size_t hash_value(const Kv1JourneyPatternTimingLink::Key &k);
1512size_t hash_value(const Kv1Point::Key &k);
1513size_t hash_value(const Kv1PointOnLink::Key &k);
1514size_t hash_value(const Kv1Icon::Key &k);
1515size_t hash_value(const Kv1Notice::Key &k);
1516size_t hash_value(const Kv1TimeDemandGroup::Key &k);
1517size_t hash_value(const Kv1TimeDemandGroupRunTime::Key &k);
1518size_t hash_value(const Kv1PeriodGroup::Key &k);
1519size_t hash_value(const Kv1SpecificDay::Key &k);
1520size_t hash_value(const Kv1TimetableVersion::Key &k);
1521size_t hash_value(const Kv1PublicJourney::Key &k);
1522size_t hash_value(const Kv1PeriodGroupValidity::Key &k);
1523size_t hash_value(const Kv1ExceptionalOperatingDay::Key &k);
1524size_t hash_value(const Kv1ScheduleVersion::Key &k);
1525size_t hash_value(const Kv1PublicJourneyPassingTimes::Key &k);
1526size_t hash_value(const Kv1OperatingDay::Key &k);
1527
1528#endif // OEUF_LIBTMI8_KV1_TYPES_HPP
diff --git a/lib/libtmi8/include/tmi8/kv6_parquet.hpp b/lib/libtmi8/include/tmi8/kv6_parquet.hpp
new file mode 100644
index 0000000..33b57ca
--- /dev/null
+++ b/lib/libtmi8/include/tmi8/kv6_parquet.hpp
@@ -0,0 +1,46 @@
1// vim:set sw=2 ts=2 sts et:
2
3#ifndef OEUF_LIBTMI8_KV6_PARQUET_HPP
4#define OEUF_LIBTMI8_KV6_PARQUET_HPP
5
6#include <filesystem>
7
8#include <arrow/api.h>
9#include <arrow/io/api.h>
10#include <parquet/arrow/writer.h>
11
12static const size_t MAX_PARQUET_CHUNK = 10000;
13
14struct ParquetBuilder {
15 ParquetBuilder();
16 arrow::Result<std::shared_ptr<arrow::Table>> getTable();
17
18 std::shared_ptr<arrow::Schema> schema;
19
20 arrow::StringBuilder types;
21 arrow::StringBuilder data_owner_codes;
22 arrow::StringBuilder line_planning_numbers;
23 arrow::Date32Builder operating_days;
24 arrow::UInt32Builder journey_numbers;
25 arrow::UInt8Builder reinforcement_numbers;
26 arrow::TimestampBuilder timestamps{arrow::timestamp(arrow::TimeUnit::SECOND), arrow::default_memory_pool()};
27 arrow::StringBuilder sources;
28 arrow::Int16Builder punctualities;
29 arrow::StringBuilder user_stop_codes;
30 arrow::UInt16Builder passage_sequence_numbers;
31 arrow::UInt32Builder vehicle_numbers;
32 arrow::UInt32Builder block_codes;
33 arrow::StringBuilder wheelchair_accessibles;
34 arrow::UInt8Builder number_of_coaches;
35 arrow::Int32Builder rd_ys;
36 arrow::Int32Builder rd_xs;
37 arrow::UInt32Builder distance_since_last_user_stops;
38};
39
40[[nodiscard]]
41arrow::Status writeArrowRecordsAsParquetFile(arrow::RecordBatchReader &rbr, std::filesystem::path filename);
42
43[[nodiscard]]
44arrow::Status writeArrowTableAsParquetFile(const arrow::Table &table, std::filesystem::path filename);
45
46#endif // OEUF_LIBTMI8_KV6_PARQUET_HPP