From 3d22c00120518f8c5207fe1049a00506091cd43c Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 4 Jan 2020 22:51:59 +0100 Subject: show train route on map --- lib/DBInfoscreen.pm | 2 + lib/DBInfoscreen/Controller/Map.pm | 93 +++++++++++++++++++++++++++++ lib/DBInfoscreen/Controller/Stationboard.pm | 44 ++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 lib/DBInfoscreen/Controller/Map.pm (limited to 'lib') diff --git a/lib/DBInfoscreen.pm b/lib/DBInfoscreen.pm index b062c9d..c1455ff 100644 --- a/lib/DBInfoscreen.pm +++ b/lib/DBInfoscreen.pm @@ -281,6 +281,8 @@ sub startup { $r->get('/_wr/:train/:departure')->to('wagenreihung#wagenreihung'); + $r->get('/map/:tripid/:lineno')->to('map#route'); + $self->defaults( layout => 'app' ); $self->sessions->default_expiration( 3600 * 24 * 28 ); diff --git a/lib/DBInfoscreen/Controller/Map.pm b/lib/DBInfoscreen/Controller/Map.pm new file mode 100644 index 0000000..b22c5ea --- /dev/null +++ b/lib/DBInfoscreen/Controller/Map.pm @@ -0,0 +1,93 @@ +package DBInfoscreen::Controller::Map; +use Mojo::Base 'Mojolicious::Controller'; +use Mojo::JSON qw(decode_json); + +my $dbf_version = qx{git describe --dirty} || 'experimental'; + +chomp $dbf_version; + +sub get_hafas_polyline { + my ( $ua, $cache, $trip_id, $line ) = @_; + + $ua->request_timeout(2); + #say "https://2.db.transport.rest/trips/${trip_id}?lineName=${line}&polyline=true"; + my $res + = $ua->get( +"https://2.db.transport.rest/trips/${trip_id}?lineName=${line}&polyline=true" + => { 'User-Agent' => "dbf.finalrewind.org/${dbf_version}" } )->result; + if ( $res->is_error ) { + return; + } + + my $json = decode_json( $res->body ); + my @coordinate_list; + + for my $feature ( @{ $json->{polyline}{features} } ) { + if ( exists $feature->{geometry}{coordinates} ) { + push( @coordinate_list, $feature->{geometry}{coordinates} ); + } + + #if ($feature->{type} eq 'Feature') { + # say "Feature " . $feature->{properties}{name}; + #} + } + + return { + name => $json->{line}{name} // '?', + polyline => [@coordinate_list], + stopovers => $json->{stopovers}, + }; +} + +sub route { + my ($self) = @_; + my $trip_id = $self->stash('tripid'); + my $line_no = $self->stash('lineno'); + + my $pl = get_hafas_polyline( $self->ua, $self->app->cache_iris_main, + $trip_id, $line_no ); + my @polyline = @{ $pl->{polyline} }; + my @line_pairs; + my @station_coordinates; + + for my $i ( 1 .. $#polyline ) { + push( + @line_pairs, + [ + [ $polyline[ $i - 1 ][1], $polyline[ $i - 1 ][0] ], + [ $polyline[$i][1], $polyline[$i][0] ] + ] + ); + } + + for my $stop ( @{ $pl->{stopovers} // [] } ) { + push( + @station_coordinates, + [ + [ + $stop->{stop}{location}{latitude}, + $stop->{stop}{location}{longitude} + ], + $stop->{stop}{name} + ] + ); + } + + $self->render( + 'route_map', + title => $pl->{name}, + hide_opts => 1, + with_map => 1, + polyline_groups => [ + { + polylines => \@line_pairs, + color => '#00838f', + opacity => 0.6, + fit_bounds => 1, + } + ], + station_coordinates => [@station_coordinates], + ); +} + +1; diff --git a/lib/DBInfoscreen/Controller/Stationboard.pm b/lib/DBInfoscreen/Controller/Stationboard.pm index 9ebaca4..e32e78d 100644 --- a/lib/DBInfoscreen/Controller/Stationboard.pm +++ b/lib/DBInfoscreen/Controller/Stationboard.pm @@ -117,6 +117,46 @@ sub check_wagonorder_with_wings { return; } +sub get_hafas_trip_id { + my ( $ua, $cache, $train ) = @_; + + my $eva = $train->station_uic; + my $dep_ts = DateTime->now( time_zone => 'Europe/Berlin' ); + if ( $train->sched_departure ) { + $dep_ts = $train->sched_departure->epoch; + } + elsif ( $train->sched_arrival ) { + $dep_ts = $train->sched_arrival->epoch; + } + + $ua->request_timeout(2); + my $res + = $ua->get( +"https://2.db.transport.rest/stations/${eva}/departures?duration=5&when=$dep_ts" + )->result; + if ( $res->is_error ) { + return; + } + + my $json = decode_json( $res->body ); + + #say "looking for " . $train->train_no; + for my $result ( @{$json} ) { + my $trip_id = $result->{tripId}; + my $fahrt = $result->{line}{fahrtNr}; + #say "checking $fahrt"; + if ( $result->{line} and $result->{line}{fahrtNr} == $train->train_no ) + { + #say "Trip ID is $trip_id"; + return $trip_id; + } + else { + #say "unmatched Trip ID $trip_id"; + } + } + return; +} + sub check_wagonorder { my ( $ua, $cache, $train_no, $wr_link ) = @_; @@ -985,6 +1025,10 @@ sub handle_request { ) ]; + $departures[-1]{trip_id} + = get_hafas_trip_id( $self->ua, $self->app->cache_iris_main, + $result ); + if ( $departures[-1]{wr_link} and not check_wagonorder_with_wings( -- cgit v1.2.3