Unverified Commit 5e72665c authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

train details: use HAFAS route as source of truth. Fixes handling of ring lines

parent 480dee69
Loading
Loading
Loading
Loading
+28 −91
Original line number Diff line number Diff line
@@ -811,98 +811,37 @@ sub render_train {
		$opt{language} = 'en';
	}

	$self->hafas->get_route_timestamps_p(%opt)->then(
	$self->hafas->get_route_p(%opt)->then(
		sub {
			my ( $route_ts, $journey ) = @_;
			my ( $route, $journey ) = @_;

			$departure->{trip_id}  = $journey->id;
			$departure->{operator} = $journey->operator;

			if ( my $load = $route_ts->{$station_name}{load} ) {
			# Use HAFAS route as source of truth; ignore IRIS data
			$departure->{route_pre_diff}  = [];
			$departure->{route_post_diff} = $route;
			my $split;
			for my $i ( 0 .. $#{ $departure->{route_post_diff} } ) {
				if ( $departure->{route_post_diff}[$i]{name} eq $station_name )
				{
					$split = $i;
					if ( my $load = $route->[$i]{load} ) {
						if ( %{$load} ) {
							$departure->{utilization}
							  = [ $load->{FIRST}, $load->{SECOND} ];
						}
					}

			# If a train number changes on the way, IRIS routes are incomplete,
			# whereas HAFAS data has all stops -> merge HAFAS stops into IRIS
			# stops. This is a rare case, one point where it can be observed is
			# the TGV service at Frankfurt/Karlsruhe/Mannheim.
			my @hafas_stations = $journey->route;
			if ( my @iris_stations = @{ $departure->{route_pre_diff} } ) {
				my @missing_pre;
				for my $station (@hafas_stations) {
					if (
						List::MoreUtils::any {
							$_->{name} eq $station->loc->name
						}
						@iris_stations
					  )
					{
						unshift(
							@{ $departure->{route_pre_diff} },
							@missing_pre
						);
						last;
					}
					push(
						@missing_pre,
						{
							name  => $station->loc->name,
							hafas => 1
						}
					);
				}
			}
			if ( my @iris_stations = @{ $departure->{route_post_diff} } ) {
				my @missing_post;
				for my $station ( reverse @hafas_stations ) {
					if (
						List::MoreUtils::any {
							$_->{name} eq $station->loc->name
						}
						@iris_stations
					  )
					{
						push(
							@{ $departure->{route_post_diff} },
							@missing_post
						);
					last;
				}
					unshift(
						@missing_post,
						{
							name  => $station->loc->name,
							hafas => 1
						}
					);
				}
			}

			if ($route_ts) {
				if ( $route_ts->{ $result->station }{rt_bogus} ) {

					#$departure->{missing_realtime} = 1;
				}
				for my $elem (
			if ( defined $split ) {
				for my $i ( 0 .. $split - 1 ) {
					push(
						@{ $departure->{route_pre_diff} },
					@{ $departure->{route_post_diff} }
				  )
				{
					if ( $elem->{name}
						=~ m{^Betriebsstelle nicht bekannt (\d+)$} )
					{
						my $eva = $1;
						if ( $route_ts->{$eva} ) {
							$elem->{name} = $route_ts->{$eva}{name};
						}
					}
					for my $key ( keys %{ $route_ts->{ $elem->{name} } // {} } )
					{
						$elem->{$key} = $route_ts->{ $elem->{name} }{$key};
					}
						shift( @{ $departure->{route_post_diff} } )
					);
				}
			}

@@ -1003,6 +942,7 @@ sub render_train {
	)->wait;
}

# /z/:train/*station
sub station_train_details {
	my ($self)   = @_;
	my $train_no = $self->stash('train');
@@ -1036,6 +976,7 @@ sub station_train_details {

	$self->render_later;

	# Always performs an IRIS request
	$self->get_results_p( $station, %opt )->then(
		sub {
			my ($status) = @_;
@@ -1117,6 +1058,7 @@ sub station_train_details {
	)->wait;
}

# /z/:train
sub train_details {
	my ($self) = @_;
	my $train = $self->stash('train');
@@ -1182,9 +1124,9 @@ sub train_details {

	my $linetype = 'bahn';

	$self->hafas->get_route_timestamps_p(%opt)->then(
	$self->hafas->get_route_p(%opt)->then(
		sub {
			my ( $route_ts, $journey ) = @_;
			my ( $route, $journey ) = @_;

			$res->{trip_id} = $journey->id;

@@ -1221,19 +1163,14 @@ sub train_details {
			$res->{destination} = $journey->route_end;
			$res->{operator}    = $journey->operator;

			$res->{route_post_diff}
			  = [ map { { name => $_->loc->name } } $journey->route ];
			for my $elem ( @{ $res->{route_post_diff} } ) {
				for my $key ( keys %{ $route_ts->{ $elem->{name} } // {} } ) {
					$elem->{$key} = $route_ts->{ $elem->{name} }{$key};
				}
			}
			$res->{route_post_diff} = $route;

			if ( my $req_name = $self->param('highlight') ) {
				my $split;
				for my $i ( 0 .. $#{ $res->{route_post_diff} } ) {
					if ( $res->{route_post_diff}[$i]{name} eq $req_name ) {
						$split = $i;
						last;
					}
				}
				if ( defined $split ) {
+31 −29
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ sub new {

}

sub get_route_timestamps_p {
sub get_route_p {
	my ( $self, %opt ) = @_;

	my $promise = Mojo::Promise->new;
@@ -88,12 +88,12 @@ sub get_route_timestamps_p {
		sub {
			my ($hafas) = @_;
			my $journey = $hafas->result;
			my $ret     = {};

			my @ret;
			my $station_is_past = 1;
			for my $stop ( $journey->route ) {
				my $name = $stop->loc->name;
				$ret->{$name} = $ret->{ $stop->loc->eva } = {
				push(
					@ret,
					{
						name           => $stop->loc->name,
						eva            => $stop->loc->eva,
						sched_arr      => $stop->sched_arr,
@@ -107,27 +107,29 @@ sub get_route_timestamps_p {
						platform       => $stop->platform,
						sched_platform => $stop->sched_platform,
						load           => $stop->load,
						isAdditional   => $stop->is_additional,
						isCancelled    => (
							( $stop->arr_cancelled or not $stop->sched_arr )
						  and ( $stop->dep_cancelled or not $stop->sched_dep )
							  and
							  ( $stop->dep_cancelled or not $stop->sched_dep )
						),
				};
					}
				);
				if (
					    $station_is_past
					and not $ret->{$name}{isCancelled}
					and not $ret[-1]{isCancelled}
					and $now->epoch < (
						$ret->{$name}{rt_arr} // $ret->{$name}{rt_dep}
						  // $ret->{$name}{sched_arr}
						  // $ret->{$name}{sched_dep} // $now
						$ret[-1]{rt_arr} // $ret[-1]{rt_dep}
						  // $ret[-1]{sched_arr} // $ret[-1]{sched_dep} // $now
					)->epoch
				  )
				{
					$station_is_past = 0;
				}
				$ret->{$name}{isPast} = $station_is_past;
				$ret[-1]{isPast} = $station_is_past;
			}

			$promise->resolve( $ret, $journey );
			$promise->resolve( \@ret, $journey );
			return;
		}
	)->catch(