On the 4th of July 1989, Soviet MiG-23 pilot Nikolai Skuridin was on a routine training flight near Kolobrzeg, Poland, when his afterburner failed. Skuridin ejected, thinking the engine was completely dead, but the plane recovered and proceeded on autopilot into the west.

vliegroute MIG-23
Graphics of the flight involving unmanned Soviet MiG-23M "Flogger-B" before crashing into a house in Kortrijk, Belgium, on 4 July 1989, killing an 18-year-old man (taken from French newspaper Libération, description in French).

It must have had a lot of fuel, because it crossed out of Poland into East Germany, then into West Germany, then into the Netherlands, where a startled American air base sent up two F-15s to keep it company. As the MiG passed into Belgium the F-15s were told to shoot it down when it reached the North Sea, but it finally ran out of fuel near the French border, crashing into a house and killing a teenager.

The whole trip had covered 560 miles. Belgian Foreign Minister Mark Eyskens complained that the Soviets had issued no warning and no indication as to whether the pilotless plane was carrying dangerous weapons. It turned out that it was unarmed but carrying ammunition for a 23mm machine gun.

Assignment

Prior to departure, the pilot or flight dispatcher of an airplain must file a flight plan with the local aviation authority. This document generally includes basic information such as departure and arrival points, estimated time and route, alternate airports in case of bad weather, type of flight, number of people on board and information about the aircraft itself.

For this assignment, you are given a text file in CSV format (comma-separated values) containing information about a series of airports. The file contains twelve information fields for each airport. Of importance for this assignment is only the unique 3-letter code of the airport (first field), together with the latitude and longitude (fields 6 and 7 respectively) where the airport is located. Your task is to use the information in the text file to implement some simple route planning software that can determine the route for given airports of departure and arrival, and a given maximal range of the airplane.

Because it might well be that the distance between the airports of departure and arrival is larger than the range of the airplane, the route planning software might need to select some stopover airports where the airplane can refuel. The flight plan is determined by starting at the airport of departure, and then successively selecting the next unvisited airport within the range of the airplane that is closest to the destination (the airport of arrival). This procedure is repeated until the airport of arrival has been reached, or until no more airport can be reached that meets the required conditions.

In this assignment, locations on Earth are represented as tuples containing two floating point numbers, respectively representing the latitude and longitude of the location (expressed in degrees). These are called the coordinates of the location. To determine the distance between two airports having coordinates $$(b_1, l_1)$$ en $$(b_2, l_2)$$, we will make use of the Haversine distance $$d$$ between two points on a sphere that can be calculated by means of the following formula \[\begin{aligned}[c] a & = \left(\sin\left(\frac{b_2-b_1}{2}\right)\right)^2 + \cos(b_1)\cos(b_2)\left(\sin\left(\frac{l_2-l_1}{2}\right)\right)^2 \\ c & = \arctan\left(\sqrt{\frac{a}{1-a}}\right) \\ d & = 2rc \end{aligned}\] with $$r$$ equal to the radius of the sphere. Your task is to:

CSV format

CSV format (comma-separated values) is a specification for storing tabular data (numbers and text) in plain text files. Each line of the file is a data record. Each record consists of one or more fields, separated by commas. The use of the comma as a field separator is the source of the name for this file format. Consider the following tabel as an example

year make model description price
1997 Ford E350 airco, abs, moon 3000.00
1999 Chevy Venture "Extended Edition" 4900.00
1999 Chevy Venture "Extended Edition, Very Large" 5000.00
1996 Jeep Grand Cherokee MUST SELL!
air, moon roof, loaded
4799.00

The above table of data may be represented in CSV format as follows

Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4799.00

This illustrates some additional rules that must be followed by CSV files:

In order not to take into account all these extra rules when processing CSV files, it is always a good option to use the csv module in Python, which is part of the Python Standard Library.

Example

The following interactie sessions assumes the text file airports.csv1 is located in the current directory.

>>> coords = coordinates('airports.csv')
>>> len(coords)
9187
>>> type(coords)
<class 'dict'>
>>> coords['BRU']
(50.902222, 4.485833)
>>> coords['CDG']
(49.016667, 2.55)
>>> coords['DCA']
(38.851944, -77.037778)
>>> coords['LAX']
(33.9425, -118.407222)

>>> haversine((50.902222, 4.485833), (49.016667, 2.55)) # BRU <-> CDG
251.2480027355068
>>> haversine((38.851944, -77.037778), (33.9425, -118.407222)) # DCA <-> LAX
3710.8262543589817

>>> flightplan('DCA', 'LAX', coords)
['DCA', 'MTO', 'HLC', 'BFG', 'LAX']
>>> flightplan('DCA', 'LAX', coords, range=2000)
['DCA', 'DDC', 'LAX']
>>> flightplan('DCA', 'LAX', coords, range=4000)
['DCA', 'LAX']

>>> flightplan('BRU', 'CDG', coords)
['BRU', 'CDG']
>>> flightplan('BRU', 'CDG', coords, range=50)
Traceback (most recent call last):
AssertionError: no possible route