Fix beeline distance calculation when start/stop has no geo-coordinates

This commit is contained in:
Daniel Friesel 2019-08-13 21:30:59 +02:00
parent c9592e3f76
commit e259a5e5dd
2 changed files with 54 additions and 18 deletions

View file

@ -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->{km_route} = $km_route;
$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_beeline} = $km_beeline;
$ref->{skip_beeline} = $skip;
my $kmh_divisor
= ( $ref->{rt_duration} // $ref->{sched_duration}
@ -2685,7 +2681,8 @@ sub startup {
'get_travel_distance' => sub {
my ( $self, $from, $to, $route_ref ) = @_;
my $distance = 0;
my $distance_intermediate = 0;
my $distance_beeline = 0;
my $skipped = 0;
my $geo = Geo::Distance->new();
my @stations = map { $_->[0] } @{$route_ref};
@ -2695,18 +2692,33 @@ sub startup {
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 );
}
);

View file

@ -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 {