From 630cfe75900885856ad0a30e45c4c572a7dc54c1 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 3 Apr 2021 10:45:43 +0200 Subject: map: improve position estimation for delayed trains HAFAS does not provide delays of past stops, so we estimate it ourselves (assuming that the delay at the previous stop is identical to the delay at the next stop) --- lib/DBInfoscreen/Controller/Map.pm | 42 +++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/DBInfoscreen/Controller/Map.pm b/lib/DBInfoscreen/Controller/Map.pm index b4c9134..8912e5d 100644 --- a/lib/DBInfoscreen/Controller/Map.pm +++ b/lib/DBInfoscreen/Controller/Map.pm @@ -235,7 +235,7 @@ sub estimate_train_positions { # next_stop: {type, station} # positions: [current position [lat, lon], 2s from now, 4s from now, ...] sub estimate_train_positions2 { - my (%opt) = @_; + my ( $self, %opt ) = @_; my $now = $opt{now}; my @route = @{ $opt{route} // [] }; @@ -249,6 +249,9 @@ sub estimate_train_positions2 { and $now < ( $route[$i]{arr} // $route[$i]{dep} ) ) { + # HAFAS does not provide delays for past stops + $self->backpropagate_delay( $route[ $i - 1 ], $route[$i] ); + # (current position, future positons...) in 2 second steps @train_positions = estimate_train_positions( from => $route[ $i - 1 ], @@ -568,13 +571,13 @@ sub intersection { my @route2 = stopovers_to_route( @{ $pl2->{raw}{stopovers} // [] } ); - my $train1_pos = estimate_train_positions2( + my $train1_pos = $self->estimate_train_positions2( now => $now, route => \@route1, features => $pl1->{raw}{polyline}{features}, ); - my $train2_pos = estimate_train_positions2( + my $train2_pos = $self->estimate_train_positions2( now => $now, route => \@route2, features => $pl2->{raw}{polyline}{features}, @@ -662,6 +665,25 @@ sub intersection { )->wait; } +sub backpropagate_delay { + my ( $self, $prev_stop, $next_stop ) = @_; + + if ( ( $next_stop->{arr_delay} || $next_stop->{dep_delay} ) + and not( $prev_stop->{dep_delay} || $prev_stop->{arr_delay} ) ) + { + $self->log->debug("need to back-propagate delay"); + my $delay = $next_stop->{arr_delay} || $next_stop->{dep_delay}; + if ( $prev_stop->{arr} ) { + $prev_stop->{arr}->add( minutes => $delay ); + $prev_stop->{arr_delay} = $delay; + } + if ( $prev_stop->{dep} ) { + $prev_stop->{dep}->add( minutes => $delay ); + $prev_stop->{dep_delay} = $delay; + } + } +} + sub route { my ($self) = @_; my $trip_id = $self->stash('tripid'); @@ -689,6 +711,12 @@ sub route { my @route = stopovers_to_route( @{ $pl->{raw}{stopovers} // [] } ); + my $train_pos = $self->estimate_train_positions2( + now => $now, + route => \@route, + features => $pl->{raw}{polyline}{features}, + ); + # Prepare from/to markers and name/time/delay overlays for stations for my $stop (@route) { my @stop_lines = ( $stop->{name} ); @@ -738,12 +766,6 @@ sub route { [ [ $stop->{lat}, $stop->{lon} ], [@stop_lines], ] ); } - my $train_pos = estimate_train_positions2( - now => $now, - route => \@route, - features => $pl->{raw}{polyline}{features}, - ); - push( @markers, { @@ -822,7 +844,7 @@ sub ajax_route { my @route = stopovers_to_route( @{ $pl->{raw}{stopovers} // [] } ); - my $train_pos = estimate_train_positions2( + my $train_pos = $self->estimate_train_positions2( now => $now, route => \@route, features => $pl->{raw}{polyline}{features}, -- cgit v1.2.3