diff options
| author | Daniel Friesel <derf@finalrewind.org> | 2022-11-05 22:01:51 +0100 | 
|---|---|---|
| committer | Daniel Friesel <derf@finalrewind.org> | 2022-11-05 22:01:51 +0100 | 
| commit | 528f59dbd2be3c58ebdec16a3e047df7796452a2 (patch) | |
| tree | 15ddb339d393a8ec3b596ac4b2da0dd12defbbaa | |
| parent | 087d3871e127175652c5acc8e44c3c7e358ce05f (diff) | |
obtain polylines via mgate (T-S-DE-HAFAS)
| -rwxr-xr-x | lib/Travelynx.pm | 133 | ||||
| -rw-r--r-- | lib/Travelynx/Helper/HAFAS.pm | 135 | 
2 files changed, 95 insertions, 173 deletions
| diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index 7f1295e..7c8b48e 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -994,82 +994,6 @@ sub startup {  				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 $route = $journey->{route}; @@ -1136,11 +1060,14 @@ sub startup {  					);  					return $self->hafas->get_route_timestamps_p( -						trip_id => $trip_id ); +						train         => $train, +						trip_id       => $trip_id, +						with_polyline => not $journey->{polyline} +					);  				}  			)->then(  				sub { -					my ( $route_data, $journey ) = @_; +					my ( $route_data, $journey, $polyline ) = @_;  					for my $station ( @{$route} ) {  						$station->[1] @@ -1172,6 +1099,56 @@ sub startup {  						],  						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;  				}  			)->catch( diff --git a/lib/Travelynx/Helper/HAFAS.pm b/lib/Travelynx/Helper/HAFAS.pm index 62814b6..7b42384 100644 --- a/lib/Travelynx/Helper/HAFAS.pm +++ b/lib/Travelynx/Helper/HAFAS.pm @@ -34,97 +34,6 @@ sub new {  	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 {  	my ( $self, $url, %opt ) = @_; @@ -186,14 +95,16 @@ sub get_route_timestamps_p {  			# name => $opt{train_no},  		}, -		cache      => $self->{realtime_cache}, -		promise    => 'Mojo::Promise', -		user_agent => $self->{user_agent}->request_timeout(10) +		with_polyline => $opt{with_polyline}, +		cache         => $self->{realtime_cache}, +		promise       => 'Mojo::Promise', +		user_agent    => $self->{user_agent}->request_timeout(10),  	)->then(  		sub {  			my ($hafas) = @_;  			my $journey = $hafas->result;  			my $ret     = {}; +			my $polyline;  			my $station_is_past = 1;  			for my $stop ( $journey->route ) { @@ -228,7 +139,41 @@ sub get_route_timestamps_p {  				$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;  		}  	)->catch( | 
