diff --git a/gtfs-realtime/proto/gtfs-realtime.proto b/gtfs-realtime/proto/gtfs-realtime.proto index bd7d02ab4..44f544779 100644 --- a/gtfs-realtime/proto/gtfs-realtime.proto +++ b/gtfs-realtime/proto/gtfs-realtime.proto @@ -296,6 +296,22 @@ message TripUpdate { // formally adopted in the future. optional int32 delay = 5; + // Defines updated properties of the trip + message TripProperties { + // Defines the identifier of a new trip that is a duplicate of an existing trip defined in (CSV) GTFS trips.txt + // but will start at a different service date and/or time (defined using the TripProperties.start_date and + // TripProperties.start_time fields). See definition of trips.trip_id in (CSV) GTFS. Its value must be different + // than the ones used in the (CSV) GTFS. Required if schedule_relationship=DUPLICATED, forbidden otherwise. + optional string trip_id = 1; + // Service date on which the DUPLICATED trip will be run, in YYYYMMDD format. Required if + // schedule_relationship=DUPLICATED, forbidden otherwise. + optional string start_date = 2; + // Departure start time of the trip when it’s duplicated. See definition of stop_times.departure_time in (CSV) GTFS. + // Required if schedule_relationship=DUPLICATED, forbidden otherwise. + optional string start_time = 3; + } + optional TripProperties trip_properties = 6; + // The extensions namespace allows 3rd-party developers to extend the // GTFS Realtime Specification in order to add and evaluate new features and // modifications to the spec. @@ -564,7 +580,8 @@ 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 - // necessary. + // necessary. When schedule_relationship is DUPLICATED, the trip_id identifies the trip from static GTFS to be + // duplicated. optional string trip_id = 1; // The route_id from the GTFS that this selector refers to. @@ -613,7 +630,7 @@ message TripDescriptor { // An extra trip that was added in addition to a running schedule, for // example, to replace a broken vehicle or to respond to sudden passenger // load. - ADDED = 1; + ADDED = 1 [deprecated = true]; // A trip that is running with no schedule associated to it (GTFS frequencies.txt exact_times=0). // Trips with ScheduleRelationship=UNSCHEDULED must also set all StopTimeUpdates.ScheduleRelationship=UNSCHEDULED. @@ -623,7 +640,17 @@ message TripDescriptor { CANCELED = 3; // Should not be used - for backwards-compatibility only. - REPLACEMENT = 5 [deprecated=true]; + REPLACEMENT = 5 [deprecated = true]; + + // An extra trip that was added in addition to a running schedule, for example, to replace a broken vehicle or to + // respond to sudden passenger load. Used with TripProperties.trip_id, TripProperties.start_date, and + // TripProperties.start_time to copy an existing trip from static GTFS but start at a different service + // date and/or time. Duplicating a trip is allowed if the service related to the original trip in (CSV) GTFS + // (in calendar.txt or calendar_dates.txt) is operating within the next 30 days. The trip to be duplicated is + // identified via TripDescriptor.trip_id. This enumeration does not modify the existing trip referenced by + // TripDescriptor.trip_id - if a producer wants to cancel the original trip, it must publish a separate TripUpdate + // with the value of CANCELED. + DUPLICATED = 6; } optional ScheduleRelationship schedule_relationship = 4; diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 8f34d290c..8abee2c41 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -49,6 +49,7 @@ Fields labeled as **experimental** are subject to change and not yet formally ad * [StopTimeUpdate](#message-stoptimeupdate) * [StopTimeEvent](#message-stoptimeevent) * [ScheduleRelationship](#enum-schedulerelationship) + * [TripProperties](#message-tripproperties) * [VehiclePosition](#message-vehicleposition) * [TripDescriptor](#message-tripdescriptor) * [ScheduleRelationship](#enum-schedulerelationship-1) @@ -129,7 +130,8 @@ Depending on the value of ScheduleRelationship, a TripUpdate can specify: * A trip that proceeds along the schedule. * A trip that proceeds along a route but has no fixed schedule. -* A trip that has been added or removed with regard to schedule. +* A trip that has been canceled. +* A new trip that is a copy of an existing trip in static GTFS. It will run at the service date and time specified in TripProperties. The updates can be for future, predicted arrival/departure events, or for past events that already occurred. In most cases information about past events is a measured value thus its uncertainty value is recommended to be 0\. Although there could be cases when this does not hold so it is allowed to have uncertainty value different from 0 for past events. If an update's uncertainty is not 0, either the update is an approximate prediction for a trip that has not completed or the measurement is not precise or the update was a prediction for the past that has not been verified after the event occurred. @@ -148,6 +150,7 @@ Note that the update can describe a trip that has already completed.To this end, | **stop_time_update** | [StopTimeUpdate](#message-stoptimeupdate) | Conditionally required | Many | Updates to StopTimes for the trip (both future, i.e., predictions, and in some cases, past ones, i.e., those that already happened). The updates must be sorted by stop_sequence, and apply for all the following stops of the trip up to the next specified stop_time_update. At least one stop_time_update must be provided for the trip unless the trip.schedule_relationship is CANCELED - if the trip is canceled, no stop_time_updates need to be provided. | | **timestamp** | [uint64](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Optional | One | Moment at which the vehicle's real-time progress was measured. In POSIX time (i.e., the number of seconds since January 1st 1970 00:00:00 UTC). | | **delay** | [int32](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Optional | One | The current schedule deviation for the trip. Delay should only be specified when the prediction is given relative to some existing schedule in GTFS.
Delay (in seconds) can be positive (meaning that the vehicle is late) or negative (meaning that the vehicle is ahead of schedule). Delay of 0 means that the vehicle is exactly on time.
Delay information in StopTimeUpdates take precedent of trip-level delay information, such that trip-level delay is only propagated until the next stop along the trip with a StopTimeUpdate delay value specified.
Feed providers are strongly encouraged to provide a TripUpdate.timestamp value indicating when the delay value was last updated, in order to evaluate the freshness of the data.
**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.| +| **trip_properties** | [TripProperties](#message-tripproperties) | Optional | One | Provides the updated properties for the trip. | ## _message_ StopTimeEvent @@ -196,6 +199,18 @@ The relation between this StopTime and the static schedule. | **NO_DATA** | No data is given for this stop. It indicates that there is no realtime information available. When set NO_DATA is propagated through subsequent stops so this is the recommended way of specifying from which stop you do not have realtime information. When NO_DATA is set neither arrival nor departure should be supplied. | | **UNSCHEDULED** | The vehicle is operating a frequency-based trip (GTFS frequencies.txt with exact_times = 0). This value should not be used for trips that are not defined in GTFS frequencies.txt, or trips in GTFS frequencies.txt with exact_times = 1. Trips containing `stop_time_updates` with `schedule_relationship: UNSCHEDULED` must also set the TripDescriptor `schedule_relationship: UNSCHEDULED`
**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.
. +## _message_ TripProperties + +Defines updated properties of the trip + +#### Fields + +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------|------------|----------------|-------------------|-------------------| +| **trip_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Conditionally required | One | Defines the identifier of a new trip that is a duplicate of an existing trip defined in (CSV) GTFS trips.txt but will start at a different service date and/or time (defined using `TripProperties.start_date` and `TripProperties.start_time`). See definition of `trips.trip_id` in (CSV) GTFS. Its value must be different than the ones used in the (CSV) GTFS. This field is required if `schedule_relationship` is `DUPLICATED`, and forbidden otherwise. | +| **start_date** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Conditionally required | One | Service date on which the duplicated trip will be run. Must be provided in YYYYMMDD format. This field is required if `schedule_relationship` is `DUPLICATED`, and forbidden otherwise. | +| **start_time** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Conditionally required | One | Defines the departure start time of the trip when it’s duplicated. See definition of `stop_times.departure_time` in (CSV) GTFS. This field is required if `schedule_relationship` is `DUPLICATED`, and forbidden otherwise. | + ## _message_ VehiclePosition Realtime positioning information for a given vehicle. @@ -378,7 +393,7 @@ TripDescriptor.route_id cannot be used within an Alert EntitySelector to specify | _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | |------------------|------------|----------------|-------------------|-------------------| -| **trip_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Conditionally required | One | The trip_id from the GTFS feed that this selector refers to. For non frequency-based trips (trips not defined in GTFS frequencies.txt), this field is enough to uniquely identify the trip. For frequency-based trips defined in GTFS frequencies.txt, trip_id, start_time, and start_date are all required. For scheduled-based trips (trips not defined in GTFS frequencies.txt), trip_id can only be omitted if the trip can be uniquely identified by a combination of route_id, direction_id, start_time, and start_date, and all those fields are provided. | +| **trip_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Conditionally required | One | The trip_id from the GTFS feed that this selector refers to. For non frequency-based trips (trips not defined in GTFS frequencies.txt), this field is enough to uniquely identify the trip. For frequency-based trips defined in GTFS frequencies.txt, trip_id, start_time, and start_date are all required. For scheduled-based trips (trips not defined in GTFS frequencies.txt), trip_id can only be omitted if the trip can be uniquely identified by a combination of route_id, direction_id, start_time, and start_date, and all those fields are provided. When `schedule_relationship` is `DUPLICATED`, the `trip_id` identifies the trip from static GTFS to be duplicated. | | **route_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Conditionally required | One | The route_id from the GTFS that this selector refers to. If trip_id is omitted, route_id, direction_id, start_time, and schedule_relationship=SCHEDULED must all be set to identify a trip instance. TripDescriptor.route_id should not be used within an Alert EntitySelector to specify a route-wide alert that affects all trips for a route - use EntitySelector.route_id instead. | | **direction_id** | [uint32](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Conditionally required | One | The direction_id from the GTFS feed trips.txt file, indicating the direction of travel for trips this selector refers to. If trip_id is omitted, direction_id must be provided.
**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) | Conditionally required | One | 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 defined in GTFS frequencies.txt, start_time is required and 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 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. If trip_id is omitted, start_time must be provided. 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. | @@ -387,16 +402,16 @@ TripDescriptor.route_id cannot be used within an Alert EntitySelector to specify ## _enum_ ScheduleRelationship -The relation between this trip and the static schedule. If a trip is done in accordance with temporary schedule, not reflected in GTFS, then it shouldn't be marked as SCHEDULED, but marked as ADDED. +The relation between this trip and the static schedule. #### Values | _**Value**_ | _**Comment**_ | |-------------|---------------| | **SCHEDULED** | Trip that is running in accordance with its GTFS schedule, or is close enough to the scheduled trip to be associated with it. | -| **ADDED** | An extra trip that was added in addition to a running schedule, for example, to replace a broken vehicle or to respond to sudden passenger load. | | **UNSCHEDULED** | A trip that is running with no schedule associated to it - this value is used to identify trips defined in GTFS frequencies.txt with exact_times = 0. It should not be used to describe trips not defined in GTFS frequencies.txt, or trips in GTFS frequencies.txt with exact_times = 1. Trips with `schedule_relationship: UNSCHEDULED` must also set all StopTimeUpdates `schedule_relationship: UNSCHEDULED`| | **CANCELED** | A trip that existed in the schedule but was removed. | +| **DUPLICATED** | An extra trip that was added in addition to a running schedule, for example, to replace a broken vehicle or to respond to sudden passenger load. Used with `TripProperties.trip_id`, `TripProperties.start_date`, and `TripProperties.start_time` to copy an existing trip from static GTFS but start at a different service date and/or time. Duplicating a trip is allowed if the service related to the original trip in (CSV) GTFS (in `calendar.txt` or `calendar_dates.txt`) is operating today or within the next 30 days. The trip to be duplicated from (CSV) GTFS is identified via `TripDescriptor.trip_id`. This enumeration does not modify the existing trip referenced by `TripDescriptor.trip_id` - if a producer wants to cancel the original trip, it must publish a separate TripUpdate with the value of `CANCELED`. | ## _message_ VehicleDescriptor diff --git a/gtfs-realtime/spec/en/trip-updates.md b/gtfs-realtime/spec/en/trip-updates.md index 67ba5a653..bd3b1b33c 100644 --- a/gtfs-realtime/spec/en/trip-updates.md +++ b/gtfs-realtime/spec/en/trip-updates.md @@ -1,4 +1,4 @@ -Trip updates represent fluctuations in the timetable. We would expect to receive trip updates for all trips you have scheduled that are realtime-capable. These updates would give a predicted arrival or departure time for stops along the route. Trip updates can also provide for more complex scenarios where trips are canceled or added to the schedule, or even re-routed. +Trip updates represent fluctuations in the timetable. We would expect to receive trip updates for all trips you have scheduled that are realtime-capable. These updates would give a predicted arrival or departure time for stops along the route. **Reminder:** In [GTFS](https://developers.google.com/transit/gtfs/), a trip is a sequence of two of more stops occurring at a specific time. @@ -55,9 +55,9 @@ The information provided by the trip descriptor depends on the schedule relation |_**Value**_|_**Comment**_| |-----------|-------------| | **Scheduled** | This trip is running according to a GTFS schedule, or is close enough to still be associated with it. | -| **Added** | This trip was not scheduled and has been added. For example, to cope with demand, or replace a broken down vehicle. | | **Unscheduled** | This trip is running and is never associated with a schedule. For example, if there is no schedule and the buses run on a shuttle service. | | **Canceled** | This trip was scheduled, but is now removed. | +| **Duplicated** | This new trip is a copy of an existing trip in static GTFS. The new trip will run at the service date and time specified in TripProperties. | In most cases, you should provide the trip_id of the scheduled trip in GTFS that this update relates to.