Distance and Bearing: Difference between revisions

Added Perl
(fix for display jq)
(Added Perl)
Line 552:
Thurrock Airfield United Kingdom EGMT 68.4 272
cpu time = 183 ms, real time = 183 ms.</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl" line>use v5.36;
use utf8;
binmode STDOUT, ':utf8';
use Text::CSV 'csv';
use Math::Trig;
 
use constant EARTH_RADIUS_IN_NAUTICAL_MILES => 6372.8 / 1.852;
use constant TAU => 2 * 2 * atan2(1, 0);
 
sub degrees ( $rad ) { $rad / TAU * 360 }
sub radians ( $deg ) { $deg * TAU / 360 }
sub haversine ( $x ) { sin($x / 2)**2 }
sub arc_haver ( $x ) { asin(sqrt($x)) * 2 }
 
sub great_circle_distance ( $p1, $l1, $p2, $l2 ) {
arc_haver(
haversine($p2 - $p1)
+ haversine($l2 - $l1) * cos($p1) * cos($p2)
);
}
 
sub great_circle_bearing ( $p1, $l1, $p2, $l2 ) {
atan2( cos($p2) * sin($l2 - $l1),
cos($p1)*sin($p2) - sin($p1) * cos($p2) * cos($l2 - $l1),
);
}
 
sub distance_and_bearing ( $lat1, $lon1, $lat2, $lon2 ) {
my @ll = map { radians $_ } $lat1, $lon1, $lat2, $lon2;
my $dist = great_circle_distance(@ll);
my $theta = great_circle_bearing( @ll);
$dist * EARTH_RADIUS_IN_NAUTICAL_MILES, degrees( $theta < 0 ? $theta + TAU : $theta);
}
 
sub find_nearest_airports ( $latitude, $longitude, $csv_path ) {
my $airports = csv(
in => $csv_path,
headers => [<ID Name City Country IATA ICAO Latitude Longitude>],
);
 
for my $row (@$airports) {
($$row{'Distance'},$$row{'Bearing'}) = distance_and_bearing( $latitude, $longitude, $$row{'Latitude'}, $$row{'Longitude'} );
}
 
sort { $a->{'Distance'} <=> $b->{'Distance'} } @$airports;
}
 
my($lat, $lon, $wanted, $csv) = (51.514669, 2.198581, 20, 'ref/airports.dat');
printf "%7s\t%7s\t%-7s\t%-15s\t%s\n", <Dist Bear ICAO Country Name>;
for my $airport (find_nearest_airports($lat, $lon, $csv)) {
printf "%7.1f\t %03d\t%-7s\t%-15s\t%s\n", map { $airport->{$_} } <Distance Bearing ICAO Country Name>;
last unless --$wanted
}
 
</syntaxhighlight>
{{out}}
<pre> Dist Bear ICAO Country Name
30.7 146 EBFN Belgium Koksijde Air Base
31.3 127 EBOS Belgium Ostend-Bruges International Airport
33.6 252 EGMH United Kingdom Kent International Airport
34.4 195 LFAC France Calais-Dunkerque Airport
42.6 105 EBKW Belgium Westkapelle heliport
51.6 240 EGMK United Kingdom Lympne Airport
52.8 114 EBUL Belgium Ursel Air Base
56.2 274 EGMC United Kingdom Southend Airport
56.4 162 LFQT France Merville-Calonne Airport
56.5 137 EBKT Belgium Wevelgem Airport
58.0 235 EGMD United Kingdom Lydd Airport
59.0 309 EGUW United Kingdom RAF Wattisham
59.3 339 EGSM United Kingdom Beccles Airport
59.7 146 LFQO France Lille/Marcq-en-Baroeul Airport
62.2 250 EGKH United Kingdom Lashenden (Headcorn) Airfield
63.7 200 LFAT France Le Touquet-Côte d'Opale Airport
64.2 261 EGTO United Kingdom Rochester Airport
66.3 149 LFQQ France Lille-Lesquin Airport
68.4 271 EGMT United Kingdom Thurrock Airfield
72.5 313 EGXH United Kingdom RAF Honington</pre>
 
=={{header|Phix}}==
2,392

edits