The file busiest_airports.txt provides details of the 30 busiest airports in the world in 2014. The tab-delimited fields are: three-letter IATA code, airport name, airport location, latitude and longitude (both in degrees).
Write a program to determine the distance between two airports identified by their three-letter IATA code, using the Haversine formula (see, for example, Exercise 4.4.2) and assuming a spherical Earth of radius 6378.1 km).
The following solution uses a structured array. Note that the strings in this array are bytestrings and so for comparison and output we must encode and decode appropriately.
import sys
import numpy as np
haversin = lambda alpha: np.sin(alpha/2)**2
def gc_distance(airport_coords1, airport_coords2):
"""
Return the great-circle distance between two coordinates on the Earth
provided as two (latitude, longitude) tuples in radians.
"""
# Earth's radius, km
R = 6378.1
(phi1, lambda1), (phi2, lambda2) = airport_coords1, airport_coords2
d = 2 * R * np.arcsin(np.sqrt(haversin(phi2-phi1)
+ np.cos(phi1)*np.cos(phi2)*haversin(lambda2-lambda1)))
return d
iata1, iata2 = sys.argv[1:]
dt = np.dtype([('IATA', 'S50'), ('Name', 'S50'), ('Location', 'S50'),
('Latitude', 'f8'), ('Longitude', 'f8')])
to_radians = lambda alpha: np.radians(float(alpha))
airports = np.loadtxt('busiest_airports.txt', dtype=dt, delimiter='\t',
converters={3: to_radians, 4: to_radians})
def get_airport(iata):
"""
Return the airport with IATA code iata from the airports array or
raise an Exception if it isn't recognised.
"""
b_iata = bytes(iata, encoding='ascii')
airport = airports[airports['IATA']==b_iata]
# check we retrieved an airport: NB we can't use assert airport, ...
# because of a bug in numpy versions older than 1.8
assert len(airport)==1, 'Airport not recognised: {:s}'.format(iata)
return airport
airport1 = get_airport(iata1)
airport2 = get_airport(iata2)
airport_coords1 = airport1[['Latitude','Longitude']][0]
airport_coords2 = airport2[['Latitude','Longitude']][0]
airport_name1 = airport1['Name'][0].decode()
airport_name2 = airport2['Name'][0].decode()
d = gc_distance(airport_coords1, airport_coords2)
print('Distance from {:s} ({:3s}) to {:s} ({:3s}) is {:d} km'.format(
airport_name1, iata1, airport_name2, iata2, int(d)))
For example:
$ python airport-distances.py SFO LHR
Distance from San Francisco International Airport (SFO) to London Heathrow
Airport (LHR) is 8625 km