diff options
| -rw-r--r-- | lib/DBInfoscreen/Controller/Map.pm | 342 | 
1 files changed, 0 insertions, 342 deletions
| diff --git a/lib/DBInfoscreen/Controller/Map.pm b/lib/DBInfoscreen/Controller/Map.pm index 4748e11..4b953dc 100644 --- a/lib/DBInfoscreen/Controller/Map.pm +++ b/lib/DBInfoscreen/Controller/Map.pm @@ -42,84 +42,6 @@ sub get_route_indexes {  	return ( $from_index, $to_index );  } -# Returns timestamped train positions between stop1 and stop2 (must not have -# intermittent stops) in 10-second steps. -sub estimate_timestamped_positions { -	my (%opt) = @_; - -	my $from_dt   = $opt{from}{dep}; -	my $to_dt     = $opt{to}{arr}; -	my $from_name = $opt{from}{name}; -	my $to_name   = $opt{to}{name}; -	my $features  = $opt{features}; - -	my $duration = $to_dt->epoch - $from_dt->epoch; - -	my @train_positions; - -	my @completion_ratios -	  = map { ( $_ * 10 / $duration ) } ( 0 .. $duration / 10 ); - -	my ( $from_index, $to_index ) -	  = get_route_indexes( $features, $from_name, $to_name ); - -	my $location_epoch = $from_dt->epoch; -	my $distance       = GIS::Distance->new; - -	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}; -			if ( $prev and $this ) { -				$total_distance -				  += $distance->distance_metal( $prev->[1], $prev->[0], -					$this->[1], $this->[0] ); -			} -		} -		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}; -			if ( $prev and $this ) { -				my $prev_distance = $total_distance; -				$total_distance -				  += $distance->distance_metal( $prev->[1], $prev->[0], -					$this->[1], $this->[0] ); -				for my $i ( @train_positions .. $#marker_distances ) { -					my $marker_distance = $marker_distances[$i]; -					if ( $total_distance > $marker_distance ) { - -						# completion ratio for the line between (prev, this) -						my $sub_ratio = 1; -						if ( $total_distance != $prev_distance ) { -							$sub_ratio = ( $marker_distance - $prev_distance ) -							  / ( $total_distance - $prev_distance ); -						} - -						my $lat = $prev->[1] -						  + ( $this->[1] - $prev->[1] ) * $sub_ratio; -						my $lon = $prev->[0] -						  + ( $this->[0] - $prev->[0] ) * $sub_ratio; - -						push( @train_positions, -							[ $location_epoch, $lat, $lon ] ); -						$location_epoch += 10; -					} -				} -				if ( @train_positions == @completion_ratios ) { -					return @train_positions; -				} -			} -		} -		if (@train_positions) { -			return @train_positions; -		} -	} -	return; -} -  # Input:  #   now: DateTime  #   from: current/previous stop @@ -305,146 +227,6 @@ sub estimate_train_positions2 {  	};  } -sub estimate_train_intersection { -	my (%opt) = @_; -	my @route1 = @{ $opt{routes}[0] // [] }; -	my @route2 = @{ $opt{routes}[1] // [] }; - -	my $ret; - -	my $i1 = 0; -	my $i2 = 0; - -	my @pairs; -	my @meeting_points; -	my $distance = GIS::Distance->new; - -	# skip last route element as we compare route[i] with route[i+1] -	while ( $i1 < $#route1 and $i2 < $#route2 ) { -		my $dep1 = $route1[$i1]{dep}; -		my $arr1 = $route1[ $i1 + 1 ]{arr}; -		my $dep2 = $route2[$i2]{dep}; -		my $arr2 = $route2[ $i2 + 1 ]{arr}; - -		if ( not( $dep1 and $arr1 ) ) { - -			#say "skip 1 $route1[$i1]{name}"; -			$i1++; -			next; -		} - -		if ( not( $dep2 and $arr2 ) ) { - -			#say "skip 2 $route2[$i2]{name}"; -			$i2++; -			next; -		} - -		if ( $arr1 <= $dep2 ) { -			$i1++; -		} -		elsif ( $arr2 <= $dep1 ) { -			$i2++; -		} -		elsif ( $arr2 <= $arr1 ) { -			push( @pairs, [ $i1, $i2 ] ); -			if (    $route1[$i1]{name} eq $route2[ $i2 + 1 ]{name} -				and $route2[$i2]{name} eq $route1[ $i1 + 1 ]{name} ) -			{ -              # both i1 name == i2+1 name and i1 name == i2 name are valid cases -              # (trains don't just intersect when they travel in opposing -              # directions -- they may also travel in the same direction -              # with different speed and overtake each other). -              # We need both stop pairs later on, so we save both. -				$ret->{stop_pair} = [ -					[ $route1[$i1]{name}, $route1[ $i1 + 1 ]{name} ], -					[ $route2[$i2]{name}, $route2[ $i2 + 1 ]{name} ] -				]; -			} -			$i2++; -		} -		elsif ( $arr1 <= $arr2 ) { -			push( @pairs, [ $i1, $i2 ] ); -			if (    $route1[$i1]{name} eq $route2[ $i2 + 1 ]{name} -				and $route2[$i2]{name} eq $route1[ $i1 + 1 ]{name} ) -			{ -				$ret->{stop_pair} = [ -					[ $route1[$i1]{name}, $route1[ $i1 + 1 ]{name} ], -					[ $route2[$i2]{name}, $route2[ $i2 + 1 ]{name} ] -				]; -			} -			$i1++; -		} -		else { -			$i1++; -		} -	} - -	for my $pair (@pairs) { -		my ( $i1, $i2 ) = @{$pair}; -		my @train1_positions = estimate_timestamped_positions( -			from     => $route1[$i1], -			to       => $route1[ $i1 + 1 ], -			features => $opt{features}[0], -		); -		my @train2_positions = estimate_timestamped_positions( -			from     => $route2[$i2], -			to       => $route2[ $i2 + 1 ], -			features => $opt{features}[1], -		); -		$i1 = 0; -		$i2 = 0; -		while ( $i1 <= $#train1_positions and $i2 <= $#train2_positions ) { -			if ( $train1_positions[$i1][0] < $train2_positions[$i2][0] ) { -				$i1++; -			} -			elsif ( $train1_positions[$i2][0] < $train2_positions[$i2][0] ) { -				$i2++; -			} -			else { -				if ( -					( -						my $distance_km = $distance->distance_metal( -							$train1_positions[$i1][1], -							$train1_positions[$i1][2], -							$train2_positions[$i2][1], -							$train2_positions[$i2][2] -						) -					) < 1 -				  ) -				{ -					my $ts = DateTime->from_epoch( -						epoch     => $train1_positions[$i1][0], -						time_zone => 'Europe/Berlin' -					); -					$ret->{first_meeting_time} //= $ts; -					push( -						@meeting_points, -						{ -							timestamp => $ts, -							lat       => ( -								    $train1_positions[$i1][1] -								  + $train2_positions[$i2][1] -							) / 2, -							lon => ( -								    $train1_positions[$i1][2] -								  + $train2_positions[$i2][2] -							) / 2, -							distance => $distance_km, -						} -					); -				} -				$i1++; -				$i2++; -			} -		} -	} - -	$ret->{meeting_points} = \@meeting_points; - -	return $ret; -} -  sub route_to_ajax {  	my (@stopovers) = @_; @@ -549,130 +331,6 @@ sub polyline_to_line_pairs {  	return @line_pairs;  } -sub intersection { -	my ($self) = @_; - -	my @trips    = split( qr{;}, $self->stash('trips') ); -	my @trip_ids = map { [ split( qr{,}, $_ ) ] } @trips; - -	$self->render_later; - -	my @polyline_requests -	  = map { $self->hafas->get_polyline_p( @{$_} ) } @trip_ids; -	Mojo::Promise->all(@polyline_requests)->then( -		sub { -			my ( $pl1, $pl2 ) = map { $_->[0] } @_; -			my @polyline1 = @{ $pl1->{polyline} }; -			my @polyline2 = @{ $pl2->{polyline} }; -			my @station_coordinates; - -			my @markers; -			my $next_stop; - -			my $now = DateTime->now( time_zone => 'Europe/Berlin' ); - -			my @line1_pairs = polyline_to_line_pairs(@polyline1); -			my @line2_pairs = polyline_to_line_pairs(@polyline2); - -			my @route1 -			  = stopovers_to_route( @{ $pl1->{raw}{stopovers} // [] } ); -			my @route2 -			  = stopovers_to_route( @{ $pl2->{raw}{stopovers} // [] } ); - -			my $train1_pos = $self->estimate_train_positions2( -				now      => $now, -				route    => \@route1, -				features => $pl1->{raw}{polyline}{features}, -			); - -			my $train2_pos = $self->estimate_train_positions2( -				now      => $now, -				route    => \@route2, -				features => $pl2->{raw}{polyline}{features}, -			); - -			my $intersection = estimate_train_intersection( -				routes   => [ \@route1, \@route2 ], -				features => [ -					$pl1->{raw}{polyline}{features}, -					$pl2->{raw}{polyline}{features} -				], -			); - -			for my $meeting_point ( @{ $intersection->{meeting_points} } ) { -				push( -					@station_coordinates, -					[ -						[ $meeting_point->{lat}, $meeting_point->{lon} ], -						[ $meeting_point->{timestamp}->strftime('%H:%M') ] -					] -				); -			} - -			push( -				@markers, -				{ -					lat   => $train1_pos->{position_now}[0], -					lon   => $train1_pos->{position_now}[1], -					title => $pl1->{name} -				}, -				{ -					lat   => $train2_pos->{position_now}[0], -					lon   => $train2_pos->{position_now}[1], -					title => $pl2->{name} -				}, -			); - -			$self->render( -				'route_map', -				title        => "DBF", -				hide_opts    => 1, -				with_map     => 1, -				intersection => 1, -				train1_no => -				  scalar( $pl1->{raw}{line}{additionalName} // $pl1->{name} ), -				train2_no => -				  scalar( $pl2->{raw}{line}{additionalName} // $pl2->{name} ), -				likely_pair => $intersection->{stop_pair} -				? $intersection->{stop_pair}[0] -				: undef, -				time            => scalar $intersection->{first_meeting_time}, -				polyline_groups => [ -					{ -						polylines  => [ @line1_pairs, @line2_pairs ], -						color      => '#ffffff', -						opacity    => 0, -						fit_bounds => 1, -					}, -					{ -						polylines => [@line1_pairs], -						color     => '#005080', -						opacity   => 0.6, -					}, -					{ -						polylines => [@line2_pairs], -						color     => '#800050', -						opacity   => 0.6, -					} -				], -				markers             => [@markers], -				station_coordinates => [@station_coordinates], -			); -		} -	)->catch( -		sub { -			my ($err) = @_; -			$self->render( -				'route_map', -				title     => "DBF", -				hide_opts => 1, -				with_map  => 1, -				error     => $err, -			); -		} -	)->wait; -} -  sub backpropagate_delay {  	my ( $self, $prev_stop, $next_stop ) = @_; | 
