summaryrefslogtreecommitdiff
path: root/lib/Travelynx/Model/Journeys.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Travelynx/Model/Journeys.pm')
-rwxr-xr-xlib/Travelynx/Model/Journeys.pm245
1 files changed, 186 insertions, 59 deletions
diff --git a/lib/Travelynx/Model/Journeys.pm b/lib/Travelynx/Model/Journeys.pm
index 97c4681..343d680 100755
--- a/lib/Travelynx/Model/Journeys.pm
+++ b/lib/Travelynx/Model/Journeys.pm
@@ -118,8 +118,10 @@ sub add {
my $db = $opt{db};
my $uid = $opt{uid};
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
- my $dep_station = $self->{stations}->search( $opt{dep_station} );
- my $arr_station = $self->{stations}->search( $opt{arr_station} );
+ my $dep_station = $self->{stations}
+ ->search( $opt{dep_station}, backend_id => $opt{backend_id} );
+ my $arr_station = $self->{stations}
+ ->search( $opt{arr_station}, backend_id => $opt{backend_id} );
if ( not $dep_station ) {
return ( undef, 'Unbekannter Startbahnhof' );
@@ -167,16 +169,36 @@ sub add {
my @route;
if ( not $route_has_start ) {
- push( @route, [ $dep_station->{name}, $dep_station->{eva}, {} ] );
+ push(
+ @route,
+ [
+ $dep_station->{name},
+ $dep_station->{eva},
+ {
+ lat => $dep_station->{lat},
+ lon => $dep_station->{lon},
+ }
+ ]
+ );
}
if ( $opt{route} ) {
my @unknown_stations;
for my $station ( @{ $opt{route} } ) {
- my $station_info = $self->{stations}->search($station);
+ my $station_info = $self->{stations}
+ ->search( $station, backend_id => $opt{backend_id} );
if ($station_info) {
- push( @route,
- [ $station_info->{name}, $station_info->{eva}, {} ] );
+ push(
+ @route,
+ [
+ $station_info->{name},
+ $station_info->{eva},
+ {
+ lat => $station_info->{lat},
+ lon => $station_info->{lon},
+ }
+ ]
+ );
}
else {
push( @route, [ $station, undef, {} ] );
@@ -198,7 +220,17 @@ sub add {
}
if ( not $route_has_stop ) {
- push( @route, [ $arr_station->{name}, $arr_station->{eva}, {} ] );
+ push(
+ @route,
+ [
+ $arr_station->{name},
+ $arr_station->{eva},
+ {
+ lat => $arr_station->{lat},
+ lon => $arr_station->{lon},
+ }
+ ]
+ );
}
my $entry = {
@@ -218,6 +250,7 @@ sub add {
edited => 0x3fff,
cancelled => $opt{cancelled} ? 1 : 0,
route => JSON->new->encode( \@route ),
+ backend_id => $opt{backend_id},
};
if ( $opt{comment} ) {
@@ -515,7 +548,7 @@ sub get {
my @select
= (
- qw(journey_id train_type train_line train_no checkin_ts sched_dep_ts real_dep_ts dep_eva dep_ds100 dep_name dep_lat dep_lon checkout_ts sched_arr_ts real_arr_ts arr_eva arr_ds100 arr_name arr_lat arr_lon cancelled edited route messages user_data visibility effective_visibility)
+ qw(journey_id is_iris is_hafas backend_name backend_id train_type train_line train_no checkin_ts sched_dep_ts real_dep_ts dep_eva dep_ds100 dep_name dep_lat dep_lon checkout_ts sched_arr_ts real_arr_ts arr_eva arr_ds100 arr_name arr_lat arr_lon cancelled edited route messages user_data visibility effective_visibility)
);
my %where = (
user_id => $uid,
@@ -573,6 +606,10 @@ sub get {
my $ref = {
id => $entry->{journey_id},
+ is_iris => $entry->{is_iris},
+ is_hafas => $entry->{is_hafas},
+ backend_name => $entry->{backend_name},
+ backend_id => $entry->{backend_id},
type => $entry->{train_type},
line => $entry->{train_line},
no => $entry->{train_no},
@@ -632,7 +669,10 @@ sub get {
my $rename = $self->{renamed_station};
for my $stop ( @{ $ref->{route} } ) {
if ( $stop->[0] =~ m{^Betriebsstelle nicht bekannt (\d+)$} ) {
- if ( my $s = $self->{stations}->get_by_eva($1) ) {
+ if ( my $s
+ = $self->{stations}
+ ->get_by_eva( $1, backend_id => $ref->{backend_id} ) )
+ {
$stop->[0] = $s->{name};
}
}
@@ -767,14 +807,40 @@ sub get_oldest_ts {
return undef;
}
-sub get_latest_checkout_station_id {
+sub get_latest_checkout_latlon {
+ my ( $self, %opt ) = @_;
+ my $uid = $opt{uid};
+ my $db = $opt{db} // $self->{pg}->db;
+
+ my $res_h = $db->select(
+ 'journeys_str',
+ [ 'arr_lat', 'arr_lon', ],
+ {
+ user_id => $uid,
+ cancelled => 0
+ },
+ {
+ limit => 1,
+ order_by => { -desc => 'journey_id' }
+ }
+ )->hash;
+
+ if ( not $res_h ) {
+ return;
+ }
+
+ return $res_h->{arr_lat}, $res_h->{arr_lon};
+
+}
+
+sub get_latest_checkout_ids {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $res_h = $db->select(
'journeys',
- ['checkout_station_id'],
+ [ 'checkout_station_id', 'backend_id', ],
{
user_id => $uid,
cancelled => 0
@@ -789,7 +855,7 @@ sub get_latest_checkout_station_id {
return;
}
- return $res_h->{checkout_station_id};
+ return $res_h->{checkout_station_id}, $res_h->{backend_id};
}
sub get_latest_checkout_stations {
@@ -800,7 +866,10 @@ sub get_latest_checkout_stations {
my $res = $db->select(
'journeys_str',
- [ 'arr_name', 'arr_eva', 'train_id' ],
+ [
+ 'arr_name', 'arr_eva', 'train_id', 'backend_id',
+ 'backend_name', 'is_hafas'
+ ],
{
user_id => $uid,
cancelled => 0
@@ -821,9 +890,10 @@ sub get_latest_checkout_stations {
push(
@ret,
{
- name => $row->{arr_name},
- eva => $row->{arr_eva},
- hafas => ( $row->{train_id} =~ m{[|]} ? 1 : 0 ),
+ name => $row->{arr_name},
+ eva => $row->{arr_eva},
+ hafas => $row->{is_hafas} ? $row->{backend_name} : 0,
+ backend_id => $row->{backend_id},
}
);
}
@@ -1082,19 +1152,62 @@ sub get_travel_distance {
->warn("Journey $journey->{id} has no from_name for EVA $from_eva");
}
+ # Work around inconsistencies caused by a multiple EVA IDs mapping to the same station name
+ if (
+ @{ $polyline_ref // [] }
+ and not List::MoreUtils::any { $_->[2] and $_->[2] == $from_eva }
+ @{ $polyline_ref // [] }
+ )
+ {
+ $self->{log}->debug(
+"Journey $journey->{id} from_eva ($from_eva) is not part of polyline"
+ );
+ for my $entry ( @{$route_ref} ) {
+ if ( $entry->[0] eq $from and $entry->[1] ) {
+ $from_eva = $entry->[1];
+ $self->{log}->debug("... setting to $from_eva");
+ last;
+ }
+ }
+ }
+ if (
+ @{ $polyline_ref // [] }
+ and not List::MoreUtils::any { $_->[2] and $_->[2] == $to_eva }
+ @{ $polyline_ref // [] }
+ )
+ {
+ $self->{log}->debug(
+ "Journey $journey->{id} to_eva ($to_eva) is not part of polyline");
+ for my $entry ( @{$route_ref} ) {
+ if ( $entry->[0] eq $to and $entry->[1] ) {
+ $to_eva = $entry->[1];
+ $self->{log}->debug("... setting to $to_eva");
+ last;
+ }
+ }
+ }
+
my $distance_polyline = 0;
my $distance_intermediate = 0;
- my $distance_beeline = 0;
- my $skipped = 0;
my $geo = GIS::Distance->new();
- my @stations = map { $_->[0] } @{$route_ref};
- my @route = after_incl { $_ eq $from } @stations;
- @route = before_incl { $_ eq $to } @route;
+ my $distance_beeline
+ = $geo->distance_metal( @{$from_latlon}, @{$to_latlon} );
+ my @route
+ = after_incl { ( $_->[1] and $_->[1] == $from_eva ) or $_->[0] eq $from }
+ @{$route_ref};
+ @route
+ = before_incl { ( $_->[1] and $_->[1] == $to_eva ) or $_->[0] eq $to }
+ @route;
- if ( @route < 2 ) {
+ if (
+ @route < 2
+ or ( $route[-1][0] ne $to
+ and ( not $route[-1][1] or $route[-1][1] != $to_eva ) )
+ )
+ {
# I AM ERROR
- return ( 0, 0, 0 );
+ return ( 0, 0, $distance_beeline );
}
my @polyline = after_incl { $_->[2] and $_->[2] == $from_eva }
@@ -1102,34 +1215,32 @@ sub get_travel_distance {
@polyline
= before_incl { $_->[2] and $_->[2] == $to_eva } @polyline;
- my $prev_station = shift @polyline;
- for my $station (@polyline) {
- $distance_polyline += $geo->distance_metal(
- $prev_station->[1], $prev_station->[0],
- $station->[1], $station->[0]
- );
- $prev_station = $station;
- }
-
- $prev_station = $self->{latlon_by_station}->{ shift @route };
- if ( not $prev_station ) {
- return ( $distance_polyline, 0, 0 );
- }
-
- for my $station_name (@route) {
- if ( my $station = $self->{latlon_by_station}->{$station_name} ) {
- $distance_intermediate += $geo->distance_metal(
- $prev_station->[0], $prev_station->[1],
- $station->[0], $station->[1]
+ # ensure that before_incl matched -- otherwise, @polyline is too long
+ if ( @polyline and $polyline[-1][2] == $to_eva ) {
+ my $prev_station = shift @polyline;
+ for my $station (@polyline) {
+ $distance_polyline += $geo->distance_metal(
+ $prev_station->[1], $prev_station->[0],
+ $station->[1], $station->[0]
);
$prev_station = $station;
}
}
- $distance_beeline = $geo->distance_metal( @{$from_latlon}, @{$to_latlon} );
+ if ( defined $route[0][2]{lat} and defined $route[0][2]{lon} ) {
+ my $prev_station = shift @route;
+ for my $station (@route) {
+ if ( defined $station->[2]{lat} and defined $station->[2]{lon} ) {
+ $distance_intermediate += $geo->distance_metal(
+ $prev_station->[2]{lat}, $prev_station->[2]{lon},
+ $station->[2]{lat}, $station->[2]{lon}
+ );
+ $prev_station = $station;
+ }
+ }
+ }
- return ( $distance_polyline, $distance_intermediate,
- $distance_beeline, $skipped );
+ return ( $distance_polyline, $distance_intermediate, $distance_beeline );
}
sub grep_single {
@@ -1694,28 +1805,29 @@ sub get_stats {
return $stats;
}
-sub get_latest_dest_id {
+sub get_latest_dest_ids {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
if (
- my $id = $self->{in_transit}->get_checkout_station_id(
+ my ( $id, $backend_id ) = $self->{in_transit}->get_checkout_ids(
uid => $uid,
db => $db
)
)
{
- return $id;
+ return ( $id, $backend_id );
}
- return $self->get_latest_checkout_station_id(
+ return $self->get_latest_checkout_ids(
uid => $uid,
db => $db
);
}
+# Returns a listref of {eva, name} hashrefs for the specified backend.
sub get_connection_targets {
my ( $self, %opt ) = @_;
@@ -1724,21 +1836,32 @@ sub get_connection_targets {
// DateTime->now( time_zone => 'Europe/Berlin' )->subtract( months => 4 );
my $db = $opt{db} //= $self->{pg}->db;
my $min_count = $opt{min_count} // 3;
+ my $dest_id = $opt{eva};
if ( $opt{destination_name} ) {
- return (
- [],
- [ { eva => $opt{eva}, name => $opt{destination_name} } ]
- );
+ return {
+ eva => $opt{eva},
+ name => $opt{destination_name}
+ };
}
- my $dest_id = $opt{eva} // $self->get_latest_dest_id(%opt);
+ my $backend_id = $opt{backend_id};
+
+ if ( not $dest_id ) {
+ ( $dest_id, $backend_id ) = $self->get_latest_dest_ids(%opt);
+ }
if ( not $dest_id ) {
- return ( [], [] );
+ return;
}
- my $dest_ids = [ $dest_id, $self->{stations}->get_meta( eva => $dest_id ) ];
+ my $dest_ids = [
+ $dest_id,
+ $self->{stations}->get_meta(
+ eva => $dest_id,
+ backend_id => $backend_id,
+ )
+ ];
my $res = $db->select(
'journeys',
@@ -1746,7 +1869,8 @@ sub get_connection_targets {
{
user_id => $uid,
checkin_station_id => $dest_ids,
- real_departure => { '>', $threshold }
+ real_departure => { '>', $threshold },
+ backend_id => $opt{backend_id},
},
{
group_by => ['checkout_station_id'],
@@ -1756,8 +1880,11 @@ sub get_connection_targets {
my @destinations
= $res->hashes->grep( sub { shift->{count} >= $min_count } )
->map( sub { shift->{dest} } )->each;
- @destinations = $self->{stations}->get_by_evas(@destinations);
- return ( $dest_ids, \@destinations );
+ @destinations = $self->{stations}->get_by_evas(
+ backend_id => $opt{backend_id},
+ evas => [@destinations]
+ );
+ return @destinations;
}
sub update_visibility {