Skip to content
Closed
Show file tree
Hide file tree
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
12 changes: 6 additions & 6 deletions gtfs-realtime/proto/gtfs-realtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ message Position {
// addition, absolute arrival/departure times must be provided.
message TripDescriptor {
// The trip_id from the GTFS feed that this selector refers to.
// For non frequency-based trips, this field is enough to uniquely identify
// the trip. For frequency-based trip, start_time and start_date might also be
// For trips defined in frequencies.txt, this field is enough to uniquely identify
// the trip. For trips defined in frequencies.txt, start_time and start_date might also be
// necessary.
optional string trip_id = 1;

Expand All @@ -505,16 +505,16 @@ message TripDescriptor {
optional uint32 direction_id = 6;

// The initially scheduled start time of this trip instance.
// When the trip_id corresponds to a non-frequency-based trip, this field
// When the trip_id corresponds to a trip not defined in frequencies.txt, this field
// should either be omitted or be equal to the value in the GTFS feed. When
// the trip_id correponds to a frequency-based trip, the start_time must be
// the trip_id corresponds to a trip defined in frequencies.txt, the start_time must be
// specified for trip updates and vehicle positions. If the trip corresponds
// to exact_times=1 GTFS record, then start_time must be some multiple
// to exact_times=1 frequencies.txt trip, then start_time must be some multiple
// (including zero) of headway_secs later than frequencies.txt start_time for
// the corresponding time period. If the trip corresponds to exact_times=0,
// then its start_time may be arbitrary, and is initially expected to be the
// first departure of the trip. Once established, the start_time of this
// frequency-based trip should be considered immutable, even if the first
// exact_times=0 trip should be considered immutable, even if the first
// departure time changes -- that time change may instead be reflected in a
// StopTimeUpdate.
// Format and semantics of the field is same as that of
Expand Down
27 changes: 22 additions & 5 deletions gtfs-realtime/spec/en/examples/trip-updates-full.asciipb
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ entity {

# second entity containing update information for another trip
entity {
id: "3"
id: "2"
trip_update {
trip {
# frequency based trips are defined by their
# headway-defined schedule trips (exact_times=1) are defined by their
# trip_id in GTFS and
trip_id: "frequency-expanded-trip"
# start_time
trip_id: "headway-defined-schedule-trip"
# start_time, which must be some multiple (including zero) of headway_secs later than frequencies.txt start_time
start_time: "11:15:35"
}
stop_time_update {
Expand All @@ -71,8 +71,25 @@ entity {
delay: -2
}
}
}

# third entity containing update information for another trip
entity {
id: "3"
trip_update {
trip {
# frequency-based trips (exact_times=0) are defined by their
# trip_id in GTFS and
trip_id: "frequency-based-trip"
# start_time, which is immutable and defined when vehicle information for this trip instance is first published
start_time: "11:15:35"
}
stop_time_update {
stop_sequence: 9
stop_sequence: 1
arrival {
# Becaused this is a frequency-based trip (exact_times=0), time (not delay) must be used
time: 1486496765
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions gtfs-realtime/spec/en/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,10 @@ A descriptor that identifies an instance of a GTFS trip, or all instances of a t

| _**Field Name**_ | _**Type**_ | _**Cardinality**_ | _**Description**_ |
|------------------|------------|-------------------|-------------------|
| **trip_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | optional | The trip_id from the GTFS feed that this selector refers to. For non frequency-based trips, this field is enough to uniquely identify the trip. For frequency-based trip, start_time and start_date might also be necessary. |
| **trip_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | optional | The trip_id from the GTFS feed that this selector refers to. For trips not defined in GTFS frequencies.txt, this field is enough to uniquely identify the trip. For trips defined in frequencies.txt, start_time and start_date might also be necessary. |
| **route_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | optional | The route_id from the GTFS that this selector refers to. |
| **direction_id** | [uint32](https://developers.google.com/protocol-buffers/docs/proto#scalar) | optional | The direction_id from the GTFS feed trips.txt file, indicating the direction of travel for trips this selector refers to.<br>**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.<br>|
| **start_time** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | optional | The initially scheduled start time of this trip instance. When the trip_id corresponds to a non-frequency-based trip, this field should either be omitted or be equal to the value in the GTFS feed. When the trip_id correponds to a frequency-based trip, the start_time must be specified for trip updates and vehicle positions. If the trip corresponds to exact_times=1 GTFS record, then start_time must be some multiple (including zero) of headway_secs later than frequencies.txt start_time for the corresponding time period. If the trip corresponds to exact_times=0, then its start_time may be arbitrary, and is initially expected to be the first departure of the trip. Once established, the start_time of this frequency-based trip should be considered immutable, even if the first departure time changes -- that time change may instead be reflected in a StopTimeUpdate. Format and semantics of the field is same as that of GTFS/frequencies.txt/start_time, e.g., 11:15:35 or 25:15:35. |
| **start_time** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | optional | The initially scheduled start time of this trip instance. When the trip_id corresponds to a trip not defined in frequencies.txt, this field should either be omitted or be equal to the value in the GTFS feed. When the trip_id correponds to a trip defined in frequencies.txt, the start_time must be specified for trip updates and vehicle positions. If the trip corresponds to exact_times=1 trip from frequencies.txt, then start_time must be some multiple (including zero) of headway_secs later than frequencies.txt start_time for the corresponding time period. If the trip corresponds to exact_times=0, then its start_time may be arbitrary, and is initially expected to be the first departure of the trip. Once established, the start_time of this exact_times=0 trip should be considered immutable, even if the first departure time changes -- that time change may instead be reflected in a StopTimeUpdate. Format and semantics of the field is same as that of GTFS/frequencies.txt/start_time, e.g., 11:15:35 or 25:15:35. |
| **start_date** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | optional | The scheduled start date of this trip instance. This field must be provided to disambiguate trips that are so late as to collide with a scheduled trip on a next day. For example, for a train that departs 8:00 and 20:00 every day, and is 12 hours late, there would be two distinct trips on the same time. This field can be provided but is not mandatory for schedules in which such collisions are impossible - for example, a service running on hourly schedule where a vehicle that is one hour late is not considered to be related to schedule anymore. In YYYYMMDD format. |
| **schedule_relationship** | [ScheduleRelationship](#enum-schedulerelationship-1) | optional |

Expand Down
7 changes: 3 additions & 4 deletions gtfs-realtime/spec/en/trip-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ For example, if the following data appears in the GTFS-rt feed:

Each [StopTimeUpdate](reference.md#StopTimeUpdate) is linked to a stop. Ordinarily this can be done using either a GTFS stop_sequence or a GTFS stop_id. However, in the case you are providing an update for a trip without a GTFS trip_id, you must specify stop_id as stop_sequence has no value. The stop_id must still reference a stop_id in GTFS. If the same stop_id is visited more than once in a trip, then stop_sequence should be provided in all StopTimeUpdates for that stop_id on that trip.

The update can provide a exact timing for **arrival** and/or **departure** at a stop in [StopTimeUpdates](reference.md#StopTimeUpdate) using [StopTimeEvent](reference.md#StopTimeEvent). This should contain either an absolute **time** or a **delay** (i.e. an offset from the scheduled time in seconds). Delay can only be used in case the trip update refers to a scheduled GTFS trip, as opposed to a frequency-based trip. In this case, time should be equal to scheduled time + delay. You may also specify **uncertainty** of the prediction along with [StopTimeEvent](reference.md#StopTimeEvent), which is discussed in more detail in section [Uncertainty](#uncertainty) further down the page.
The update can provide a exact timing for **arrival** and/or **departure** at a stop in [StopTimeUpdates](reference.md#StopTimeUpdate) using [StopTimeEvent](reference.md#StopTimeEvent). This should contain either an absolute **time** or a **delay** (i.e. an offset from the scheduled time in seconds). Delay can only be used in case the trip update refers to a scheduled GTFS trip, as opposed to a frequency-based trip (a trip defined in frequencies.txt with exact_times=0). For schedule-based trips, time should be equal to scheduled time + delay. You may also specify **uncertainty** of the prediction along with [StopTimeEvent](reference.md#StopTimeEvent), which is discussed in more detail in section [Uncertainty](#uncertainty) further down the page.

For each [StopTimeUpdate](reference.md#StopTimeUpdate), the default schedule relationship is **scheduled**. (Note that this is different from the schedule relationship for the trip). You may change this to **skipped** if the stop will not be stopped at, or **no data** if you only have realtime data for some of the trip.

Expand Down Expand Up @@ -59,7 +59,7 @@ In most cases, you should provide the trip_id of the scheduled trip in GTFS that

#### Systems with repeated trip_ids

For systems using repeated trip_ids, for example trips modeled using frequencies.txt, that is frequency-based trips, the trip_id is not in itself a unique identifier of a single journey, as it lacks a
For systems using repeated trip_ids, for example trips modeled using frequencies.txt, the trip_id is not in itself a unique identifier of a single journey, as it lacks a
specific time component. In order to uniquely identify such trips within a
TripDescriptor, a triple of identifiers must be provided:

Expand All @@ -82,8 +82,7 @@ first stop at 10:13:00.

#### Alternative trip matching

Trips which are not frequency based may also be uniquely identified by a
TripDescriptor including the combination of:
Trips not defined in frequencies.txt may also be uniquely identified by a TripDescriptor including the combination of:

* __route_id__
* __direction_id__
Expand Down
21 changes: 13 additions & 8 deletions gtfs/spec/en/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ This specification defines the following files along with their associated conte
| [fare_attributes.txt](#fare_attributestxt) | Optional | Fare information for a transit organization's routes. |
| [fare_rules.txt](#fare_rulestxt) | Optional | Rules for applying fare information for a transit organization's routes. |
| [shapes.txt](#shapestxt) | Optional | Rules for drawing lines on a map to represent a transit organization's routes. |
| [frequencies.txt](#frequenciestxt) | Optional | Headway (time between trips) for routes with variable frequency of service. |
| [frequencies.txt](#frequenciestxt) | Optional | Trips with variable frequency of service based on a headway (estimated time between trips) or headway-defined schedules. |
| [transfers.txt](#transferstxt) | Optional | Rules for making connections at transfer points between routes. |
| [feed_info.txt](#feed_infotxt) | Optional | Additional information about the feed itself, including publisher, version, and expiration information. |

Expand Down Expand Up @@ -379,20 +379,25 @@ Shapes describe the physical path that a vehicle takes, and are defined in the f

File: **Optional**

This table is intended to represent schedules that don't have a fixed list of stop times. When trips are defined in frequencies.txt, the trip planner ignores the absolute values of the **arrival_time** and **departure_time** fields for those trips in [stop_times.txt](#stop_timestxt). Instead, the **stop_times** table defines the sequence of stops and the time difference between each stop.
This table is used to represent two types of transit service:

* frequency-based trips - Service that does not have a schedule of stop times (**exact_times** is **0** or **empty**). Instead, operators make their best effort to serve stops periodically based on a headway. For example, a rider can expect a bus to depart approximately every 15 minutes, but the vehicle will not attempt to adhere to a preset scheduled departure time such as 10:00 am. Therefore, in the absence of real-time information, every subsequent departure is expected with a interval of **headway_secs** from the most recent departure.
* headway-defined schedules - Service that adheres to a schedule (**exact_times** is **1**). This table can be used to represent simple scheduled service based on a fixed interval without fully listing out all scheduled trips via the [trips.txt](#tripstxt) and [stop_times.txt](#stop_timestxt) files. Instead, the scheduled start time is defined in this table along with the set time between each departure (i.e., headway). Consumers will then expand this to represent scheduled service as if each of these trips were defined in [trips.txt](#tripstxt) and [stop_times.txt](#stop_timestxt).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am having trouble with the term "headway-defined schedules" for service that adheres to a schedule (exact_times is 1). I keep thinking about "headway" as particularly meaningful because of its context with customers. i.e.. "Service every 10 minutes" shows how headway is presents a "schedule" in customer-facing context. (exact_times = 0).

In transit operations, the similar term "headway-based" seems to often indicate the absence of an exact schedule. Or, at least appeared to, based on a Google search:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not in love with "headway-defined schedule" either - I'm open to proposals for how to name exact_times=1 service. "Headway" can definitely be associated with frequency-based service, but unfortunately we're stuck with the field name headway_secs for both types of service. The main rule is that we can't use the word "frequency" for exact_times=1, and we can't use "schedule" for exact_times=0.

When trips are defined in frequencies.txt, the trip planner ignores the absolute values of the **arrival_time** and **departure_time** fields for those trips in [stop_times.txt](#stop_timestxt). Instead, the **stop_times** table defines the sequence of stops and the time difference between each stop.

| Field Name | Required | Details |
| ------ | ------ | ------ |
| trip_id | **Required** | The **trip_id** contains an ID that identifies a trip on which the specified frequency of service applies. Trip IDs are referenced from the [trips.txt](#tripstxt) file. |
| start_time | **Required** | The **start_time** field specifies the time at which the first vehicle departs from the first stop of the trip with the specified frequency. The time is measured from "noon minus 12h" (effectively midnight, except for days on which daylight savings time changes occur) at the beginning of the service day. For times occurring after midnight, enter the time as a value greater than 24:00:00 in HH:MM:SS local time for the day on which the trip schedule begins. E.g. 25:35:00. |
| end_time | **Required** | The **end_time** field indicates the time at which service changes to a different frequency (or ceases) at the first stop in the trip. The time is measured from "noon minus 12h" (effectively midnight, except for days on which daylight savings time changes occur) at the beginning of the service day. For times occurring after midnight, enter the time as a value greater than 24:00:00 in HH:MM:SS local time for the day on which the trip schedule begins. E.g. 25:35:00. |
| trip_id | **Required** | The **trip_id** contains an ID that identifies a trip on which the specified headway of service applies. Trip IDs are referenced from the [trips.txt](#tripstxt) file. |
| start_time | **Required** | The **start_time** field specifies the time at which the first vehicle departs from the first stop of the trip with the specified headway. The time is measured from "noon minus 12h" (effectively midnight, except for days on which daylight savings time changes occur) at the beginning of the service day. For times occurring after midnight, enter the time as a value greater than 24:00:00 in HH:MM:SS local time for the day on which the trip schedule begins. E.g. 25:35:00. |
| end_time | **Required** | The **end_time** field indicates the time at which service changes to a different headway (or ceases) at the first stop in the trip. The time is measured from "noon minus 12h" (effectively midnight, except for days on which daylight savings time changes occur) at the beginning of the service day. For times occurring after midnight, enter the time as a value greater than 24:00:00 in HH:MM:SS local time for the day on which the trip schedule begins. E.g. 25:35:00. |
| headway_secs | **Required** | The **headway_secs** field indicates the time between departures from the same stop (headway) for this trip type, during the time interval specified by **start_time** and **end_time**. The headway value must be entered in seconds. |
| | | Periods in which headways are defined (the rows in frequencies.txt) shouldn't overlap for the same trip, since it's hard to determine what should be inferred from two overlapping headways. However, a headway period may begin at the exact same time that another one ends, for instance: |
| | | `A, 05:00:00, 07:00:00, 600` |
| | | `B, 07:00:00, 12:00:00, 1200` |
| exact_times | Optional | The **exact_times** field determines if frequency-based trips should be exactly scheduled based on the specified headway information. Valid values for this field are: |
| | |* **0** or **(empty)** - Frequency-based trips are not exactly scheduled. This is the default behavior. |
| | |* **1** - Frequency-based trips are exactly scheduled. For a frequencies.txt row, trips are scheduled starting with trip_start_time = start_time + x * headway_secs for all x in (0, 1, 2, ...) where trip_start_time < end_time. |
| exact_times | Optional | The **exact_times** field determines if trips represent frequency-based service or scheduled-based service using on the specified headway information. Valid values for this field are: |
| | |* **0** or **(empty)** - Trips are frequency-based. Operators make their best effort to serve stops periodically based on a headway, but there is no fixed schedule. This is the default behavior. |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barbeau What do you think about adding an extra note in here to specify expectations around a UI? Or is this superfluous? Proposed additions are in bold italic.

Field Name Required Details
exact_times Optional The exact_times field determines if trips represent frequency-based service or scheduled-based service using on the specified headway information. Valid values for this field are:
* 0 or (empty) - Trips are frequency-based. Operators make their best effort to serve stops periodically based on a headway, but there is no fixed schedule. A user interface should therefore not show scheduled pickup and drop-off times. This is the default behavior.
* 1 - Trips are scheduled. For a frequencies.txt row, trips are scheduled starting with trip_start_time = start_time + x * headway_secs for all x in (0, 1, 2, ...) where trip_start_time < end_time. A user interface may show scheduled pickup and drop-off times.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's not a bad idea. It helps shape expectations of how the information is used by consumers. I'll work on tweaking this.

| | |* **1** - Trips are scheduled. For a frequencies.txt row, trips are scheduled starting with trip_start_time = start_time + x * headway_secs for all x in (0, 1, 2, ...) where trip_start_time < end_time. |
| | | The value of **exact_times** must be the same for all frequencies.txt rows with the same **trip_id**. If **exact_times** is 1 and a frequencies.txt row has a **start_time** equal to **end_time**, no trip must be scheduled. When **exact_times** is 1, care must be taken to choose an **end_time** value that is greater than the last desired trip start time but less than the last desired trip start time + **headway_secs**. |

### transfers.txt
Expand Down