summaryrefslogtreecommitdiff
path: root/lib/Travel/Routing
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Travel/Routing')
-rw-r--r--lib/Travel/Routing/DE/EFA.pm175
-rw-r--r--lib/Travel/Routing/DE/EFA/Route.pm6
-rw-r--r--lib/Travel/Routing/DE/EFA/Route/Message.pm6
-rw-r--r--lib/Travel/Routing/DE/EFA/Route/Part.pm51
-rw-r--r--lib/Travel/Routing/DE/VRR.pm10
5 files changed, 103 insertions, 145 deletions
diff --git a/lib/Travel/Routing/DE/EFA.pm b/lib/Travel/Routing/DE/EFA.pm
index a1e07ff..80bfb68 100644
--- a/lib/Travel/Routing/DE/EFA.pm
+++ b/lib/Travel/Routing/DE/EFA.pm
@@ -5,9 +5,7 @@ use warnings;
use 5.010;
use utf8;
-no if $] >= 5.018, warnings => "experimental::smartmatch";
-
-use Carp qw(cluck);
+use Carp qw(cluck);
use Encode qw(encode);
use Travel::Routing::DE::EFA::Route;
use Travel::Routing::DE::EFA::Route::Message;
@@ -42,7 +40,7 @@ use Exception::Class (
},
);
-our $VERSION = '2.19';
+our $VERSION = '2.24';
sub set_time {
my ( $self, %conf ) = @_;
@@ -176,17 +174,19 @@ sub number_of_trips {
sub select_interchange_by {
my ( $self, $prefer ) = @_;
- given ($prefer) {
- when ('speed') { $self->{post}->{routeType} = 'LEASTTIME' }
- when ('waittime') { $self->{post}->{routeType} = 'LEASTINTERCHANGE' }
- when ('distance') { $self->{post}->{routeType} = 'LEASTWALKING' }
- default {
- Travel::Routing::DE::EFA::Exception::Setup->throw(
- option => 'select_interchange_by',
- have => $prefer,
- want => 'speed / waittime / distance',
- );
- }
+ if ( $prefer eq 'speed' ) { $self->{post}->{routeType} = 'LEASTTIME' }
+ elsif ( $prefer eq 'waittime' ) {
+ $self->{post}->{routeType} = 'LEASTINTERCHANGE';
+ }
+ elsif ( $prefer eq 'distance' ) {
+ $self->{post}->{routeType} = 'LEASTWALKING';
+ }
+ else {
+ Travel::Routing::DE::EFA::Exception::Setup->throw(
+ option => 'select_interchange_by',
+ have => $prefer,
+ want => 'speed / waittime / distance',
+ );
}
return;
@@ -195,17 +195,15 @@ sub select_interchange_by {
sub train_type {
my ( $self, $include ) = @_;
- given ($include) {
- when ('local') { $self->{post}->{lineRestriction} = 403 }
- when ('ic') { $self->{post}->{lineRestriction} = 401 }
- when ('ice') { $self->{post}->{lineRestriction} = 400 }
- default {
- Travel::Routing::DE::EFA::Exception::Setup->throw(
- option => 'train_type',
- have => $include,
- want => 'local / ic / ice',
- );
- }
+ if ( $include eq 'local' ) { $self->{post}->{lineRestriction} = 403 }
+ elsif ( $include eq 'ic' ) { $self->{post}->{lineRestriction} = 401 }
+ elsif ( $include eq 'ice' ) { $self->{post}->{lineRestriction} = 400 }
+ else {
+ Travel::Routing::DE::EFA::Exception::Setup->throw(
+ option => 'train_type',
+ have => $include,
+ want => 'local / ic / ice',
+ );
}
return;
@@ -229,7 +227,7 @@ sub use_near_stops {
sub walk_speed {
my ( $self, $walk_speed ) = @_;
- if ( $walk_speed ~~ [ 'normal', 'fast', 'slow' ] ) {
+ if ( $walk_speed =~ m{ ^ (?: normal | fast | slow ) $ }x ) {
$self->{post}->{changeSpeed} = $walk_speed;
}
else {
@@ -305,7 +303,7 @@ sub place {
@{ $self->{post} }{ "place_${which}", "name_${which}" } = ( $place, $stop );
- if ( $type ~~ [qw[address poi stop]] ) {
+ if ( $type =~ m{ ^ (?: address | poi | stop ) $ }x ) {
$self->{post}->{"type_${which}"} = $type;
}
@@ -660,6 +658,8 @@ sub parse_xml_part {
$e_astime //= $e_atime;
my $delay = $e_delay ? $e_delay->getAttribute('delayMinutes') : 0;
+ my $delay_arr
+ = $e_delay ? $e_delay->getAttribute('delayMinutesArr') : 0;
my ( @dep_rms, @dep_sms, @arr_rms, @arr_sms );
@@ -675,17 +675,19 @@ sub parse_xml_part {
}
my $hash = {
- delay => $delay,
departure_date => $self->itddate_str($e_ddate),
+ departure_delay => $delay,
departure_time => $self->itdtime_str($e_dtime),
departure_sdate => $self->itddate_str($e_dsdate),
departure_stime => $self->itdtime_str($e_dstime),
departure_stop => $e_dep->getAttribute('name'),
departure_platform => $e_dep->getAttribute('platformName'),
+ occupancy => $e_dep->getAttribute('occupancy'),
train_line => $e_mot->getAttribute('name'),
train_product => $e_mot->getAttribute('productName'),
train_destination => $e_mot->getAttribute('destination'),
arrival_date => $self->itddate_str($e_adate),
+ arrival_delay => $delay_arr,
arrival_time => $self->itdtime_str($e_atime),
arrival_sdate => $self->itddate_str($e_asdate),
arrival_stime => $self->itdtime_str($e_astime),
@@ -715,8 +717,8 @@ sub parse_xml_part {
$hash->{arrival_stationmaps} = \@arr_sms;
for my $ve ( $e->findnodes($xp_via) ) {
- my $e_vdate = ( $ve->findnodes($xp_date) )[-1];
- my $e_vtime = ( $ve->findnodes($xp_time) )[-1];
+ my $e_vdate = ( $ve->findnodes($xp_date) )[0];
+ my $e_vtime = ( $ve->findnodes($xp_time) )[0];
if ( not( $e_vdate and $e_vtime )
or ( $e_vdate->getAttribute('weekday') == -1 ) )
@@ -724,10 +726,13 @@ sub parse_xml_part {
next;
}
- my $name = $ve->getAttribute('name');
- my $platform = $ve->getAttribute('platformName');
+ my $name = $ve->getAttribute('name');
+ my $platform = $ve->getAttribute('platformName');
+ my $arr_delay = $ve->getAttribute('arrDelay');
- if ( $name ~~ [ $hash->{departure_stop}, $hash->{arrival_stop} ] ) {
+ if ( $name eq $hash->{departure_stop}
+ or $name eq $hash->{arrival_stop} )
+ {
next;
}
@@ -737,7 +742,8 @@ sub parse_xml_part {
$self->itddate_str($e_vdate),
$self->itdtime_str($e_vtime),
$name,
- $platform
+ $platform,
+ $arr_delay,
]
);
}
@@ -819,7 +825,7 @@ sub check_ambiguous_xml {
if ( $s_place eq 'list' ) {
Travel::Routing::DE::EFA::Exception::Ambiguous->throw(
- post_key => 'place',
+ post_key => 'place',
post_value =>
( $e_place->findnodes($xp_place_input) )[0]->textContent,
possibilities => join( q{ | },
@@ -829,7 +835,7 @@ sub check_ambiguous_xml {
}
if ( $s_name eq 'list' ) {
Travel::Routing::DE::EFA::Exception::Ambiguous->throw(
- post_key => 'name',
+ post_key => 'name',
post_value =>
( $e_name->findnodes($xp_name_input) )[0]->textContent,
possibilities => join( q{ | },
@@ -898,40 +904,11 @@ sub get_efa_urls {
name => 'Nahverkehrsgesellschaft Baden-Württemberg',
shortname => 'NVBW',
},
-
- # HTTPS not supported
- {
- url => 'http://efa.svv-info.at/sbs/XSLT_TRIP_REQUEST2',
- name => 'Salzburger Verkehrsverbund',
- shortname => 'SVV',
- },
-
- # HTTPS: invalid certificate
- {
- url =>
- 'http://www.travelineeastmidlands.co.uk/em/XSLT_TRIP_REQUEST2',
- name => 'Traveline East Midlands',
- shortname => 'TLEM',
- },
{
url => 'https://efa.vagfr.de/vagfr3/XSLT_TRIP_REQUEST2',
name => 'Freiburger Verkehrs AG',
shortname => 'VAG',
},
-
- # HTTPS: unsupported protocol
- {
- url => 'http://mobil.vbl.ch/vblmobil/XML_TRIP_REQUEST2',
- name => 'Verkehrsbetriebe Luzern',
- shortname => 'VBL',
- },
-
- # HTTPS not supported
- {
- url => 'http://fahrplan.verbundlinie.at/stv/XSLT_TRIP_REQUEST2',
- name => 'Verkehrsverbund Steiermark',
- shortname => 'Verbundlinie',
- },
{
url => 'https://efa.vgn.de/vgnExt_oeffi/XML_TRIP_REQUEST2',
name => 'Verkehrsverbund Grossraum Nuernberg',
@@ -945,32 +922,22 @@ sub get_efa_urls {
shortname => 'VMV',
},
{
- url => 'https://efa.vor.at/wvb/XSLT_TRIP_REQUEST2',
- name => 'Verkehrsverbund Ost-Region',
- shortname => 'VOR',
- encoding => 'iso-8859-15',
- },
-
- # HTTPS not spported
- {
- url => 'http://fahrplanauskunft.vrn.de/vrn/XML_TRIP_REQUEST2',
+ url => 'https://www.vrn.de/mngvrn/XML_TRIP_REQUEST2',
name => 'Verkehrsverbund Rhein-Neckar',
shortname => 'VRN',
},
{
- url => 'https://efa.vrr.de/vrr/XSLT_TRIP_REQUEST2',
+ url => 'https://app.vrr.de/vrrstd/XML_TRIP_REQUEST2',
name => 'Verkehrsverbund Rhein-Ruhr',
shortname => 'VRR',
},
{
- url => 'https://app.vrr.de/vrrstd/XML_TRIP_REQUEST2',
+ url => 'https://efa.vrr.de/rbgstd3/XSLT_TRIP_REQUEST2',
name => 'Verkehrsverbund Rhein-Ruhr (alternative)',
shortname => 'VRR2',
},
-
- # HTTPS not supported
{
- url => 'http://efa.vvo-online.de:8080/dvb/XSLT_TRIP_REQUEST2',
+ url => 'https://efa.vvo-online.de/VMSSL3/XSLT_TRIP_REQUEST2',
name => 'Verkehrsverbund Oberelbe',
shortname => 'VVO',
},
@@ -995,7 +962,7 @@ 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 => 'http://efa.vrr.de/vrr/XSLT_TRIP_REQUEST2',
+ efa_url => 'https://app.vrr.de/vrrstd/XML_TRIP_REQUEST2';',
origin => [ 'Essen', 'HBf' ],
destination => [ 'Duisburg', 'HBf' ],
);
@@ -1014,7 +981,7 @@ Travel::Routing::DE::EFA - unofficial interface to EFA-based itinerary services
=head1 VERSION
-version 2.19
+version 2.24
=head1 DESCRIPTION
@@ -1041,47 +1008,9 @@ Valid hash keys and their values are:
=item B<efa_url> => I<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.
-
-=over
-
-=item * Austria
-
-=over
-
-=item * L<http://efa.ivb.at/ivb/XSLT_TRIP_REQUEST2> (Innsbrucker Verkehrsbetriebe)
-
-=item * L<http://efa.svv-info.at/sbs/XSLT_TRIP_REQUEST2> (Salzburger Verkehrsverbund)
-
-=item * L<http://efa.vor.at/wvb/XSLT_TRIP_REQUEST2> (Verkehrsverbund Ost-Region)
-
-=item * L<http://efaneu.vmobil.at/vvv/XSLT_TRIP_REQUEST2> (Vorarlberger Verkehrsverbund)
-
-=item * L<http://www.linzag.at/static/XSLT_TRIP_REQUEST2> (Linz AG) B<[!]>
-
-=item * The STV / Verkehrsverbund Steiermark is not supported since it returns
-data with broken encoding
-
-=back
-
-=item * Germany
-
-=over
-
-=item * L<http://212.114.197.7/vgnExt_oeffi/XML_TRIP_REQUEST2> (Verkehrsverbund GroE<szlig>raum NE<uuml>rnberg)
-
-=item * L<http://efa.vrr.de/vrr/XSLT_TRIP_REQUEST2> (Verkehrsverbund Rhein-Ruhr)
-
-=item * L<http://app.vrr.de/standard/XML_TRIP_REQUEST2> (Verkehrsverbund Rhein-Ruhr with support for B<--full-route>)
-
-=item * L<http://www2.vvs.de/vvs/XSLT_TRIP_REQUEST2> (Verkehrsverbund Stuttgart)
-
-=back
-
-=back
+See C<< efa --list >> for a list of supported services.
-If you found a URL not listed here, please send it to
+If you found a URL not listed there, please send it to
E<lt>derf@finalrewind.orgE<gt>.
=item B<origin> => B<[> I<city>B<,> I<stop> [ B<,> I<type> ] B<]>
@@ -1285,7 +1214,7 @@ None known.
=head1 AUTHOR
-Copyright (C) 2009-2020 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+Copyright (C) 2009-2023 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt>
=head1 LICENSE
diff --git a/lib/Travel/Routing/DE/EFA/Route.pm b/lib/Travel/Routing/DE/EFA/Route.pm
index 61a7c31..87d4e4b 100644
--- a/lib/Travel/Routing/DE/EFA/Route.pm
+++ b/lib/Travel/Routing/DE/EFA/Route.pm
@@ -8,7 +8,7 @@ use parent 'Class::Accessor';
use Travel::Routing::DE::EFA::Route::Part;
-our $VERSION = '2.19';
+our $VERSION = '2.24';
Travel::Routing::DE::EFA::Route->mk_ro_accessors(
qw(duration ticket_text ticket_type fare_adult fare_child vehicle_time));
@@ -52,7 +52,7 @@ Travel::Routing::DE::EFA::Route - Single route (connection) between two points
=head1 VERSION
-version 2.19
+version 2.24
=head1 DESCRIPTION
@@ -114,7 +114,7 @@ Travel::Routing::DE::EFA(3pm), Travel::Routing::DE::EFA::Route::Part(3pm).
=head1 AUTHOR
-Copyright (C) 2011-2015 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+Copyright (C) 2011-2015 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt>
=head1 LICENSE
diff --git a/lib/Travel/Routing/DE/EFA/Route/Message.pm b/lib/Travel/Routing/DE/EFA/Route/Message.pm
index ffa707c..6ae2e19 100644
--- a/lib/Travel/Routing/DE/EFA/Route/Message.pm
+++ b/lib/Travel/Routing/DE/EFA/Route/Message.pm
@@ -6,7 +6,7 @@ use 5.010;
use parent 'Class::Accessor';
-our $VERSION = '2.19';
+our $VERSION = '2.24';
Travel::Routing::DE::EFA::Route::Message->mk_ro_accessors(
qw(is_detailed summary subject subtitle raw_content));
@@ -58,7 +58,7 @@ route or route part.
=head1 VERSION
-version 2.19
+version 2.24
=head1 DESCRIPTION
@@ -129,7 +129,7 @@ Travel::Routing::DE::EFA(3pm), Travel::Routing::DE::EFA::Route::Part(3pm).
=head1 AUTHOR
-Copyright (C) 2015 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+Copyright (C) 2015 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt>
=head1 LICENSE
diff --git a/lib/Travel/Routing/DE/EFA/Route/Part.pm b/lib/Travel/Routing/DE/EFA/Route/Part.pm
index 3a15fc3..7ed2722 100644
--- a/lib/Travel/Routing/DE/EFA/Route/Part.pm
+++ b/lib/Travel/Routing/DE/EFA/Route/Part.pm
@@ -6,17 +6,25 @@ use 5.010;
use parent 'Class::Accessor';
-our $VERSION = '2.19';
+our $VERSION = '2.24';
+
+my %occupancy = (
+ MANY_SEATS => 1,
+ FEW_SEATS => 2,
+ STANDING_ONLY => 3
+);
Travel::Routing::DE::EFA::Route::Part->mk_ro_accessors(
qw(arrival_platform arrival_stop
- arrival_date arrival_time arrival_sdate arrival_stime delay
- departure_platform
+ arrival_date arrival_time arrival_sdate arrival_stime arrival_delay
+ delay
+ departure_platform departure_delay
departure_stop departure_date departure_time departure_sdate
departure_stime
footpath_duration footpath_type
+ occupancy
train_destination train_line train_product
- )
+ )
);
sub new {
@@ -24,6 +32,15 @@ sub new {
my $ref = \%conf;
+ if ( $ref->{occupancy} and exists $occupancy{ $ref->{occupancy} } ) {
+ $ref->{occupancy} = $occupancy{ $ref->{occupancy} };
+ }
+ else {
+ delete $ref->{occupancy};
+ }
+
+ $ref->{delay} = $ref->{departure_delay};
+
return bless( $ref, $obj );
}
@@ -154,7 +171,7 @@ points, without interchanges
=head1 VERSION
-version 2.19
+version 2.24
=head1 DESCRIPTION
@@ -174,6 +191,10 @@ included in the calculation, "Scheduled" means it isn't.
=over
+=item $part->arrival_delay
+
+arrival delay in minutes, 0 if unknown
+
=item $part->arrival_stop
arrival stop (city name plus station name)
@@ -223,7 +244,11 @@ Returns a list of Travel::Routing::DE::EFA::Route::Message(3pm) objects.
=item $part->delay
-delay in minutes, 0 if unknown
+alias for departure_delay
+
+=item $part->departure_delay
+
+departure delay in minutes, 0 if unknown
=item $part->departure_stop
@@ -302,6 +327,11 @@ Returns true if this part of the route has been cancelled (i.e., the entire
route is probably useless), false otherwise. For unknown reasons, EFA may
sometimes return routes which contain cancelled departures.
+=item $part->occupancy
+
+Returns expected occupancy, if available. Values range from 1 (low occupancy)
+to 3 (very high occupancy).
+
=item $part->regular_notes
Remarks about the line serving this connaction part. Returns a list of
@@ -325,9 +355,10 @@ In those cases, B<train_destination> and B<train_line> are usually empty.
=item $part->via
-Returns a list of C<< [ "DD.MM.YYYY", "HH:MM", stop, platform ] >> arrayrefs
-encoding the stops passed between B<departure_stop> and B<arrival_stop>,
-if supported by the backend. Returns nothing / an empty list otherwise.
+Returns a list of C<< [ "DD.MM.YYYY", "HH:MM", stop, platform, delay ] >>
+arrayrefs encoding the stops passed between B<departure_stop> and
+B<arrival_stop>, if supported by the backend. Returns nothing / an empty list
+otherwise. Date and time refer to schedule data and do not account for delays.
=back
@@ -354,7 +385,7 @@ Class::Accessor(3pm).
=head1 AUTHOR
-Copyright (C) 2011-2017 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+Copyright (C) 2011-2021 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt>
=head1 LICENSE
diff --git a/lib/Travel/Routing/DE/VRR.pm b/lib/Travel/Routing/DE/VRR.pm
index 126748c..9e485d6 100644
--- a/lib/Travel/Routing/DE/VRR.pm
+++ b/lib/Travel/Routing/DE/VRR.pm
@@ -4,16 +4,14 @@ use strict;
use warnings;
use 5.010;
-no if $] >= 5.018, warnings => "experimental::smartmatch";
-
-our $VERSION = '2.19';
+our $VERSION = '2.24';
use parent 'Travel::Routing::DE::EFA';
sub new {
my ( $class, %opt ) = @_;
- $opt{efa_url} = 'http://efa.vrr.de/vrr/XSLT_TRIP_REQUEST2';
+ $opt{efa_url} = 'https://app.vrr.de/vrrstd/XML_TRIP_REQUEST2';
return $class->SUPER::new(%opt);
}
@@ -49,7 +47,7 @@ Travel::Routing::DE::VRR - unofficial interface to the efa.vrr.de German itinera
=head1 VERSION
-version 2.19
+version 2.24
=head1 DESCRIPTION
@@ -102,7 +100,7 @@ None known.
=head1 AUTHOR
-Copyright (C) 2009-2020 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+Copyright (C) 2009-2021 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt>
=head1 LICENSE