diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Travel/Status/DE/EFA.pm | 46 | ||||
-rw-r--r-- | lib/Travel/Status/DE/EFA/Departure.pm | 11 | ||||
-rw-r--r-- | lib/Travel/Status/DE/EFA/Info.pm | 4 | ||||
-rw-r--r-- | lib/Travel/Status/DE/EFA/Line.pm | 4 | ||||
-rw-r--r-- | lib/Travel/Status/DE/EFA/Services.pm.PL | 10 | ||||
-rw-r--r-- | lib/Travel/Status/DE/EFA/Stop.pm | 6 | ||||
-rw-r--r-- | lib/Travel/Status/DE/EFA/Trip.pm | 111 | ||||
-rw-r--r-- | lib/Travel/Status/DE/VRR.pm | 4 |
8 files changed, 155 insertions, 41 deletions
diff --git a/lib/Travel/Status/DE/EFA.pm b/lib/Travel/Status/DE/EFA.pm index 5d47565..be08b9a 100644 --- a/lib/Travel/Status/DE/EFA.pm +++ b/lib/Travel/Status/DE/EFA.pm @@ -5,7 +5,7 @@ use warnings; use 5.010; use utf8; -our $VERSION = '3.07'; +our $VERSION = '3.13'; use Carp qw(confess cluck); use DateTime; @@ -54,7 +54,7 @@ sub new_p { } )->catch( sub { - my ($err) = @_; + my ( $err, $self ) = @_; $promise->reject($err); return; } @@ -206,6 +206,7 @@ sub new { stop => $opt{stopseq}{stop_id}, tripCode => $opt{stopseq}{key}, date => $opt{stopseq}{date}, + time => $opt{stopseq}{time}, coordOutputFormat => 'WGS84[DD.DDDDD]', outputFormat => 'rapidJson', useRealtime => '1', @@ -412,15 +413,37 @@ sub check_for_ambiguous { for my $m ( @{ $json->{dm}{message} // [] } ) { if ( $m->{name} eq 'error' and $m->{value} eq 'name list' ) { - $self->{errstr} = "ambiguous name parameter"; - $self->{name_candidates} - = [ map { $_->{name} } @{ $json->{dm}{points} // [] } ]; + $self->{errstr} = "ambiguous name parameter"; + $self->{name_candidates} = []; + for my $point ( @{ $json->{dm}{points} // [] } ) { + my $place = $point->{ref}{place}; + push( + @{ $self->{name_candidates} }, + Travel::Status::DE::EFA::Stop->new( + place => $place, + full_name => $point->{name}, + name => $point->{name} =~ s{\Q$place\E,? ?}{}r, + id_num => $point->{ref}{id}, + ) + ); + } return; } if ( $m->{name} eq 'error' and $m->{value} eq 'place list' ) { - $self->{errstr} = "ambiguous name parameter"; - $self->{place_candidates} - = [ map { $_->{name} } @{ $json->{dm}{points} // [] } ]; + $self->{errstr} = "ambiguous name parameter"; + $self->{place_candidates} = []; + for my $point ( @{ $json->{dm}{points} // [] } ) { + my $place = $point->{ref}{place}; + push( + @{ $self->{place_candidates} }, + Travel::Status::DE::EFA::Stop->new( + place => $place, + full_name => $point->{name}, + name => $point->{name} =~ s{\Q$place\E,? ?}{}r, + id_num => $point->{ref}{id}, + ) + ); + } return; } } @@ -605,6 +628,11 @@ sub results_dm { my ($self) = @_; my $json = $self->{response}; + # Oh EFA, you so silly + if ( $json->{departureList} and ref( $json->{departureList} ) eq 'HASH' ) { + $json->{departureList} = [ $json->{departureList}{departure} ]; + } + my @results; for my $departure ( @{ $json->{departureList} // [] } ) { push( @@ -680,7 +708,7 @@ Travel::Status::DE::EFA - unofficial EFA departure monitor =head1 VERSION -version 3.07 +version 3.13 =head1 DESCRIPTION diff --git a/lib/Travel/Status/DE/EFA/Departure.pm b/lib/Travel/Status/DE/EFA/Departure.pm index 6dfe717..ec17a12 100644 --- a/lib/Travel/Status/DE/EFA/Departure.pm +++ b/lib/Travel/Status/DE/EFA/Departure.pm @@ -10,7 +10,7 @@ use Travel::Status::DE::EFA::Stop; use parent 'Class::Accessor'; -our $VERSION = '3.07'; +our $VERSION = '3.13'; Travel::Status::DE::EFA::Departure->mk_ro_accessors( qw(countdown datetime delay destination is_cancelled key line lineref mot @@ -177,10 +177,11 @@ sub id { return $self->{id} = sprintf( '%s@%d(%s)%d', $self->stateless =~ s{ }{}gr, - scalar $self->route_pre - ? ( $self->route_pre )[0]->id_num + scalar $self->route_pre ? ( $self->route_pre )[0]->id_num : $self->stop_id_num, - $self->sched_datetime->strftime('%Y%m%d'), + ( scalar $self->route_pre and ( $self->route_pre )[0]->sched_dep ) + ? ( $self->route_pre )[0]->sched_dep->strftime('%Y%m%dT%H:%M') + : $self->sched_datetime->strftime('%Y%m%dT%H:%M'), $self->key ); } @@ -303,7 +304,7 @@ departure received by Travel::Status::DE::EFA =head1 VERSION -version 3.07 +version 3.13 =head1 DESCRIPTION diff --git a/lib/Travel/Status/DE/EFA/Info.pm b/lib/Travel/Status/DE/EFA/Info.pm index 076b162..424c9f1 100644 --- a/lib/Travel/Status/DE/EFA/Info.pm +++ b/lib/Travel/Status/DE/EFA/Info.pm @@ -6,7 +6,7 @@ use 5.010; use parent 'Class::Accessor'; -our $VERSION = '3.07'; +our $VERSION = '3.13'; Travel::Status::DE::EFA::Info->mk_ro_accessors( qw(link_url link_text subject content subtitle additional_text)); @@ -58,7 +58,7 @@ Travel::Status::DE::EFA::Info - Information about a public transit stop =head1 VERSION -version 3.07 +version 3.13 =head1 DESCRIPTION diff --git a/lib/Travel/Status/DE/EFA/Line.pm b/lib/Travel/Status/DE/EFA/Line.pm index b4e7186..061c904 100644 --- a/lib/Travel/Status/DE/EFA/Line.pm +++ b/lib/Travel/Status/DE/EFA/Line.pm @@ -6,7 +6,7 @@ use 5.010; use parent 'Class::Accessor'; -our $VERSION = '3.07'; +our $VERSION = '3.13'; Travel::Status::DE::EFA::Line->mk_ro_accessors( qw(direction mot name number operator route type valid)); @@ -57,7 +57,7 @@ requested station =head1 VERSION -version 3.07 +version 3.13 =head1 DESCRIPTION diff --git a/lib/Travel/Status/DE/EFA/Services.pm.PL b/lib/Travel/Status/DE/EFA/Services.pm.PL index 1a22338..81027d7 100644 --- a/lib/Travel/Status/DE/EFA/Services.pm.PL +++ b/lib/Travel/Status/DE/EFA/Services.pm.PL @@ -35,6 +35,10 @@ sub load_instance { # VRT: Encoding issues # VVSt: NXDOMAIN my %efa_instance = ( + BEG => { + url => 'https://bahnland-bayern.de/efa', + name => 'Bayerische Eisenbahngesellschaft', + }, BSVG => { url => 'https://bsvg.efa.de/bsvagstd', name => 'Braunschweiger Verkehrs-GmbH', @@ -60,6 +64,10 @@ my %efa_instance = ( name => 'Nahverkehr Westfalen-Lippe', }, Rolph => { load_instance('de/rolph') }, + RVV => { + url => 'https://efa.rvv.de/efa', + name => 'Regensburger Verkehrsverbund', + }, VAG => { url => 'https://efa.vagfr.de/vagfr3', name => 'Freiburger Verkehrs AG', @@ -100,7 +108,7 @@ use warnings; use 5.014; use utf8; -our $VERSION = '3.07'; +our $VERSION = '3.13'; # Most of these have been adapted from # <https://github.com/public-transport/transport-apis> and diff --git a/lib/Travel/Status/DE/EFA/Stop.pm b/lib/Travel/Status/DE/EFA/Stop.pm index 30806a0..910111e 100644 --- a/lib/Travel/Status/DE/EFA/Stop.pm +++ b/lib/Travel/Status/DE/EFA/Stop.pm @@ -6,12 +6,12 @@ use 5.010; use parent 'Class::Accessor'; -our $VERSION = '3.07'; +our $VERSION = '3.13'; Travel::Status::DE::EFA::Stop->mk_ro_accessors( qw(sched_arr rt_arr arr arr_delay sched_dep rt_dep dep dep_delay - occupancy delay distance_m + occupancy delay distance_m is_cancelled place name full_name id_num id_code latlon platform niveau) ); @@ -93,7 +93,7 @@ in a Travel::Status::DE::EFA::Result's route =head1 VERSION -version 3.07 +version 3.13 =head1 DESCRIPTION diff --git a/lib/Travel/Status/DE/EFA/Trip.pm b/lib/Travel/Status/DE/EFA/Trip.pm index 9d53487..5b86695 100644 --- a/lib/Travel/Status/DE/EFA/Trip.pm +++ b/lib/Travel/Status/DE/EFA/Trip.pm @@ -9,7 +9,7 @@ use Travel::Status::DE::EFA::Stop; use parent 'Class::Accessor'; -our $VERSION = '3.07'; +our $VERSION = '3.13'; Travel::Status::DE::EFA::Trip->mk_ro_accessors( qw(operator product product_class name line number type id dest_name dest_id) @@ -24,7 +24,7 @@ sub new { operator => $json->{operator}{name}, product => $json->{product}{name}, product_class => $json->{product}{class}, - polyline => $json->{coords}, + polyline_raw => $conf{json}{leg}{coords}, name => $json->{name}, line => $json->{disassembledName}, number => $json->{properties}{trainNumber}, @@ -39,8 +39,10 @@ sub new { time_zone => 'UTC' ), }; - if ( ref( $ref->{polyline} ) eq 'ARRAY' and @{ $ref->{polyline} } == 1 ) { - $ref->{polyline} = $ref->{polyline}[0]; + if ( ref( $ref->{polyline_raw} ) eq 'ARRAY' + and @{ $ref->{polyline_raw} } == 1 ) + { + $ref->{polyline_raw} = $ref->{polyline_raw}[0]; } return bless( $ref, $obj ); } @@ -48,13 +50,61 @@ sub new { sub polyline { my ( $self, %opt ) = @_; - if ( $opt{fallback} and not @{ $self->{polyline} // [] } ) { + if ( $self->{polyline} ) { + return @{ $self->{polyline} }; + } + + if ( not @{ $self->{polyline_raw} // [] } ) { + if ( $opt{fallback} ) { + return map { + { + lat => $_->{latlon}[0], + lon => $_->{latlon}[1], + stop => $_, + } + } $self->route; + } + return; + } + + $self->{polyline} = [ map { { lat => $_->[0], lon => $_->[1] } } + @{ $self->{polyline_raw} } ]; + my $distance; + + eval { + require GIS::Distance; + $distance = GIS::Distance->new; + }; - # TODO add $_->{id} as well? - return map { $_->{latlon} } $self->route; + if ($distance) { + my %min_dist; + for my $stop ( $self->route ) { + for my $polyline_index ( 0 .. $#{ $self->{polyline} } ) { + my $pl = $self->{polyline}[$polyline_index]; + my $dist = $distance->distance_metal( + $stop->{latlon}[0], + $stop->{latlon}[1], + $pl->{lat}, $pl->{lon} + ); + if ( not $min_dist{ $stop->{id_code} } + or $min_dist{ $stop->{id_code} }{dist} > $dist ) + { + $min_dist{ $stop->{id_code} } = { + dist => $dist, + index => $polyline_index, + }; + } + } + } + for my $stop ( $self->route ) { + if ( $min_dist{ $stop->{id_code} } ) { + $self->{polyline}[ $min_dist{ $stop->{id_code} }{index} ]{stop} + = $stop; + } + } } - return @{ $self->{polyline} // [] }; + return @{ $self->{polyline} }; } sub parse_dt { @@ -102,14 +152,16 @@ sub route { sched_dep => $self->parse_dt( $stop->{departureTimePlanned} ), rt_arr => $self->parse_dt( $stop->{arrivalTimeEstimated} ), rt_dep => $self->parse_dt( $stop->{departureTimeEstimated} ), - latlon => $stop->{coord}, - full_name => $name_full, - name => $name, - place => $place, - niveau => $stop->{niveau}, - platform => $platform, - id_code => $id_code, - id_num => $id_num, + occupancy => $stop->{properties}{occupancy}, + is_cancelled => $stop->{isCancelled}, + latlon => $stop->{coord}, + full_name => $name_full, + name => $name, + place => $place, + niveau => $stop->{niveau}, + platform => $platform, + id_code => $id_code, + id_num => $id_num, ) ); } @@ -125,6 +177,9 @@ sub TO_JSON { # lazy loading $self->route; + # lazy loading + $self->polyline; + my $ret = { %{$self} }; delete $ret->{strptime_obj}; @@ -150,7 +205,7 @@ trip =head1 VERSION -version 3.07 +version 3.13 =head1 DESCRIPTION @@ -214,6 +269,28 @@ Note: The EFA API requires a stop to be specified when requesting trip details. The stops returned by this accessor appear to be limited to stops after the requested stop; earlier ones may be missing. +=item $journey->polyline(I<%opt>) + +List of geocoordinates that describe the trips's route. +Each list entry is a hash with the following keys. + +=over + +=item * lon (longitude) + +=item * lat (latitude) + +=item * stop (Stop object for this location, if any. undef otherwise) + +=back + +Note that stop is not provided by the backend and instead inferred by this +module. + +If the backend does not provide geocoordinates and this accessor was called +with B< fallback > set to a true value, it returns the list of stop coordinates +instead. Otherwise, it returns an empty list. + =back =head2 INTERNAL diff --git a/lib/Travel/Status/DE/VRR.pm b/lib/Travel/Status/DE/VRR.pm index ee21593..6782523 100644 --- a/lib/Travel/Status/DE/VRR.pm +++ b/lib/Travel/Status/DE/VRR.pm @@ -4,7 +4,7 @@ use strict; use warnings; use 5.010; -our $VERSION = '3.07'; +our $VERSION = '3.13'; use parent 'Travel::Status::DE::EFA'; @@ -43,7 +43,7 @@ Travel::Status::DE::VRR - unofficial VRR departure monitor. =head1 VERSION -version 3.07 +version 3.13 =head1 DESCRIPTION |