In this assignment , you will implement a program called mayday that prints a list of airports and runways that are closest to a given location. The program will list airports that have runways longer than a given minimum length. It will also print the distance from the given location to the airport. In a fictional scenario, a pilot who encounters an emergency situation would use your program to get a list of the nearest landing options. The pilot would enter his/her current location as latitude and longitude (in degrees decimal) as well as the minimum runway length needed to land (in ft).
This assignment will test your C++ proficiency in opening and reading text files, using strings, using STL containers, using STL algorithms, and implementing function objects.
The program will first read data from two text files containing information about Federal Aviation Administration (FAA) facilities and runways. The files Facilities.txt and Runways.txt are provided and contain a list of 19700 facilities (such as airports, heliports, seaplane bases) and 23595 runways located mostly in the United States, but also in remote locations. Each line in the Facilities.txt file contains the description of a facility (airport, heliport or seaplane base). The first part of the line contains the site number, a 10-character string that uniquely identifies the facility. The rest of the line contains other information, including the facility type, name, code, and position (latitude and longitude in various formats). For example, San Francisco International Airport has site number 02187. *A, type AIRPORT, code SFO, name SAN FRANCISCO INTL, latitude 135427.7000N and longitude 440551.5000w (expressed in seconds decimal). The positions of these fields in the line are (starting at position 1):
Other fields are not relevant to this assignment.
Each line in the Runways.txt file contains the description of a runway. The first part of the line contains the site number of the facility it belongs to (i.e. the 10-character string described above). The rest of the line contains other information about the runway, including its name and length (in feet). For example, runway 10L/28R of San Francisco International airport has site number 02187. *A, name 10L/28R and a length of 11870 ft. The positions of these fields in the line are (starting at position 1):
Other fields are not relevant to this assignment.
The mayday program will read from the command line arguments the current position (latitude and longitude in degrees decimal) and minimum runway length from the command line arguments.
The program should then open and read the text files, create appropriate Facility and Runway objects, and store them using STL vectors. The facilities should then be sorted in order of proximity to the current location using the STL sort algorithm and a function object Closer defined in the file Closer.h. The program should then examine each facility in order of proximity and search for runways that belong to this facility (as identified by the site number) and have a length larger than or equal to the minimum runway length required. This search will use the STL find_if algorithm and a function object SiteNumber defined in the file SiteNumber.h. For each facility (up to a maximum of 10 facilities) the program will print the type, code, name, and distance from the current position, followed by a list of runways having a sufficient length.
You are given the files Facility.h and Runway. h which define classes that represent facilities and runways respectively. You should not modify these files. You must create the files Facility.cpp and Runway.cpp to implement the member functions of the classes Facility and Runway. You are also given a file mayday.cpp which contains an incomplete implementation of the main function. You must add lines to the file mayday.cpp to complete the implementation in three places identified with the comment
// Insert your code here
The comments preceding the above line indicate what must be implemented. You should not remove lines from the file mayday.cpp. You must create the files Closer.h and SiteNumber.h to include the definition of the corresponding function objects. You are also given the files gcdistance. h and gcdistance.cpp that include the implementation of the calculation of the distance between two locations on Earth specified by their latitudes and longitudes. These two files should not be modified.
The member functions of the Facility class are defined as follows:
Facility (string s)
The constructor takes a single string argument. The argument s contains a full line read from the Facilities. txt file. The constructor should initialize the data members of Facility by selecting the appropriate substrings from the argument. The latitude and longitude fields should be converted to double values using the convert_latitude and convert_longitude member functions. The sign of the latitude_ and longitude_ data members should be determined by checking whether the latitude and longitude fields end with N or S, and E or W respectively.
string site_number (void) const
This function returns the facility's site number.
string type (void) const
This function returns the facility's type.
string code (void) const
This function returns the facility's code.
string name (void) const
This function returns the facility's name.
double latitude (void) const
This function returns the latitude of the facility in degrees decimal. Latitudes in the southern hemisphere are negative numbers.
double longitude (void) const
This function returns the longitude of the facility in degrees decimal. Longitudes in the western hemisphere are negative numbers.
double distance (double lat, double lon) const
This function returns the distance in nautical miles between the facility and the position defined by (lat,lon) in degrees decimal. The implementation of this function uses the gcdistance function provided in files gcdistance.h and gcdistance.cpp.
double convert_latitude (string s) const
This function converts the string s representing a latitude in seconds decimal to a double value in degrees decimal. One degree is 3600 seconds. The sign of the result is positive if the string s ends with N and negative if it ends with S. For example, the latitude represented by the string 135427.7000N should be converted to the value 37.6188
double convert_longitude (string s) const
This function converts the string s representing a longitude in seconds decimal to a double value in degrees decimal. One degree is 3600 seconds. The sign of the result is positive if the string s ends with E and negative if it ends with W. For example, the longitude represented by the string 440551.5000w should be converted to the value -122.3754.
The member functions of the Runway class are defined as follows:
Runway (string s)
The constructor takes a single string argument. The argument s contains a full line read from the Runway.txt file. The constructor should initialize the data members of Runway by selecting the appropriate substrings from the argument.
string site_number (void) const
This function returns the site number of the facility that the runway belongs to.
string name (void) const
This function returns the name of the runway.
int length (void) const
This function returns the length of the runway in ft.
int convert_length (string s) const
This function converts the string s representing a runway length to an int value in feet (use the stoi function).
Two function objects must be defined. The Closer function object (to be defined in the file Closer. h) is used to sort facilities in order of proximity to the current location. The SiteNumber function object (to be defined in the file SiteNumber.h) is used to find a runway having a given site number.
The test programs testFacility.cpp and testRunway.cpp are provided and should not be modified. These programs will be used (with the corresponding input and output files) to test that your implementation of the Facility and Runway classes is correct.
Your task is to implement the files Facility.cpp, Runway.cpp., Closer.h, SiteNumber.h, and complete the implementation in mayday.cpp. The files Facility.h and Runway. h are provided and should not be modified. The Makefile is provided and should not be modified. The mayday executable and other executables should be built using the command
$ make
Five test cases of the mayday program are provided with corresponding output files. Shell scripts files named testmayday1.sh to testmayday5.sh are provided and include the invocation of the mayday program with its command line arguments. The files testmayday1.out to testmayday5.out contain the corresponding output.
1) testmayday1.sh: Sacramento International Airport
You are flying over Sacramento International airport. Your position is (38.6954, -121.5910) and you request a minimum landing length of 6000 ft.
2) testmayday2.sh: Helicopter on downtown Sacramento
You are flying a helicopter over downtown Sacramento. Your position is (38.55, -121.49) and you request a minimum landing length of 40 ft.
3) testmayday3.sh: Flight 1549
You are flying an Airbus A320 and just took off from New York La Guardia airport. You lost power after hitting a flock of birds. Your position is (40.8615, -73.8775) and you request a minimum landing length of 6000 ft.
4) testmayday4.sh: South Pacific Ocean
You are flying over the South Pacific Ocean. Your position is (-15, -134) and you request a minimum landing length of 6000 ft.
5) testmayday5.sh: Space Shuttle approach to CA
You are flying a Space Shuttle, approaching the California coast. Your position is (35, -123) and you request a minimum landing length of 15000 ft.
Two test cases for the programs testFacility and testRunway are also provided.
Use the mayday executable and the testFacility and testRunway executables together with the corresponding input and output files to check your implementation. Verify that your program reproduces the test output exactly. Use the diff command to compare your output files with the reference test output files. Note that other test files may also be used when grading your implementation.
Facility.h
//
// Facility.h
//
#ifndef FACILITY_H
#define FACILITY_H
#include < string >
class Facility
{
public:
Facility(std::string s);
std::string site_number(void) const;
std::string type(void) const;
std::string code(void) const;
std::string name(void) const;
double latitude(void) const;
double longitude(void) const;
double distance(double lat, double lon) const;
private:
const std::string site_number_;
const std::string type_;
const std::string code_;
const std::string name_;
const double latitude_, longitude_;
double convert_latitude(std::string s) const;
double convert_longitude(std::string s) const;
};
#endif
Runway.h
//
// Runway.h
//
#ifndef RUNWAY_H
#define RUNWAY_H
#include < string >
class Runway
{
public:
Runway(std::string s);
std::string site_number(void) const;
std::string name(void) const;
int length(void) const;
private:
int convert_length(std::string s) const;
const std::string site_number_;
const std::string name_;
const int length_;
};
#endif
gcdistance.h
//
// gcdistance.h
//
#ifndef GCDISTANCE_H
#define GCDISTANCE_H
double gcdistance(double lat1, double lon1, double lat2, double lon2);
#endif
gcdistance.cpp
//
// gcdistance.cpp
//
// great circle distance between points (lat1,lon1) and (lat2,lon2)
// input in degrees decimal
// output in nautical miles (NM)
#define _USE_MATH_DEFINES
#include "gcdistance.h"
#include < cmath >
double gcdistance(double lat1, double lon1, double lat2, double lon2)
{
// convert latitudes and longitudes from degrees to radians
const double lat1r = lat1 * (M_PI / 180.0);
const double lon1r = lon1 * (M_PI / 180.0);
const double lat2r = lat2 * (M_PI / 180.0);
const double lon2r = lon2 * (M_PI / 180.0);
// psi = central angle between the points (lat1,lon1) and
// (lat2,lon2) on a sphere
double c = cos(lat1r)*cos(lat2r)*cos(lon1r - lon2r) + sin(lat1r)*sin(lat2r);
// truncate possible numerical errors in cos to [-1,1] interval
c = fmin(c, 1.0);
c = fmax(c, -1.0);
const double psi = acos(c);
// R_Earth = 6371 km
// 1 NM = 1.852 km
// 1 degree = 60.0405 NM on a great circle
return 60.0405 * psi * (180.0 / M_PI);
}
mayday.cpp
//
// mayday.cpp
//
// use: mayday latitude longitude min_length
//
// Provide a list of facilities and runways closest to the location specified
// by the coordinates (latitude,longitude).
// Only facilities having runways longer than min_length are printed.
// Only runways longer than min_length are printed.
//
// Input:
// latitude, longitude in degrees decimal
// min_length in ft
// Output:
// list of nearest facilities and runways including distance in nautical miles
#include "Facility.h"
#include "Runway.h"
#include "Closer.h"
#include "SiteNumber.h"
#include < iostream >
#include < iomanip >
#include < string >
#include < fstream >
#include < sstream >
#include < algorithm >
#include < vector >
#include < cassert >
#include < cmath >
using namespace std;
int main(int argc, char **argv)
{
// use: mayday current_latitude current_longitude min_runway_length
// latitude and longitudes in degrees decimal
// min runway length of runway in ft
assert(argc == 4);
const double current_latitude = atof(argv[1]);
const double current_longitude = atof(argv[2]);
const int min_runway_length = atoi(argv[3]);
vector< Facility* > facilities;
// load facilities data
ifstream facilitiesFile("Facilities.txt");
if (!facilitiesFile.is_open())
{
cout < < "Failed to open Facilities.txt file" < < endl;
return 0;
}
string line;
while (getline(facilitiesFile, line))
facilities.push_back(new Facility(line));
facilitiesFile.close();
// sort facilities in order of proximity to the current position
sort(facilities.begin(), facilities.end(),
Closer(current_latitude, current_longitude));
vector< Runway* > runways;
// load runways data
// Insert your code here
return 0;
}
Closer.h
#ifndef closer_h
#define closer_h
#include "Facility.h"
struct Closer
{
double lat_;
double lon_;
Closer(double lat, double lon) :
lat_(lat),
lon_(lon)
{
}
bool operator()(Facility *facility1, Facility *facility2) const
{
double f1Distance = facility1->distance(lat_, lon_);
double f2Distance = facility2->distance(lat_, lon_);
return f1Distance < f2Distance;
}
};
#endif