From dedcea3312e16a4e0b150fd05856efa4ae8e9115 Mon Sep 17 00:00:00 2001 From: barbeau Date: Tue, 7 Feb 2017 14:56:17 -0500 Subject: [PATCH] Clarify definition of "frequency-based" trip types Clearly specifies the difference between `exact_times`=0 vs 1 trips using the following definitions: * `exact_times`=0 trips are the only trips referred to as "frequency-based" * `exact_times`=1 trips are referred to as "headway-defined schedules" * When `exact_times` 0 and 1 trips are both referenced, this proposal refers to them as "trips defined in frequencies.txt" (instead of "frequency-based trips") --- gtfs-realtime/proto/gtfs-realtime.proto | 12 ++++----- .../en/examples/trip-updates-full.asciipb | 27 +++++++++++++++---- gtfs-realtime/spec/en/reference.md | 4 +-- gtfs-realtime/spec/en/trip-updates.md | 7 +++-- gtfs/spec/en/reference.md | 21 +++++++++------ 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/gtfs-realtime/proto/gtfs-realtime.proto b/gtfs-realtime/proto/gtfs-realtime.proto index 5766bc576..055bcb9e2 100644 --- a/gtfs-realtime/proto/gtfs-realtime.proto +++ b/gtfs-realtime/proto/gtfs-realtime.proto @@ -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; @@ -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 diff --git a/gtfs-realtime/spec/en/examples/trip-updates-full.asciipb b/gtfs-realtime/spec/en/examples/trip-updates-full.asciipb index cc245cf75..39bbaa4e4 100644 --- a/gtfs-realtime/spec/en/examples/trip-updates-full.asciipb +++ b/gtfs-realtime/spec/en/examples/trip-updates-full.asciipb @@ -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 { @@ -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 + } } } } diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index aa03be1ee..f90c272d6 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -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.
**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.
| -| **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 | diff --git a/gtfs-realtime/spec/en/trip-updates.md b/gtfs-realtime/spec/en/trip-updates.md index 60933605f..3d5279350 100644 --- a/gtfs-realtime/spec/en/trip-updates.md +++ b/gtfs-realtime/spec/en/trip-updates.md @@ -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. @@ -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: @@ -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__ diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 6bfd0884b..b577bddd2 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -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. | @@ -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). + +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. | +| | |* **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