From dc181de89a7ebf0fccf3acf5aefc2076c3c83e95 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Wed, 25 Sep 2024 16:05:47 +0100 Subject: [PATCH 01/17] specify ADDED and REPLACEMENT schedule relationships, and add more fields in TripProperties and StopTimeProperties to support fields needed for such trips --- gtfs-realtime/proto/gtfs-realtime.proto | 65 ++++++++++++++--- gtfs-realtime/spec/en/reference.md | 92 ++++++++++++++++--------- 2 files changed, 112 insertions(+), 45 deletions(-) diff --git a/gtfs-realtime/proto/gtfs-realtime.proto b/gtfs-realtime/proto/gtfs-realtime.proto index d3cfe529..943bc909 100644 --- a/gtfs-realtime/proto/gtfs-realtime.proto +++ b/gtfs-realtime/proto/gtfs-realtime.proto @@ -271,6 +271,28 @@ message TripUpdate { // (e.g., `VehiclePosition.stop_id`). // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. optional string assigned_stop_id = 1; + + // The updated headsign of the vehicle at the stop. + optional string stop_headsign = 2; + + // The updated pickup of the vehicle at the stop. + optional DropOffPickupType pickup_type = 3; + + // The updated drop off of the vehicle at the stop. + optional DropOffPickupType drop_off_type = 4; + + // The updated timing point status of the vehicle at the stop. + // If false, the vehicle will no longer wait at the stop; + // if true, the vehicle will wait until the scheduled time at the stop. + optional bool timepoint = 5; + + // Identifies the boarding booking rule at this stop time. + // Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`. + optional string pickup_booking_rule_id = 6; + + // Identifies the alighting booking rule at this stop time. + // Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`. + optional string drop_off_booking_rule_id = 7; // The extensions namespace allows 3rd-party developers to extend the // GTFS Realtime Specification in order to add and evaluate new features @@ -279,6 +301,20 @@ message TripUpdate { // The following extension IDs are reserved for private use by any organization. extensions 9000 to 9999; + + enum DropOffPickupType { + // Regularly scheduled pickup/dropoff. + REGULAR = 0; + + // No pickup/dropoff available + NONE = 1; + + // Must phone agency to arrange pickup/dropoff. + PHONE_AGENCY = 2; + + // Must coordinate with driver to arrange pickup/dropoff. + COORDINATE_WITH_DRIVER = 3; + } } // Realtime updates for certain properties defined within GTFS stop_times.txt @@ -378,6 +414,18 @@ message TripUpdate { // be marked as schedule_relationship=SKIPPED. // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. optional string shape_id = 4; + + // Specifies the headsign for this trip when it differs from the original. + // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. + optional string trip_headsign = 5; + + // Specifies the name for this trip when it differs from the original. + // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. + optional string trip_short_name = 6; + + // Specifies the block for this trip when it differs from the original. + // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. + optional string block_id = 7; // The extensions namespace allows 3rd-party developers to extend the // GTFS Realtime Specification in order to add and evaluate new features @@ -793,13 +841,7 @@ message TripDescriptor { // enough to the scheduled trip to be associated with it. SCHEDULED = 0; - // 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. - // NOTE: Currently, behavior is unspecified for feeds that use this mode. There are discussions on the GTFS GitHub - // [(1)](https://github.com/google/transit/issues/106) [(2)](https://github.com/google/transit/pull/221) - // [(3)](https://github.com/google/transit/pull/219) around fully specifying or deprecating ADDED trips and the - // documentation will be updated when those discussions are finalized. + // An extra trip unrelated to any existing trips, for example, to respond to sudden passenger load. ADDED = 1; // A trip that is running with no schedule associated to it (GTFS frequencies.txt exact_times=0). @@ -809,8 +851,8 @@ message TripDescriptor { // A trip that existed in the schedule but was removed. CANCELED = 3; - // Should not be used - for backwards-compatibility only. - REPLACEMENT = 5 [deprecated=true]; + // A trip that replaces an existing trip in the schedule. + REPLACEMENT = 5; // 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 TripUpdate.TripProperties.trip_id, TripUpdate.TripProperties.start_date, @@ -818,8 +860,9 @@ message TripDescriptor { // 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 TripUpdate.TripDescriptor.trip_id. This enumeration does not modify the existing trip referenced by - // TripUpdate.TripDescriptor.trip_id - if a producer wants to cancel the original trip, it must publish a separate - // TripUpdate with the value of CANCELED or DELETED. Trips defined in GTFS frequencies.txt with exact_times that is + // TripUpdate.TripDescriptor.trip_id - if a producer wants to replace the original trip, a value of `REPLACEMENT` should be used instead. + // + // Trips defined in GTFS frequencies.txt with exact_times that is // empty or equal to 0 cannot be duplicated. The VehiclePosition.TripDescriptor.trip_id for the new trip must contain // the matching value from TripUpdate.TripProperties.trip_id and VehiclePosition.TripDescriptor.ScheduleRelationship // must also be set to DUPLICATED. diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 801762be..35b34032 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -144,6 +144,7 @@ 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 replaces an existing trip in static GTFS. * 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. @@ -157,14 +158,14 @@ Note that the update can describe a trip that has already completed.To this end, **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|------------------|------------|----------------|-------------------|-------------------| -| **trip** | [TripDescriptor](#message-tripdescriptor) | Required | One | The Trip that this message applies to. There can be at most one TripUpdate entity for each actual trip instance. If there is none, that means there is no prediction information available. It does *not* mean that the trip is progressing according to schedule. | -| **vehicle** | [VehicleDescriptor](#message-vehicledescriptor) | Optional | One | Additional information on the vehicle that is serving this trip. | -| **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, DELETED, or DUPLICATED. If the trip is canceled or deleted, no stop_time_updates need to be provided. If stop_time_updates are provided for a canceled or deleted trip then the trip.schedule_relationship takes precedence over any stop_time_updates and their associated schedule_relationship. If the trip is duplicated, stop_time_updates may be provided to indicate real-time information for the new trip. | -| **timestamp** | [uint64](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The most recent moment at which the vehicle's real-time progress was measured to estimate StopTimes in the future. When StopTimes in the past are provided, arrival/departure times may be earlier than this value. In POSIX time (i.e., the number of seconds since January 1st 1970 00:00:00 UTC). | -| **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#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.

**Caution:** this message is still **experimental**, and subject to change. It may be formally adopted in the future. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|----------------------|------------------------------------------------------------------|------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **trip** | [TripDescriptor](#message-tripdescriptor) | Required | One | The Trip that this message applies to. There can be at most one TripUpdate entity for each actual trip instance. If there is none, that means there is no prediction information available. It does *not* mean that the trip is progressing according to schedule. | +| **vehicle** | [VehicleDescriptor](#message-vehicledescriptor) | Optional | One | Additional information on the vehicle that is serving this trip. | +| **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.
If trip.schedule_relationship is SCHEDULED, at least one stop_time_update must be provided for the trip.
If trip.schedule_relationship is ADDED or REPLACEMENT, stop_time_updates must be provided for all stops in the added or replacement trip, and the stop times in the static GTFS are not used.
If the trip is canceled or deleted, no stop_time_updates need to be provided. If stop_time_updates are provided for a canceled or deleted trip then the trip.schedule_relationship takes precedence over any stop_time_updates and their associated schedule_relationship. If the trip is duplicated, stop_time_updates may be provided to indicate real-time information for the new trip. | +| **timestamp** | [uint64](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The most recent moment at which the vehicle's real-time progress was measured to estimate StopTimes in the future. When StopTimes in the past are provided, arrival/departure times may be earlier than this value. In POSIX time (i.e., the number of seconds since January 1st 1970 00:00:00 UTC). | +| **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#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.

**Caution:** this message is still **experimental**, and subject to change. It may be formally adopted in the future. | ## _message_ StopTimeEvent @@ -223,9 +224,26 @@ Realtime update for certain properties defined within GTFS stop_times.txt. **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|------------------|------------|----------------|-------------------|-------------------| -| **assigned_stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Supports real-time stop assignments. Refers to a `stop_id` defined in the GTFS `stops.txt`.
The new `assigned_stop_id` should not result in a significantly different trip experience for the end user than the `stop_id` defined in GTFS `stop_times.txt`. In other words, the end user should not view this new `stop_id` as an "unusual change" if the new stop was presented within an app without any additional context. For example, this field is intended to be used for platform assignments by using a `stop_id` that belongs to the same station as the stop originally defined in GTFS `stop_times.txt`.
To assign a stop without providing any real-time arrival or departure predictions, populate this field and set `StopTimeUpdate.schedule_relationship = NO_DATA`.
If this field is populated, `StopTimeUpdate.stop_sequence` must be populated and `StopTimeUpdate.stop_id` should not be populated. Stop assignments should be reflected in other GTFS-realtime fields as well (e.g., `VehiclePosition.stop_id`).

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------------------|------------------------------------------------------------------|----------------|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **assigned_stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Supports real-time stop assignments. Refers to a `stop_id` defined in the GTFS `stops.txt`.
The new `assigned_stop_id` should not result in a significantly different trip experience for the end user than the `stop_id` defined in GTFS `stop_times.txt`. In other words, the end user should not view this new `stop_id` as an "unusual change" if the new stop was presented within an app without any additional context. For example, this field is intended to be used for platform assignments by using a `stop_id` that belongs to the same station as the stop originally defined in GTFS `stop_times.txt`.
To assign a stop without providing any real-time arrival or departure predictions, populate this field and set `StopTimeUpdate.schedule_relationship = NO_DATA`.
If this field is populated, `StopTimeUpdate.stop_sequence` must be populated and `StopTimeUpdate.stop_id` should not be populated. Stop assignments should be reflected in other GTFS-realtime fields as well (e.g., `VehiclePosition.stop_id`).

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **stop_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated headsign of the vehicle at the stop. | +| **drop_off_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated drop off of the vehicle at the stop. | +| **pickup_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated pickup of the vehicle at the stop. | +| **timepoint** | [bool](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated timing point status of the vehicle at the stop. If false, the vehicle will no longer wait at the stop; if true, the vehicle will wait until the scheduled time at the stop. | +| **pickup_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the boarding booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `pickup_type=PHONE_AGENCY`. | +| **drop_off_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the alighting booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `drop_off_type=PHONE_AGENCY`. | + +## _enum_ DropOffPickupType + +**Values** + +| _**Value**_ | _**Comment**_ | +|----------------------------|--------------------------------------------------------| +| **REGULAR** | Regularly scheduled pickup/dropoff. | +| **NONE** | No pickup/dropoff available. | +| **PHONE_AGENCY** | Must phone agency to arrange pickup/dropoff. | +| **COORDINATE_WITH_DRIVER** | Must coordinate with driver to arrange pickup/dropoff. | ## _message_ TripProperties @@ -235,12 +253,15 @@ Defines updated properties of the trip **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|------------------|------------|----------------|-------------------|-------------------| -| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **start_time** | [string](https://protobuf.dev/programming-guides/proto2/#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. Scheduled arrival and departure times for the duplicated trip are calculated based on the offset between the original trip `departure_time` and this field. For example, if a GTFS trip has stop A with a `departure_time` of `10:00:00` and stop B with `departure_time` of `10:01:00`, and this field is populated with the value of `10:30:00`, stop B on the duplicated trip will have a scheduled `departure_time` of `10:31:00`. Real-time prediction `delay` values are applied to this calculated schedule time to determine the predicted time. For example, if a departure `delay` of `30` is provided for stop B, then the predicted departure time is `10:31:30`. Real-time prediction `time` values do not have any offset applied to them and indicate the predicted time as provided. For example, if a departure `time` representing 10:31:30 is provided for stop B, then the predicted departure time is `10:31:30`.This field is required if `schedule_relationship` is `DUPLICATED`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the shape of the vehicle travel path for this trip when it differs from the original. Refers to a shape defined in the (CSV) GTFS or a new shape entity in a real-time feed. See definition of `trips.shape_id` in (CSV) GTFS.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|---------------------|------------|----------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **start_time** | [string](https://protobuf.dev/programming-guides/proto2/#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. Scheduled arrival and departure times for the duplicated trip are calculated based on the offset between the original trip `departure_time` and this field. For example, if a GTFS trip has stop A with a `departure_time` of `10:00:00` and stop B with `departure_time` of `10:01:00`, and this field is populated with the value of `10:30:00`, stop B on the duplicated trip will have a scheduled `departure_time` of `10:31:00`. Real-time prediction `delay` values are applied to this calculated schedule time to determine the predicted time. For example, if a departure `delay` of `30` is provided for stop B, then the predicted departure time is `10:31:30`. Real-time prediction `time` values do not have any offset applied to them and indicate the predicted time as provided. For example, if a departure `time` representing 10:31:30 is provided for stop B, then the predicted departure time is `10:31:30`.This field is required if `schedule_relationship` is `DUPLICATED`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **trip_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the headsign for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **trip_short_name** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the name for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **block_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the block for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the shape of the vehicle travel path for this trip when it differs from the original. Refers to a shape defined in the (CSV) GTFS or a new shape entity in a real-time feed. See definition of `trips.shape_id` in (CSV) GTFS.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | ## _message_ VehiclePosition @@ -453,29 +474,32 @@ TripDescriptor.route_id cannot be used within an Alert EntitySelector to specify **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|------------------|------------|----------------|-------------------|-------------------| -| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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 within a TripUpdate, the trip_id identifies the trip from static GTFS to be duplicated. When schedule_relationship is DUPLICATED within a VehiclePosition, the trip_id identifies the new duplicate trip and must contain the value for the corresponding TripUpdate.TripProperties.trip_id. | -| **route_id** | [string](https://protobuf.dev/programming-guides/proto2/#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://protobuf.dev/programming-guides/proto2/#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://protobuf.dev/programming-guides/proto2/#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. | -| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | The start date of this trip instance in YYYYMMDD format. For scheduled trips (trips not defined in GTFS frequencies.txt), 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. This field is required for frequency-based trips defined in GTFS frequencies.txt. If trip_id is omitted, start_date must be provided. | -| **schedule_relationship** | [ScheduleRelationship](#enum-schedulerelationship-1) | Optional | One | The relation between this trip and the static schedule. If TripDescriptor is provided in an Alert `EntitySelector`, the `schedule_relationship` field is ignored by consumers when identifying the matching trip instance. +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|---------------------------|------------------------------------------------------------------|------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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 ADDED, it must be specified with a unique value not exist in the GTFS static, When schedule_relationship is DUPLICATED within a TripUpdate, the trip_id identifies the trip from static GTFS to be duplicated. When schedule_relationship is DUPLICATED within a VehiclePosition, the trip_id identifies the new duplicate trip and must contain the value for the corresponding TripUpdate.TripProperties.trip_id. | +| **route_id** | [string](https://protobuf.dev/programming-guides/proto2/#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. If schedule_relationship=ADDED, route_id specifies the route which the added trip belongs to. | +| **direction_id** | [uint32](https://protobuf.dev/programming-guides/proto2/#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://protobuf.dev/programming-guides/proto2/#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. | +| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | The start date of this trip instance in YYYYMMDD format. For scheduled trips (trips not defined in GTFS frequencies.txt), 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. This field is required for frequency-based trips defined in GTFS frequencies.txt. If trip_id is omitted, start_date must be provided. | +| **schedule_relationship** | [ScheduleRelationship](#enum-schedulerelationship-1) | Optional | One | The relation between this trip and the static schedule. If TripDescriptor is provided in an Alert `EntitySelector`, the `schedule_relationship` field is ignored by consumers when identifying the matching trip instance. | ## _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.
+If a new trip is done in accordance with temporary schedule, not reflected in GTFS, then it shouldn't be marked as SCHEDULED, but marked as ADDED.
+If a trip is done in accordance with a modified schedule, not reflected in GTFS, then it shouldn't be marked as SCHEDULED, but marked as REPLACEMENT.
**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. *NOTE: Currently, behavior is unspecified for feeds that use this mode. There are discussions on the GTFS GitHub [(1)](https://github.com/google/transit/issues/106) [(2)](https://github.com/google/transit/pull/221) [(3)](https://github.com/google/transit/pull/219) around fully specifying or deprecating ADDED trips and the documentation will be updated when those discussions are finalized.* | -| **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** | A new trip that is the same as an existing scheduled trip except for service start date and time. Used with `TripUpdate.TripProperties.trip_id`, `TripUpdate.TripProperties.start_date`, and `TripUpdate.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 `TripUpdate.TripDescriptor.trip_id`.

This enumeration does not modify the existing trip referenced by `TripUpdate.TripDescriptor.trip_id` - if a producer wants to cancel the original trip, it must publish a separate `TripUpdate` with the value of CANCELED. Trips defined in GTFS `frequencies.txt` with `exact_times` that is empty or equal to `0` cannot be duplicated. The `VehiclePosition.TripDescriptor.trip_id` for the new trip must contain the matching value from `TripUpdate.TripProperties.trip_id` and `VehiclePosition.TripDescriptor.ScheduleRelationship` must also be set to `DUPLICATED`.

*Existing producers and consumers that were using the ADDED enumeration to represent duplicated trips must follow the [migration guide](/gtfs-realtime/spec/en/examples/migration-duplicated.md) to transition to the DUPLICATED enumeration.* | -| **DELETED** | A trip that existed in the schedule but was removed that must not be shown to users.

DELETED should be used instead of CANCELED to indicate that a transit provider would like to entirely remove information about the corresponding trip from consuming applications, so the trip is not shown as cancelled to riders, e.g. a trip that is entirely being replaced by another trip. This designation becomes particularly important if several trips are cancelled and replaced with substitute service. If consumers were to show explicit information about the cancellations it would distract from the more important real-time predictions.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| _**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 unrelated to any existing trips, for example, to respond to sudden passenger load. The complete journey of the added trip must be specified via `StopTimeUpdate`s. | +| **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. | +| **REPLACEMENT** | A trip that replaces an existing scheduled trip, for example, with a changed schedule or a diverted route. The complete journey of the replacement trip must be specified via `StopTimeUpdate`s, and the original schedule from the GTFS static isn't used for the replaced instance. | +| **DUPLICATED** | A new trip that is the same as an existing scheduled trip except for service start date and time. Used with `TripUpdate.TripProperties.trip_id`, `TripUpdate.TripProperties.start_date`, and `TripUpdate.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 `TripUpdate.TripDescriptor.trip_id`.

This enumeration does not modify the existing trip referenced by `TripUpdate.TripDescriptor.trip_id` - if a producer wants to replace the original trip, a value of `REPLACEMENT` should be used instead. Trips defined in GTFS `frequencies.txt` with `exact_times` that is empty or equal to `0` cannot be duplicated. The `VehiclePosition.TripDescriptor.trip_id` for the new trip must contain the matching value from `TripUpdate.TripProperties.trip_id` and `VehiclePosition.TripDescriptor.ScheduleRelationship` must also be set to `DUPLICATED`.

*Existing producers and consumers that were using the ADDED enumeration to represent duplicated trips must follow the [migration guide](/gtfs-realtime/spec/en/examples/migration-duplicated.md) to transition to the DUPLICATED enumeration.* | +| **DELETED** | A trip that existed in the schedule but was removed that must not be shown to users.

DELETED should be used instead of CANCELED to indicate that a transit provider would like to entirely remove information about the corresponding trip from consuming applications, so the trip is not shown as cancelled to riders, e.g. a trip that is entirely being replaced by another trip. This designation becomes particularly important if several trips are cancelled and replaced with substitute service. If consumers were to show explicit information about the cancellations it would distract from the more important real-time predictions.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | ## _message_ VehicleDescriptor From b439cf86ece12fe585bf94d2cf9d8ceabd5d19da Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Wed, 25 Sep 2024 16:19:44 +0100 Subject: [PATCH 02/17] remove the recommendation that ADDED is not specified --- gtfs-realtime/best-practices/best-practices.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gtfs-realtime/best-practices/best-practices.md b/gtfs-realtime/best-practices/best-practices.md index 4956a1b5..3e577946 100644 --- a/gtfs-realtime/best-practices/best-practices.md +++ b/gtfs-realtime/best-practices/best-practices.md @@ -71,10 +71,6 @@ If separate `VehiclePosition` and `TripUpdate` feeds are provided, [TripDescript For example, a `VehiclePosition` entity has `vehicle_id:A` and `trip_id:4`, then the corresponding `TripUpdate` entity should also have `vehicle_id:A` and `trip_id:4`. -| Field Name | Recommendation | -| --- | --- | -| `schedule_relationship` | The behavior of `ADDED` trips are unspecified and the use of this enumeration is not recommended. | - ### VehicleDescriptor If separate `VehiclePosition` and `TripUpdate` feeds are provided, [TripDescriptor](#TripDescriptor) and [VehicleDescriptor](#VehicleDescriptor) ID values pairing should match between the two feeds. From 5a9853f3879a89116af14887e213eb38d4e0d129 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Wed, 25 Sep 2024 16:52:38 +0100 Subject: [PATCH 03/17] disallow TripModification on trips with TripUpdate.schedule_relationship=REPLACEMENT --- gtfs-realtime/proto/gtfs-realtime.proto | 2 +- gtfs-realtime/spec/en/reference.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gtfs-realtime/proto/gtfs-realtime.proto b/gtfs-realtime/proto/gtfs-realtime.proto index 943bc909..fa25c8b8 100644 --- a/gtfs-realtime/proto/gtfs-realtime.proto +++ b/gtfs-realtime/proto/gtfs-realtime.proto @@ -1160,7 +1160,7 @@ message TripModifications { } message SelectedTrips { - // A list of trips affected with this replacement that all have the same new `shape_id`. + // A list of trips affected with this replacement that all have the same new `shape_id`. A `TripUpdate` with `schedule_relationship=REPLACEMENT` must not already exist for the trip. repeated string trip_ids = 1; // The ID of the new shape for the modified trips in this SelectedTrips. // May refer to a new shape added using a GTFS-RT Shape message, or to an existing shape defined in the GTFS-Static feed’s shapes.txt. diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 35b34032..87ca2ea8 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -695,10 +695,10 @@ List of selected trips with an associated shape. **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|------------------|------------|----------------|-------------------|-------------------| -| **trip_ids** | [uint32](https://protobuf.dev/programming-guides/proto2/#scalar) | Many | One | A list of trip_id from the original (CSV) GTFS that are affected by the containing replacement. Need to contain at least one trip_id. | -| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Required | One | The ID of the new shape for the modified trips in this SelectedTrips. May refer to a new shape added using a GTFS-RT Shape message, or to an existing shape defined in the GTFS-Static feed’s shapes.txt. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------|------------------------------------------------------------------|----------------|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **trip_ids** | [uint32](https://protobuf.dev/programming-guides/proto2/#scalar) | Many | One | A list of trip_id from the original (CSV) GTFS that are affected by the containing replacement. Need to contain at least one trip_id. A `TripUpdate` with `schedule_relationship=REPLACEMENT` must not already exist for the trip. | +| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Required | One | The ID of the new shape for the modified trips in this SelectedTrips. May refer to a new shape added using a GTFS-RT Shape message, or to an existing shape defined in the GTFS-Static feed’s shapes.txt. | ## _message_ ReplacementStop From 21ccde59242ade4aa84639c5bf0c9ccde06c71e7 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Thu, 26 Sep 2024 14:22:15 +0100 Subject: [PATCH 04/17] revert formatting --- gtfs-realtime/spec/en/reference.md | 94 +++++++++++++++--------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 87ca2ea8..86ab0c39 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -158,14 +158,14 @@ Note that the update can describe a trip that has already completed.To this end, **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|----------------------|------------------------------------------------------------------|------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **trip** | [TripDescriptor](#message-tripdescriptor) | Required | One | The Trip that this message applies to. There can be at most one TripUpdate entity for each actual trip instance. If there is none, that means there is no prediction information available. It does *not* mean that the trip is progressing according to schedule. | -| **vehicle** | [VehicleDescriptor](#message-vehicledescriptor) | Optional | One | Additional information on the vehicle that is serving this trip. | -| **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.
If trip.schedule_relationship is SCHEDULED, at least one stop_time_update must be provided for the trip.
If trip.schedule_relationship is ADDED or REPLACEMENT, stop_time_updates must be provided for all stops in the added or replacement trip, and the stop times in the static GTFS are not used.
If the trip is canceled or deleted, no stop_time_updates need to be provided. If stop_time_updates are provided for a canceled or deleted trip then the trip.schedule_relationship takes precedence over any stop_time_updates and their associated schedule_relationship. If the trip is duplicated, stop_time_updates may be provided to indicate real-time information for the new trip. | -| **timestamp** | [uint64](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The most recent moment at which the vehicle's real-time progress was measured to estimate StopTimes in the future. When StopTimes in the past are provided, arrival/departure times may be earlier than this value. In POSIX time (i.e., the number of seconds since January 1st 1970 00:00:00 UTC). | -| **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#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.

**Caution:** this message is still **experimental**, and subject to change. It may be formally adopted in the future. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------|------------|----------------|-------------------|-------------------| +| **trip** | [TripDescriptor](#message-tripdescriptor) | Required | One | The Trip that this message applies to. There can be at most one TripUpdate entity for each actual trip instance. If there is none, that means there is no prediction information available. It does *not* mean that the trip is progressing according to schedule. | +| **vehicle** | [VehicleDescriptor](#message-vehicledescriptor) | Optional | One | Additional information on the vehicle that is serving this trip. | +| **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.
If trip.schedule_relationship is SCHEDULED, at least one stop_time_update must be provided for the trip.
If trip.schedule_relationship is ADDED or REPLACEMENT, stop_time_updates must be provided for all stops in the added or replacement trip, and the stop times in the static GTFS are not used.
If the trip is canceled or deleted, no stop_time_updates need to be provided. If stop_time_updates are provided for a canceled or deleted trip then the trip.schedule_relationship takes precedence over any stop_time_updates and their associated schedule_relationship. If the trip is duplicated, stop_time_updates may be provided to indicate real-time information for the new trip. | +| **timestamp** | [uint64](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The most recent moment at which the vehicle's real-time progress was measured to estimate StopTimes in the future. When StopTimes in the past are provided, arrival/departure times may be earlier than this value. In POSIX time (i.e., the number of seconds since January 1st 1970 00:00:00 UTC). | +| **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#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.

**Caution:** this message is still **experimental**, and subject to change. It may be formally adopted in the future. | ## _message_ StopTimeEvent @@ -224,15 +224,15 @@ Realtime update for certain properties defined within GTFS stop_times.txt. **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|------------------------------|------------------------------------------------------------------|----------------|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **assigned_stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Supports real-time stop assignments. Refers to a `stop_id` defined in the GTFS `stops.txt`.
The new `assigned_stop_id` should not result in a significantly different trip experience for the end user than the `stop_id` defined in GTFS `stop_times.txt`. In other words, the end user should not view this new `stop_id` as an "unusual change" if the new stop was presented within an app without any additional context. For example, this field is intended to be used for platform assignments by using a `stop_id` that belongs to the same station as the stop originally defined in GTFS `stop_times.txt`.
To assign a stop without providing any real-time arrival or departure predictions, populate this field and set `StopTimeUpdate.schedule_relationship = NO_DATA`.
If this field is populated, `StopTimeUpdate.stop_sequence` must be populated and `StopTimeUpdate.stop_id` should not be populated. Stop assignments should be reflected in other GTFS-realtime fields as well (e.g., `VehiclePosition.stop_id`).

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **stop_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated headsign of the vehicle at the stop. | -| **drop_off_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated drop off of the vehicle at the stop. | -| **pickup_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated pickup of the vehicle at the stop. | -| **timepoint** | [bool](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated timing point status of the vehicle at the stop. If false, the vehicle will no longer wait at the stop; if true, the vehicle will wait until the scheduled time at the stop. | -| **pickup_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the boarding booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `pickup_type=PHONE_AGENCY`. | -| **drop_off_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the alighting booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `drop_off_type=PHONE_AGENCY`. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------|------------|----------------|-------------------|-------------------| +| **assigned_stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Supports real-time stop assignments. Refers to a `stop_id` defined in the GTFS `stops.txt`.
The new `assigned_stop_id` should not result in a significantly different trip experience for the end user than the `stop_id` defined in GTFS `stop_times.txt`. In other words, the end user should not view this new `stop_id` as an "unusual change" if the new stop was presented within an app without any additional context. For example, this field is intended to be used for platform assignments by using a `stop_id` that belongs to the same station as the stop originally defined in GTFS `stop_times.txt`.
To assign a stop without providing any real-time arrival or departure predictions, populate this field and set `StopTimeUpdate.schedule_relationship = NO_DATA`.
If this field is populated, `StopTimeUpdate.stop_sequence` must be populated and `StopTimeUpdate.stop_id` should not be populated. Stop assignments should be reflected in other GTFS-realtime fields as well (e.g., `VehiclePosition.stop_id`).

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **stop_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated headsign of the vehicle at the stop. | +| **drop_off_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated drop off of the vehicle at the stop. | +| **pickup_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated pickup of the vehicle at the stop. | +| **timepoint** | [bool](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated timing point status of the vehicle at the stop. If false, the vehicle will no longer wait at the stop; if true, the vehicle will wait until the scheduled time at the stop. | +| **pickup_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the boarding booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `pickup_type=PHONE_AGENCY`. | +| **drop_off_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the alighting booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `drop_off_type=PHONE_AGENCY`. | ## _enum_ DropOffPickupType @@ -253,15 +253,15 @@ Defines updated properties of the trip **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|---------------------|------------|----------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **start_time** | [string](https://protobuf.dev/programming-guides/proto2/#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. Scheduled arrival and departure times for the duplicated trip are calculated based on the offset between the original trip `departure_time` and this field. For example, if a GTFS trip has stop A with a `departure_time` of `10:00:00` and stop B with `departure_time` of `10:01:00`, and this field is populated with the value of `10:30:00`, stop B on the duplicated trip will have a scheduled `departure_time` of `10:31:00`. Real-time prediction `delay` values are applied to this calculated schedule time to determine the predicted time. For example, if a departure `delay` of `30` is provided for stop B, then the predicted departure time is `10:31:30`. Real-time prediction `time` values do not have any offset applied to them and indicate the predicted time as provided. For example, if a departure `time` representing 10:31:30 is provided for stop B, then the predicted departure time is `10:31:30`.This field is required if `schedule_relationship` is `DUPLICATED`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **trip_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the headsign for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **trip_short_name** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the name for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **block_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the block for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the shape of the vehicle travel path for this trip when it differs from the original. Refers to a shape defined in the (CSV) GTFS or a new shape entity in a real-time feed. See definition of `trips.shape_id` in (CSV) GTFS.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------|------------|----------------|-------------------|-------------------| +| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#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`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **start_time** | [string](https://protobuf.dev/programming-guides/proto2/#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. Scheduled arrival and departure times for the duplicated trip are calculated based on the offset between the original trip `departure_time` and this field. For example, if a GTFS trip has stop A with a `departure_time` of `10:00:00` and stop B with `departure_time` of `10:01:00`, and this field is populated with the value of `10:30:00`, stop B on the duplicated trip will have a scheduled `departure_time` of `10:31:00`. Real-time prediction `delay` values are applied to this calculated schedule time to determine the predicted time. For example, if a departure `delay` of `30` is provided for stop B, then the predicted departure time is `10:31:30`. Real-time prediction `time` values do not have any offset applied to them and indicate the predicted time as provided. For example, if a departure `time` representing 10:31:30 is provided for stop B, then the predicted departure time is `10:31:30`.This field is required if `schedule_relationship` is `DUPLICATED`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **trip_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the headsign for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **trip_short_name** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the name for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **block_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the block for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the shape of the vehicle travel path for this trip when it differs from the original. Refers to a shape defined in the (CSV) GTFS or a new shape entity in a real-time feed. See definition of `trips.shape_id` in (CSV) GTFS.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | ## _message_ VehiclePosition @@ -474,14 +474,14 @@ TripDescriptor.route_id cannot be used within an Alert EntitySelector to specify **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|---------------------------|------------------------------------------------------------------|------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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 ADDED, it must be specified with a unique value not exist in the GTFS static, When schedule_relationship is DUPLICATED within a TripUpdate, the trip_id identifies the trip from static GTFS to be duplicated. When schedule_relationship is DUPLICATED within a VehiclePosition, the trip_id identifies the new duplicate trip and must contain the value for the corresponding TripUpdate.TripProperties.trip_id. | -| **route_id** | [string](https://protobuf.dev/programming-guides/proto2/#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. If schedule_relationship=ADDED, route_id specifies the route which the added trip belongs to. | -| **direction_id** | [uint32](https://protobuf.dev/programming-guides/proto2/#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://protobuf.dev/programming-guides/proto2/#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. | -| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | The start date of this trip instance in YYYYMMDD format. For scheduled trips (trips not defined in GTFS frequencies.txt), 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. This field is required for frequency-based trips defined in GTFS frequencies.txt. If trip_id is omitted, start_date must be provided. | -| **schedule_relationship** | [ScheduleRelationship](#enum-schedulerelationship-1) | Optional | One | The relation between this trip and the static schedule. If TripDescriptor is provided in an Alert `EntitySelector`, the `schedule_relationship` field is ignored by consumers when identifying the matching trip instance. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------|------------|----------------|-------------------|-------------------| +| **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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 ADDED, it must be specified with a unique value not exist in the GTFS static, When schedule_relationship is DUPLICATED within a TripUpdate, the trip_id identifies the trip from static GTFS to be duplicated. When schedule_relationship is DUPLICATED within a VehiclePosition, the trip_id identifies the new duplicate trip and must contain the value for the corresponding TripUpdate.TripProperties.trip_id. | +| **route_id** | [string](https://protobuf.dev/programming-guides/proto2/#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. If schedule_relationship=ADDED, route_id specifies the route which the added trip belongs to. | +| **direction_id** | [uint32](https://protobuf.dev/programming-guides/proto2/#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://protobuf.dev/programming-guides/proto2/#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. | +| **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | The start date of this trip instance in YYYYMMDD format. For scheduled trips (trips not defined in GTFS frequencies.txt), 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. This field is required for frequency-based trips defined in GTFS frequencies.txt. If trip_id is omitted, start_date must be provided. | +| **schedule_relationship** | [ScheduleRelationship](#enum-schedulerelationship-1) | Optional | One | The relation between this trip and the static schedule. If TripDescriptor is provided in an Alert `EntitySelector`, the `schedule_relationship` field is ignored by consumers when identifying the matching trip instance. ## _enum_ ScheduleRelationship @@ -491,15 +491,15 @@ If a trip is done in accordance with a modified schedule, not reflected in GTFS, **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 unrelated to any existing trips, for example, to respond to sudden passenger load. The complete journey of the added trip must be specified via `StopTimeUpdate`s. | -| **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. | -| **REPLACEMENT** | A trip that replaces an existing scheduled trip, for example, with a changed schedule or a diverted route. The complete journey of the replacement trip must be specified via `StopTimeUpdate`s, and the original schedule from the GTFS static isn't used for the replaced instance. | -| **DUPLICATED** | A new trip that is the same as an existing scheduled trip except for service start date and time. Used with `TripUpdate.TripProperties.trip_id`, `TripUpdate.TripProperties.start_date`, and `TripUpdate.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 `TripUpdate.TripDescriptor.trip_id`.

This enumeration does not modify the existing trip referenced by `TripUpdate.TripDescriptor.trip_id` - if a producer wants to replace the original trip, a value of `REPLACEMENT` should be used instead. Trips defined in GTFS `frequencies.txt` with `exact_times` that is empty or equal to `0` cannot be duplicated. The `VehiclePosition.TripDescriptor.trip_id` for the new trip must contain the matching value from `TripUpdate.TripProperties.trip_id` and `VehiclePosition.TripDescriptor.ScheduleRelationship` must also be set to `DUPLICATED`.

*Existing producers and consumers that were using the ADDED enumeration to represent duplicated trips must follow the [migration guide](/gtfs-realtime/spec/en/examples/migration-duplicated.md) to transition to the DUPLICATED enumeration.* | -| **DELETED** | A trip that existed in the schedule but was removed that must not be shown to users.

DELETED should be used instead of CANCELED to indicate that a transit provider would like to entirely remove information about the corresponding trip from consuming applications, so the trip is not shown as cancelled to riders, e.g. a trip that is entirely being replaced by another trip. This designation becomes particularly important if several trips are cancelled and replaced with substitute service. If consumers were to show explicit information about the cancellations it would distract from the more important real-time predictions.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | +| _**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 unrelated to any existing trips, for example, to respond to sudden passenger load. The complete journey of the added trip must be specified via `StopTimeUpdate`s. | +| **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. | +| **REPLACEMENT** | A trip that replaces an existing scheduled trip, for example, with a changed schedule or a diverted route. The complete journey of the replacement trip must be specified via `StopTimeUpdate`s, and the original schedule from the GTFS static isn't used for the replaced instance. | +| **DUPLICATED** | A new trip that is the same as an existing scheduled trip except for service start date and time. Used with `TripUpdate.TripProperties.trip_id`, `TripUpdate.TripProperties.start_date`, and `TripUpdate.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 `TripUpdate.TripDescriptor.trip_id`.

This enumeration does not modify the existing trip referenced by `TripUpdate.TripDescriptor.trip_id` - if a producer wants to cancel the original trip, it must publish a separate `TripUpdate` with the value of CANCELED. Trips defined in GTFS `frequencies.txt` with `exact_times` that is empty or equal to `0` cannot be duplicated. The `VehiclePosition.TripDescriptor.trip_id` for the new trip must contain the matching value from `TripUpdate.TripProperties.trip_id` and `VehiclePosition.TripDescriptor.ScheduleRelationship` must also be set to `DUPLICATED`.

*Existing producers and consumers that were using the ADDED enumeration to represent duplicated trips must follow the [migration guide](/gtfs-realtime/spec/en/examples/migration-duplicated.md) to transition to the DUPLICATED enumeration.* | +| **DELETED** | A trip that existed in the schedule but was removed that must not be shown to users.

DELETED should be used instead of CANCELED to indicate that a transit provider would like to entirely remove information about the corresponding trip from consuming applications, so the trip is not shown as cancelled to riders, e.g. a trip that is entirely being replaced by another trip. This designation becomes particularly important if several trips are cancelled and replaced with substitute service. If consumers were to show explicit information about the cancellations it would distract from the more important real-time predictions.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | ## _message_ VehicleDescriptor @@ -695,10 +695,10 @@ List of selected trips with an associated shape. **Fields** -| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | -|------------------|------------------------------------------------------------------|----------------|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **trip_ids** | [uint32](https://protobuf.dev/programming-guides/proto2/#scalar) | Many | One | A list of trip_id from the original (CSV) GTFS that are affected by the containing replacement. Need to contain at least one trip_id. A `TripUpdate` with `schedule_relationship=REPLACEMENT` must not already exist for the trip. | -| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Required | One | The ID of the new shape for the modified trips in this SelectedTrips. May refer to a new shape added using a GTFS-RT Shape message, or to an existing shape defined in the GTFS-Static feed’s shapes.txt. | +| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | +|------------------|------------|----------------|-------------------|-------------------| +| **trip_ids** | [uint32](https://protobuf.dev/programming-guides/proto2/#scalar) | Many | One | A list of trip_id from the original (CSV) GTFS that are affected by the containing replacement. Need to contain at least one trip_id. A `TripUpdate` with `schedule_relationship=REPLACEMENT` must not already exist for the trip. | +| **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Required | One | The ID of the new shape for the modified trips in this SelectedTrips. May refer to a new shape added using a GTFS-RT Shape message, or to an existing shape defined in the GTFS-Static feed’s shapes.txt. | ## _message_ ReplacementStop From b6d07cce5048f07efcd6e981799b8795960fb80c Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Thu, 26 Sep 2024 14:39:27 +0100 Subject: [PATCH 05/17] specify that route_id is required for added trips --- gtfs-realtime/spec/en/reference.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 86ab0c39..e432be96 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -456,7 +456,7 @@ A geographic position of a vehicle. ## _message_ TripDescriptor -A descriptor that identifies a single instance of a GTFS trip. +A descriptor that identifies a single instance of a GTFS trip, unless `schedule_relationship` is `ADDED`, in such case, it specifies a new instance of trip to be added. To specify a single trip instance, in many cases a `trip_id` by itself is sufficient. However, the following cases require additional information to resolve to a single trip instance: @@ -472,12 +472,14 @@ Note that if the trip_id is not known, then station sequence ids in TripUpdate a TripDescriptor.route_id cannot be used within an Alert EntitySelector to specify a route-wide alert that affects all trips for a route - use EntitySelector.route_id instead. +If `schedule_relationship` is `ADDED`, `trip_id` must be set to a value not exist in the GTFS feed, and `route_id` must be set to associate the trip to a route. `start_date` should be set, and `direction_id` may be set for the new trip. + **Fields** | _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | |------------------|------------|----------------|-------------------|-------------------| | **trip_id** | [string](https://protobuf.dev/programming-guides/proto2/#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 ADDED, it must be specified with a unique value not exist in the GTFS static, When schedule_relationship is DUPLICATED within a TripUpdate, the trip_id identifies the trip from static GTFS to be duplicated. When schedule_relationship is DUPLICATED within a VehiclePosition, the trip_id identifies the new duplicate trip and must contain the value for the corresponding TripUpdate.TripProperties.trip_id. | -| **route_id** | [string](https://protobuf.dev/programming-guides/proto2/#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. If schedule_relationship=ADDED, route_id specifies the route which the added trip belongs to. | +| **route_id** | [string](https://protobuf.dev/programming-guides/proto2/#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. When schedule_relationship is ADDED, route_id must be specified for route which the added trip belongs to. | | **direction_id** | [uint32](https://protobuf.dev/programming-guides/proto2/#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://protobuf.dev/programming-guides/proto2/#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. | | **start_date** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | The start date of this trip instance in YYYYMMDD format. For scheduled trips (trips not defined in GTFS frequencies.txt), 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. This field is required for frequency-based trips defined in GTFS frequencies.txt. If trip_id is omitted, start_date must be provided. | From 6bc14c8dbd9aae394654861d2ec668bce86c7572 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Thu, 26 Sep 2024 14:52:20 +0100 Subject: [PATCH 06/17] Clarify the use of StopTimeUpdate to specify the whole journey in added or replacement trips --- gtfs-realtime/spec/en/reference.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index e432be96..eedadfe5 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -191,14 +191,16 @@ Realtime update for arrival and/or departure events for a given stop on a trip. Updates can be supplied for both past and future events. The producer is allowed, although not required, to drop past events. The update is linked to a specific stop either through stop_sequence or stop_id, so one of these fields must necessarily be set. 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. +In added or replacement trips, updates are used to specify the stops visited by the trip without referring to the GTFS Static. In such trips, `stop_id`, `stop_sequence`, `departure` and `arrival` must all be set. + **Fields** | _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | |------------------|------------|----------------|-------------------|-------------------| -| **stop_sequence** | [uint32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Must be the same as in stop_times.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty. stop_sequence is required for trips that visit the same stop_id more than once (e.g., a loop) to disambiguate which stop the prediction is for. If `StopTimeProperties.assigned_stop_id` is populated, then `stop_sequence` must be populated. | -| **stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Must be the same as in stops.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty. If `StopTimeProperties.assigned_stop_id` is populated, it is preferred to omit `stop_id` and use only `stop_sequence`. If `StopTimeProperties.assigned_stop_id` and `stop_id` are populated, `stop_id` must match `assigned_stop_id`. | -| **arrival** | [StopTimeEvent](#message-stoptimeevent) | Conditionally required | One | If schedule_relationship is empty or SCHEDULED, either arrival or departure must be provided within a StopTimeUpdate - both fields cannot be empty. arrival and departure may both be empty when schedule_relationship is SKIPPED. If schedule_relationship is NO_DATA, arrival and departure must be empty. | -| **departure** | [StopTimeEvent](#message-stoptimeevent) | Conditionally required | One | If schedule_relationship is empty or SCHEDULED, either arrival or departure must be provided within a StopTimeUpdate - both fields cannot be empty. arrival and departure may both be empty when schedule_relationship is SKIPPED. If schedule_relationship is NO_DATA, arrival and departure must be empty. | +| **stop_sequence** | [uint32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Must be the same as in stop_times.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty. stop_sequence is required for trips that visit the same stop_id more than once (e.g., a loop) to disambiguate which stop the prediction is for. If `StopTimeProperties.assigned_stop_id` is populated, then `stop_sequence` must be populated. For added and replacement trips, this field is compulsory and must be increasing along the trip. | +| **stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Must be the same as in stops.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty. If `StopTimeProperties.assigned_stop_id` is populated, it is preferred to omit `stop_id` and use only `stop_sequence`. If `StopTimeProperties.assigned_stop_id` and `stop_id` are populated, `stop_id` must match `assigned_stop_id`. For added and replacement trips, this field is compulsory. | +| **arrival** | [StopTimeEvent](#message-stoptimeevent) | Conditionally required | One | If schedule_relationship is empty or SCHEDULED, either arrival or departure must be provided within a StopTimeUpdate - both fields cannot be empty. For added and replacement trips, both must be provided. arrival and departure may both be empty when schedule_relationship is SKIPPED. If schedule_relationship is NO_DATA, arrival and departure must be empty. | +| **departure** | [StopTimeEvent](#message-stoptimeevent) | Conditionally required | One | If schedule_relationship is empty or SCHEDULED, either arrival or departure must be provided within a StopTimeUpdate - both fields cannot be empty. For added and replacement trips, both must be provided. arrival and departure may both be empty when schedule_relationship is SKIPPED. If schedule_relationship is NO_DATA, arrival and departure must be empty. | | **departure_occupancy_status** | [OccupancyStatus](#enum-occupancystatus) | Optional | One | The predicted state of passenger occupancy for the vehicle immediately after departure from the given stop. If provided, stop_sequence must be provided. To provide departure_occupancy_status without providing any real-time arrival or departure predictions, populate this field and set StopTimeUpdate.schedule_relationship = NO_DATA.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | | **schedule_relationship** | [ScheduleRelationship](#enum-schedulerelationship) | Optional | One | The default relationship is SCHEDULED. | | **stop_time_properties** | [StopTimeProperties](#message-stoptimeproperties) | Optional | One | Realtime updates for certain properties defined within GTFS stop_times.txt

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | @@ -213,7 +215,7 @@ The relation between this StopTime and the static schedule. |-------------|---------------| | **SCHEDULED** | The vehicle is proceeding in accordance with its static schedule of stops, although not necessarily according to the times of the schedule. This is the **default** behavior. At least one of arrival and departure must be provided. Frequency-based trips (GTFS frequencies.txt with exact_times = 0) should not have a SCHEDULED value and should use UNSCHEDULED instead. | | **SKIPPED** | The stop is skipped, i.e., the vehicle will not stop at this stop. Arrival and departure are optional. When set `SKIPPED` is not propagated to subsequent stops in the same trip (i.e., the vehicle will stop at subsequent stops in the trip unless those stops also have a `stop_time_update` with `schedule_relationship: SKIPPED`). Delay from a previous stop in the trip *does* propagate over the `SKIPPED` stop. In other words, if a `stop_time_update` with an `arrival` or `departure` prediction is not set for a stop after the `SKIPPED` stop, the prediction upstream of the `SKIPPED` stop will be propagated to the stop after the `SKIPPED` stop and subsequent stops in the trip until a `stop_time_update` for a subsequent stop is provided. | -| **NO_DATA** | No data is given for this stop. It indicates that there is no realtime timing 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 timing information. When NO_DATA is set neither arrival nor departure should be supplied. | +| **NO_DATA** | No data is given for this stop. It indicates that there is no realtime timing 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 timing information. When NO_DATA is set neither arrival nor departure should be supplied. NO_DATA must not be used for added or replacement trips, as the StopTimeUpdate defines the stop list of the trip. | | **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_ StopTimeProperties From 87d28c78f1a24d13fefc4831e109b3efc84d8779 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Thu, 26 Sep 2024 14:58:00 +0100 Subject: [PATCH 07/17] Clarify the time and delay for added and replacement trips --- gtfs-realtime/spec/en/reference.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index eedadfe5..ea08efcb 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -171,8 +171,8 @@ Note that the update can describe a trip that has already completed.To this end, Timing information for a single predicted event (either arrival or departure). Timing consists of delay and/or estimated time, and uncertainty. -* delay should be used when the prediction is given relative to some existing schedule in GTFS. -* time should be given whether there is a predicted schedule or not. If both time and delay are specified, time will take precedence (although normally, time, if given for a scheduled trip, should be equal to scheduled time in GTFS + delay). +* delay should be used when the prediction is given relative to some existing schedule in GTFS. For added or replacement trips, the existence of the delay field indicates that there is a scheduled time, calculated by time - delay, at the stop for the trip, in addition to the estimated time. +* time should be given whether there is a predicted schedule or not, and must be given for added or replacement trips. If both time and delay are specified, time will take precedence (although normally, time, if given for a scheduled trip, should be equal to scheduled time in GTFS + delay). Uncertainty applies equally to both time and delay. The uncertainty roughly specifies the expected error in true delay (but note, we don't yet define its precise statistical meaning). It's possible for the uncertainty to be 0, for example for trains that are driven under computer timing control. @@ -181,7 +181,7 @@ Uncertainty applies equally to both time and delay. The uncertainty roughly spec | _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | |------------------|------------|----------------|-------------------|-------------------| | **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | 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. Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. | -| **time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Event as absolute time. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. | +| **time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Estimated or actual event as absolute time. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. For added or replacement trips, time must be provided as there is no schedule in GTFS static. | | **uncertainty** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | If uncertainty is omitted, it is interpreted as unknown. To specify a completely certain prediction, set its uncertainty to 0. | ## _message_ StopTimeUpdate From 991caac4710d35948659170f139a10a230f8d36c Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Mon, 30 Sep 2024 11:47:42 +0100 Subject: [PATCH 08/17] Update gtfs-realtime/spec/en/reference.md Accept suggestion by @leonardehrenfried for definition of TripUpdate.ScheduleRelationship = ADDED Co-authored-by: Leonard Ehrenfried --- gtfs-realtime/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index ea08efcb..940043f6 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -498,7 +498,7 @@ If a trip is done in accordance with a modified schedule, not reflected in GTFS, | _**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 unrelated to any existing trips, for example, to respond to sudden passenger load. The complete journey of the added trip must be specified via `StopTimeUpdate`s. | +| **ADDED** | An extra trip unrelated to any existing trips, for example, to respond to sudden passenger load. The complete journey of the added trip, including all stops and times, must be specified via `StopTimeUpdate`s. | | **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. | | **REPLACEMENT** | A trip that replaces an existing scheduled trip, for example, with a changed schedule or a diverted route. The complete journey of the replacement trip must be specified via `StopTimeUpdate`s, and the original schedule from the GTFS static isn't used for the replaced instance. | From fea9f815bd54f2f1ba41ccf0cf56185ea9d3f978 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Mon, 30 Sep 2024 11:48:19 +0100 Subject: [PATCH 09/17] Update gtfs-realtime/spec/en/reference.md formatting fix Co-authored-by: Leonard Ehrenfried --- gtfs-realtime/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 940043f6..e5fd92e9 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -171,7 +171,7 @@ Note that the update can describe a trip that has already completed.To this end, Timing information for a single predicted event (either arrival or departure). Timing consists of delay and/or estimated time, and uncertainty. -* delay should be used when the prediction is given relative to some existing schedule in GTFS. For added or replacement trips, the existence of the delay field indicates that there is a scheduled time, calculated by time - delay, at the stop for the trip, in addition to the estimated time. +* delay should be used when the prediction is given relative to some existing schedule in GTFS. For added or replacement trips, the existence of the delay field indicates that there is a scheduled time, calculated by `time - delay`, at the stop for the trip, in addition to the estimated time. * time should be given whether there is a predicted schedule or not, and must be given for added or replacement trips. If both time and delay are specified, time will take precedence (although normally, time, if given for a scheduled trip, should be equal to scheduled time in GTFS + delay). Uncertainty applies equally to both time and delay. The uncertainty roughly specifies the expected error in true delay (but note, we don't yet define its precise statistical meaning). It's possible for the uncertainty to be 0, for example for trains that are driven under computer timing control. From b6faa23eab094affbc1307dab1e8a31d76036c2a Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Wed, 2 Oct 2024 16:55:49 +0100 Subject: [PATCH 10/17] restore formatting --- gtfs-realtime/spec/en/reference.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index e5fd92e9..9906c5d3 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -489,9 +489,7 @@ If `schedule_relationship` is `ADDED`, `trip_id` must be set to a value not exis ## _enum_ ScheduleRelationship -The relation between this trip and the static schedule.
-If a new trip is done in accordance with temporary schedule, not reflected in GTFS, then it shouldn't be marked as SCHEDULED, but marked as ADDED.
-If a trip is done in accordance with a modified schedule, not reflected in GTFS, then it shouldn't be marked as SCHEDULED, but marked as REPLACEMENT.
+The relation between this trip and the static schedule. If a new trip is done in accordance with temporary schedule, not reflected in GTFS, then it shouldn't be marked as SCHEDULED, but marked as ADDED. If a trip is done in accordance with a modified schedule, not reflected in GTFS, then it shouldn't be marked as SCHEDULED, but marked as REPLACEMENT. **Values** From 0e62760ec6884850953b82b6d82206aab136a6cf Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Tue, 8 Oct 2024 12:45:30 +0100 Subject: [PATCH 11/17] add scheduled time --- gtfs-realtime/proto/gtfs-realtime.proto | 6 ++++++ gtfs-realtime/spec/en/reference.md | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/gtfs-realtime/proto/gtfs-realtime.proto b/gtfs-realtime/proto/gtfs-realtime.proto index fa25c8b8..10cbd08d 100644 --- a/gtfs-realtime/proto/gtfs-realtime.proto +++ b/gtfs-realtime/proto/gtfs-realtime.proto @@ -190,6 +190,12 @@ message TripUpdate { // To specify a completely certain prediction, set its uncertainty to 0. optional int32 uncertainty = 3; + // Scheduled time for an added or replacement trip. + // In Unix time (i.e., number of seconds since January 1st 1970 00:00:00 + // UTC). + // Required if the parent StopTimeUpdate specifies stop_time_properties.timepoint = true + optional int64 scheduled_time = 4; + // 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. diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 9906c5d3..e33e79f1 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -169,10 +169,11 @@ Note that the update can describe a trip that has already completed.To this end, ## _message_ StopTimeEvent -Timing information for a single predicted event (either arrival or departure). Timing consists of delay and/or estimated time, and uncertainty. +Timing information for a single predicted event (either arrival or departure). Timing consists of delay and/or estimated time, and uncertainty. A scheduled time can also be added for added or replacement trips. -* delay should be used when the prediction is given relative to some existing schedule in GTFS. For added or replacement trips, the existence of the delay field indicates that there is a scheduled time, calculated by `time - delay`, at the stop for the trip, in addition to the estimated time. +* delay should be used when the prediction is given relative to some existing schedule in GTFS. * time should be given whether there is a predicted schedule or not, and must be given for added or replacement trips. If both time and delay are specified, time will take precedence (although normally, time, if given for a scheduled trip, should be equal to scheduled time in GTFS + delay). +* scheduled time may be given if the trip is an added or replacement trip, and must be given if the stop is specified as a timepoint. Uncertainty applies equally to both time and delay. The uncertainty roughly specifies the expected error in true delay (but note, we don't yet define its precise statistical meaning). It's possible for the uncertainty to be 0, for example for trains that are driven under computer timing control. @@ -182,6 +183,7 @@ Uncertainty applies equally to both time and delay. The uncertainty roughly spec |------------------|------------|----------------|-------------------|-------------------| | **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | 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. Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. | | **time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Estimated or actual event as absolute time. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. For added or replacement trips, time must be provided as there is no schedule in GTFS static. | +| **scheduled_time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Scheduled time for an added or replacement trip. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). The vehicle will wait for this time if StopTimeUpdate.stop_time_properties.timepoint is 1 or unspecified. A scheduled time must be given if StopTimeUpdate.stop_time_properties.timepoint is true. | | **uncertainty** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | If uncertainty is omitted, it is interpreted as unknown. To specify a completely certain prediction, set its uncertainty to 0. | ## _message_ StopTimeUpdate From 896129e0aa133c8328ce6b56ff8b934bcbba1901 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Tue, 8 Oct 2024 12:49:25 +0100 Subject: [PATCH 12/17] allow scheduled time for duplicated trip as well --- gtfs-realtime/spec/en/reference.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index e33e79f1..cb646bcf 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -169,11 +169,11 @@ Note that the update can describe a trip that has already completed.To this end, ## _message_ StopTimeEvent -Timing information for a single predicted event (either arrival or departure). Timing consists of delay and/or estimated time, and uncertainty. A scheduled time can also be added for added or replacement trips. +Timing information for a single predicted event (either arrival or departure). Timing consists of delay and/or estimated time, and uncertainty. A scheduled time can also be added for added, replacement or duplicated trips. * delay should be used when the prediction is given relative to some existing schedule in GTFS. * time should be given whether there is a predicted schedule or not, and must be given for added or replacement trips. If both time and delay are specified, time will take precedence (although normally, time, if given for a scheduled trip, should be equal to scheduled time in GTFS + delay). -* scheduled time may be given if the trip is an added or replacement trip, and must be given if the stop is specified as a timepoint. +* scheduled time may be given if the trip is an added, replacement or duplicated trip, and must be given if the stop is specified as a timepoint. Uncertainty applies equally to both time and delay. The uncertainty roughly specifies the expected error in true delay (but note, we don't yet define its precise statistical meaning). It's possible for the uncertainty to be 0, for example for trains that are driven under computer timing control. @@ -183,7 +183,7 @@ Uncertainty applies equally to both time and delay. The uncertainty roughly spec |------------------|------------|----------------|-------------------|-------------------| | **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | 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. Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. | | **time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Estimated or actual event as absolute time. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. For added or replacement trips, time must be provided as there is no schedule in GTFS static. | -| **scheduled_time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Scheduled time for an added or replacement trip. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). The vehicle will wait for this time if StopTimeUpdate.stop_time_properties.timepoint is 1 or unspecified. A scheduled time must be given if StopTimeUpdate.stop_time_properties.timepoint is true. | +| **scheduled_time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Scheduled time for an added, replacement or duplicated trip. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). The vehicle will wait for this time if StopTimeUpdate.stop_time_properties.timepoint is 1 or unspecified.
**Required** if StopTimeUpdate.stop_time_properties.timepoint is true.
**Forbidden** if TripUpdate.schedule_relationship is not ADDED, REPLACEMENT or DUPLICATED. | | **uncertainty** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | If uncertainty is omitted, it is interpreted as unknown. To specify a completely certain prediction, set its uncertainty to 0. | ## _message_ StopTimeUpdate From 43a9b00e6630beabb2a85d39518243ff5b8d4f63 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Tue, 8 Oct 2024 12:52:12 +0100 Subject: [PATCH 13/17] fix wording --- gtfs-realtime/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index cb646bcf..8f547f94 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -183,7 +183,7 @@ Uncertainty applies equally to both time and delay. The uncertainty roughly spec |------------------|------------|----------------|-------------------|-------------------| | **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | 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. Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. | | **time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Estimated or actual event as absolute time. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. For added or replacement trips, time must be provided as there is no schedule in GTFS static. | -| **scheduled_time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Scheduled time for an added, replacement or duplicated trip. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). The vehicle will wait for this time if StopTimeUpdate.stop_time_properties.timepoint is 1 or unspecified.
**Required** if StopTimeUpdate.stop_time_properties.timepoint is true.
**Forbidden** if TripUpdate.schedule_relationship is not ADDED, REPLACEMENT or DUPLICATED. | +| **scheduled_time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Scheduled time for an added, replacement or duplicated trip. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). The vehicle will wait for this time if StopTimeUpdate.stop_time_properties.timepoint is true or unspecified.
**Required** if StopTimeUpdate.stop_time_properties.timepoint is true.
**Forbidden** if TripUpdate.schedule_relationship is not ADDED, REPLACEMENT or DUPLICATED. | | **uncertainty** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | If uncertainty is omitted, it is interpreted as unknown. To specify a completely certain prediction, set its uncertainty to 0. | ## _message_ StopTimeUpdate From 3ff34bfb5153a61a0793d2dc8f14cfb2f370e971 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Tue, 3 Dec 2024 12:02:55 +0000 Subject: [PATCH 14/17] remove fields that I am not going to use --- gtfs-realtime/proto/gtfs-realtime.proto | 17 ----------------- gtfs-realtime/spec/en/reference.md | 4 ---- 2 files changed, 21 deletions(-) diff --git a/gtfs-realtime/proto/gtfs-realtime.proto b/gtfs-realtime/proto/gtfs-realtime.proto index 7b38f13a..01cff4ac 100644 --- a/gtfs-realtime/proto/gtfs-realtime.proto +++ b/gtfs-realtime/proto/gtfs-realtime.proto @@ -287,19 +287,6 @@ message TripUpdate { // The updated drop off of the vehicle at the stop. optional DropOffPickupType drop_off_type = 4; - // The updated timing point status of the vehicle at the stop. - // If false, the vehicle will no longer wait at the stop; - // if true, the vehicle will wait until the scheduled time at the stop. - optional bool timepoint = 5; - - // Identifies the boarding booking rule at this stop time. - // Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`. - optional string pickup_booking_rule_id = 6; - - // Identifies the alighting booking rule at this stop time. - // Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`. - optional string drop_off_booking_rule_id = 7; - // 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. @@ -429,10 +416,6 @@ message TripUpdate { // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. optional string trip_short_name = 6; - // Specifies the block for this trip when it differs from the original. - // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future. - optional string block_id = 7; - // 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. diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 9936f4c6..17c7091d 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -237,9 +237,6 @@ Realtime update for certain properties defined within GTFS stop_times.txt. | **stop_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated headsign of the vehicle at the stop. | | **drop_off_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated drop off of the vehicle at the stop. | | **pickup_type** | [DropOffPickupType](#enum-dropoffpickuptype) | Optional | One | The updated pickup of the vehicle at the stop. | -| **timepoint** | [bool](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | The updated timing point status of the vehicle at the stop. If false, the vehicle will no longer wait at the stop; if true, the vehicle will wait until the scheduled time at the stop. | -| **pickup_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the boarding booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `pickup_type=PHONE_AGENCY`. | -| **drop_off_booking_rule_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Identifies the alighting booking rule at this stop time. Refers to a `booking_rule_id` defined in the GTFS `booking_rules.txt`.
Recommended when `drop_off_type=PHONE_AGENCY`. | ## _enum_ DropOffPickupType @@ -267,7 +264,6 @@ Defines updated properties of the trip | **start_time** | [string](https://protobuf.dev/programming-guides/proto2/#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. Scheduled arrival and departure times for the duplicated trip are calculated based on the offset between the original trip `departure_time` and this field. For example, if a GTFS trip has stop A with a `departure_time` of `10:00:00` and stop B with `departure_time` of `10:01:00`, and this field is populated with the value of `10:30:00`, stop B on the duplicated trip will have a scheduled `departure_time` of `10:31:00`. Real-time prediction `delay` values are applied to this calculated schedule time to determine the predicted time. For example, if a departure `delay` of `30` is provided for stop B, then the predicted departure time is `10:31:30`. Real-time prediction `time` values do not have any offset applied to them and indicate the predicted time as provided. For example, if a departure `time` representing 10:31:30 is provided for stop B, then the predicted departure time is `10:31:30`.This field is required if `schedule_relationship` is `DUPLICATED`, otherwise this field must not be populated and will be ignored by consumers.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | | **trip_headsign** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the headsign for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | | **trip_short_name** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the name for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | -| **block_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the block for this trip when it differs from the original.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | | **shape_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | Specifies the shape of the vehicle travel path for this trip when it differs from the original. Refers to a shape defined in the (CSV) GTFS or a new shape entity in a real-time feed. See definition of `trips.shape_id` in (CSV) GTFS.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | ## _message_ VehiclePosition From 573124ca994a219665529d838381ef4eb9272b23 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Tue, 3 Dec 2024 12:04:56 +0000 Subject: [PATCH 15/17] Update gtfs-realtime/spec/en/reference.md Co-authored-by: Guillaume Campagna --- gtfs-realtime/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 17c7091d..3fd78972 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -203,7 +203,7 @@ In added or replacement trips, updates are used to specify the stops visited by | _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ | |------------------|------------|----------------|-------------------|-------------------| | **stop_sequence** | [uint32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Must be the same as in stop_times.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty. stop_sequence is required for trips that visit the same stop_id more than once (e.g., a loop) to disambiguate which stop the prediction is for. If `StopTimeProperties.assigned_stop_id` is populated, then `stop_sequence` must be populated. For added and replacement trips, this field is compulsory and must be increasing along the trip. | -| **stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Must be the same as in stops.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty. If `StopTimeProperties.assigned_stop_id` is populated, it is preferred to omit `stop_id` and use only `stop_sequence`. If `StopTimeProperties.assigned_stop_id` and `stop_id` are populated, `stop_id` must match `assigned_stop_id`. For added and replacement trips, this field is compulsory. | +| **stop_id** | [string](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Must be the same as in stops.txt in the corresponding GTFS feed. Either stop_sequence or stop_id must be provided within a StopTimeUpdate - both fields cannot be empty. If `StopTimeProperties.assigned_stop_id` is populated, it is preferred to omit `stop_id` and use only `stop_sequence`. If `StopTimeProperties.assigned_stop_id` and `stop_id` are populated, `stop_id` must match `assigned_stop_id`. For added and replacement trips, this field is required. | | **arrival** | [StopTimeEvent](#message-stoptimeevent) | Conditionally required | One | If schedule_relationship is empty or SCHEDULED, either arrival or departure must be provided within a StopTimeUpdate - both fields cannot be empty. For added and replacement trips, both must be provided. arrival and departure may both be empty when schedule_relationship is SKIPPED. If schedule_relationship is NO_DATA, arrival and departure must be empty. | | **departure** | [StopTimeEvent](#message-stoptimeevent) | Conditionally required | One | If schedule_relationship is empty or SCHEDULED, either arrival or departure must be provided within a StopTimeUpdate - both fields cannot be empty. For added and replacement trips, both must be provided. arrival and departure may both be empty when schedule_relationship is SKIPPED. If schedule_relationship is NO_DATA, arrival and departure must be empty. | | **departure_occupancy_status** | [OccupancyStatus](#enum-occupancystatus) | Optional | One | The predicted state of passenger occupancy for the vehicle immediately after departure from the given stop. If provided, stop_sequence must be provided. To provide departure_occupancy_status without providing any real-time arrival or departure predictions, populate this field and set StopTimeUpdate.schedule_relationship = NO_DATA.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. | From ade68aecf431db49d3bcbc55dcb43090dfd0b0dc Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Tue, 3 Dec 2024 12:08:34 +0000 Subject: [PATCH 16/17] Update gtfs-realtime/spec/en/reference.md Co-authored-by: Guillaume Campagna --- gtfs-realtime/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 3fd78972..c5163da0 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -196,7 +196,7 @@ Realtime update for arrival and/or departure events for a given stop on a trip. Updates can be supplied for both past and future events. The producer is allowed, although not required, to drop past events. The update is linked to a specific stop either through stop_sequence or stop_id, so one of these fields must necessarily be set. 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. -In added or replacement trips, updates are used to specify the stops visited by the trip without referring to the GTFS Static. In such trips, `stop_id`, `stop_sequence`, `departure` and `arrival` must all be set. +In added or replacement trips, updates are used to specify the stops visited by the trip without referring to an existing trip in the GTFS Static. In such trips, `stop_id`, `stop_sequence`, `departure` and `arrival` must all be set. **Fields** From 2f019d883f59082e285662c1b8c0769d10bed02e Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Tue, 3 Dec 2024 12:07:55 +0000 Subject: [PATCH 17/17] remove reference to timepoint for scheduled time as it is removed from the change --- gtfs-realtime/proto/gtfs-realtime.proto | 1 - gtfs-realtime/spec/en/reference.md | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gtfs-realtime/proto/gtfs-realtime.proto b/gtfs-realtime/proto/gtfs-realtime.proto index 01cff4ac..5d2adaa7 100644 --- a/gtfs-realtime/proto/gtfs-realtime.proto +++ b/gtfs-realtime/proto/gtfs-realtime.proto @@ -193,7 +193,6 @@ message TripUpdate { // Scheduled time for an added or replacement trip. // In Unix time (i.e., number of seconds since January 1st 1970 00:00:00 // UTC). - // Required if the parent StopTimeUpdate specifies stop_time_properties.timepoint = true optional int64 scheduled_time = 4; // The extensions namespace allows 3rd-party developers to extend the diff --git a/gtfs-realtime/spec/en/reference.md b/gtfs-realtime/spec/en/reference.md index 17c7091d..ebf85dd9 100644 --- a/gtfs-realtime/spec/en/reference.md +++ b/gtfs-realtime/spec/en/reference.md @@ -176,7 +176,7 @@ Timing information for a single predicted event (either arrival or departure). T * delay should be used when the prediction is given relative to some existing schedule in GTFS. * time should be given whether there is a predicted schedule or not, and must be given for added or replacement trips. If both time and delay are specified, time will take precedence (although normally, time, if given for a scheduled trip, should be equal to scheduled time in GTFS + delay). -* scheduled time may be given if the trip is an added, replacement or duplicated trip, and must be given if the stop is specified as a timepoint. +* scheduled time may be given if the trip is an added, replacement or duplicated trip. Uncertainty applies equally to both time and delay. The uncertainty roughly specifies the expected error in true delay (but note, we don't yet define its precise statistical meaning). It's possible for the uncertainty to be 0, for example for trains that are driven under computer timing control. @@ -186,7 +186,7 @@ Uncertainty applies equally to both time and delay. The uncertainty roughly spec |------------------|------------|----------------|-------------------|-------------------| | **delay** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | 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. Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. | | **time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Estimated or actual event as absolute time. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). Either delay or time must be provided within a StopTimeEvent - both fields cannot be empty. For added or replacement trips, time must be provided as there is no schedule in GTFS static. | -| **scheduled_time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Scheduled time for an added, replacement or duplicated trip. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC). The vehicle will wait for this time if StopTimeUpdate.stop_time_properties.timepoint is true or unspecified.
**Required** if StopTimeUpdate.stop_time_properties.timepoint is true.
**Forbidden** if TripUpdate.schedule_relationship is not ADDED, REPLACEMENT or DUPLICATED. | +| **scheduled_time** | [int64](https://protobuf.dev/programming-guides/proto2/#scalar) | Conditionally required | One | Scheduled time for an added, replacement or duplicated trip. In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC).
**Forbidden** if TripUpdate.schedule_relationship is not ADDED, REPLACEMENT or DUPLICATED. | | **uncertainty** | [int32](https://protobuf.dev/programming-guides/proto2/#scalar) | Optional | One | If uncertainty is omitted, it is interpreted as unknown. To specify a completely certain prediction, set its uncertainty to 0. | ## _message_ StopTimeUpdate