Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1a432c7
Update migration-duplicated example
Sergiodero May 27, 2025
42d9829
Update EN proto files
Sergiodero May 27, 2025
9cfa57e
Update EN Feed Updates
Sergiodero May 27, 2025
21541f9
Update EN realtime best practices
Sergiodero May 27, 2025
7943546
Update En Realtime reference
Sergiodero May 28, 2025
cb8ddce
Update EN Realtime revision history
Sergiodero May 28, 2025
0748d7f
Update ES Protobuf
Sergiodero May 29, 2025
ab9916b
Update FR protobuf
Sergiodero May 29, 2025
dae0ae0
Update JA protobuf
Sergiodero May 29, 2025
ee1fc5a
Update ES realtime revision history
Sergiodero May 29, 2025
9cdc2b4
Update ES trip updates
Sergiodero May 29, 2025
fc92922
Fix link in EN trip updates
Sergiodero May 29, 2025
2d973cf
Update ES realtime best practices
Sergiodero May 29, 2025
7f00343
Update ES realtime example migration duplicated
Sergiodero May 29, 2025
696755b
Fix link in EN Realtime reference
Sergiodero May 29, 2025
84d3992
Update ES Realtime Reference
Sergiodero May 29, 2025
5a9bb43
Update FR Realtime revision history
Sergiodero May 29, 2025
494cf20
Update FR Realtime trip updates
Sergiodero May 29, 2025
57a7042
update realtime best practices
Sergiodero May 29, 2025
12071d6
update FR realtime example migration-duplicated
Sergiodero May 29, 2025
e96c8eb
Update JA Realtime revision history
Sergiodero May 29, 2025
858b079
Update JA realtime trip updates
Sergiodero May 29, 2025
cd5c8e8
Update JA realtime best practices
Sergiodero May 29, 2025
2dd487e
Update JA realtime example migration-duplicated
Sergiodero May 29, 2025
e2a85d6
Update FR realtime reference
Sergiodero Jun 2, 2025
d68a144
Update JA realtime reference
Sergiodero Jun 2, 2025
8602d67
Fix FR Migration Duplicated example
Sergiodero Jun 4, 2025
128bc42
Fix FR Trip updates
Sergiodero Jun 4, 2025
63a038d
Fix EN Migration Duplicated example typos
Sergiodero Jun 4, 2025
d6404b3
Fix Es Migration Duplicated example typos
Sergiodero Jun 4, 2025
8582dc3
Fix JA Migration duplicated typos
Sergiodero Jun 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

### Revision History

#### May 2025

