obtain polylines via mgate (T-S-DE-HAFAS)
This commit is contained in:
parent
087d3871e1
commit
528f59dbd2
2 changed files with 95 additions and 173 deletions
133
lib/Travelynx.pm
133
lib/Travelynx.pm
|
@ -994,82 +994,6 @@ sub startup {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $journey->{data}{trip_id}
|
|
||||||
and not $journey->{polyline} )
|
|
||||||
{
|
|
||||||
my ( $origin_eva, $destination_eva, $polyline_str );
|
|
||||||
$self->hafas->get_polyline_p( $train,
|
|
||||||
$journey->{data}{trip_id} )->then(
|
|
||||||
sub {
|
|
||||||
my ($ret) = @_;
|
|
||||||
my $polyline = $ret->{polyline};
|
|
||||||
$origin_eva = 0 + $ret->{raw}{origin}{id};
|
|
||||||
$destination_eva = 0 + $ret->{raw}{destination}{id};
|
|
||||||
|
|
||||||
# work around Cache::File turning floats into strings
|
|
||||||
for my $coord ( @{$polyline} ) {
|
|
||||||
@{$coord} = map { 0 + $_ } @{$coord};
|
|
||||||
}
|
|
||||||
|
|
||||||
$polyline_str = JSON->new->encode($polyline);
|
|
||||||
|
|
||||||
my $pl_res = $db->select(
|
|
||||||
'polylines',
|
|
||||||
['id'],
|
|
||||||
{
|
|
||||||
origin_eva => $origin_eva,
|
|
||||||
destination_eva => $destination_eva,
|
|
||||||
polyline => $polyline_str
|
|
||||||
},
|
|
||||||
{ limit => 1 }
|
|
||||||
);
|
|
||||||
|
|
||||||
my $polyline_id;
|
|
||||||
if ( my $h = $pl_res->hash ) {
|
|
||||||
$polyline_id = $h->{id};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eval {
|
|
||||||
$polyline_id = $db->insert(
|
|
||||||
'polylines',
|
|
||||||
{
|
|
||||||
origin_eva => $origin_eva,
|
|
||||||
destination_eva => $destination_eva,
|
|
||||||
polyline => $polyline_str
|
|
||||||
},
|
|
||||||
{ returning => 'id' }
|
|
||||||
)->hash->{id};
|
|
||||||
};
|
|
||||||
if ($@) {
|
|
||||||
$self->app->log->warn(
|
|
||||||
"add_route_timestamps: insert polyline: $@"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($polyline_id) {
|
|
||||||
$self->in_transit->set_polyline_id(
|
|
||||||
uid => $uid,
|
|
||||||
db => $db,
|
|
||||||
polyline_id => $polyline_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
)->catch(
|
|
||||||
sub {
|
|
||||||
my ($err) = @_;
|
|
||||||
if ( $err =~ m{extra content at the end}i ) {
|
|
||||||
$self->app->log->debug(
|
|
||||||
"add_route_timestamps: $err");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$self->app->log->warn("add_route_timestamps: $err");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
)->wait;
|
|
||||||
}
|
|
||||||
|
|
||||||
my ($platform) = ( ( $train->platform // 0 ) =~ m{(\d+)} );
|
my ($platform) = ( ( $train->platform // 0 ) =~ m{(\d+)} );
|
||||||
|
|
||||||
my $route = $journey->{route};
|
my $route = $journey->{route};
|
||||||
|
@ -1136,11 +1060,14 @@ sub startup {
|
||||||
);
|
);
|
||||||
|
|
||||||
return $self->hafas->get_route_timestamps_p(
|
return $self->hafas->get_route_timestamps_p(
|
||||||
trip_id => $trip_id );
|
train => $train,
|
||||||
|
trip_id => $trip_id,
|
||||||
|
with_polyline => not $journey->{polyline}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
)->then(
|
)->then(
|
||||||
sub {
|
sub {
|
||||||
my ( $route_data, $journey ) = @_;
|
my ( $route_data, $journey, $polyline ) = @_;
|
||||||
|
|
||||||
for my $station ( @{$route} ) {
|
for my $station ( @{$route} ) {
|
||||||
$station->[1]
|
$station->[1]
|
||||||
|
@ -1172,6 +1099,56 @@ sub startup {
|
||||||
],
|
],
|
||||||
him_messages => \@messages,
|
him_messages => \@messages,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($polyline) {
|
||||||
|
my $coords = $polyline->{coords};
|
||||||
|
my $from_eva = $polyline->{from_eva};
|
||||||
|
my $to_eva = $polyline->{to_eva};
|
||||||
|
|
||||||
|
my $polyline_str = JSON->new->encode($coords);
|
||||||
|
|
||||||
|
my $pl_res = $db->select(
|
||||||
|
'polylines',
|
||||||
|
['id'],
|
||||||
|
{
|
||||||
|
origin_eva => $from_eva,
|
||||||
|
destination_eva => $to_eva,
|
||||||
|
polyline => $polyline_str
|
||||||
|
},
|
||||||
|
{ limit => 1 }
|
||||||
|
);
|
||||||
|
|
||||||
|
my $polyline_id;
|
||||||
|
if ( my $h = $pl_res->hash ) {
|
||||||
|
$polyline_id = $h->{id};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eval {
|
||||||
|
$polyline_id = $db->insert(
|
||||||
|
'polylines',
|
||||||
|
{
|
||||||
|
origin_eva => $from_eva,
|
||||||
|
destination_eva => $to_eva,
|
||||||
|
polyline => $polyline_str
|
||||||
|
},
|
||||||
|
{ returning => 'id' }
|
||||||
|
)->hash->{id};
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
$self->app->log->warn(
|
||||||
|
"add_route_timestamps: insert polyline: $@"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($polyline_id) {
|
||||||
|
$self->in_transit->set_polyline_id(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db,
|
||||||
|
polyline_id => $polyline_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
)->catch(
|
)->catch(
|
||||||
|
|
|
@ -34,97 +34,6 @@ sub new {
|
||||||
return bless( \%opt, $class );
|
return bless( \%opt, $class );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_polyline_p {
|
|
||||||
my ( $self, $train, $trip_id ) = @_;
|
|
||||||
|
|
||||||
my $line = $train->line // 0;
|
|
||||||
my $backend = $self->{hafas_rest_api};
|
|
||||||
my $url = "${backend}/trips/${trip_id}?lineName=${line}&polyline=true";
|
|
||||||
my $cache = $self->{main_cache};
|
|
||||||
my $promise = Mojo::Promise->new;
|
|
||||||
my $version = $self->{version};
|
|
||||||
|
|
||||||
if ( my $content = $cache->thaw($url) ) {
|
|
||||||
return $promise->resolve($content);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $log_url = $url;
|
|
||||||
$log_url =~ s{://\K[^:]+:[^@]+\@}{***@};
|
|
||||||
|
|
||||||
$self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} )
|
|
||||||
->then(
|
|
||||||
sub {
|
|
||||||
my ($tx) = @_;
|
|
||||||
|
|
||||||
if ( my $err = $tx->error ) {
|
|
||||||
$promise->reject(
|
|
||||||
"hafas->get_polyline_p($log_url) returned HTTP $err->{code} $err->{message}"
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $body = decode( 'utf-8', $tx->res->body );
|
|
||||||
my $json = JSON->new->decode($body);
|
|
||||||
my @station_list;
|
|
||||||
my @coordinate_list;
|
|
||||||
|
|
||||||
for my $feature ( @{ $json->{polyline}{features} } ) {
|
|
||||||
if ( exists $feature->{geometry}{coordinates} ) {
|
|
||||||
my $coord = $feature->{geometry}{coordinates};
|
|
||||||
if ( exists $feature->{properties}{type}
|
|
||||||
and $feature->{properties}{type} eq 'stop' )
|
|
||||||
{
|
|
||||||
push( @{$coord}, $feature->{properties}{id} );
|
|
||||||
push( @station_list, $feature->{properties}{name} );
|
|
||||||
}
|
|
||||||
push( @coordinate_list, $coord );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my $ret = {
|
|
||||||
name => $json->{line}{name} // '?',
|
|
||||||
polyline => [@coordinate_list],
|
|
||||||
raw => $json,
|
|
||||||
};
|
|
||||||
|
|
||||||
$cache->freeze( $url, $ret );
|
|
||||||
|
|
||||||
# borders (Gr" as in "Grenze") are only returned by HAFAS.
|
|
||||||
# They are not stations.
|
|
||||||
my $iris_stations = join( '|', $train->route );
|
|
||||||
my $hafas_stations
|
|
||||||
= join( '|', grep { $_ !~ m{(\(Gr\)|\)Gr)$} } @station_list );
|
|
||||||
|
|
||||||
# Do not return polyline if it belongs to an entirely different
|
|
||||||
# train. Trains with longer routes (e.g. due to train number
|
|
||||||
# changes, which are handled by HAFAS but left out in IRIS)
|
|
||||||
# are okay though.
|
|
||||||
if ( $iris_stations ne $hafas_stations
|
|
||||||
and index( $hafas_stations, $iris_stations ) == -1 )
|
|
||||||
{
|
|
||||||
$self->{log}->info( 'Ignoring polyline for '
|
|
||||||
. $train->line
|
|
||||||
. ": IRIS route does not agree with HAFAS route: $iris_stations != $hafas_stations"
|
|
||||||
);
|
|
||||||
$promise->reject(
|
|
||||||
"hafas->get_polyline_p($log_url): polyline route mismatch");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$promise->resolve($ret);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
)->catch(
|
|
||||||
sub {
|
|
||||||
my ($err) = @_;
|
|
||||||
$promise->reject("hafas->get_polyline_p($log_url): $err");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
)->wait;
|
|
||||||
|
|
||||||
return $promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub get_json_p {
|
sub get_json_p {
|
||||||
my ( $self, $url, %opt ) = @_;
|
my ( $self, $url, %opt ) = @_;
|
||||||
|
|
||||||
|
@ -186,14 +95,16 @@ sub get_route_timestamps_p {
|
||||||
|
|
||||||
# name => $opt{train_no},
|
# name => $opt{train_no},
|
||||||
},
|
},
|
||||||
cache => $self->{realtime_cache},
|
with_polyline => $opt{with_polyline},
|
||||||
promise => 'Mojo::Promise',
|
cache => $self->{realtime_cache},
|
||||||
user_agent => $self->{user_agent}->request_timeout(10)
|
promise => 'Mojo::Promise',
|
||||||
|
user_agent => $self->{user_agent}->request_timeout(10),
|
||||||
)->then(
|
)->then(
|
||||||
sub {
|
sub {
|
||||||
my ($hafas) = @_;
|
my ($hafas) = @_;
|
||||||
my $journey = $hafas->result;
|
my $journey = $hafas->result;
|
||||||
my $ret = {};
|
my $ret = {};
|
||||||
|
my $polyline;
|
||||||
|
|
||||||
my $station_is_past = 1;
|
my $station_is_past = 1;
|
||||||
for my $stop ( $journey->route ) {
|
for my $stop ( $journey->route ) {
|
||||||
|
@ -228,7 +139,41 @@ sub get_route_timestamps_p {
|
||||||
$ret->{$name}{isPast} = $station_is_past;
|
$ret->{$name}{isPast} = $station_is_past;
|
||||||
}
|
}
|
||||||
|
|
||||||
$promise->resolve( $ret, $journey );
|
if ( $journey->polyline ) {
|
||||||
|
my @station_list;
|
||||||
|
my @coordinate_list;
|
||||||
|
|
||||||
|
for my $coord ( $journey->polyline ) {
|
||||||
|
if ( $coord->{name} ) {
|
||||||
|
push( @coordinate_list,
|
||||||
|
[ $coord->{lon}, $coord->{lat}, $coord->{eva} ] );
|
||||||
|
push( @station_list, $coord->{name} );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
push( @coordinate_list,
|
||||||
|
[ $coord->{lon}, $coord->{lat} ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my $iris_stations = join( '|', $opt{train}->route );
|
||||||
|
my $hafas_stations = join( '|', @station_list );
|
||||||
|
if ( $iris_stations eq $hafas_stations
|
||||||
|
or index( $hafas_stations, $iris_stations ) != -1 )
|
||||||
|
{
|
||||||
|
$polyline = {
|
||||||
|
from_eva => ( $journey->route )[0]{eva},
|
||||||
|
to_eva => ( $journey->route )[-1]{eva},
|
||||||
|
coords => \@coordinate_list,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->{log}->info( 'Ignoring polyline for '
|
||||||
|
. $opt{train}->line
|
||||||
|
. ": IRIS route does not agree with HAFAS route: $iris_stations != $hafas_stations"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$promise->resolve( $ret, $journey, $polyline );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
)->catch(
|
)->catch(
|
||||||
|
|
Loading…
Reference in a new issue