Travel::Routing::DE::EFA - unofficial interface to EFA-based itinerary services


	use Travel::Routing::DE::EFA;

	my $efa = Travel::Routing::DE::EFA->new(
		efa_url     => '',
		origin      => [ 'Essen',    'HBf' ],
		destination => [ 'Duisburg', 'HBf' ],

	for my $route ( $efa->routes ) {
		for my $part ( $route->parts ) {
				"%s at %s -> %s at %s, via %s to %s\n",
				$part->departure_time, $part->departure_stop,
				$part->arrival_time,   $part->arrival_stop,
				$part->train_line,     $part->train_destination,
		print "\n";


version 2.14


Travel::Routing::DE::EFA is a client for EFA-based itinerary services. You pass it the start/stop of your journey, maybe a time and a date and more details, and it returns the up-to-date scheduled connections between those two stops.

It uses LWP::UserAgent and XML::LibXML for this.


$efa = Travel::Routing::DE::EFA->new(%opts)

Returns a new Travel::Routing::DE::EFA object and sets up its POST data via %opts.

Valid hash keys and their values are:

efa_url => efa_url

Mandatory. Sets the entry point to the EFA itinerary service. The following URLs (grouped by country) are known. A service marked with [!] is not completely supported yet and may not work at all.

* Austria

* (Innsbrucker Verkehrsbetriebe)
* (Salzburger Verkehrsverbund)
* (Verkehrsverbund Ost-Region)
* (Vorarlberger Verkehrsverbund)
* (Linz AG) [!]
* The STV / Verkehrsverbund Steiermark is not supported since it returns data with broken encoding

* Germany

* (Verkehrsverbund Großraum Nürnberg)
* (Verkehrsverbund Rhein-Ruhr)
* (Verkehrsverbund Rhein-Ruhr with support for --full-route)
* (Verkehrsverbund Stuttgart)

If you found a URL not listed here, please send it to <>.

origin => [ city, stop [ , type ] ]

Mandatory. Sets the start of the journey. type is optional and may be one of stop (default), address (street and house number) or poi ("point of interest").

destination => [ city, stop [ , type ] ]

Mandatory. Sets the end of the journey, see origin.

via => [ city, stop [ , type ] ]

Optional. Specifies an intermediate stop which the resulting itinerary must contain. See origin for arguments.

arrival_time => HH:MM

Journey end time

departure_time => HH:MM

Journey start time. Default: now

date => DD.MM.[YYYY]

Journey date. Default: today

exclude => \@exclude

Do not use certain transport types for itinerary. Accepted arguments: zug, s-bahn, u-bahn, stadtbahn, tram, stadtbus, regionalbus, schnellbus, seilbahn, schiff, ast, sonstige

max_interchanges => num

Set maximum number of interchanges

num_results => num

Return up to num connections. If unset, the default of the respective EFA server is used (usually 4 or 5).

select_interchange_by => speed|waittime|distance

Prefer either fast connections (default), connections with low wait time or connections with little distance to walk

use_near_stops => $int

If $int is a true value: Take stops close to the stop/start into account and possibly use them instead. Up to $int minutes of walking are considered acceptable.

Otherwise: Do not take stops close to stop/start into account.

train_type => local|ic|ice

Include only local trains into itinerary (default), all but ICEs, or all.

The latter two are usually way more expensive for short routes.

walk_speed => slow|fast|normal

Set walk speed. Default: normal

with_bike => 0|1

If true: Request connections allowing passengers with bikes. Note that the backed may return an empty result if no such connection exists or bike-support simply isn't known.

with_low_platform => 0|1

If true: Request connections which only use low-platform ("Niederflur") vehicles. Note that the backed will return an empty result if no such connection exists.

with_wheelchair => 0|1

If true: Request connections which are wheelchair-accessible. Again, note that the backend may return an empty result if no such connection exists or wheelchair-support isn't known.

without_elevators => 0|1

If true: Request that transfers do not require usage of elevators.

without_escalators => 0|1

If true: Request that transfers do not require usage of escalators.

without_solid_stairs => 0|1

If true: Request that transfers do not require stairs to be taken (i.e. ramps, escalators, elevators or similar must be available).

lwp_options => \%hashref

Options to pass to LWP::UserAgent->new.

submit => 0|1

By default, new will create a POST request and submit it. If you do not want it to be submitted yet, set this to 0.


Submit the query to efa_url. %opts is passed on to LWP::UserAgent->new.


Returns a list of Travel::Routing::DE::EFA::Route(3pm) elements. Each one contains one method of getting from start to stop.


The following methods act like the arguments to new. See there.




Returns a list of known EFA entry points. Each list element is a hashref with the following elements.

url: service URL as passed to efa_url
name: Name of the entity operating this service
shortname: Short name of the entity


When encountering an error, Travel::Routing::DE::EFA throws a Travel::Routing::DE::EFA::Exception(3pm) object.


* LWP::UserAgent(3pm)
* XML::LibXML(3pm)


None known.


* Travel::Routing::DE::EFA::Exception(3pm)
* Travel::Routing::DE::EFA::Route(3pm)
* WWW::EFA is another implementation, using Moose.


Copyright (C) 2009-2015 by Daniel Friesel <>