public-transport / transport.rest

Information about the *.transport.rest APIs.

Home Page:https://transport.rest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to get a list of all trains at a station in a given time frame?

plnms opened this issue · comments

commented

For a personal project I'd like to get a list of all trains at a station in a certain time frame such as provided by bahn.expert and DBF. I can't use one of /stops/:id/arrivals or /stops/:id/departures, at least not with only one query, since AFAIK /stops/:id/departures misses the data of trains that end at the station queried and /stops/:id/arrivals misses the trains that start at this station. I tried to use /trips with a station ID and a time frame, but every request that I have tried has returned a 400.

Is there any easy way to achieve my goal? And could you maybe extend the documentation for /trips, because I really don't understand how to use this?

I assume you're referring to the v6.db.transport.rest? I'm asking because this repo is an "umbrella" repo for multiple APIs.

For a personal project I'd like to get a list of all trains at a station in a certain time frame […]. I can't use one of /stops/:id/arrivals or /stops/:id/departures, at least not with only one query, since AFAIK /stops/:id/departures misses the data of trains that end at the station queried and /stops/:id/arrivals misses the trains that start at this station.

Indeed, you'd have fetch both sets of trains/trips and combine them. You can use the rel=next Link header exposed by the API to iterate over departures and/or arrivals:

curl 'https://v6.db.transport.rest/stops/8000263/departures?when=2023-02-14T10%3A43%2B01%3A00' -fsSL -I | grep link
# link: […] <?when=2023-02-14T10%3A53%2B01%3A00>; rel=next

I tried to use /trips with a station ID and a time frame, but every request that I have tried has returned a 400.

This is an unfortunate combination of two issues:

  • hafas-rest-api@6, a library used by v6.db.transport.rest, used to require a query, so you'd have to send query=* to still get all trains/trips, which is very unobvious. I have changed this, now omitting query should work.
  • HAFAS's JourneyMatch, the API beneath the /trips endpoint, is a very maverick thing: It only accepts very specific combinations of parameters, and I don't know anyone who has completely reverse-engineered it (my attempt). For many queries it either yields NO_MATCH or TOO_MANY. Unfortunately, this means that it is barely usable to fulfil use cases like yours.

Is there any easy way to achieve my goal? And could you maybe extend the documentation for /trips, because I really don't understand how to use this?

I would like to, but as I said: I don't know either what its limitations are.

commented

Excuse me for not specifying it but yes, I am referring to v6.db.transport.rest. Also excuse me for the late reply. Your explanations are very helpful, thank you! The /trips endpoint / HAFAS's JourneyMatch really are behaving weirdly now that I know how to play with /trips. If I find out anything helpful I'll let you know.

One minor request: What do you think of adding an example request to both /trips and /locations/nearby in the documentation? They are the only endpoints not to have one, and I found these examples very helpful in the other documentation entries. When experimenting, it's easier to find mistakes in a request altered from one known to work than in an entirely made up one. A very simple example for /trips would be

https://v6.db.transport.rest/trips?query=ICE%20529&onlyCurrentlyRunning=false

– but feel free to use a better one. I haven't played around with the other endpoint.

commented

Example using some more features, not using query:

https://v6.db.transport.rest/trips?fromWhen=2023-02-21T19:00:00Z&untilWhen=2023-02-21T20:00:00Z&currentlyStoppingAt=8000287&onlyCurrentlyRunning=false

This means "give me all trains meeting the following criteria":

  • time frame of one hour, today 8pm to 9pm (German time): selected by fromWhen and untilWhen
  • stopping at Oberkotzau station: selected by currentlyStoppingAt – the parameter is confusingly named in this context, as my query selects every train that will be "currently" stopping at the station in the given time frame
  • show trains that are not currently running, because they might not have begun their journey for time frames ending in the future / they might already have reached their terminus: selected by onlyCurrentlyRunning=false

This is actually pretty close to what I originally wanted to achieve. If cautiously used with additionally filtering out everything that's not a train (bus=false etc.) I can use it even for stations as big as Cologne central (8000207) without running into the fearsome TOO_MANY phenomenon.

Yes, please submit a PR with example URLs! Just add multiple, with a comment on each explaining what it does.

You'll have to adapt examples in api-docs.js; Then, please test your changes using npm run docs.

commented

The more I'm playing around with this, the weirder it gets. I don't want to give unhelpful information, so expect this to take some time.

Also, I've never really used Node, but I'm happy to execute this one command if it's just that.

Also, I've never really used Node, but I'm happy to execute this one command if it's just that.

If it's about not "polluting" your system with a toolchain that you usually don't need, you can do it in Docker: docker run --rm -it -v $PWD:/app node:18-alpine /bin/sh -c 'npm run docs'.

If it's about getting used to a new toolchain: Let me know if you encounter any issues! (Preferably, in the aforementioned PR.)

commented

Well. Both. Excuse me if I'm stupid, but I can't execute this either way. The Docker command (with nom replaced by npm) returns that it can't find '//package.json', and a locally installed npm, when called with npm run docs, is apparently looking for a script called 'docs' which does not exist.

The Docker command (with nom replaced by npm) returns that it can't find //package.json.

True, the command specified can't work. docker run --rm -it -v $PWD:/app -w /app node:18-alpine /bin/sh -c 'npm i && npm run docs' does for me.

a locally installed npm, when called with npm run docs, is apparently looking for a script called 'docs' which does not exist.

Did you run it inside the db-rest repo? All those commands refer to db-rest.

Summing this up:

Unfortunately, AFAICT, the very network-centric use case "give me all trips in a certain time frame connecting A and B" is not well-served by the underlying HAFAS API, as it has always been mainly user-/routing-centric. HAFAS' JourneyMatch is weird and fussy about possible inputs.

If you do find out more helpful information about it, please don't hesitate to comment in derhuerst/BahnhofsAbfahrten#1, so that others can benefit from this knowledge, too! It would also be great to add documentation about JourneyMatch to `hafts-client's API docs.

As a workaround, you can of course always use /stops/:id/departures & /stops/:id/arrivals, with the aforementioned limitations.

Please re-open this Issues if you have more related questions.