user
It is very important in aviation to have knowledge of the nearby airports at any time in flight.

Task

Determine the distance and bearing from an Airplane to the 20 nearest Airports whenever requested.
Use the non-commercial data from openflights.org airports.dat as reference.

A request comes from an airplane at position ( latitude, longitude ): ( **51.514669, 2.198581** ).

Your report should contain the following information from table airports.dat (column shown in brackets):

Name(2), Country(4), ICAO(6), Distance and Bearing calculated from Latitude(7) and Longitude(8).

Distance is measured in nautical miles (NM). Resolution is 0.1 NM.

Bearing is measured in degrees (°). 0° = 360° = north then clockwise 90° = east, 180° = south, 270° = west. Resolution is 1°.

See
:   * openflights.org/data:  Airport, airline and route data
    * Movable Type Scripts:  Calculate distance, bearing and more between Latitude/Longitude points
assistant
```
use Text::CSV;

constant $EARTH_RADIUS_IN_NAUTICAL_MILES = 6372.8 / 1.852;

sub degrees   ( Real $rad ) { $rad / tau * 360 }
sub radians   ( Real $deg ) { $deg * tau / 360 }
sub haversine ( Real $x   ) { ($x / 2).sin.²   }
sub arc_haver ( Real $x   ) { $x.sqrt.asin * 2 }

sub great_circle_distance ( \φ1, \λ1, \φ2, \λ2 ) {
    # https://en.wikipedia.org/wiki/Haversine_formula
    #   latitude (represented by φ) and longitude (represented by λ)
    #   hav(θ) = hav(φ₂ − φ₁) + cos(φ₁) cos(φ₂) hav(λ₂ − λ₁)
    arc_haver(
        haversine(φ2 - φ1)
      + haversine(λ2 - λ1) * cos(φ1) * cos(φ2)
    );
}

sub great_circle_bearing ( \φ1, \λ1, \φ2, \λ2 ) {
    atan2(                          φ2.cos * (λ2 - λ1).sin,
        φ1.cos * φ2.sin - φ1.sin * φ2.cos * (λ2 - λ1).cos,
    );
}

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);

    return  $dist * $EARTH_RADIUS_IN_NAUTICAL_MILES,
            degrees( $theta + (tau if $theta < 0) )
}

sub find_nearest_airports ( $latitude, $longitude, $csv_path ) {
    my &d_and_b_from_here = &distance_and_bearing.assuming($latitude, $longitude);

    my @airports = csv(
        in => $csv_path,
        headers => [<ID Name City Country IATA ICAO Latitude Longitude>],
    );

    for @airports -> %row {
        %row<Distance Bearing> = d_and_b_from_here( +%row<Latitude>, +%row<Longitude> );
    }

    return @airports.sort(*.<Distance>);
}

sub MAIN ( $lat = 51.514669, $long = 2.198581, $wanted = 20, $csv = 'airports.dat' ) {
    printf "%7s\t%7s\t%-7s\t%-15s\t%s\n", <Dist Bear ICAO Country Name>;

    for find_nearest_airports($lat, $long, $csv).head($wanted) {
        printf "%7.1f\t    %03d\t%-7s\t%-15s\t%s\n",
            .<Distance Bearing ICAO Country Name>;
    }
}

```

Output:

```
   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
   57.3	    089	EHMZ   	Netherlands    	Midden-Zeeland 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
```