Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions gtfs-realtime/proto/gtfs-realtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ message TripUpdate {
// NOTE: This field is still experimental, and subject to change. It may be
// formally adopted in the future.
UNSCHEDULED = 3;

// The vehicle's relationship with the static schedule differs in a way that impacts the rider experience,
// such as a vehicle not picking up passengers because a vehicle is "drop-off only" to catch up back to
// schedule when it's running late. StopTimeProperties must included to specify how the relationship
// has been modified.
MODIFIED = 4;
}
optional ScheduleRelationship schedule_relationship = 5
[default = SCHEDULED];
Expand All @@ -260,6 +266,54 @@ 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;

// Supports real-time changes to pickup_type when it differs from what's specified in (CSV) GTFS
// in stop_times.txt. See definition of stop_times.pickup_type in (CSV) GTFS.
// If pickup_type is specified, StopTimeUpdate.schedule_relationship should be MODIFIED.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional PickupType pickup_type = 2;

// Supports real-time changes to drop_off_type when it differs from what's specified in (CSV) GTFS
// in stop_times.txt. See definition of stop_times.drop_off_type in (CSV) GTFS.
// If drop_off_type is specified, StopTimeUpdate.schedule_relationship should be MODIFIED.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional DropOffType drop_off_type = 3;

// Indicates the pickup method for an updated stop time when it differs from what's specified in (CSV) GTFS
// in stop_times.txt. By default, if pickup_type is neither specified in real-time or in (CSV) GTFS, it is
// considered REGULAR_PICKUP.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
enum PickupType {
// See definition of stop_times.pickup_type=0 in (CSV) GTFS.
REGULAR_PICKUP = 0;

// See definition of stop_times.pickup_type=1 in (CSV) GTFS.
NO_PICKUP = 1;

// See definition of stop_times.pickup_type=2 in (CSV) GTFS.
MUST_PHONE_AGENCY_PICKUP = 2;

// See definition of stop_times.pickup_type=3 in (CSV) GTFS.
MUST_ASK_DRIVER_PICKUP = 3;
}

// Indicates the drop off method for an updated stop time when it differs from what's specified in (CSV) GTFS
// in stop_times.txt. By default, if drop_off_type is neither specified in real-time or in (CSV) GTFS, it is
// considered REGULAR_DROP_OFF.
// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
enum DropOffType {
// See definition of stop_times.drop_off_type=0 in (CSV) GTFS.
REGULAR_DROP_OFF = 0;

// See definition of stop_times.drop_off_type=1 in (CSV) GTFS.
NO_DROP_OFF = 1;

// See definition of stop_times.drop_off_type=2 in (CSV) GTFS.
MUST_PHONE_AGENCY_DROP_OFF = 2;

// See definition of stop_times.drop_off_type=3 in (CSV) GTFS.
MUST_ASK_DRIVER_DROP_OFF = 3;
}

// 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
40 changes: 40 additions & 0 deletions gtfs-realtime/spec/en/examples/migration-modified.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Migration Guide - Transition from SKIPPED to MODIFIED

The GTFS-realtime `StopTimeUpdate.schedule_relationship` of `SKIPPED` indicates that a vehicle will not be serving a particular stop that was originally scheduled as a part of `stop_times.txt` in GTFS-static.

The GTFS-static `pickup_type` and `drop_off_type` fields within `stop_times.txt` allow an agency to specify details on what a rider needs to do in order to board/alight at a given stop (e.g. a rider must explicitly request a drop-off at a stop, otherwise the driver will skip the stop).

This migration guide defines how existing producers who use the `SKIPPED` enumeration as a best approximation of partial service at a stop can provide a more nuanced picture of the level of service through `pickup_type` and `drop_off_type` via `StopTimeProperties`. The goal is to minimize disruption to producers and consumers during the transition.

