Commit 33be5602 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

working train intersection demo \o/

parent d2f3efbd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -351,6 +351,9 @@ sub startup {
	$r->get('/map/:tripid/:lineno')->to('map#route');
	$r->get('/intersection/:trips')->to('map#intersection');

	$r->get('/map')->to('map#search_form');
	$r->get('/_trainsearch')->to('map#search');

	$self->defaults( layout => 'app' );

	$r->get('/')->to('stationboard#handle_request');
+114 −3
Original line number Diff line number Diff line
@@ -274,7 +274,7 @@ sub estimate_train_positions2 {
		}
	}

	if ( not $next_stop ) {
	if ( @route and not $next_stop ) {
		@train_positions = ( [ $route[-1]{lat}, $route[-1]{lon} ] );
		$next_stop       = {
			type    => 'present',
@@ -313,13 +313,15 @@ sub estimate_train_intersection {
		my $arr2 = $route2[ $i2 + 1 ]{arr};

		if ( not( $dep1 and $arr1 ) ) {
			say "skip 1 $route1[$i1]{name}";

			#say "skip 1 $route1[$i1]{name}";
			$i1++;
			next;
		}

		if ( not( $dep2 and $arr2 ) ) {
			say "skip 2 $route2[$i2]{name}";

			#say "skip 2 $route2[$i2]{name}";
			$i2++;
			next;
		}
@@ -857,4 +859,113 @@ sub ajax_route {
	)->wait;
}

sub search {
	my ($self) = @_;

	my $t1 = $self->param('train1');
	my $t2 = $self->param('train2');

	my $t1_data;
	my $t2_data;

	my $now       = DateTime->now( time_zone => 'Europe/Berlin' );
	my $date_yy   = $now->strftime('%d.%m.%y');
	my $date_yyyy = $now->strftime('%d.%m.%Y');

	# Doesn't seem to matter -- so far, HAFAS is happy as long as the date part
	# starts with a number. HAFAS-internal tripIDs use this format (withouth
	# leading zero for day of month < 10) though, so let's stick with it.
	my $date_map = $now->strftime('%d%m%Y');

	if ( $t1 and $t1 =~ m{^\S+\s+\d+$} ) {
		$t1_data = $self->hafas->trainsearch(
			train_no  => $t1,
			date_yy   => $date_yy,
			date_yyyy => $date_yyyy
		);
	}
	else {
		$self->render(
			'trainsearch',
			title     => 'Fahrtverlauf',
			hide_opts => 1,
			error     => $t1
			? "Züge müssen im Format 'Zugtyp Nummer' angegeben werden, z.B. 'RE 1234'"
			: undef,
		);
		return;
	}

	if ( $t2 and $t2 =~ m{^\S+\s+\d+$} ) {
		$t2_data = $self->hafas->trainsearch( train_no => $t2 );
	}
	elsif ($t2) {
		$self->render(
			'trainsearch',
			title     => 'Fahrtverlauf',
			hide_opts => 1,
			error =>
"Züge müssen im Format 'Zugtyp Nummer' angegeben werden, z.B. 'RE 1234'",
		);
		return;
	}

	if ( not $t1_data ) {
		$self->render(
			'trainsearch',
			title     => 'Fahrtverlauf',
			hide_opts => 1,
			error     => "Zug $t1 nicht gefunden"
		);
		return;
	}

	if ( $t2 and not $t2_data ) {
		$self->render(
			'trainsearch',
			title     => 'Fahrtverlauf',
			hide_opts => 1,
			error     => "Zug $t2 nicht gefunden"
		);
		return;
	}

	if ( $t1 and not $t2 ) {
		$self->redirect_to(
			sprintf(
				"/map/1|%d|%d|%d|%s/0",
				$t1_data->{id},   $t1_data->{cycle},
				$t1_data->{pool}, $date_map
			)
		);
	}
	elsif ( $t1 and $t2 ) {
		$self->redirect_to(
			sprintf(
				"/intersection/1|%d|%d|%d|%s,0;1|%d|%d|%d|%s,0",
				$t1_data->{id},   $t1_data->{cycle}, $t1_data->{pool},
				$date_map,        $t2_data->{id},    $t2_data->{cycle},
				$t2_data->{pool}, $date_map
			)
		);
	}
	else {
		$self->render(
			'trainsearch',
			title     => 'Fahrtverlauf',
			hide_opts => 1,
		);
	}
}

sub search_form {
	my ($self) = @_;

	$self->render(
		'trainsearch',
		title     => 'Fahrtverlauf',
		hide_opts => 1,
	);
}

1;
+38 −22
Original line number Diff line number Diff line
@@ -151,35 +151,27 @@ sub hafas_xml_req {
	return $ret;
}

sub get_route_timestamps {
sub trainsearch {
	my ( $self, %opt ) = @_;

	my $base
	  = 'https://reiseauskunft.bahn.de/bin/trainsearch.exe/dn?L=vs_json&start=yes&rt=1';
	my ( $date_yy, $date_yyyy, $train_no, $train_origin );

	if ( $opt{train} ) {
		$date_yy      = $opt{train}->start->strftime('%d.%m.%y');
		$date_yyyy    = $opt{train}->start->strftime('%d.%m.%Y');
		$train_no     = $opt{train}->type . ' ' . $opt{train}->train_no;
		$train_origin = $opt{train}->origin;
	}
	else {
	if ( not $opt{date_yy} ) {
		my $now = DateTime->now( time_zone => 'Europe/Berlin' );
		$date_yy   = $now->strftime('%d.%m.%y');
		$date_yyyy = $now->strftime('%d.%m.%Y');
		$train_no  = $opt{train_no};
		$opt{date_yy}   = $now->strftime('%d.%m.%y');
		$opt{date_yyyy} = $now->strftime('%d.%m.%Y');
	}

	my $trainsearch = $self->hafas_json_req( $self->{main_cache},
		"${base}&date=${date_yy}&trainname=${train_no}" );
		"${base}&date=$opt{date_yy}&trainname=$opt{train_no}" );

	if ( not $trainsearch ) {
		return;
	}

	# Fallback: Take first result
	my $trainlink = $trainsearch->{suggestions}[0]{trainLink};
	my $result = $trainsearch->{suggestions}[0];

	# Try finding a result for the current date
	for my $suggestion ( @{ $trainsearch->{suggestions} // [] } ) {
@@ -187,8 +179,8 @@ sub get_route_timestamps {
       # Drunken API, sail with care. Both date formats are used interchangeably
		if (
			exists $suggestion->{depDate}
			and (  $suggestion->{depDate} eq $date_yy
				or $suggestion->{depDate} eq $date_yyyy )
			and (  $suggestion->{depDate} eq $opt{date_yy}
				or $suggestion->{depDate} eq $opt{date_yyyy} )
		  )
		{
			# Train numbers are not unique, e.g. IC 149 refers both to the
@@ -197,28 +189,52 @@ sub get_route_timestamps {
			# requests with the stationFilter=80 parameter.  Checking the origin
			# station seems to be the more generic solution, so we do that
			# instead.
			if ( $train_origin and $suggestion->{dep} eq $train_origin ) {
				$trainlink = $suggestion->{trainLink};
			if (    $opt{train_origin}
				and $suggestion->{dep} eq $opt{train_origin} )
			{
				$result = $suggestion;
				last;
			}
		}
	}

	if ( not $trainlink ) {
	return $result;
}

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

	if ( $opt{train} ) {
		$opt{date_yy}      = $opt{train}->start->strftime('%d.%m.%y');
		$opt{date_yyyy}    = $opt{train}->start->strftime('%d.%m.%Y');
		$opt{train_no}     = $opt{train}->type . ' ' . $opt{train}->train_no;
		$opt{train_origin} = $opt{train}->origin;
	}
	else {
		my $now = DateTime->now( time_zone => 'Europe/Berlin' );
		$opt{date_yy}   = $now->strftime('%d.%m.%y');
		$opt{date_yyyy} = $now->strftime('%d.%m.%Y');
	}

	my $trainsearch_result = $self->trainsearch(%opt);

	if ( not $trainsearch_result ) {
		return;
	}

	$base = 'https://reiseauskunft.bahn.de/bin/traininfo.exe/dn';
	my $trainlink = $trainsearch_result->{trainLink};

	my $base = 'https://reiseauskunft.bahn.de/bin/traininfo.exe/dn';

	my $traininfo = $self->hafas_json_req( $self->{realtime_cache},
		"${base}/${trainlink}?rt=1&date=${date_yy}&L=vs_json" );
		"${base}/${trainlink}?rt=1&date=$opt{date_yy}&L=vs_json" );

	if ( not $traininfo or $traininfo->{error} ) {
		return;
	}

	my $traindelay = $self->hafas_xml_req( $self->{realtime_cache},
		"${base}/${trainlink}?rt=1&date=${date_yy}&L=vs_java3" );
		"${base}/${trainlink}?rt=1&date=$opt{date_yy}&L=vs_java3" );

	my $ret = {};

+1 −1
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@

<div class="container">
% if (my $error = stash 'error') {
<div class="error"><strong>Backend-Fehler:</strong>
<div class="error"><strong>Fehler:</strong>
<pre>
%= $error
</pre>
+4 −0
Original line number Diff line number Diff line
@@ -86,6 +86,10 @@ Die eingezeichnete Route stammt aus dem HAFAS und ist im Detail oft
fehlerbehaftet.<br/>
Die Zugposition auf der Karte ist eine DBF-eigene Schätzung und kann erheblich
von den tatsächlichen Gegebenheiten abweichen.
% if (stash('intersection')) {
<br/>In dieser Ansicht sind Live-Updates der Zug- und Begegnungspositionen noch
nicht implementiert.
% }
</div>

% if (my $op = stash('operator')) {
Loading