* Deprecates schedule_relationship `ADDED` in favour of `NEW` and adds `REPLACEMENT`. See [discussion](https://github.com/google/transit/pull/504).
* Further clarifications to trip modifications. See [discussion](https://github.com/google/transit/pull/542).

#### December 2024

* Added new string field that matches feed_info.feed_version from the GTFS Schedule feed that the realtime data is based on. See [discussion](https://github.com/google/transit/pull/434).
Expand Down
72 changes: 68 additions & 4 deletions docs/en/documentation/realtime/examples/migration-duplicated.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,77 @@
## Migration Guide - Transition from ADDED to DUPLICATED trips
## Migration Guide - Transition from ADDED to NEW or DUPLICATED trips

The GTFS-realtime `trip.schedule_relationship` of `NEW` represents a new trip that runs on a schedule unrelated to any existing scheduled trip.

The GTFS-realtime `trip.schedule_relationship` of `DUPLICATED` represents a new trip that is the same as an existing scheduled trip except for service start date and time.

This migration guide defines how existing producers and consumers that were using the `ADDED` enumeration to represent duplicated trips should transition to the `DUPLICATED` enumeration. The goal is to minimize disruption to producers and consumers during the transition.
This migration guide defines how existing producers and consumers that were using the `ADDED` enumeration should transition to either the `NEW` and the `DUPLICATED` enumeration. The goal is to minimize disruption to producers and consumers during the transition.

*If you are a producer or consumer that has **not** used the `ADDED` enumeration, no action is required - you can produce/consume `NEW` and/or `DUPLICATED` trips without producing/consuming any `ADDED` entities.*

*If you are a producer or consumer that has **not** used the `ADDED` enumeration to describe duplicated trips, no action is required - you can produce/consume `DUPLICATED` trips without producing/consuming any `ADDED` entities.*
For a full history of the `NEW` enumeration, see the [`NEW` and `REPLACEMENT` proposal on GitHub](https://github.com/google/transit/pull/504).

For a full history of the `DUPLICATED` enumeration, see the [`DUPLICATED` proposal on GitHub](https://github.com/google/transit/pull/221).

### Which one to migrate to

Both `NEW` and `DUPLICATED` enumeration are used to specify a trip which was not originally scheduled to run in the GTFS static.

Use `NEW` if your trip cannot be described using any scheduled trips as a template. For example, if the trip calls at different stops from the regular trips of the route, or if the extra trip is pickup only at the beginning of the route despite that the regular trips allow both pickup and drop off at all stops.

Use `DUPLICATED` if your trip is a copy of a scheduled trip, which may run at the same, or at different times of the original scheduled trip.

### Using ADDED and NEW entities in the same feed

If you are a producer who has been using the `ADDED` enumeration to specify trips which are unrelated to the schedule, to avoid disruption to existing consumers it is recommended that you continue to produce `ADDED` entities for these trips but also add `NEW` entities for the same trip.

However, to prevent consumers from accidentally adding the same trip twice, the entities referencing the same trip **must** be linked using the same `trip_id`, `route_id` and `start_date`.
In addition, the contents of the `stop_time_update` must also be the same as well.

#### Producers

~~~
entity {
id: "ei0"
trip_update {
trip: {
trip_id: "1" // <-- a trip_id not found in the static GTFS
route_id: "A"
schedule_relationship: ADDED
start_date: "20200821" // <-- New trip date
start_time: "11:30:00" // <-- New trip time
}
stop_time_update {
... // The full list of the calling points of the trip
}
}
}

entity {
id: "ei10"
trip_update {
trip: {
trip_id: "1" // <-- The same trip_id as the above
route_id: "A" // <-- The same route_id as the above
schedule_relationship: NEW
start_date: "20200821" // <-- The same date as the above
start_time: "11:30:00" // <-- The same time as the above
}
stop_time_update {
... // <-- The same content as the above
}
}
}
~~~

It is suggested that you notify existing consumers (e.g., via a developer mailing list) that the use of `ADDED` is being deprecated by a set deadline and that consumers should start consuming the `NEW` trips instead. The above strategy being used to match `ADDED` and `NEW` trip entities should also be mentioned and a link to this migration guide should be included. After the deadline passes, you can remove the `ADDED` entities from your feed and publish only the `NEW` entities for newly-added trips.

#### Consumers

As mentioned above, producers will transition from `ADDED` to `NEW` enumerations by initially publishing two entities for each new trip using the same `trip_id`.

Therefore, when a consumer implements support for `NEW` trips, it is important that consumers ignore any `ADDED` trips that have the same `trip_id` as a `NEW` trip `trip_id`.


### Using ADDED and DUPLICATED entities in same feed

#### Producers
Expand Down Expand Up @@ -93,7 +157,7 @@ entity {
}
~~~

It is suggested that you notify existing consumers (e.g., via a developer mailing list) that the use of `ADDED` for duplicated trips is being deprecated by a set deadline and that consumers should start consuming the `DUPLICATED` trips instead. The above strategy being used to match `ADDED` and `DUPLICATED` trip entities should also be mentioned and a link to this migration guide should be included. After the deadline passes, you can remove the `ADDED` entities from your feed and publish only the `DUPLICATED` entities for duplicated trips.
It is suggested that you notify existing consumers (e.g., via a developer mailing list) that the use of `ADDED` is being deprecated by a set deadline and that consumers should start consuming the `DUPLICATED` trips instead. The above strategy being used to match `ADDED` and `DUPLICATED` trip entities should also be mentioned and a link to this migration guide should be included. After the deadline passes, you can remove the `ADDED` entities from your feed and publish only the `DUPLICATED` entities for duplicated trips.

#### Consumers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ If a vehicle is serving multiple trips within the same block (for more informati

## StopTimeUpdate

A trip update consists of one or more updates to vehicle stop times, which are referred to as [StopTimeUpdates](../../reference/#message-stoptimeupdate). These can be supplied for past and future stop times. You are allowed, but not required, to drop past stop times. Producers should not drop a past `StopTimeUpdate` if it refers to a stop with a scheduled arrival time in the future for the given trip (i.e. the vehicle has passed the stop ahead of schedule), as otherwise it will be concluded that there is no update for this stop.
A trip update consists of one or more updates to vehicle stop times, which are referred to as [StopTimeUpdates](../../reference/#message-stoptimeupdate). These can be supplied for past and future stop times. You are allowed, but not required, to drop past stop times, unless the trip is a new or replacement trip not found in the GTFS static. Producers should not drop a past `StopTimeUpdate` if it refers to a stop with a scheduled arrival time in the future for the given trip (i.e. the vehicle has passed the stop ahead of schedule), as otherwise it will be concluded that there is no update for this stop.

For example, if the following data appears in the GTFS-rt feed:

Expand Down
96 changes: 71 additions & 25 deletions docs/en/documentation/realtime/gtfs-realtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ message TripUpdate {
// To specify a completely certain prediction, set its uncertainty to 0.
optional int32 uncertainty = 3;

// Scheduled time for a NEW, REPLACEMENT, or DUPLICATED trip.
// In Unix time (i.e., number of seconds since January 1st 1970 00:00:00
// UTC).
// Optional if TripUpdate.schedule_relationship is NEW, REPLACEMENT or DUPLICATED, forbidden otherwise.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
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.
Expand Down Expand Up @@ -277,6 +284,32 @@ message TripUpdate {
// 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.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional string stop_headsign = 2;

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;
}

// The updated pickup of the vehicle at the stop.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional DropOffPickupType pickup_type = 3;

// The updated drop off of the vehicle at the stop.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional DropOffPickupType drop_off_type = 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.
Expand Down Expand Up @@ -374,16 +407,23 @@ message TripUpdate {
// populated and will be ignored by consumers.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional string start_time = 3;
// Specifies the shape of the vehicle travel path when the trip shape differs from the shape specified in
// (CSV) GTFS or to specify it in real-time when it's not provided by (CSV) GTFS, such as a vehicle that takes differing
// paths based on rider demand. See definition of trips.shape_id in (CSV) GTFS. If a shape is neither defined in (CSV) GTFS
// nor in real-time, the shape is considered unknown. This field can refer to a shape defined in the (CSV) GTFS in shapes.txt
// or a Shape in the (protobuf) real-time feed. The order of stops (stop sequences) for this trip must remain the same as
// (CSV) GTFS. Stops that are a part of the original trip but will no longer be made, such as when a detour occurs, should
// be marked as schedule_relationship=SKIPPED.
// Specifies the identifier of the shape of the vehicle travel path when the trip shape differs from the shape specified in (CSV) GTFS
// or to specify it in real-time when it's not provided by (CSV) GTFS, such as a vehicle that takes differing paths based on rider demand. See definition of trips.shape_id in (CSV) GTFS.
// If a shape is neither defined in (CSV) GTFS nor in real-time, the shape is considered unknown. This field can refer to a shape defined in the (CSV) GTFS in shapes.txt or a `Shape` in the same (protobuf) real-time feed.
// The order of stops (stop sequences) for this trip must remain the same as (CSV) GTFS.
// If it refers to a `Shape` entity in the same real-time feed, the value of this field should be the one of the `shape_id` inside the entity, and _not_ the `id` of `FeedEntity`.
// Stops that are a part of the original trip but will no longer be made, such as when a detour occurs, should be marked as schedule_relationship=SKIPPED or more details can be provided via a `TripModifications` message.
// 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;

// 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.
Expand Down Expand Up @@ -798,14 +838,10 @@ 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.
ADDED = 1;
// This value has been deprecated as the behavior was unspecified.
// Use DUPLICATED for an extra trip that is the same as a scheduled trip except the start date or time,
// or NEW for an extra trip that is unrelated to an existing trip.
ADDED = 1 [deprecated = true];

// A trip that is running with no schedule associated to it (GTFS frequencies.txt exact_times=0).
// Trips with ScheduleRelationship=UNSCHEDULED must also set all StopTimeUpdates.ScheduleRelationship=UNSCHEDULED.
Expand All @@ -814,8 +850,9 @@ 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.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
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,
Expand All @@ -824,7 +861,10 @@ message TripDescriptor {
// (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 with the value of CANCELED or DELETED. 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.
Expand All @@ -844,6 +884,10 @@ message TripDescriptor {
// real-time predictions.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
DELETED = 7;

// An extra trip unrelated to any existing trips, for example, to respond to sudden passenger load.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
NEW = 8;
}
optional ScheduleRelationship schedule_relationship = 4;

Expand All @@ -869,8 +913,8 @@ message TripDescriptor {
extensions 9000 to 9999;
}

// Linkage to any modifications done to this trip (shape changes, removal or addition of stops).
// If this field is provided, the `trip_id`, `route_id`, `direction_id`, `start_time`, `start_date` fields of the `TripDescriptor` MUST be left empty, to avoid confusion by consumers that aren't looking for the `ModifiedTripSelector` value.
// Linkage to any modifications done to this trip (shape changes, removal or addition of stops).
// If this field is provided, the `trip_id`, `route_id`, `direction_id`, `start_time`, `start_date` fields of the `TripDescriptor` MUST be left empty, to avoid confusion by consumers that aren't looking for the `ModifiedTripSelector` value.
optional ModifiedTripSelector modified_trip = 7;

// The extensions namespace allows 3rd-party developers to extend the
Expand Down Expand Up @@ -1051,7 +1095,7 @@ message Shape {
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional string shape_id = 1;

// Encoded polyline representation of the shape. This polyline must contain at least two points.
// Encoded polyline representation of the shape. This polyline must contain at least two points and represent the full shape of the trip where it's used.
// For more information about encoded polylines, see https://developers.google.com/maps/documentation/utilities/polylinealgorithm
// This field is required as per reference.md, but needs to be specified here optional because "Required is Forever"
// See https://developers.google.com/protocol-buffers/docs/proto#specifying_field_rules
Expand Down Expand Up @@ -1139,10 +1183,11 @@ 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.
// The ID of the new shape for the modified trips in this SelectedTrips.
// May refer to a new shape added using a `Shape` message in the same GTFS-RT feed, or to an existing shape defined in the GTFS-Static feed’s shapes.txt.
// If it refers to a `Shape` entity in the real-time feed, the value of this field should be the one of the `shape_id` inside the entity, and _not_ the `id` of `FeedEntity`.
optional string shape_id = 2;

// The extensions namespace allows 3rd-party developers to extend the
Expand Down Expand Up @@ -1200,7 +1245,8 @@ message ReplacementStop {
// This value MUST be monotonically increasing and may only be a negative number if the first stop of the original trip is the reference stop.
optional int32 travel_time_to_stop = 1;

// The replacement stop ID which will now be visited by the trip. May refer to a new stop added using a GTFS-RT Stop message, or to an existing stop defined in the GTFS-Static feed’s stops.txt. The stop MUST have location_type=0 (routable stops).
// The replacement stop ID which will now be visited by the trip. May refer to a new stop added using a GTFS-RT `Stop` message in the same GTFS-RT feed, or to an existing stop defined in the (CSV) GTFS feed’s `stops.txt`.
// If it refers to a `Shape` entity in the real-time feed, the value of this field should be the one of the `stop_id` inside the entity, and _not_ the `id` of `FeedEntity`. The replacement stop MUST have `location_type=0` (routable stops).
optional string stop_id = 2;

// The extensions namespace allows 3rd-party developers to extend the
Expand Down
Loading