See the [Add pickup and drop-off types to GTFS-RT proposal on GitHub](https://github.com/google/transit/pull/265).

### Initially providing SKIPPED and pickup_type / drop_off_type in same feed

#### Producers

If you are a producer who uses the `SKIPPED` enumeration as a best approximation of partial service at a stop, to avoid disruption to existing consumers, it is recommended that you continue to produce `SKIPPED` entities for those stop time updates but also add `pickup_type` and `drop_off_type` entities for the same `StopTimeUpdate`.

Here's an example of indicating to consumers that a vehicle will be "drop-off only":

~~~
entity {
id: "ei0"
trip_update {
...
stop_time_update {
...
schedule_relationship: SKIPPED
stop_time_properties {
pickup_type: NO_PICKUP
drop_off_type: MUST_ASK_DRIVER_DROP_OFF
}
}
}
}
~~~

It is suggested that you notify existing consumers (e.g., via a developer mailing list) that the use of `SKIPPED` for partial service at a stop is being deprecated in favor of more nuanced information by a set deadline and that consumers should start consuming the `MODIFIED` enumeration as well as `pickup_type` and `drop_off_type`. You should also provide a link to this migration guide. After the deadline passes, you can stop using `SKIPPED` entities for scenarios where `pickup_type` or `drop_off_typ` are included and start using `MODIFIED` instead.

#### Consumers
`pickup_type` and `drop_off_type` set in `StopTimeProperties` takes precedence over `schedule_relationship=SKIPPED`, meaning that real-time arrival information should still be used to inform passengers rather being ignored, perhaps with additional instructions or notification on how to board/alight, similar to what may happen with those fields being specified in `stop_times.txt`.
34 changes: 34 additions & 0 deletions gtfs-realtime/spec/en/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ The relation between this StopTime and the static schedule.
| **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 information available. When set NO_DATA is propagated through subsequent stops so this is the recommended way of specifying from which stop you do not have realtime information. When NO_DATA is set neither arrival nor departure should be supplied. |
| **UNSCHEDULED** | The vehicle is operating a frequency-based trip (GTFS frequencies.txt with exact_times = 0). This value should not be used for trips that are not defined in GTFS frequencies.txt, or trips in GTFS frequencies.txt with exact_times = 1. Trips containing `stop_time_updates` with `schedule_relationship: UNSCHEDULED` must also set the TripDescriptor `schedule_relationship: UNSCHEDULED` <br><br>**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.
| **MODIFIED** | The vehicle's relationship with the static schedule differs in a way that impacts the rider experience, such as a vehicle not picking up passengers because a vehicle is "drop-off only" to catch up back to schedule when it's running late. StopTimeProperties must included to specify how the relationship has been modified. <br><br>**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.

## _message_ StopTimeProperties

Expand All @@ -213,6 +214,39 @@ Realtime update for certain properties defined within GTFS stop_times.txt.
| _**Field Name**_ | _**Type**_ | _**Required**_ | _**Cardinality**_ | _**Description**_ |
|------------------|------------|----------------|-------------------|-------------------|
| **assigned_stop_id** | [string](https://developers.google.com/protocol-buffers/docs/proto#scalar) | Optional | One | Supports real-time stop assignments. Refers to a `stop_id` defined in the GTFS `stops.txt`. <br> 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`. <br> To assign a stop without providing any real-time arrival or departure predictions, populate this field and set `StopTimeUpdate.schedule_relationship = NO_DATA`. <br> 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`). <br><br>**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. |
| **pickup_type** | [PickupType](#enum-pickuptype) | Optional | One | Supports real-time changes to pickup_type when it differs from what's specified in (CSV) GTFS in `stop_times.txt`. See definition of `stop_times.pickup_type` in (CSV) GTFS. If `pickup_type` is specified, `StopTimeUpdate.schedule_relationship` should be `MODIFIED`. <br><br>**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. |
| **drop_off_type** | [DropOffType](#enum-dropofftype) | Optional | One | Supports real-time changes to drop_off_type when it differs from what's specified in (CSV) GTFS in `stop_times.txt`. See definition of `stop_times.drop_off_type` in (CSV) GTFS. If drop_off_type is specified, `StopTimeUpdate.schedule_relationship` should be `MODIFIED`.
<br><br>**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future. |

## _enum_ PickupType

Indicates the pickup method for an updated stop time when it differs from what's specified in (CSV) GTFS in stop_times.txt By default, if pickup_type is neither specified in real-time or in (CSV) GTFS, it is considered REGULAR_PICKUP.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.

#### Values

| _**Value**_ | _**Comment**_ |
|-------------|---------------|
| **REGULAR_PICKUP** | See definition of stop_times.pickup_type=0 in (CSV) GTFS. |
| **NO_PICKUP** | See definition of stop_times.pickup_type=1 in (CSV) GTFS. |
| **MUST_PHONE_AGENCY_PICKUP** | See definition of stop_times.pickup_type=2 in (CSV) GTFS. |
| **MUST_ASK_DRIVER_PICKUP** | See definition of stop_times.pickup_type=3 in (CSV) GTFS. |

## _enum_ DropOffType

Indicates the drop off method for an updated stop time when it differs from what's specified in (CSV) GTFS in stop_times.txt. By default, if drop_off_type is neither specified in real-time or in (CSV) GTFS, it is considered REGULAR_DROP_OFF.

**Caution:** this field is still **experimental**, and subject to change. It may be formally adopted in the future.

#### Values

| _**Value**_ | _**Comment**_ |
|-------------|---------------|
| **REGULAR_DROP_OFF** | See definition of stop_times.drop_off_type=0 in (CSV) GTFS. |
| **NO_DROP_OFF** | See definition of stop_times.drop_off_type=1 in (CSV) GTFS. |
| **MUST_PHONE_AGENCY_DROP_OFF** | See definition of stop_times.drop_off_type=2 in (CSV) GTFS. |
| **MUST_ASK_DRIVER_DROP_OFF** | See definition of stop_times.drop_off_type=3 in (CSV) GTFS. |

## _message_ TripProperties

Expand Down
4 changes: 2 additions & 2 deletions gtfs-realtime/spec/en/trip-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ Each [StopTimeUpdate](reference.md#StopTimeUpdate) is linked to a stop. Ordinari

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

For each [StopTimeUpdate](reference.md#StopTimeUpdate), the default schedule relationship is **scheduled**. (Note that this is different from the schedule relationship for the trip). You may change this to **skipped** if the stop will not be stopped at, or **no data** if you only have realtime data for some of the trip.
For each [StopTimeUpdate](reference.md#StopTimeUpdate), the default schedule relationship is **scheduled**. (Note that this is different from the schedule relationship for the trip). You may change this to **skipped** if the stop will not be stopped at, **modified** if stop time properties are different than what's specified in `stop_times.txt`, or **no data** if you only have realtime data for some of the trip.

**Updates should be sorted by stop_sequence** (or stop_ids in the order they occur in the trip).

If one or more stops are missing along the trip the `delay` from the update (or, if only `time` is provided in the update, a delay computed by comparing the `time` against the GTFS schedule time) is propagated to all subsequent stops. This means that updating a stop time for a certain stop will change all subsequent stops in the absence of any other information. Note that updates with a schedule relationship of `SKIPPED` will not stop delay propagation, but updates with schedule relationships of `SCHEDULED` (also the default value if schedule relationship is not provided) or `NO_DATA` will.
If one or more stops are missing along the trip the `delay` from the update (or, if only `time` is provided in the update, a delay computed by comparing the `time` against the GTFS schedule time) is propagated to all subsequent stops. This means that updating a stop time for a certain stop will change all subsequent stops in the absence of any other information. Note that updates with a schedule relationship of `SKIPPED` or `MODIFIED` will not stop delay propagation, but updates with schedule relationships of `SCHEDULED` (also the default value if schedule relationship is not provided) or `NO_DATA` will.

**Example 1**

Expand Down