From e259a5e5ddce5fea34dace29efa05910fc8f0300 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Tue, 13 Aug 2019 21:30:59 +0200 Subject: Fix beeline distance calculation when start/stop has no geo-coordinates --- lib/Travelynx.pm | 54 +++++++++++++++++++++++++++------------ lib/Travelynx/Command/database.pm | 18 ++++++++++++- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index ef927ea..ba34d8a 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -2247,16 +2247,12 @@ sub startup { = $ref->{rt_arrival}->epoch ? $ref->{rt_arrival}->epoch - $ref->{rt_departure}->epoch : undef; - my ( $km, $skip ) + my ( $km_route, $km_beeline, $skip ) = $self->get_travel_distance( $ref->{from_name}, $ref->{to_name}, $ref->{route} ); - $ref->{km_route} = $km; - $ref->{skip_route} = $skip; - ( $km, $skip ) - = $self->get_travel_distance( $ref->{from_name}, - $ref->{to_name}, - [ [ $ref->{from_name} ], [ $ref->{to_name} ] ] ); - $ref->{km_beeline} = $km; + $ref->{km_route} = $km_route; + $ref->{skip_route} = $skip; + $ref->{km_beeline} = $km_beeline; $ref->{skip_beeline} = $skip; my $kmh_divisor = ( $ref->{rt_duration} // $ref->{sched_duration} @@ -2685,28 +2681,44 @@ sub startup { 'get_travel_distance' => sub { my ( $self, $from, $to, $route_ref ) = @_; - my $distance = 0; - my $skipped = 0; - my $geo = Geo::Distance->new(); - my @stations = map { $_->[0] } @{$route_ref}; - my @route = after_incl { $_ eq $from } @stations; + my $distance_intermediate = 0; + my $distance_beeline = 0; + my $skipped = 0; + my $geo = Geo::Distance->new(); + my @stations = map { $_->[0] } @{$route_ref}; + my @route = after_incl { $_ eq $from } @stations; @route = before_incl { $_ eq $to } @route; if ( @route < 2 ) { # I AM ERROR - return 0; + return ( 0, 0 ); } my $prev_station = get_station( shift @route ); if ( not $prev_station ) { - return 0; + return ( 0, 0 ); } + # Geo-coordinates for stations outside Germany are not available + # at the moment. When calculating distance with intermediate stops, + # these are simply left out (as if they were not part of the route). + # For beeline distance calculation, we use the route's first and last + # station with known geo-coordinates. + my $from_station_beeline; + my $to_station_beeline; + for my $station_name (@route) { if ( my $station = get_station($station_name) ) { + if ( not $from_station_beeline and $#{$prev_station} >= 4 ) + { + $from_station_beeline = $prev_station; + } + if ( $#{$station} >= 4 ) { + $to_station_beeline = $station; + } if ( $#{$prev_station} >= 4 and $#{$station} >= 4 ) { - $distance + $distance_intermediate += $geo->distance( 'kilometer', $prev_station->[3], $prev_station->[4], $station->[3], $station->[4] ); } @@ -2717,7 +2729,15 @@ sub startup { } } - return ( $distance, $skipped ); + if ( $from_station_beeline and $to_station_beeline ) { + $distance_beeline = $geo->distance( + 'kilometer', $from_station_beeline->[3], + $from_station_beeline->[4], $to_station_beeline->[3], + $to_station_beeline->[4] + ); + } + + return ( $distance_intermediate, $distance_beeline, $skipped ); } ); diff --git a/lib/Travelynx/Command/database.pm b/lib/Travelynx/Command/database.pm index e561373..c52a0a9 100644 --- a/lib/Travelynx/Command/database.pm +++ b/lib/Travelynx/Command/database.pm @@ -558,7 +558,7 @@ my @migrations = ( add column messages_new jsonb; } ); - my $res = $db->select( 'journeys', [ 'id', 'messages', 'route' ] ); + my $res = $db->select( 'journeys', [ 'id', 'messages', 'route' ] ); my $json = JSON->new; for my $journey ( $res->hashes->each ) { @@ -689,6 +689,22 @@ my @migrations = ( } ); }, + + # v15 -> v16 + # Beeline distance calculation now also works when departure or arrival + # station do not have geo-coordinates (by resorting to the first/last + # station in the route which does have geo-coordinates). Previously, + # beeline distances were reported as zero in this case. Clear caches + # to recalculate total distances per year / month. + sub { + my ($db) = @_; + $db->query( + qq{ + truncate journey_stats; + update schema_version set version = 16; + } + ); + }, ); sub setup_db { -- cgit v1.2.3