Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2 draft #63

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 121 additions & 70 deletions spec/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ A station is a larger building or area that can be identified by a name. It is u
```js
{
type: 'station', // required
id: '123456', // unique, url-safe, required
id: '123456', // unique, required
name: 'Berlin Hauptbahnhof', // official non-abbreviated name, required
// todo: other names
location: { // location object, optional
Expand All @@ -76,7 +76,7 @@ If the underlying data source does not allow such a fine-grained distinction, us
```js
{
type: 'stop', // required
id: '12345678', // unique, url-safe, required
id: '12345678', // unique, required
station: '123456', // station id or station object, required
name: 'Berlin Hauptbahnhof (tief)', // official non-abbreviated name, required
// todo: other names
Expand All @@ -97,7 +97,7 @@ A `station` can be part of multiple `region`s.
```js
{
type: 'region', // required
id: '1234', // unique, url-safe, required
id: '1234', // unique, required
name: 'Bretagne', // official non-abbreviated name, required
// todo: other names
stations: [ // station ids or station objects, required
Expand All @@ -111,7 +111,7 @@ A `station` can be part of multiple `region`s.
```js
{
type: 'line', // required
id: '123', // unique, url-safe, required
id: '123', // unique, required
name: 'ICE 599', // official non-abbreviated name, required
mode: 'train', // see section on modes, required
subMode: …, // reserved for future use
Expand All @@ -130,7 +130,7 @@ For a very consistent subway service, there may be one route for each direction.
```js
{
type: 'route', // required
id: '1234', // unique, url-safe, required
id: '1234', // unique, required
line: '123', // line id or line object, required,
mode: 'bus', // see section on modes, overrides `line` mode, e.g. for replacements services
subMode: …, // reserved for future use
Expand All @@ -141,15 +141,32 @@ For a very consistent subway service, there may be one route for each direction.
}
```

### `trip`

A `trip` represents a single run of a vehicle at a specific time. Passengers taking a trip usually don't enter the vehicle before the trip's first arrival or after its last departure.

```js
{
type: 'trip', // required
id: '1234', // unique, required
line: '1234', // line id or object, optional
route: '1234', // route id or object, optional
mode: 'bus', // required if route is an id or if the trip mode differs from the route mode
subMode: '…', // reserved for future use
stopovers: [] // list of stopover objects, required, must contain at least two entries
}
```

### `schedule`

*Note:* There are many ways to format schedules of public transport routes. This one tries to balance the amount of data and consumability. It is specifically geared towards urban public transport, with frequent trains and homogenous travels.
*Note:* While FPTF already offers `trip` to describe public transport timetables, a large list of `trip`s tends to contain a lot of duplicate information, especially in urban public transport, with frequent trains and homogenous travels. In those cases, schedules come in handy, describing a set of trips. However, unlike `trip`, they don't allow storing real time data.

```js
{
type: 'schedule', // required
id: '12345', // unique, url-safe, required
id: '12345', // unique, required
route: '1234', // route id or object, required
line: '1234', // line id or object, optional
mode: 'bus', // see section on modes, overrides `route`/`line` mode, e.g. for replacements services
subMode: …, // reserved for future use
sequence: [
Expand All @@ -169,12 +186,12 @@ For a very consistent subway service, there may be one route for each direction.
departure: 150 // optional, when the vehicle leaves the route
}
],
starts: [ // array of Unix timestamps, required
1488379661, // start time of the trip
1488379761,
1488379861,
1488379961
]
starts: { // object trip.id -> ISO 8601 string (with timezone), required
'trip1234': '2019-03-29T20:00:00+01:00', // start time of the trip
'trip2345': '2019-03-30T20:00:00+01:00',
'trip3456': '2019-03-31T20:00:00+02:00',
'trip4567': '2019-04-01T20:00:00+02:00',
}
}
```

Expand All @@ -183,7 +200,7 @@ For a very consistent subway service, there may be one route for each direction.
```js
{
type: 'operator', // required
id: 'sncf', // unique, url-safe, required
id: 'sncf', // unique, required
name: 'Société nationale des chemins de fer français' // official non-abbreviated name, required
}
```
Expand All @@ -201,22 +218,36 @@ A `stopover` represents a vehicle stopping at a stop/station at a specific time.
stop: '12345-678',

// - ISO 8601 string (with stop/station timezone)
// - required if `departure` is null
// - required if `departure` is `null`
// - realtime/prognosis data if available, otherwise plan data, otherwise `null`
arrival: '2017-03-17T15:00:00+02:00',

// - seconds relative to scheduled arrival
// - optional
// - ISO 8601 string (with stop/station timezone)
// - plan data if available, otherwise `null`
plannedArrival: '2017-03-17T15:45:00+02:00',

// - if realtime/prognosis & plan data is available
// - required
// - value must be `arrival - plannedArrival` in seconds
// - otherwise optional
arrivalDelay: -45,

arrivalPlatform: '4-1', // string, optional

// - ISO 8601 string (with stop/station timezone)
// - required if `arrival` is null
departure: '2017-03-16T20:00:00+01:00',
// - required if `arrival` is `null`
// - realtime/prognosis data if available, otherwise plan data, otherwise `null`
departure: '2017-03-17T15:02:00+02:00',

// - seconds relative to scheduled departure
// - optional
departureDelay: 120,
// - ISO 8601 string (with stop/station timezone)
// - plan data if available, otherwise `null`
plannedDeparture: '2017-03-17T15:02:00+02:00',

// - if realtime/prognosis & plan data is available
// - required
// - value must be `arrival - plannedArrival` in seconds
// - otherwise optional
departureDelay: null,

departurePlatform: null, // string, optional
}
Expand All @@ -229,74 +260,94 @@ A `journey` is a computed set of directions to get from A to B at a specific tim
```js
{
type: 'journey', // required
id: '12345', // unique, url-safe, required
legs: [ // array of objects, required
{
// - station/stop/location id or object
// - required
origin: '12345678',
id: '12345', // unique, optional
legs: [], // array of leg objects, required, must contain at least one entry
price: { // optional
amount: 19.95, // number, required
currency: 'EUR' // ISO 4217 code, required
}
}
```

// station/stop/location id or object
// - required
destination: '87654321',
### `leg`

// - ISO 8601 string (with origin timezone)
// - required
departure: '2017-03-16T20:00:00+01:00',
A `leg` is a section of a `journey`. Legs that don't involve on-demand transport (e.g. bike-sharing or walking) usually correspond to a specific part of a `trip` taken by the user.

// - seconds relative to scheduled departure
// - optional
departureDelay: 120,
```js
{
type: 'leg', // required
id: '12345', // unique, optional

departurePlatform: '4-1', // string, optional
// - station/stop/location id or object
// - required
origin: '12345678',

// - ISO 8601 string (with destination timezone)
// - required
arrival: '2017-03-17T15:00:00+02:00',
// station/stop/location id or object
// - required
destination: '87654321',

// - seconds relative to scheduled arrival
// - optional
arrivalDelay: -45,
// - ISO 8601 string (with stop/station timezone)
// - required if `arrival` is `null`
// - realtime/prognosis data if available, otherwise plan data, otherwise `null`
departure: '2017-03-17T15:02:00+02:00',

arrivalPlatform: '9', // string, optional
// - ISO 8601 string (with stop/station timezone)
// - plan data if available, otherwise `null`
plannedDeparture: '2017-03-17T15:02:00+02:00',

// - array of stopover objects
// - optional
stopovers: […],
// - if realtime/prognosis & plan data is available
// - required
// - value must be `arrival - plannedArrival` in seconds
// - otherwise optional
departureDelay: null,

// - schedule id or object
// - optional
schedule: '1234',
departurePlatform: null, // string, optional

// - see section on modes
// - overrides `schedule`'s `mode`
mode: 'train',
// - ISO 8601 string (with stop/station timezone)
// - required if `departure` is `null`
// - realtime/prognosis data if available, otherwise plan data, otherwise `null`
arrival: '2017-03-17T15:00:00+02:00',

subMode: …, // reserved for future use
// - ISO 8601 string (with stop/station timezone)
// - plan data if available, otherwise `null`
plannedArrival: '2017-03-17T15:45:00+02:00',

public: true, // is it publicly accessible?
// - if realtime/prognosis & plan data is available
// - required
// - value must be `arrival - plannedArrival` in seconds
// - otherwise optional
arrivalDelay: -45,

// - operator id or object
// - overrides `schedule`'s `operator`
operator: 'sncf'
arrivalPlatform: '4-1', // string, optional

// use this if pricing information is available for specific legs
price: { // optional
amount: 12.50, // number, required
currency: 'EUR' // ISO 4217 code, required
}
}
// …
],
// - array of stopover objects
// - optional
stopovers: […],

// - schedule id or object
// - optional
schedule: '1234',

// - see section on modes
// - overrides `schedule`'s `mode`
mode: 'train',

subMode: …, // reserved for future use

public: true, // is it publicly accessible?

// - operator id or object
// - overrides `schedule`'s `operator`
operator: 'sncf'

// use this if pricing information is available for specific legs
price: { // optional
amount: 19.95, // number, required
amount: 12.50, // number, required
currency: 'EUR' // ISO 4217 code, required
}
}
```

The `departureDelay` and `arrivalDelay` fields should only contain a value if realtime data or a prognosis based on realtime data is actually available.

## modes

As discussed in [#4](https://github.com/public-transport/friendly-public-transport-format/issues/4), we decided to have two fields `mode` and `subMode`.
Expand Down