Skip to content

Commit

Permalink
Integrate external MKdown files (#505)
Browse files Browse the repository at this point in the history
  • Loading branch information
fredericsimard authored Jul 25, 2024
1 parent 462dfdb commit 76da847
Show file tree
Hide file tree
Showing 17 changed files with 704 additions and 79 deletions.
18 changes: 8 additions & 10 deletions docs/realtime/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ For example, a `VehiclePosition` entity has `vehicle_id:A` and `trip_id:4`, then
| --- | --- |
| `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.
Expand Down Expand Up @@ -129,6 +128,7 @@ General guidelines for alerts:
| --- | --- |
| `description_text` | Use line breaks to make your service alert easier to read. |


## Practice Recommendations Organized by Use Case

### Frequency-based trips
Expand All @@ -140,26 +140,24 @@ A frequency-based trip does not follow a fixed schedule but attempts to maintain
* As required by the spec, when describing `trip` in [TripUpdate](#TripUpdate) or [VehiclePosition](#VehiclePosition) by using [TripDescriptor](#TripDescriptor), all of `trip_id`, `start_time`, and `start_date` must be provided. Additionally, `schedule_relationship` should be `UNSCHEDULED`.
(e.g., re-enforcement trips).


## About This Document
## About This Document

### Objectives

The objectives of maintaining GTFS Realtime Best Practices are to:
The objectives of these GTFS Best Practices are:

* Support greater interoperability of transit data
* Improve end-user customer experience in public transportation apps
* Make it easier for software developers to deploy and scale applications, products, and services
* Facilitate the use of GTFS in various application categories (beyond its original focus on trip planning)

### How to propose or amend published GTFS Realtime Best Practices

The Best Practices are in the process of being merged into the official GTFS Realtime reference, and some GTFS Best Practices will be removed from this document as this is happening.

If you'd like to suggest a new best practice, please go to the [GTFS Reference GitHub repository](https://github.com/google/transit/) to open an issue or create a PR, or contact [specifications@mobilitydata.org](mailto:specifications@mobilitydata.org).
### Contributing
New Best Practices are now being added directly into the [spec](https://gtfs.org/schedule/reference/) in order to gradually consolidate both documents.
If you'd like to suggest a new best practice, please go to the [GTFS Reference GitHub repository](https://github.com/google/transit/), [open an issue](https://github.com/google/transit/issues/new/choose) or create a Pull Request, or contact [specifications@mobilitydata.org](mailto:specifications@mobilitydata.org).

### Linking to This Document

Please link here in order to provide feed producers with guidance for correct formation of GTFS Realtime data. Each individual recommendation has an anchor link. Click the recommendation to get the URL for the in-page anchor link.

If a GTFS Realtime-consuming application makes requirements or recommendations for GTFS Realtime data practices that are not described here, it is recommended to publish a document with those requirements or recommendations to supplement these common best practices.


12 changes: 12 additions & 0 deletions docs/realtime/feed-entities/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ use data on current speed and odometer readings from the vehicle.

[More about Vehicle Position updates...](vehicle-positions.md)

## Trip Modifications

#### "These trips are affected by a detour on certain days"

Trip modifications are used to describe detours which affect a set of trips.

A trip modification can cancel certain stops, adjust the timing for trips,
provide a new shape that trips will take and provide the location of temporary
stops along the way.

[More about Trip Modifications...](trip-modifications.md)

## Historical remark on feed types

Early versions of GTFS Realtime Specification required each feed to only contain
Expand Down
62 changes: 62 additions & 0 deletions docs/realtime/feed-entities/trip-modifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Trip Modifications

# Trip Modifications

A `TripModifications` message identifies a list of similar `trip_ids` from the (CSV) GTFS which are all affected by particular modifications, such as a detour.

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

## SLO: Service-level objective

The frequency of data updates is expected to be approximately hourly (~24 times/day). Ingestion time may depend on the total number of affected trips. Consumers are expected to ingest a single TripModification within 5 minutes, and a feed with hundreds of detours within 20 minutes.

## TripModifications

The `TripModifications` is in effect on all of the listed service\_dates, until it is removed from the feed. On any given service date, a trip MUST NOT be assigned to more than one `TripModifications` object.

There MAY be multiple `TripModifications` for a given stop pattern. It may be desirable to split the trips into multiple modifications e.g. if the `propagated_modification_delay` changes significantly, over the course of the detour.

The trips created through GTFS-TripModifications modify and replace each specified `trip_id`, and don't create a copy or additional run. Modifications are applied on the schedule information, like if a static GTFS (CSV) was modified.

The scheduled stop times of each replacement trip are created from those of the affected trip, by performing the changes listed in modifications. `stop_sequence` for all stop times are replaced by a new value of 1 to n, starting with 1 on the first stop_time and increasing by 1 for each stop in the trip. A `TripUpdate` message must be provided to publish real-time arrival/departure times for the replacement trip.


## Linkage to TripUpdates

* A TripUpdate SHOULD be provided using a `ModifiedTripSelector` inside the TripUpdate's `TripDescriptor`.
* When the TripUpdate refers to the replacement trip, the consumer should behave as if the static GTFS would have been modified with the TripModifications (e.g. `arrival_time`, `departure_time`, `stop_sequence`, `stop_id` on replacement stops).
* When providing a `ModifiedTripSelector`, the other fields of the `TripDescriptor` MUST be left empty, to avoid confusion by consumers that aren't looking for the `ModifiedTripSelector` value.
* TripUpdate feeds providing updates with `ModifiedTripSelector` SHOULD also include a TripUpdate targeting clients that don't support TripModifications. In other words, there should be two TripUpdates: one for clients with modified trips (with `TripModifications`) and one for clients with the originial unmodified GTFS (without `TripModifications`).
* Providing a TripUpdate with a `ModifiedTripSelector` is the only way to create predictions at replacement stops.
* If no such TripUpdate is found, TripUpdates for the original `trip_id` will apply to the modified trip.
* In this case, the static GTFS information used should be from the static GTFS before any TripModifications applied.
* Real time information can be available to the common stops between the previous trip and the new modified trip; however, no ETA would be available at the replacement stops.

## Modification

A `Modification` message describes changes to each affected trip starting at `start_stop_selector`. There can be zero, one, or more than one stop time(s) replaced by a `Modification`. The spans of the modifications MUST not overlap. Spans may not be contiguous; in this case the two modifications MUST be merged into one. These stop times are replaced with a new stop time for each replacement stop described by `replacement_stops`.

The sequence of `replacement_stops` may be of arbitrary length. For example, 3 stops could be replaced by 2, 4, or 0 stops as the situation may require.

![](../../assets/trip_modification.png)

_An example showing the effect of a modification on a particular trip. This modification may also be applied to several other trips._

![](../../assets/propagated_delay.png)

_Propagated detour delays affect all stops following the end of a modification. If a trip has multiple modifications, the delays are accumulated._

## ReplacementStop

Each `ReplacementStop` message defines a stop that will now be visited by the trip, and optionally specifies the estimated travel time to the stop. The `ReplacementStop` message is used to construct the scheduled `stop_time` for the stop.

When `travel_time_to_stop` is specified, the `arrival_time` is calculated from a reference stop in the original trip, plus the offset in `travel_time_to_stop`. Otherwise, the `arrival_time` can be be interpolated based on the total duration of the modification in the original trip.

The `departure_time` always equals the `arrival_time`.

The optional fields of [`stop_times.txt`](../schedule/reference/#stop_timestxt) in the (CSV) GTFS specification are all set to their default values.

![](../../assets/first_stop_reference.png)

_If a modification affects the first stop of the trip, that stop also serves as the reference stop of the modification._

156 changes: 156 additions & 0 deletions docs/realtime/gtfs-realtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ message FeedEntity {

// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
optional Shape shape = 6;
optional Stop stop = 7;
optional TripModifications trip_modifications = 8;

// The extensions namespace allows 3rd-party developers to extend the
// GTFS Realtime Specification in order to add and evaluate new features and
Expand Down Expand Up @@ -840,6 +842,15 @@ message TripDescriptor {
}
optional ScheduleRelationship schedule_relationship = 4;

message ModifiedTripSelector {
// The 'id' from the FeedEntity in which the contained TripModifications object affects this trip.
optional string modifications_id = 1;

// The trip_id from the GTFS feed that is modified by the modifications_id
optional string affected_trip_id = 2;
}
optional ModifiedTripSelector modified_trip = 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.
Expand Down Expand Up @@ -1033,3 +1044,148 @@ message Shape {
// The following extension IDs are reserved for private use by any organization.
extensions 9000 to 9999;
}

// Describes a stop which is served by trips. All fields are as described in the GTFS-Static specification.
// NOTE: This message is still experimental, and subject to change. It may be formally adopted in the future.
message Stop {
enum WheelchairBoarding {
UNKNOWN = 0;
AVAILABLE = 1;
NOT_AVAILABLE = 2;
}

optional string stop_id = 1;
optional TranslatedString stop_code = 2;
optional TranslatedString stop_name = 3;
optional TranslatedString tts_stop_name = 4;
optional TranslatedString stop_desc = 5;
optional float stop_lat = 6;
optional float stop_lon = 7;
optional string zone_id = 8;
optional TranslatedString stop_url = 9;
optional string parent_station = 11;
optional string stop_timezone = 12;
optional WheelchairBoarding wheelchair_boarding = 13 [default = UNKNOWN];
optional string level_id = 14;
optional TranslatedString platform_code = 15;

// 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.
extensions 1000 to 1999;

// The following extension IDs are reserved for private use by any organization.
extensions 9000 to 9999;
}

// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
message TripModifications {
// A `Modification` message replaces a span of n stop times from each affected trip starting at `start_stop_selector`.
message Modification {
// The stop selector of the first stop_time of the original trip that is to be affected by this modification.
// Used in conjuction with `end_stop_selector`.
// `start_stop_selector` is required and is used to define the reference stop used with `travel_time_to_stop`.
optional StopSelector start_stop_selector = 1;

// The stop selector of the last stop of the original trip that is to be affected by this modification.
// The selection is inclusive, so if only one stop_time is replaced by that modification, `start_stop_selector` and `end_stop_selector` must be equivalent.
// If no stop_time is replaced, `end_stop_selector` must not be provided. It's otherwise required.
optional StopSelector end_stop_selector = 2;

// The number of seconds of delay to add to all departure and arrival times following the end of this modification.
// If multiple modifications apply to the same trip, the delays accumulate as the trip advances.
optional int32 propagated_modification_delay = 3 [default = 0];

// A list of replacement stops, replacing those of the original trip.
// The length of the new stop times may be less, the same, or greater than the number of replaced stop times.
repeated ReplacementStop replacement_stops = 4;

// An `id` value from the `FeedEntity` message that contains the `Alert` describing this Modification for user-facing communication.
optional string service_alert_id = 5;

// This timestamp identifies the moment when the modification has last been changed.
// In POSIX time (i.e., number of seconds since January 1st 1970 00:00:00 UTC).
optional uint64 last_modified_time = 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.
extensions 1000 to 1999;

// The following extension IDs are reserved for private use by any organization.
extensions 9000 to 9999;
}

message SelectedTrips {
// A list of trips affected with this replacement that all have the same new `shape_id`.
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.
optional string shape_id = 2;

// 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.
extensions 1000 to 1999;

// The following extension IDs are reserved for private use by any organization.
extensions 9000 to 9999;
}

// A list of selected trips affected by this TripModifications.
repeated SelectedTrips selected_trips = 1;

// A list of start times in the real-time trip descriptor for the trip_id defined in trip_ids.
// Useful to target multiple departures of a trip_id in a frequency-based trip.
repeated string start_times = 2;

// Dates on which the modifications occurs, in the YYYYMMDD format. Producers SHOULD only transmit detours occurring within the next week.
// The dates provided should not be used as user-facing information, if a user-facing start and end date needs to be provided, they can be provided in the linked service alert with `service_alert_id`
repeated string service_dates = 3;

// A list of modifications to apply to the affected trips.
repeated Modification modifications = 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.
extensions 1000 to 1999;

// The following extension IDs are reserved for private use by any organization.
extensions 9000 to 9999;
}

// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
// Select a stop by stop sequence or by stop_id. At least one of the two values must be provided.
message StopSelector {
// Must be the same as in stop_times.txt in the corresponding GTFS feed.
optional uint32 stop_sequence = 1;
// Must be the same as in stops.txt in the corresponding GTFS feed.
optional string stop_id = 2;

// 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.
extensions 1000 to 1999;

// The following extension IDs are reserved for private use by any organization.
extensions 9000 to 9999;
}

// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
message ReplacementStop {
// The difference in seconds between the arrival time at this stop and the arrival time at the reference stop. The reference stop is the stop prior to start_stop_selector. If the modification begins at the first stop of the trip, then the first stop of the trip is the reference stop.
// 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).
optional string stop_id = 2;

// 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.
extensions 1000 to 1999;

// The following extension IDs are reserved for private use by any organization.
extensions 9000 to 9999;
}
1 change: 1 addition & 0 deletions docs/realtime/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The specification currently supports the following types of information:
* **Trip updates** - delays, cancellations, changed routes
* **Service alerts** - stop moved, unforeseen events affecting a station, route or the entire network
* **Vehicle positions** - information about the vehicles including location and congestion level
* **Trip modifications** - information about detours affecting a set of trips

A feed may, although not required to, combine entities of different types. Feeds are served via HTTP and updated frequently. The file itself is a regular binary file, so any type of webserver can host and serve the file (other transfer protocols might be used as well). Alternatively, web application servers could also be used which as a response to a valid HTTP GET request will return the feed. There are no constraints on how frequently nor on the exact method of how the feed should be updated or retrieved.

Expand Down
15 changes: 8 additions & 7 deletions docs/realtime/language-bindings/dotnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
[![NuGet version](https://badge.fury.io/nu/GtfsRealtimeBindings.svg)](http://badge.fury.io/nu/GtfsRealtimeBindings)

Provides .NET classes generated from the
[GTFS-realtime](https://github.com/google/transit/tree/master/gtfs-realtime) Protocol
Buffer specification. These classes will allow you to parse a binary Protocol
[GTFS Realtime](https://gtfs.org/realtime/proto/) Protocol
Buffer specification. These classes will allow you to parse a binary Protocol
Buffer GTFS-realtime data feed into C# objects.

## Add the Dependency
Expand All @@ -24,13 +24,14 @@ from a particular URL, parsing it as a FeedMessage (the root type of the
GTFS-realtime schema), and iterating over the results.

```csharp
using System.Net;
using ProtoBuf;
using TransitRealtime;

WebRequest req = HttpWebRequest.Create("URL OF YOUR GTFS-REALTIME SOURCE GOES HERE");
FeedMessage feed = Serializer.Deserialize<FeedMessage>(req.GetResponse().GetResponseStream());
foreach (FeedEntity entity in feed.Entities) {
var client = new HttpClient();
using var stream = await client.GetStreamAsync("URL OF YOUR GTFS-REALTIME SOURCE GOES HERE");
var feed = Serializer.Deserialize<FeedMessage>(stream);
foreach (var entity in feed.Entities)
{
...
}
```
```
Loading

0 comments on commit 76da847

Please sign in to comment.