Loading lib/DBInfoscreen/Controller/Map.pm +72 −127 Original line number Diff line number Diff line Loading @@ -18,22 +18,27 @@ my $strp = DateTime::Format::Strptime->new( time_zone => 'Europe/Berlin', ); # Input: # - polyline: Travel::Status::DE::HAFAS::Journey->polyline # - from_name: station name # - to_name: station name # Ouptut: # - from_index: polyline index that corresponds to from_name # - to_index: polyline index that corresponds to to_name sub get_route_indexes { my ( $features, $from_name, $to_name ) = @_; my ( $polyline, $from_name, $to_name ) = @_; my ( $from_index, $to_index ); for my $i ( 0 .. $#{$features} ) { my $this_point = $features->[$i]; for my $i ( 0 .. $#{$polyline} ) { my $this_point = $polyline->[$i]; if ( not defined $from_index and $this_point->{properties}{type} and $this_point->{properties}{type} eq 'stop' and $this_point->{properties}{name} eq $from_name ) and $this_point->{name} and $this_point->{name} eq $from_name ) { $from_index = $i; } elsif ( $this_point->{properties}{type} and $this_point->{properties}{type} eq 'stop' and $this_point->{properties}{name} eq $to_name ) elsif ( $this_point->{name} and $this_point->{name} eq $to_name ) { $to_index = $i; last; Loading @@ -48,8 +53,8 @@ sub get_route_indexes { # {dep => DateTime, name => str, lat => float, lon => float} # to: next stop # {arr => DateTime, name => str, lat => float, lon => float} # features: https://github.com/public-transport/hafas-client/blob/5/docs/trip.md features array # (with [lon, lat] coordinates in the geometry dict) # route: Travel::Status::DE::HAFAS::Journey->route # polyline: Travel::Status::DE::HAFAS::Journey->polyline (list of lon/lat hashes) # Output: list of estimated train positions in [lat, lon] format. # - current position # - position 2 seconds from now Loading @@ -64,7 +69,8 @@ sub estimate_train_positions { my $to_dt = $opt{to}{arr} // $opt{to}{dep}; my $from_name = $opt{from}{name}; my $to_name = $opt{to}{name}; my $features = $opt{features}; my $route = $opt{route}; my $polyline = $opt{polyline}; my @train_positions; Loading @@ -77,29 +83,29 @@ sub estimate_train_positions { my $distance = GIS::Distance->new; my ( $from_index, $to_index ) = get_route_indexes( $features, $from_name, $to_name ); = get_route_indexes( $polyline, $from_name, $to_name ); if ( defined $from_index and defined $to_index ) { my $total_distance = 0; for my $j ( $from_index + 1 .. $to_index ) { my $prev = $features->[ $j - 1 ]{geometry}{coordinates}; my $this = $features->[$j]{geometry}{coordinates}; my $prev = $polyline->[ $j - 1 ]; my $this = $polyline->[$j]; if ( $prev and $this ) { $total_distance += $distance->distance_metal( $prev->[1], $prev->[0], $this->[1], $this->[0] ); += $distance->distance_metal( $prev->{lat}, $prev->{lon}, $this->{lat}, $this->{lon} ); } } my @marker_distances = map { $total_distance * $_ } @completion_ratios; $total_distance = 0; for my $j ( $from_index + 1 .. $to_index ) { my $prev = $features->[ $j - 1 ]{geometry}{coordinates}; my $this = $features->[$j]{geometry}{coordinates}; my $prev = $polyline->[ $j - 1 ]; my $this = $polyline->[$j]; if ( $prev and $this ) { my $prev_distance = $total_distance; $total_distance += $distance->distance_metal( $prev->[1], $prev->[0], $this->[1], $this->[0] ); += $distance->distance_metal( $prev->{lat}, $prev->{lon}, $this->{lat}, $this->{lon} ); for my $i ( @train_positions .. $#marker_distances ) { my $marker_distance = $marker_distances[$i]; if ( $total_distance > $marker_distance ) { Loading @@ -111,10 +117,10 @@ sub estimate_train_positions { / ( $total_distance - $prev_distance ); } my $lat = $prev->[1] + ( $this->[1] - $prev->[1] ) * $sub_ratio; my $lon = $prev->[0] + ( $this->[0] - $prev->[0] ) * $sub_ratio; my $lat = $prev->{lat} + ( $this->{lat} - $prev->{lat} ) * $sub_ratio; my $lon = $prev->{lon} + ( $this->{lon} - $prev->{lon} ) * $sub_ratio; push( @train_positions, [ $lat, $lon ] ); } Loading Loading @@ -149,7 +155,7 @@ sub estimate_train_positions { # name: str # arr: DateTime # dep: DateTime # features: ref to transport.rest features list # polyline: ref to Travel::Status::DE::HAFAS::Journey polyline list # Output: # next_stop: {type, station} # positions: [current position [lat, lon], 2s from now, 4s from now, ...] Loading Loading @@ -180,7 +186,8 @@ sub estimate_train_positions2 { from => $route[ $i - 1 ], to => $route[$i], now => $now, features => $opt{features}, route => $opt{route}, polyline => $opt{polyline}, ); $next_stop = { Loading Loading @@ -233,14 +240,12 @@ sub route_to_ajax { my @route_entries; for my $stop (@stopovers) { my @stop_entries = ( $stop->{stop}{name} ); my @stop_entries = ( $stop->{name} ); my $platform; if ( $stop->{arrival} and my $arr = $strp->parse_datetime( $stop->{arrival} ) ) { my $delay = ( $stop->{arrivalDelay} // 0 ) / 60; $platform = $stop->{arrivalPlatform}; if ( my $arr = $stop->{arr} ) { my $delay = $stop->{arr_delay} // 0; $platform = $stop->{arr_platform}; push( @stop_entries, $arr->epoch, $delay ); } Loading @@ -248,11 +253,9 @@ sub route_to_ajax { push( @stop_entries, q{}, q{} ); } if ( $stop->{departure} and my $dep = $strp->parse_datetime( $stop->{departure} ) ) { my $delay = ( $stop->{departureDelay} // 0 ) / 60; $platform //= $stop->{departurePlatform} // q{}; if ( my $dep = $stop->{dep} ) { my $delay = $stop->{dep_delay} // 0; $platform //= $stop->{dep_platform} // q{}; push( @stop_entries, $dep->epoch, $delay, $platform ); } Loading @@ -266,56 +269,6 @@ sub route_to_ajax { return join( '|', @route_entries ); } # Input: List of transport.rest stopovers # Output: List of preprocessed stops. Each is a hash with the following keys: # lat: float # lon: float # name: str # arr: DateTime # dep: DateTime # arr_delay: int # dep_delay: int # platform: str sub stopovers_to_route { my (@stopovers) = @_; my @route; for my $stop (@stopovers) { my @stop_lines = ( $stop->{stop}{name} ); my ( $platform, $arr, $dep, $arr_delay, $dep_delay ); if ( $stop->{arrival} and $arr = $strp->parse_datetime( $stop->{arrival} ) ) { $arr_delay = ( $stop->{arrivalDelay} // 0 ) / 60; $platform //= $stop->{arrivalPlatform}; } if ( $stop->{departure} and $dep = $strp->parse_datetime( $stop->{departure} ) ) { $dep_delay = ( $stop->{departureDelay} // 0 ) / 60; $platform //= $stop->{departurePlatform}; } push( @route, { lat => $stop->{stop}{location}{latitude}, lon => $stop->{stop}{location}{longitude}, name => $stop->{stop}{name}, arr => $arr, dep => $dep, arr_delay => $arr_delay, dep_delay => $dep_delay, platform => $platform, } ); } return @route; } sub polyline_to_line_pairs { my (@polyline) = @_; my @line_pairs; Loading @@ -323,8 +276,8 @@ sub polyline_to_line_pairs { push( @line_pairs, [ [ $polyline[ $i - 1 ][1], $polyline[ $i - 1 ][0] ], [ $polyline[$i][1], $polyline[$i][0] ] [ $polyline[ $i - 1 ]{lat}, $polyline[ $i - 1 ]{lon} ], [ $polyline[$i]{lat}, $polyline[$i]{lon} ] ] ); } Loading Loading @@ -362,9 +315,9 @@ sub route { $self->hafas->get_polyline_p( $trip_id, $line_no )->then( sub { my ($pl) = @_; my ($journey) = @_; my @polyline = @{ $pl->{polyline} }; my @polyline = $journey->polyline; my @station_coordinates; my @markers; Loading @@ -375,12 +328,12 @@ sub route { # used to draw the train's journey on the map my @line_pairs = polyline_to_line_pairs(@polyline); my @route = stopovers_to_route( @{ $pl->{raw}{stopovers} // [] } ); my @route = $journey->route; my $train_pos = $self->estimate_train_positions2( now => $now, route => \@route, features => $pl->{raw}{polyline}{features}, polyline => \@polyline, ); # Prepare from/to markers and name/time/delay overlays for stations Loading Loading @@ -437,34 +390,30 @@ sub route { { lat => $train_pos->{position_now}[0], lon => $train_pos->{position_now}[1], title => $pl->{name} titel => $journey->line } ); $next_stop = $train_pos->{next_stop}; $self->render( 'route_map', title => $pl->{name}, title => $journey->line, hide_opts => 1, with_map => 1, ajax_req => "${trip_id}/${line_no}", ajax_route => route_to_ajax( @{ $pl->{raw}{stopovers} // [] } ), ajax_route => route_to_ajax( $journey->route ), ajax_polyline => join( '|', map { join( ';', @{$_} ) } @{ $train_pos->{positions} } ), origin => { name => $pl->{raw}{origin}{name}, ts => $pl->{raw}{departure} ? scalar $strp->parse_datetime( $pl->{raw}{departure} ) : undef, name => $journey->route_start, ts => ( $journey->route )[0]->{dep}, }, destination => { name => $pl->{raw}{destination}{name}, ts => $pl->{raw}{arrival} ? scalar $strp->parse_datetime( $pl->{raw}{arrival} ) : undef, name => $journey->route_end, ts => ( $journey->route )[-1]->{arr}, }, train_no => scalar $pl->{raw}{line}{additionalName}, operator => scalar $pl->{raw}{line}{operator}{name}, train_no => $journey->train, operator => $journey->operator, next_stop => $next_stop, polyline_groups => [ { Loading Loading @@ -506,36 +455,32 @@ sub ajax_route { $self->hafas->get_polyline_p( $trip_id, $line_no )->then( sub { my ($pl) = @_; my ($journey) = @_; my $now = DateTime->now( time_zone => 'Europe/Berlin' ); my @route = stopovers_to_route( @{ $pl->{raw}{stopovers} // [] } ); my @route = $journey->route; my @polyline = $journey->polyline; my $train_pos = $self->estimate_train_positions2( now => $now, route => \@route, features => $pl->{raw}{polyline}{features}, polyline => \@polyline, ); my @polyline = @{ $pl->{polyline} }; $self->render( '_map_infobox', ajax_req => "${trip_id}/${line_no}", ajax_route => route_to_ajax( @{ $pl->{raw}{stopovers} // [] } ), ajax_route => route_to_ajax(@route), ajax_polyline => join( '|', map { join( ';', @{$_} ) } @{ $train_pos->{positions} } ), origin => { name => $pl->{raw}{origin}{name}, ts => $pl->{raw}{departure} ? scalar $strp->parse_datetime( $pl->{raw}{departure} ) : undef, name => $journey->route_start, ts => ( $journey->route )[0]->{dep}, }, destination => { name => $pl->{raw}{destination}{name}, ts => $pl->{raw}{arrival} ? scalar $strp->parse_datetime( $pl->{raw}{arrival} ) : undef, name => $journey->route_end, ts => ( $journey->route )[-1]->{arr}, }, next_stop => $train_pos->{next_stop}, ); Loading lib/DBInfoscreen/Helper/HAFAS.pm +16 −50 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ use 5.020; use DateTime; use Encode qw(decode encode); use Travel::Status::DE::HAFAS; use Mojo::JSON qw(decode_json); use Mojo::Promise; use XML::LibXML; Loading Loading @@ -438,68 +439,33 @@ sub get_route_timestamps_p { } # Input: (HAFAS TripID, line number) # Output: Promise returning a # https://github.com/public-transport/hafas-client/blob/4/docs/trip.md instance # on success # Output: Promise returning a Travel::Status::DE::HAFAS::Journey instance on success sub get_polyline_p { my ( $self, $trip_id, $line ) = @_; my $api = $self->{api}; my $url = "${api}/trips/${trip_id}?lineName=${line}&polyline=true"; my $log_url = $url; my $cache = $self->{realtime_cache}; my $promise = Mojo::Promise->new; $log_url =~ s{://\K[^:]+:[^@]+\@}{***@}; if ( my $content = $cache->thaw($url) ) { $promise->resolve($content); $self->{log}->debug("GET $log_url (cached)"); return $promise; } $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} ) ->then( Travel::Status::DE::HAFAS->new_p( journey => { id => $trip_id, name => $line, }, with_polyline => 1, cache => $self->{realtime_cache}, promise => 'Mojo::Promise', user_agent => $self->{user_agent}->request_timeout(5) )->then( sub { my ($tx) = @_; if ( my $err = $tx->error ) { $self->{log}->warn( "hafas->get_polyline_p($log_url): HTTP $err->{code} $err->{message}" ); $promise->reject( "GET $log_url returned HTTP $err->{code} $err->{message}"); return; } $self->{log}->debug("GET $log_url (OK)"); my $json = decode_json( $tx->res->body ); my @coordinate_list; my ($hafas) = @_; my $journey = $hafas->result; 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}; #} } my $ret = { name => $json->{line}{name} // '?', polyline => [@coordinate_list], raw => $json, }; $cache->freeze( $url, $ret ); $promise->resolve($ret); $promise->resolve($journey); return; } )->catch( sub { my ($err) = @_; $self->{log}->debug("GET $log_url (error: $err)"); $self->{log}->debug("HAFAS->new_p($trip_id, $line) error: $err"); $promise->reject($err); return; } Loading Loading
lib/DBInfoscreen/Controller/Map.pm +72 −127 Original line number Diff line number Diff line Loading @@ -18,22 +18,27 @@ my $strp = DateTime::Format::Strptime->new( time_zone => 'Europe/Berlin', ); # Input: # - polyline: Travel::Status::DE::HAFAS::Journey->polyline # - from_name: station name # - to_name: station name # Ouptut: # - from_index: polyline index that corresponds to from_name # - to_index: polyline index that corresponds to to_name sub get_route_indexes { my ( $features, $from_name, $to_name ) = @_; my ( $polyline, $from_name, $to_name ) = @_; my ( $from_index, $to_index ); for my $i ( 0 .. $#{$features} ) { my $this_point = $features->[$i]; for my $i ( 0 .. $#{$polyline} ) { my $this_point = $polyline->[$i]; if ( not defined $from_index and $this_point->{properties}{type} and $this_point->{properties}{type} eq 'stop' and $this_point->{properties}{name} eq $from_name ) and $this_point->{name} and $this_point->{name} eq $from_name ) { $from_index = $i; } elsif ( $this_point->{properties}{type} and $this_point->{properties}{type} eq 'stop' and $this_point->{properties}{name} eq $to_name ) elsif ( $this_point->{name} and $this_point->{name} eq $to_name ) { $to_index = $i; last; Loading @@ -48,8 +53,8 @@ sub get_route_indexes { # {dep => DateTime, name => str, lat => float, lon => float} # to: next stop # {arr => DateTime, name => str, lat => float, lon => float} # features: https://github.com/public-transport/hafas-client/blob/5/docs/trip.md features array # (with [lon, lat] coordinates in the geometry dict) # route: Travel::Status::DE::HAFAS::Journey->route # polyline: Travel::Status::DE::HAFAS::Journey->polyline (list of lon/lat hashes) # Output: list of estimated train positions in [lat, lon] format. # - current position # - position 2 seconds from now Loading @@ -64,7 +69,8 @@ sub estimate_train_positions { my $to_dt = $opt{to}{arr} // $opt{to}{dep}; my $from_name = $opt{from}{name}; my $to_name = $opt{to}{name}; my $features = $opt{features}; my $route = $opt{route}; my $polyline = $opt{polyline}; my @train_positions; Loading @@ -77,29 +83,29 @@ sub estimate_train_positions { my $distance = GIS::Distance->new; my ( $from_index, $to_index ) = get_route_indexes( $features, $from_name, $to_name ); = get_route_indexes( $polyline, $from_name, $to_name ); if ( defined $from_index and defined $to_index ) { my $total_distance = 0; for my $j ( $from_index + 1 .. $to_index ) { my $prev = $features->[ $j - 1 ]{geometry}{coordinates}; my $this = $features->[$j]{geometry}{coordinates}; my $prev = $polyline->[ $j - 1 ]; my $this = $polyline->[$j]; if ( $prev and $this ) { $total_distance += $distance->distance_metal( $prev->[1], $prev->[0], $this->[1], $this->[0] ); += $distance->distance_metal( $prev->{lat}, $prev->{lon}, $this->{lat}, $this->{lon} ); } } my @marker_distances = map { $total_distance * $_ } @completion_ratios; $total_distance = 0; for my $j ( $from_index + 1 .. $to_index ) { my $prev = $features->[ $j - 1 ]{geometry}{coordinates}; my $this = $features->[$j]{geometry}{coordinates}; my $prev = $polyline->[ $j - 1 ]; my $this = $polyline->[$j]; if ( $prev and $this ) { my $prev_distance = $total_distance; $total_distance += $distance->distance_metal( $prev->[1], $prev->[0], $this->[1], $this->[0] ); += $distance->distance_metal( $prev->{lat}, $prev->{lon}, $this->{lat}, $this->{lon} ); for my $i ( @train_positions .. $#marker_distances ) { my $marker_distance = $marker_distances[$i]; if ( $total_distance > $marker_distance ) { Loading @@ -111,10 +117,10 @@ sub estimate_train_positions { / ( $total_distance - $prev_distance ); } my $lat = $prev->[1] + ( $this->[1] - $prev->[1] ) * $sub_ratio; my $lon = $prev->[0] + ( $this->[0] - $prev->[0] ) * $sub_ratio; my $lat = $prev->{lat} + ( $this->{lat} - $prev->{lat} ) * $sub_ratio; my $lon = $prev->{lon} + ( $this->{lon} - $prev->{lon} ) * $sub_ratio; push( @train_positions, [ $lat, $lon ] ); } Loading Loading @@ -149,7 +155,7 @@ sub estimate_train_positions { # name: str # arr: DateTime # dep: DateTime # features: ref to transport.rest features list # polyline: ref to Travel::Status::DE::HAFAS::Journey polyline list # Output: # next_stop: {type, station} # positions: [current position [lat, lon], 2s from now, 4s from now, ...] Loading Loading @@ -180,7 +186,8 @@ sub estimate_train_positions2 { from => $route[ $i - 1 ], to => $route[$i], now => $now, features => $opt{features}, route => $opt{route}, polyline => $opt{polyline}, ); $next_stop = { Loading Loading @@ -233,14 +240,12 @@ sub route_to_ajax { my @route_entries; for my $stop (@stopovers) { my @stop_entries = ( $stop->{stop}{name} ); my @stop_entries = ( $stop->{name} ); my $platform; if ( $stop->{arrival} and my $arr = $strp->parse_datetime( $stop->{arrival} ) ) { my $delay = ( $stop->{arrivalDelay} // 0 ) / 60; $platform = $stop->{arrivalPlatform}; if ( my $arr = $stop->{arr} ) { my $delay = $stop->{arr_delay} // 0; $platform = $stop->{arr_platform}; push( @stop_entries, $arr->epoch, $delay ); } Loading @@ -248,11 +253,9 @@ sub route_to_ajax { push( @stop_entries, q{}, q{} ); } if ( $stop->{departure} and my $dep = $strp->parse_datetime( $stop->{departure} ) ) { my $delay = ( $stop->{departureDelay} // 0 ) / 60; $platform //= $stop->{departurePlatform} // q{}; if ( my $dep = $stop->{dep} ) { my $delay = $stop->{dep_delay} // 0; $platform //= $stop->{dep_platform} // q{}; push( @stop_entries, $dep->epoch, $delay, $platform ); } Loading @@ -266,56 +269,6 @@ sub route_to_ajax { return join( '|', @route_entries ); } # Input: List of transport.rest stopovers # Output: List of preprocessed stops. Each is a hash with the following keys: # lat: float # lon: float # name: str # arr: DateTime # dep: DateTime # arr_delay: int # dep_delay: int # platform: str sub stopovers_to_route { my (@stopovers) = @_; my @route; for my $stop (@stopovers) { my @stop_lines = ( $stop->{stop}{name} ); my ( $platform, $arr, $dep, $arr_delay, $dep_delay ); if ( $stop->{arrival} and $arr = $strp->parse_datetime( $stop->{arrival} ) ) { $arr_delay = ( $stop->{arrivalDelay} // 0 ) / 60; $platform //= $stop->{arrivalPlatform}; } if ( $stop->{departure} and $dep = $strp->parse_datetime( $stop->{departure} ) ) { $dep_delay = ( $stop->{departureDelay} // 0 ) / 60; $platform //= $stop->{departurePlatform}; } push( @route, { lat => $stop->{stop}{location}{latitude}, lon => $stop->{stop}{location}{longitude}, name => $stop->{stop}{name}, arr => $arr, dep => $dep, arr_delay => $arr_delay, dep_delay => $dep_delay, platform => $platform, } ); } return @route; } sub polyline_to_line_pairs { my (@polyline) = @_; my @line_pairs; Loading @@ -323,8 +276,8 @@ sub polyline_to_line_pairs { push( @line_pairs, [ [ $polyline[ $i - 1 ][1], $polyline[ $i - 1 ][0] ], [ $polyline[$i][1], $polyline[$i][0] ] [ $polyline[ $i - 1 ]{lat}, $polyline[ $i - 1 ]{lon} ], [ $polyline[$i]{lat}, $polyline[$i]{lon} ] ] ); } Loading Loading @@ -362,9 +315,9 @@ sub route { $self->hafas->get_polyline_p( $trip_id, $line_no )->then( sub { my ($pl) = @_; my ($journey) = @_; my @polyline = @{ $pl->{polyline} }; my @polyline = $journey->polyline; my @station_coordinates; my @markers; Loading @@ -375,12 +328,12 @@ sub route { # used to draw the train's journey on the map my @line_pairs = polyline_to_line_pairs(@polyline); my @route = stopovers_to_route( @{ $pl->{raw}{stopovers} // [] } ); my @route = $journey->route; my $train_pos = $self->estimate_train_positions2( now => $now, route => \@route, features => $pl->{raw}{polyline}{features}, polyline => \@polyline, ); # Prepare from/to markers and name/time/delay overlays for stations Loading Loading @@ -437,34 +390,30 @@ sub route { { lat => $train_pos->{position_now}[0], lon => $train_pos->{position_now}[1], title => $pl->{name} titel => $journey->line } ); $next_stop = $train_pos->{next_stop}; $self->render( 'route_map', title => $pl->{name}, title => $journey->line, hide_opts => 1, with_map => 1, ajax_req => "${trip_id}/${line_no}", ajax_route => route_to_ajax( @{ $pl->{raw}{stopovers} // [] } ), ajax_route => route_to_ajax( $journey->route ), ajax_polyline => join( '|', map { join( ';', @{$_} ) } @{ $train_pos->{positions} } ), origin => { name => $pl->{raw}{origin}{name}, ts => $pl->{raw}{departure} ? scalar $strp->parse_datetime( $pl->{raw}{departure} ) : undef, name => $journey->route_start, ts => ( $journey->route )[0]->{dep}, }, destination => { name => $pl->{raw}{destination}{name}, ts => $pl->{raw}{arrival} ? scalar $strp->parse_datetime( $pl->{raw}{arrival} ) : undef, name => $journey->route_end, ts => ( $journey->route )[-1]->{arr}, }, train_no => scalar $pl->{raw}{line}{additionalName}, operator => scalar $pl->{raw}{line}{operator}{name}, train_no => $journey->train, operator => $journey->operator, next_stop => $next_stop, polyline_groups => [ { Loading Loading @@ -506,36 +455,32 @@ sub ajax_route { $self->hafas->get_polyline_p( $trip_id, $line_no )->then( sub { my ($pl) = @_; my ($journey) = @_; my $now = DateTime->now( time_zone => 'Europe/Berlin' ); my @route = stopovers_to_route( @{ $pl->{raw}{stopovers} // [] } ); my @route = $journey->route; my @polyline = $journey->polyline; my $train_pos = $self->estimate_train_positions2( now => $now, route => \@route, features => $pl->{raw}{polyline}{features}, polyline => \@polyline, ); my @polyline = @{ $pl->{polyline} }; $self->render( '_map_infobox', ajax_req => "${trip_id}/${line_no}", ajax_route => route_to_ajax( @{ $pl->{raw}{stopovers} // [] } ), ajax_route => route_to_ajax(@route), ajax_polyline => join( '|', map { join( ';', @{$_} ) } @{ $train_pos->{positions} } ), origin => { name => $pl->{raw}{origin}{name}, ts => $pl->{raw}{departure} ? scalar $strp->parse_datetime( $pl->{raw}{departure} ) : undef, name => $journey->route_start, ts => ( $journey->route )[0]->{dep}, }, destination => { name => $pl->{raw}{destination}{name}, ts => $pl->{raw}{arrival} ? scalar $strp->parse_datetime( $pl->{raw}{arrival} ) : undef, name => $journey->route_end, ts => ( $journey->route )[-1]->{arr}, }, next_stop => $train_pos->{next_stop}, ); Loading
lib/DBInfoscreen/Helper/HAFAS.pm +16 −50 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ use 5.020; use DateTime; use Encode qw(decode encode); use Travel::Status::DE::HAFAS; use Mojo::JSON qw(decode_json); use Mojo::Promise; use XML::LibXML; Loading Loading @@ -438,68 +439,33 @@ sub get_route_timestamps_p { } # Input: (HAFAS TripID, line number) # Output: Promise returning a # https://github.com/public-transport/hafas-client/blob/4/docs/trip.md instance # on success # Output: Promise returning a Travel::Status::DE::HAFAS::Journey instance on success sub get_polyline_p { my ( $self, $trip_id, $line ) = @_; my $api = $self->{api}; my $url = "${api}/trips/${trip_id}?lineName=${line}&polyline=true"; my $log_url = $url; my $cache = $self->{realtime_cache}; my $promise = Mojo::Promise->new; $log_url =~ s{://\K[^:]+:[^@]+\@}{***@}; if ( my $content = $cache->thaw($url) ) { $promise->resolve($content); $self->{log}->debug("GET $log_url (cached)"); return $promise; } $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} ) ->then( Travel::Status::DE::HAFAS->new_p( journey => { id => $trip_id, name => $line, }, with_polyline => 1, cache => $self->{realtime_cache}, promise => 'Mojo::Promise', user_agent => $self->{user_agent}->request_timeout(5) )->then( sub { my ($tx) = @_; if ( my $err = $tx->error ) { $self->{log}->warn( "hafas->get_polyline_p($log_url): HTTP $err->{code} $err->{message}" ); $promise->reject( "GET $log_url returned HTTP $err->{code} $err->{message}"); return; } $self->{log}->debug("GET $log_url (OK)"); my $json = decode_json( $tx->res->body ); my @coordinate_list; my ($hafas) = @_; my $journey = $hafas->result; 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}; #} } my $ret = { name => $json->{line}{name} // '?', polyline => [@coordinate_list], raw => $json, }; $cache->freeze( $url, $ret ); $promise->resolve($ret); $promise->resolve($journey); return; } )->catch( sub { my ($err) = @_; $self->{log}->debug("GET $log_url (error: $err)"); $self->{log}->debug("HAFAS->new_p($trip_id, $line) error: $err"); $promise->reject($err); return; } Loading