Finding direct connections between stations

Thanks a bunch for explanation. Are those branches always consisting of unique stopPoints? Because otherwise how should one know to which branch timetable returned by https://api.tfl.gov.uk/Line/{id}/Timetable/{fromStopPointId} belongs to. From quick check https://api.tfl.gov.uk/Line/el3/Route/Sequence/inbound has stopPoint “490016747E” that is used as a starting point for couple of branches

Also what is a correlation of stopPointSequences branches and Route Sections returned by https://api.tfl.gov.uk/Line/{routeId}/Route if there is any?

The first and last StopPoint of each branch will often be shared amongst multiple branches, because that is where the route diverges or joins. The StopPoints in-between are usually unique, however I’d be hesitant to guarantee it.

I don’t think the API is really designed for cross-referencing timetables with route sequences, though you may be able to infer that information from the StopPoint IDs. May I ask what kind of use case you’re trying to solve?

The routeSections array returned from the Route request essentially corresponds to the orderedLineRoutes array from the Route Sequence request. In other words, these are the full end-to-end routes that are constructed from combinations of branches (which are defined in the stopPointSequences array from Route Sequence).

Thanks for clarification. I try to get “broad picture” of transportation data available to be able to utilize in our internal system - basically trying to get timetables for routes (like stop_times.txt in terms of GTFS). northern-rail especially seems to have lots of Route Sequences with stopPoints “reused” between different “branches” (“branchId” is clearly not unique) and in some cases API response with an error saying “stop removed from the route and timetable” even though that stopPoint is returned as part of Route Sequence and is not the last stop (for example “910GCARLILE” being start of 87th stopPointSequence in https://api.tfl.gov.uk/Line/northern-rail/Route/Sequence/inbound).

And while speaking about Timetables in some cases multiple instances of timetables returned: for example https://api.tfl.gov.uk/Line/102/Timetable/490007476E?direction=inbound has 2 arrays of “routes” containing schedules and knownJourneys - from a quick look seems duplicate data however comparing with a tool some differences are shown (like intervals which I not sure what do they mean :slight_smile: )

We generally don’t recommend using the Unified API for data about National Rail services; it might be worth checking out Network Rail’s or National Rail Enquiries’s open data offerings.

As for timetables, I’m not entirely sure why it’s returning two timetables, but it could be that there are two timetables with different validity periods, e.g. one timetable valid for now, and another timetable valid from a future date. If you require more granular data, you may be interested in our TransXChange files (.zip).

If the intervals between the stops are different then its likely that one set is for normal hours and the other for peak hours/Early morning/late night. Same route but different run times

On many bus routes there isn’t really a normal set of running times; they change many times during the day. A far cry from the 1960s when the running time was constant for all journeys but then you didn’t have masses of data on actual running times or the ability easily to analyse it.

I imagine than tube running times have far less variation because there aren’t any cars in the way!

@LeonByford
Returning to the bus times given on Journey Planner, would there be a case for distinguishing in the output a time generated using live data from those emanating from the schedules?

Do you mean in the Unified API or in the user interface?

In the Unified API, a Leg object looks like the following (to keep this concise, I’ve used empty objects and arrays for properties that aren’t relevant to this):

{
  "$type": "Tfl.Api.Presentation.Entities.JourneyPlanner.Leg, Tfl.Api.Presentation.Entities",
  "duration": 1,
  "instruction": {},
  "obstacles": [],
  "departureTime": "2023-06-09T08:16:00",
  "arrivalTime": "2023-06-09T08:17:00",
  "departurePoint": {},
  "arrivalPoint": {},
  "path": {},
  "routeOptions": [],
  "mode": {},
  "disruptions": [],
  "plannedWorks": [],
  "isDisrupted": false,
  "hasFixedLocations": true,
  "scheduledDepartureTime": "2023-06-09T08:15:00",
  "scheduledArrivalTime": "2023-06-09T08:16:00"
}

Note that there are two sets of timestamps. scheduledDepartureTime and scheduledArrivalTime are always the scheduled departure and arrival timestamps for that leg, without being affected by live data.

departureTime and arrivalTime, on the other hand, are affected by live data. If live data is available, they will reflect that data. If live data is not available, however, they will fall back on schedule data and be equal to scheduledDepartureTime and scheduledArrivalTime.

That said, from this data, it’s not currently possible to tell whether a given leg is using live data or not. If departureTime is different to scheduledDepartureTime or arrivalTime is different to scheduledArrivalTime, then you can tell. However, if the bus/train is running exactly on time, you won’t be able to tell if the timestamps are based on live data or not.

Would anyone find it useful for us to provide a flag to tell you whether live data is being used or not? If there is any interest, please let me know.

As for the user interface (UI), we have explored this quite extensively. Of course, we show the live data in the UI where available, but we don’t currently indicate that it is live data. So far we haven’t found a good way to indicate this. We did have the idea that if a bus is running late, we could provide some kind of indicator of that. However, for high frequency bus routes, passengers don’t tend to care if a bus is running late or not – it’s the frequency of service that’s important. There’s little point in confusing users by saying their bus is running late if it doesn’t actually make any difference to them. In some cases, a late-running bus would actually be beneficial to a given user (because they may be able to catch a bus they’d have otherwise missed).

Although we could simply add some sort of “Live” indicator in the UI, we don’t want to confuse users into thinking that the time will automatically update on their screen. The live times in Journey Planner are only live at the time that the journey is calculated, so calling them “live” in the UI could be deceptive.

TfL Go now has a feature where if you plan a journey, you may see a “Live buses at this stop” button that takes you to the live arrivals board for that stop. This is more the kind of information we would describe as “live” in the UI, because it updates on your screen. In the future, we would like to integrate this display of automatically updating information into Journey Planner a bit more seamlessly.

@LeonByford
Thanks. As with all these things, even if it can be done it doesn’t necessarily mean that it should be and there is a risk of solving one apparent issue but creating worse ones.

I was thinking primarily of the info presented to the passenger via Journey Planner but I can see that it could be a wider question. I was thinking that if a service is largely disrupted, turning short of whatever then you will get 30 minutes or so of “actuals” showing the disruption and then a discontinuity to a service which runs perfectly to schedule. A bit like the discontinuity between low and high frequency periods of operation, the one whose abolition I had failed to spot!

If you could reliably distinguish (which at the moment you can’t), my first thought would be to out a flag against the schedule-derived times rather than the live ones. I know it is a different usage but I think Hertfordshire’s stop info says “12 mins” or whatever for live data and hh:mm for schedule-derived but (even of I am correct) I doubt more than a few appreciate the difference. (On a tangent but I did laugh when I saw an at-stop info screen telling passengers that the next bnus was at 08:30 the next morning!).

Would doing anything be worth the effort? No idea; I suppose for the Journey Planner user interface it may be that 99.9% of uses are planning a journey for later on, in which case live data are irrelevant.

Thanks for your thoughts on this. Interestingly, our analytics tell us that most Journey Planner users are actually planning journeys for now or within the next couple of hours, so providing live information is quite important to us.