diff options
author | isabelle-dr | 2022-03-22 19:33:40 -0400 |
---|---|---|
committer | isabelle-dr | 2022-03-22 19:33:40 -0400 |
commit | 24e89c97cbbdd89348b1f02497a129ac8ac0a14f (patch) | |
tree | ac8432b0731525e889b6dfefa1401ce277af6893 /.idea/gtfs-realtime-book/ch-08-consuming-trip-updates.md | |
parent | ab1b75da67be3e101e40e0ae3052d73c714b8ea3 (diff) |
re arrange repo
Diffstat (limited to '.idea/gtfs-realtime-book/ch-08-consuming-trip-updates.md')
-rw-r--r-- | .idea/gtfs-realtime-book/ch-08-consuming-trip-updates.md | 380 |
1 files changed, 0 insertions, 380 deletions
diff --git a/.idea/gtfs-realtime-book/ch-08-consuming-trip-updates.md b/.idea/gtfs-realtime-book/ch-08-consuming-trip-updates.md deleted file mode 100644 index 867e30f..0000000 --- a/.idea/gtfs-realtime-book/ch-08-consuming-trip-updates.md +++ /dev/null @@ -1,380 +0,0 @@ -## 8. Consuming Trip Updates - -Of the three message types in GTFS-realtime, trip updates are the most -complex. A single trip update can contain a large quantity of data and -is used to transform the underlying schedule. Trips can be modified in a -number of ways: trips can be canceled, stops can be skipped, and arrival -times can be updated. - -This chapter will show you how to consume trip updates and will discuss -real-world scenarios and how they can be represented using trip updates. - -Similar to service alerts and vehicle positions, you can loop over the -`FeedEntity` objects from `getEntityList()` to access and then -process `TripUpdate` objects. - -```java -for (FeedEntity entity : fm.getEntityList()) { - if (entity.hasTripUpdate()) { - TripUpdate tripUpdate = entity.getTripUpdate(); - - processTripUpdate(tripUpdate); - } -} -``` - -### Timestamp - -Just like with vehicle position updates, trip updates include a -timestamp value. This indicates when the real-time data was updated, -including any subsequent arrival/departure estimates contained within -the trip update. - -You can read this value into a native `java.util.Date` object as -follows: - -```java -if (tripUpdate.hasTimestamp()) { - Date timestamp = new Date(tripUpdate.getTimestamp() * 1000); - -} -``` - -**Note:** The value is multiplied by 1,000 because the java.util.Date -class accepts milliseconds, whereas GTFS-realtime uses whole seconds. - -Two of the ways you can use the timestamp value are: - -* When telling your users arrival estimates, you can also show the - timestamp so they know when the estimate was made. A newer estimate - (e.g. one minute old) is likely to be more reliable than an older - one (e.g. ten minutes old). -* You can also use the timestamp to decide whether or not to keep the - estimate. For instance, if for some reason a feed did not refresh in - a timely manner and all of the estimates were hours old, you could - simply skip over them as they would no longer provide meaningful - information. - -### Trip Information - -Each trip update contains necessary data so the included estimates can -be linked to a trip in the corresponding GTFS feed. - -There are three ways estimate data can be provided in a trip update: - -* The trip update contains estimates for all stops. -* The trip update contains estimates for some stops. -* The trip has been canceled, so there is no stop information. - -If the trip has been added (that is, it is not a part of the schedule in -the GTFS feed), then the trip descriptor has no use in resolving the -trip back to the GTFS feed. - -However, if a trip update only contains updates for some of the stops, -you must be able to find the entire trip in the GTFS feed so you can -propagate the arrival delay to subsequent stops. - -The following code shows how to extract values such as the GTFS trip ID -and route ID from the `TripDescriptor` object. - -```java -if (tripUpdate.hasTrip()) { - TripDescriptor trip = tripUpdate.getTrip(); - - if (trip.hasTripId()) { - String tripId = trip.getTripId(); - - // ... - } - - if (trip.hasRouteId()) { - String routeId = trip.getRouteId(); - - // ... - } - - if (trip.hasStartDate()) { - String startDate = trip.getStartDate(); - - // ... - } - - if (trip.hasStartTime()) { - String startTime = trip.getStartTime(); - - // ... - } - - if (trip.hasScheduleRelationship()) { - ScheduleRelationship sr = trip.getScheduleRelationship(); - - // ... - } -} -``` - -### Trip Delay - -Although only an experimental part of the GTFS-realtime specification at -the time of writing, a trip update can also contain a delay value. A -positive number indicates the number of seconds the vehicle is late, -while a negative value indicates the number of seconds early. A value of -`0` means the vehicle is on-time. - -This value can be used for any stop along the trip that does not -otherwise have an associated `StopTimeEvent` element. - -```java -if (tripUpdate.hasDelay()) { - int delay = tripUpdate.getDelay(); - - if (delay == 0) { - // on time - - } - else if (delay < 0) { - // early - - } - else if (delay > 0) { - // late - - } -} -``` - -### Vehicle Identifiers - -The `VehicleDescriptor` object contained in a trip update provides a -number of values by which to identify a vehicle. You can access an -internal identifier (not for public display), a label (such as a vehicle -number painted on to a vehicle), or a license plate. - -The following code shows how to access these values: - -```java -if (tripUpdate.hasVehicle()) { - VehicleDescriptor vehicle = tripUpdate.getVehicle(); - - if (vehicle.hasId()) { - String id = vehicle.getId(); - - } - - if (vehicle.hasLabel()) { - String label = vehicle.getLabel(); - - } - - if (vehicle.hasLicensePlate()) { - String licensePlate = vehicle.getLicensePlate(); - - } -} -``` - -The vehicle descriptor and the values contained within are all optional. -In the case where this information is not available, you can use the -trip descriptor information provided with each vehicle position to match -up vehicle positions across multiple updates. - -### Stop Time Updates - -Each trip update contains a number of stop time updates, each of which -is a `StopTimeUpdate` object. You can access each of the -`StopTimeUpdate` objects by calling **getStopTimeUpdateList()**. - -```java -for (StopTimeUpdate stopTimeUpdate : tripUpdate.getStopTimeUpdateList()) { - // ... -} -``` - -Alternatively, you can loop over each `StopTimeUpdate` object as -follows: - -```java -for (int i = 0; i < tripUpdate.getStopTimeUpdateCount(); i++) { - StopTimeUpdate stopTimeUpdate = tripUpdate.getStopTimeUpdate(i); - - // ... -} -``` - -Each `StopTimeUpdate` object contains a schedule relationship value -(using the `ScheduleRelationship` class, which is different to that -contained in `TripDescriptor` objects). - -The schedule relationship dictates how to use the rest of the data in -the stop time update, as well as which data will be present. If the -schedule relationship value is not present, the value is assumed to be -`SCHEDULED`. - -```java -ScheduleRelationship sr; - -if (stopTimeUpdate.hasScheduleRelationship()) { - sr = stopTimeUpdate.getScheduleRelationship(); - -} -else { - sr = ScheduleRelationship.SCHEDULED; - -} - -if (sr.getNumber() == ScheduleRelationship.SCHEDULED_VALUE) { - // An arrival and/or departure estimate is provided - -} -else if (sr.getNumber() == ScheduleRelationship.NO_DATA_VALUE) { - // No real-time data available in this update - -} -else if (sr.getNumber() == ScheduleRelationship.SKIPPED_VALUE) { - // The vehicle will not stop at this stop - -} -``` - -### Stop Information - -In order to determine which stop a stop time update corresponds to, -either the stop ID or stop sequence (or both) must be specified. You can -then look up the stop based on its entry in `stops.txt`, or determine -the stop based on the corresponding entry in `stop_times.txt`. - -```java -if (stopTimeUpdate.hasStopId()) { - String stopId = stopTimeUpdate.getStopId(); - -} - -if (stopTimeUpdate.hasStopSequence()) { - int sequence = stopTimeUpdate.getStopSequence(); - -} -``` - -### Arrival/Departure Estimates - -If the `ScheduleRelationship` value is `SKIPPED` there must either -be an arrival or departure object specified. Both the arrival and -departure use the `StopTimeEvent` class, which can be accessed as -follows. - -The following code shows how to access these values: - -```java -if (sr.getNumber() == ScheduleRelationship.SCHEDULED_VALUE) { - if (stopTimeUpdate.hasArrival()) { - StopTimeEvent arrival = stopTimeUpdate.getArrival(); - - // Process the arrival - } - - if (stopTimeUpdate.hasDeparture()) { - StopTimeEvent departure = stopTimeUpdate.getDeparture(); - - // Process the departure - } -} -``` - -Each `StopTimeEvent` object contains either an absolute timestamp for -the arrival or departure, or it contains a delay value. The delay value -is relative to the scheduled time in the corresponding GTFS feed. - -```java -if (stopTimeUpdate.hasArrival()) { - StopTimeEvent arrival = stopTimeUpdate.getArrival(); - - if (arrival.hasDelay()) { - int delay = arrival.getDelay(); - - // ... - } - - if (arrival.hasTime()) { - Date time = new Date(arrival.getTime() * 1000); - - // ... - } - - if (arrival.hasUncertainty()) { - int uncertainty = arrival.getUncertainty(); - - // ... - } -} -``` - -### Trip Update Scenarios - -This chapter has shown you how to handle trip update information as it -appears in a GTFS-realtime feed. It is also important to understand the -intent of the data provider when reading these updates. Consider the -following scenarios that can occur frequently in large cities: - -1. **A train needs to skip one or more stops.** Perhaps the station has - been closed temporarily due to unforeseen circumstances. -2. **A train that was scheduled to bypass a station will now stop at - it.** Perhaps there is a temporary delay on the line so the train - will wait at a stop while the track is cleared. -3. **A bus is rerouted down a different street.** Perhaps there was a - car accident earlier and police have redirected traffic. -4. **A train will stop at a different platform.** For example, instead - of a train stopping at platform 5 at a given station, it will now - stop at platform 6. This happens frequently on large train networks - such as in Sydney. -5. **A bus trip is completely canceled.** Perhaps the bus has broken - down and there is no replacement vehicle. -6. **An unplanned trip is added.** Perhaps there is an unexpectedly - large number of passengers so extra buses are brought in to clear - the backlog. - -While each provider may represent these scenarios differently in -GTFS-realtime, it is likely each of them would be represented as -follows. - -1. **Modify the existing trip.** Include a `StopTimeUpdate` for each - stop that is to be canceled with a `ScheduleRelationship` value of - `SKIPPED`. -2. **Cancel the trip and add a new one.** Unfortunately, there is no - way in GTFS-realtime to insert a stop into an existing trip. The - `ScheduleRelationship` value for the trip would be set to - `CANCELED` (in the `TripDescriptor`, not in the - `StopTimeUpdate` elements). -3. If a bus is rerouted down a different street, how it is handled - depends on which stops are missed: - - * If no stops are to be made on the new street, cancel the stops - impacted by the detour, similar to scenario 1. - * If the bus will stop on the new street to drop passengers off or - pick them up, then cancel the trip and add a new one, similar to - scenario 2. - -4. **Cancel the trip and add a new one.** Since it is not possible to - insert a stop using GTFS-realtime, the existing trip must be - canceled and a new trip added to replace it if you want the platform - to be reflected accurately. Note, however, that many data providers - do not differentiate between platforms in their feeds, so they only - refer to the parent station instead. In this instance a platform - change should be communicated using service alerts if it could - otherwise cause confusion. -5. **Cancel the trip.** In this instance you would not need to include - any `StopTimeUpdate` elements for the trip; rather, you would - specify `CANCELED` in the `ScheduleRelationship` field of - `TripDescriptor`. -6. **Add a new trip.** When adding a new trip, all of the stops in the - trip should also be included (not just the next one). The - `ScheduleRelationship` for the trip would be set to `ADDED`. - -The important takeaway from this section is that if you are telling your -users that a trip has been canceled, you need to make it clear to them -if a new trip has replaced it, otherwise they may not correctly -understand the intent of the data. - -In these instances, hopefully the data provider also provides a -corresponding service alert so the reason for the change can be -communicated to passengers. - |