- Makefile 100%
| api | release downtown version | |
| LICENSE | add licence and finalise clockworkOrange structures | |
| mkfile | change lint | |
| README.adoc | add licence and finalise clockworkOrange structures | |
| traffic.adoc | add database indices | |
| traffic.bare | add UTC time to updates | |
TRAFFIC
1. Abstract
TRAFFIC (Transport Related Augmented File Format Improved & Corrected) is a data format used to represent public transport timetables and related information. Apart from defining format for data at rest, TRAFFIC describes an API used to exchange information between providers and clients. TRAFFIC is inspired by GTFS, but it’s more concise and not human-readable; data can be converted from GTFS format to TRAFFIC, and TRAFFIC is compatible with GTFS Realtime.
2. Comments
Comments are solicited and should be addressed to the mailing list at traffic@git.apiote.xyz.
3. Copyright Notice
Copyright (c) Adam Evyčędo
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
4. Requirements Language
5. Introduction
The primary goal set before authors of TRAFFIC is ease of use—for both, users of clients, and programmers implementing the spec. This encompasses practicality and simplicity; TRAFFIC was created to be used even on less powerful devices. That’s why TRAFFIC employs multiple indices, and—with the use of modern data structures—timetables use space more efficiently.
TRAFFIC is not meant to replace GTFS—indeed, it works in tandem with GTFS Realtime—and does not fully implement all edge cases covered by GTFS. With time, when more and more schedules will be used by TRAFFIC servers, the specification will cover more and more real-world cases, but the goal of making passengers’ lives easier will always be first.
5.1. Difference from GTFS
The most visible difference between TRAFFIC and GTFS is data structure used by the standards. Where GTFS uses zipped csv files and unnecessarily repeats much information, TRAFFIC encodes data in BARE structures, which together are packed into an xz compressed tar archive. In TRAFFIC, there are few ID fields and file offsets are used to locate a specific record. Enums are reordered so that when they specify an unknown value, it’s located at index zero, so that it’s a zero value of an enum.
6. Versioning
TRAFFIC versions are named and not numbered.
Each version name starts with next letter of English alphabet and versions are named after metro lines.
Data format is not backwards compatible between versions.
API is backwards compatible; single version of API defines one or more versions of responses.
Clients MUST include accept headers with versions of responses they understand and server MUST respond with the most recent version that both the client asked for and the server can produce, or send an error response if agreement is not possible.
As an exception, version 0 is reserved for development and MUST be sent by server if requested, irrelevant of the highest version the server can produce.
7. Names
-
Timetable is a collection of information valid for specific time in one feed.
-
Line is what GTFS names a Route
-
Stop is a specific point where a vehicle stops to pick up or drop passengers. It may be further subdivided into platforms. Stop’s name SHOULD contain the shortest ID distinguishing it from other stops of the same node.
-
Node is an abstract collection of stops. For stops to be part of the same node, they must have the same
stop_nameinstops.txtfile of GTFS feed. -
Stop code is a stable identifier, one that doesn’t change between timetable changes. It may, for example, be used in 2D codes at stops, that link to a website with realtime departures for this stop.
8. Data format specification
TRAFFIC file consists of multiple files defined below, packed into an xz compressed tar archive.
Each TRAFFIC file name must end with two dates in format YYYYMMDD separated by _ which denote first and last day of the timetable validity, followed by .tar.xz or .txz extension.
8.1. Files definitions
Each file (aside from Lua scripts and indices databases) consists of concatenated BARE encoded structures, one after another. At the top level, files do not contain lists of structures—there is no length at offset 0—because the length is not know in advance. Should need arise to read the whole file, it must be read one structure at a time till EOF. Usually, it’s enough to read one structure by skipping to a given offset and unmarshalling a single structure.
Schema for structures is defined in traffic.bare file.
8.1.1. agencies.bare
Consists of one or more Agency structures and defines firms which operate vehicles.
timezone is a name of IANA time zone for given agency.
language is a IETF BCP 47 language code.
8.1.2. calendar.bare
Consists of one or more Schedule structures and defines when a trip operates.
weekdays is a bitmap. 0th and 7th bit denote Sunday—both MUST be set for Sunday schedule; 1st through 6th bits denote respectively Monday through Saturday.
startDate and endDate MUST be in format YYYYMMDD.
8.1.3. feed_info.bare
Usually, consists of one FeedInfo structure, but MAY be empty.
It contains info about the particular timetable.
language is a IETF BCP 47 language code.
8.1.4. ix_lines.bare
Index of lines from line name to offset in lines.bare file.
Consists of multiple NameOffset structures.
name is latinised—according to feed rules—line name without non-alphanumeric characters in lower-case.
8.1.5. ix_stop_codes.bare
Index of stops from stop code to offset in stops.bare file.
Consists of multiple CodeIndex-es.
8.1.6. ix_stop_names.bare
Index of stops from stop name to offset in stops.bare file.
Consists of multiple NameOffset structures.
name is latinised—according to feed rules—line name without non-alphanumeric characters in lower-case.
8.1.7. ix_trips.bare
Index of trips from trip ID to offset in trips.bare file.
Consists of multiple NameOffset structures.
name is unchanged trip ID.
8.1.8. lines.bare
Consists of one or more Line structures and defines lines.
nextNodes in LineGraph define edges of the graph — from map key to each of its value for `nextNodes.
nextNodes value of -1 means that key is a final terminus for some or all trips.
8.1.9. stops.bare
Consists of one or more Stop structures and defines stops.
Depending on the feed, it MAY contain unused stops, ones without any departures.
zone MAY be an empty string if there is just one zone without a name.
timezone is a name of IANA time zone for given stop.
8.1.10. trips.bare
Consists of one or more Trip structures and defines trips for lines.
Currently, shapeID is not used.
8.1.11. vehicles.bare
Consists of one or more Vehicle structures and defines vehicles on trips as defined by realtime information.
8.1.12. updates.lua
This file is optional.
Contains single Lua function getUpdates(tripID, sequence, stopID, stopCode).
tripID, stopCode, and stopID are strings, sequence is a number coresponding to stop sequence in trip from static timetable.
The function returns in case of success a json-encoded LuaUpdates and an empty string; an empty string and a json-encoded LuaError in case of errors.
LuaUpdates.Updates MAY contain an entry with key '' which will be ignored.
8.1.13. vehicles.lua
This file is optional.
Contains single Lua function getVehicles(north, west, south, east).
north, west, south, east are numberts denoting boundaries of rectangle in chich to look for real-time vehicles positions
The function returns in case of success a json-encoded map of tripID to a VehicleStatus and an empty string; an empty string and a json-encoded LuaError in case of errors.
The map MAY contain an entry with key '' which will be ignored.
8.1.14. alerts.lua
This file is optional.
Contains single Lua function getAlerts(stopID, stopCode, tripID, lineID).
tripID, stopCode, stopID, and lineID are strings.
The function returns in case of success a json-encoded array of AlertLua and an empty string; an empty string and a json-encoded LuaError in case of errors.
8.1.15. index.db
Contains an SQLite database with indices. This file can be used instead of ix_*.bare files. Database schema is the following:
CREATE TABLE ix_trips(code text primary key, offset integer); CREATE TABLE ix_stop_names(name text, offset integer); CREATE INDEX ix_ix_stop_names on ix_stop_names(name); CREATE TABLE ix_stop_codes(code text primary key, offset integer); CREATE TABLE ix_lines(name text, offset integer); CREATE INDEX ix_ix_lines on ix_lines(name); CREATE TABLE ix_line_codes(code text primary key, offset integer);
8.2. Lua scripts
In Lua scripts used for accessing custom APIs following modules are available:
-
http
-
get(url: string, options: {query: string, cookies: table, headers: table, timeout: string, auth: {user: string, pass: string}}): {body: string, body_size:number, headers: table, cookies: table, status_code: number} or (nil, error: string)
-
-
json
-
decode(j: string): (decoded_value: lvalue, error: string) -
encode(v: lvalue): (encoded_json: string, error: string)
-
9. API specification
API is defined as OpenAPI spec v3.1.0 in file api/api.yml and data structure is defined as BARE schema in file api/api.bare.
The spec is extended in following ways:
-
added types
| type | description |
|---|---|
data |
unstructured binary (octet-stream) data |
-
added formats to types which correspond to primitive types used in BARE encoding
| format | BARE type |
|---|---|
bare-uint8 |
u8 |
bare-uint16 |
u16 |
bare-uint |
uint |
bare-int |
int |
bare-int8 |
i8 |
bare-float64 |
f64 |
bare-float32 |
f32 |
bare-bool |
bool |
-
added generic formats to types
| format | description |
|---|---|
uint |
unsigned integer |
-
added keys
keysanditemsto typeobject. Such object defines a map.
9.1. API specification customisation
9.1.1. API info
Fields under .info must be customised according to the entity responsible for the server.
9.1.2. API location
API specification file MUST be available at /.well-known/traffic-api and define API location in field .servers.[$i].url. First server MUST be a production server to be used by clients.
9.1.3. API security
API specification file MUST be available at /.well-known/traffic-api and define API security in field .security:
-
if the only security schema is
{}, the server is available without restrictions, -
if the only security schema is
api_key: [], the server is private and all requests must include a valid key inx-traffic-keyheader, -
if both security schemas are present, the server is rate limited for requests without the
x-traffic-keyheader.
The keys under .security key MUST NOT be empty.
9.2. Transport layer
All requests to the API MUST be performed via HTTP and they SHOULD be secured using TLS. Apart from the specification response described in subsection 8.1.2, responses to all requests are encoded using BARE.
Appendix A: Version name
Downtown is on of Singapore Mass Rapid Transit lines. It runs from Bukit Panjang station in the north-west of the country towards Expo station in the east via a loop around the city-centre for almost 42 km over 34 stations, with 2.2 km and 3 stations under construction, and another station in planning.
Clockwork Orange is an unofficial tourist name of Glasgow Subway (Fo-thalamh Ghlaschu). It consists of Outer and Inner Circle lines going the same route clockwise and couterclockwise respectively. The trains travel between 15 stations for 10.5 kilometers.
Batong (北京地铁八通线) is one of Beijing Subway lines. This line extends Line 1. It has 15 stations, is over 23 km long but runs only about 4 km underground. It will take you to the Universal Beijing Resort.
AREX (Airport Railroad Express, 인천국제공항철도) is one of Seoul metro lines. It has 14 stations, is over 63 km long and was opened in 2007. It will take you from Seoul Station to Incheon Airport and back.