1
0
Fork
You've already forked traffic
0
The protocol
  • Makefile 100%
Find a file
2025年03月15日 17:38:44 +02:00
api release downtown version 2024年05月18日 19:41:17 +02:00
LICENSE add licence and finalise clockworkOrange structures 2024年02月10日 19:04:28 +01:00
mkfile change lint 2024年02月10日 19:04:33 +01:00
README.adoc add licence and finalise clockworkOrange structures 2024年02月10日 19:04:28 +01:00
traffic.adoc add database indices 2025年03月15日 17:38:44 +02:00
traffic.bare add UTC time to updates 2024年04月22日 15:49:07 +02:00

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.

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

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here.

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_name in stops.txt file 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 keys and items to type object. 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 in x-traffic-key header,

  • if both security schemas are present, the server is rate limited for requests without the x-traffic-key header.

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.