simpleEFA

Dieser Text liegt aktuell nur auf Englisch vor.

A repo containing the sources can be found here.

simpleEFA strives to supply web developers with a lightweight and easy-to-use API for the EFA (=Elektronische FahrplanAuskunft) system.

With it, you can create cool web applications like the Station Tracker, which gives you the live departure monitor of any train, bus or tramway station in europe, or the StadtbahnTracker, which display live tram cab positions for Freiburg, Germany.

EFA provides detailed timetables, sophisticated journey planning and POI information for any given coordinate. The system is widely used by public transportation companies in Germany, Switzerland and Austria, but also in countries around the world.

Despite its circulation, little to nothing is known about its architecture, making its employment virtually impossible.

An EFA installation usually consists of several services, usually

  • TRIP_REQUEST2
  • COORD_REQUEST
  • DM_REQUEST
These services can be accessed via URIs. For example, the EFA trip planning service of the public transportation company in Freiburg, Germany (VAG) can be accessed via

http://efa.vag-freiburg.de/vagfr/XSLT_TRIP_REQUEST2

Okay, but why another API?

Recent approaches (openBAHN, sbb.xiala.net) relied entirely on scraping rendered web pages, for example the mobile versions of bahn.de or sbb.ch. While this method lacks to provide reliable internal data like station ids, it fails miserably when the layout of the web page is changed. Above that, performance is usually very poor, since a completely rendered web page has to be delivered by the server.

simpleEFA relies on the XML-interface of the EFA system, accessible via service names beginning with XML_ instead of XSLT_, e.g. XML_TRIP_REQUEST2 or XML_DM_REQUEST. These documents are usually rendered multiple times faster then the corresponding XSLT-version. Above that, results contain a lot more useful information than the standard web pages aimed at average customers.

However, sending request to the EFA XML-interface and parsing results requires deep understanding of EFA's architecture. simpleEFA is a wrapper API which enables developers to efficiently use EFA's functionality.

How do I use this thing for my application?

Download the source files here and install simpleEFA on you own server. You have to enter some EFA-service for the API to work.

Several services exist. Each of them more or less maps an existing EFA-service and returns XML containing the results.

/stationname

This is the most basic service. It expects only one parameter:

station
can be set to any UTF-8 encoded string. simpleEFA will answer with a list of stations that fit this string. Each of this stations comes with a unique id which has to be used for any further queries.

The resulting XML will be structured like this:

possible_stations
for_input
Contains the original user input
station
Multiple stations matching the input string. The text value of this node is the station name including its location. Attribute matching tells how good input and station match. Higher is better, 100% is 1000. Attribute id is a unique station id.
location_name
The location of this station, usually the city.
station_name
The name of this station.
position
The exact coordinates of this station. Format is WGS 84, lat is the latitude, lng is the longitude.
For example, a XML list of all stations matching the input string "stuttgart hauptbahnhof" can be requested by using the URL
http://example.simpleefa/stationname?station=stuttgart%20hauptbahnhof
The usual flow is to first get a station id via the /stationname interface. Using strings as station identifiers with other services will almost certainly lead to a Station not found error.

/nextdepartures

This service provides detailed timetables for any given station. It is possible to select the methods of transportation and the departure time. Parameters:

station
is the unique id of the station the next departures should be requested. You have to get this id beforehand by calling the /stationname service.
time
a timestamp in milliseconds. If left blank, you will get the next departures based on the current server time. If you want for example the next departures for a specific date and time, you have to set this parameter to the corresponding timestamp.
withoutNearStops
if set to 1, the result will include the results of connected stations. A connected station is a station that is logically connected to another station, for example the bus, train and tram station of a cities main station. Default is 0.
maxResults
the maximum number of departures to show. By default, this is set to 30.
onlyTypes
by default, all methods of transportation are shown. Each transportion type has a number. These numbers have to be seperated by an exclamation mark ("!"). The methods of transportation are
  1. Train
  2. Elevated Railway (S-Bahn in German speaking countries)
  3. Tube (U-Bahn)
  4. Light railway (Stadtbahn)
  5. Tram
  6. City Bus
  7. Regional Bus
  8. Express Coach
  9. Cable car (Bergbahn)
  10. Boat/Ship
  11. Mini/shuttle bus (AST)
  12. Other
onlyTypes=4!5!9 would only show the next connection by tram, by city bus or by boat.

The API will respond by a list containing the next departures, structured in the following way.

request
for
Contains information about the departure time and the station the departures are listed for.
station(*)
location_name
The location of this station, usually the city.
station_name
The name of this station.
position
The exact coordinates of this station. Format is WGS 84, lat is the latitude, lng is the longitude.
next_departures
Contains information about the departure time and the station the departures are listed for.
departure(*)
dateandtime
time
The departure time.
date
The departure date.
to
station
The name of the destination. Has its id as an attribute.
line
The serving line. Attributes are type, symbol and number.
train
Contains the name on the vehicle itself. Usually, this is a full train name like "Regional-Express".
route_descriptions
A optional route description which is not offered for every line. Usually, this consists of an abriged list of the served stations.

Example: the next two tram departures for the main station in Bern, Switzerland can be obtained by calling

http://example.simpleefa/nextdepartures?station=53020397&onlyTypes=4&maxResults=2 

/connections

A sophisticated service to get connections from A to B, via C. More information to come! For the time being, have a look at this example request for the next connections from Zürich, Switzerland to Lübeck, Germany via Gare du Nord in Paris, France.

http://example.simpleefa/connection?from=53000688&to=44409225&via=75040014 
It is possible to perform a connection search from coordinate to coordinate using the from_lat, from_lng, to_lat, to_lng and via_lat, via_lng parameters. It is also possible to mix coordinate and station id parameters, like this:
http://example.simpleefa/connection?from_lat=47.990087&from_lng=7.856498&to=6930119 

/coordinate

Gives you all stations near an arbitrary coordinate. The coordinate has to be given as WGS 84 coordinates.

Parameters include

lat
The latitude (WGS 84)
lng
The longitude (WGS 84)
radius
The radius to search in meters.

The query will result in a list of surrounding stations, each specified by their name, id and coordinate. It will be structured like this:

nearby_stations
for_input
lat
The latitude (WGS 84)
lng
The longitude (WGS 84)
station(*)
Multiple stations within the specified radius. Attribute id is a unique station id.
location_name
The location of this station, usually the city.
station_name
The name of this station.
position
The exact coordinates of this station. Format is WGS 84, lat is the latitude, lng is the longitude.
Example: All stations surrounding the Alte Botanische Garten in Tübingen, Germany within a radius of 350 meters can be obtained by calling
http://example.simpleefa/coordinate?lat=48.522997&lng=9.057675&radius=350 

Output formats

simpleEFA outputs XML by default. You can enable JSON-output by settin format to JSON like this:
http://example.simpleefa/coordinate?x=504260&y=5374497&radius=350&format=JSON 

Feel free to send bug reports and suggestions to simpleefa@patrickbrosi.de