Now that we have dealt with our technical debt, we can begin to write code in earnest. Hub Travel has requested that a graphic be added to their program that shows the flight path between the selected airport hubs. They also would like to use the entire database of hubs instead of the small test set we have been using. They have provided a more accurate formula for calculating distance between points on a sphere, a formula for calculating the midpoint of the flight curve since the flight path will not necessarily be a straight line, and a formula for calculating the xy coordinates on the US Map (Form 2) that correspond to the latitude and longitude. That last calculation is not as straight forward as it would at first appear. On a Mercator projection map, the latitudes appear to be curved and the longitudes are closer together at the top of the map than they are at the bottom. For those tasks in this sprint that involve adding new functions, you will need to add a unit test as well. This last sprint is an attempt to simulate an actual scrum. There are more than four tasks, which means some of you will have to do more than one task if you want to complete the entire backlog. Many of the tasks require a test unit as well as a new function; this is how Agile programming is normally done. Different tasks require different skills; select your tasks based on your ability as well as your preferences. If you have trouble with any of your tasks, be sure to ask the scrum master for help. After all, that is the scrum master’s main function.

Task 3: Create a function named IndexToCoordinatePair that calculates the decimal coordinates as Coordinates (structure already defined) given the latitude and longitude of the hub airport indicated by index. Task 3a: Write the code for the function IndexToCoordinatePair with input parameter index as type Integer, and a return value of type Coordinates. Use the function CoordinateToDegrees to convert the individual coordinates as strings into components of the returned value as type Coordinates (a pair of type Double). Task 3b: Right click anywhere within the IndexToCoordinatePair function in Airports.vb and add a unit test to the unit test framework. Add the line, target.LoadData(), to IndexToCoordinatePairTest immediately after the Dim statements. Modify the code to set index = 0, expected.lat = 33.63944 and expected.lon = 84.42806. You will need to test each component of the actual value separately. Set delta in each Assert.AreEqual call to 0.00001 to allow for rounding error. Task 3c: Run the unit tests to make sure they all run. Task 3d: Check out the master copy of the project and install your changes.   Task 4: Create a function named CoordinatePairToCartesianPair that transforms latitude/longitude coordinates in decimal degrees (a pair of type Double) into an xy point in pixels (a pair of type Integer). Task 4a: Create the function CoordinatePairToCartesianPair and add the following comment: ‘ Formula for transforming coordinates into screen positions ‘ Transform equations determined using SPSS Stepwise Regression ‘ x = int( -18.886 × lon – 17.777 × lat + 0.178 × lat × lon + 2173.268 ) ‘ y = int( -15.183 × lat + 14.772 × lon – 0.073 × lon² + 48.703 )

Write the code for this function with input parameter CoordPair as type Coordinates , and a return value of type Point. Task 4b: Right click anywhere within the CoordinatePairToCartesianPair function in Airports.vb and add a unit test to the unit test framework. Modify the code to set CoordPair.Lat = 33.63944, CoordPair.Lon=84.42806, expected.X = 486, and expected.Y=265. You may want to test each component of the actual value separately, but you don’t need to since a delta isn’t required. Task 4c: Run the unit tests to make sure they all run. Task 4d: Check out the master copy of the project and install your changes.

Task 5: Modify the Distance function to use the Haversine method instead of the Spherical Law of Cosines. Task 2a: Add the following comment to the Distance function: ‘ Haversine Formula for the distance between two points on a sphere. ‘ R.W. Sinnott, “Virtues of the Haversine”, Sky and Telescope, 68(2):159, 1984. ‘ R = earth’s radius (mean radius = 6,371km = 3958.761mi) ‘ Δlat = lat2 – lat1 ‘ Δlong = long2 – long1 ‘ a = sin²(Δlat/2) + cos(lat1) × cos(lat2) × sin²(Δlong/2) ‘ c = 2 × atan2(√a, √(1 – a)) ‘ d = R × c ‘ (Note that angles need to be in radians to pass to trig functions). Task 5b: Use this new code to replace the existing code for calculating the distance in miles between two points on the earth. Modify the code that extracts the latitude and longitude for the two hub airports indicated by index1 and index2, to use the IndexToCoordinatePair function instead. Modify the code that converts degrees to radians using DegreesToRadians to use components of the two coordinate pairs. Task 5c: Run the unit tests to make sure they all run. Task 5d: Check out the master copy of the project and install your changes.

Task 6: Create a function named MidCoordinatePair that calculates the midpoint between two points on a sphere. This task requires the prior completion of Tasks 2 and 3. Task 6a: Create a function MidCoordinatePair and add the following comment: ‘ Formula for the midpoint between two points on a sphere ‘ Ed Williams, “Aviation Formulary V1.46” ‘ at williams.best.vwh.net/avform.htm ‘ Bx = cos(lat2) ∙ cos(Δlong) ‘ By = cos(lat2) ∙ sin(Δlong) ‘ latm = atan2(sin(lat1) + sin(lat2), √((cos(lat1) + Bx)² + By²)) ‘ lonm = lon1 + atan2(By, cos(lat1) + Bx) ‘ (Note that angles need to be in radians to pass to trig functions).

Write the code for this function with input parameters index1 and index2 as type Integer, and a return value of type Coordinates. Use the function IndexToCoordinatePair to return the coordinates from the Hubs array for index1 and index2 and the function DegreesToRadians to convert the individual components of the two Coordinate pairs to Radians in order to do the calculation. After the calculation is complete, call the function RadiansToDegrees to convert the latitude and longitude back to degrees before returning the coordinate pair. Task6b: Right click anywhere within the MidCoordinatePair function in Airports.vb and add a unit test to the unit test framework. Add the line, target.LoadData(), to MidCoordinatePairTest immediately after the Dim statements. Modify the code to set index1 = 0, index2 = 1, expected.lat = 38.19098, and expected.lon=78.12139. You will need to test each component of the actual value separately. Set delta in each Assert.AreEqual call to 0.00001 to allow for rounding error. Task 6c: Run the unit tests to make sure they all run. Task 6d: Check out the master copy of the project and install your changes.

Task 7: Create a subroutine named Plot that plots a curved line on the US Map Form representing the shortest distance between two airport hubs. Task7a: Create a subroutine Plot and write code that plots a curved line on the US Map Form (Map) using the DrawCurve method of the CreateGraphics library. This will require the parameters Pen.Black and an array of points containing the xy coordinates of the starting point, midpoint, and ending point of the curve. No value for the third parameter, tension, is necessary. Task7b: In the same subroutine use the DrawRectangle method of the CreateGraphics library to draw small squares at the starting and ending points. Task 7c: Run the unit tests to make sure they all run. Task 7d: Check out the master copy of the project and install your changes.

Task 8: Add a button to the form Airports that plots a curved line on the US Map Form representing the shortest distance between two airport hubs. This task requires the prior completion of Task 7. Task8a: Create a button on the form Airports named ShowMapButton. Change the text property to “Show Map”. Task8b: In the event handler of the Click event for ShowMapButton, add code to build an array of points named XYPairs of type point that contains xy values for the starting point, midpoint, and ending point of the curve to be plotted on the US Map Form (Map). Be sure to Show Map before calling the subroutine Plot. Task 8c: Run the unit tests to make sure they all run. Task 8d: Check out the master copy of the project and install your changes.

Attachments

Now that we have dealt with our technical debt, we can begin to write code in earnest. Hub Travel has requested that a graphic be added to their program that shows the flight path between the selected airport hubs. They also would like to use the entire database of hubs instead of the small test set we have been using. They have provided a more accurate formula for calculating distance between points on a sphere, a formula for calculating the midpoint of the flight curve since the flight path will not necessarily be a straight line, and a formula for calculating the xy coordinates on the US Map (Form 2) that correspond to the latitude and longitude. That last calculation is not as straight forward as it would at first appear. On a Mercator projection map, the latitudes appear to be curved and the longitudes are closer together at the top of the map than they are at the bottom. For those tasks in this sprint that involve adding new functions, you will need to add a unit test as well. This last sprint is an attempt to simulate an actual scrum. There are more than four tasks, which means some of you will have to do more than one task if you want to complete the entire backlog. Many of the tasks require a test unit as well as a new function; this is how Agile programming is normally done. Different tasks require different skills; select your tasks based on your ability as well as your preferences. If you have trouble with any of your tasks, be sure to ask the scrum master for help. After all, that is the scrum master’s main function.

Task 3: Create a function named IndexToCoordinatePair that calculates the decimal coordinates as Coordinates (structure already defined) given the latitude and longitude of the hub airport indicated by index. Task 3a: Write the code for the function IndexToCoordinatePair with input parameter index as type Integer, and a return value of type Coordinates. Use the function CoordinateToDegrees to convert the individual coordinates as strings into components of the returned value as type Coordinates (a pair of type Double). Task 3b: Right click anywhere within the IndexToCoordinatePair function in Airports.vb and add a unit test to the unit test framework. Add the line, target.LoadData(), to IndexToCoordinatePairTest immediately after the Dim statements. Modify the code to set index = 0, expected.lat = 33.63944 and expected.lon = 84.42806. You will need to test each component of the actual value separately. Set delta in each Assert.AreEqual call to 0.00001 to allow for rounding error. Task 3c: Run the unit tests to make sure they all run. Task 3d: Check out the master copy of the project and install your changes.   Task 4: Create a function named CoordinatePairToCartesianPair that transforms latitude/longitude coordinates in decimal degrees (a pair of type Double) into an xy point in pixels (a pair of type Integer). Task 4a: Create the function CoordinatePairToCartesianPair and add the following comment: ‘ Formula for transforming coordinates into screen positions ‘ Transform equations determined using SPSS Stepwise Regression ‘ x = int( -18.886 × lon – 17.777 × lat + 0.178 × lat × lon + 2173.268 ) ‘ y = int( -15.183 × lat + 14.772 × lon – 0.073 × lon² + 48.703 )

Write the code for this function with input parameter CoordPair as type Coordinates , and a return value of type Point. Task 4b: Right click anywhere within the CoordinatePairToCartesianPair function in Airports.vb and add a unit test to the unit test framework. Modify the code to set CoordPair.Lat = 33.63944, CoordPair.Lon=84.42806, expected.X = 486, and expected.Y=265. You may want to test each component of the actual value separately, but you don’t need to since a delta isn’t required. Task 4c: Run the unit tests to make sure they all run. Task 4d: Check out the master copy of the project and install your changes.

Task 5: Modify the Distance function to use the Haversine method instead of the Spherical Law of Cosines. Task 2a: Add the following comment to the Distance function: ‘ Haversine Formula for the distance between two points on a sphere. ‘ R.W. Sinnott, “Virtues of the Haversine”, Sky and Telescope, 68(2):159, 1984. ‘ R = earth’s radius (mean radius = 6,371km = 3958.761mi) ‘ Δlat = lat2 – lat1 ‘ Δlong = long2 – long1 ‘ a = sin²(Δlat/2) + cos(lat1) × cos(lat2) × sin²(Δlong/2) ‘ c = 2 × atan2(√a, √(1 – a)) ‘ d = R × c ‘ (Note that angles need to be in radians to pass to trig functions). Task 5b: Use this new code to replace the existing code for calculating the distance in miles between two points on the earth. Modify the code that extracts the latitude and longitude for the two hub airports indicated by index1 and index2, to use the IndexToCoordinatePair function instead. Modify the code that converts degrees to radians using DegreesToRadians to use components of the two coordinate pairs. Task 5c: Run the unit tests to make sure they all run. Task 5d: Check out the master copy of the project and install your changes.

Task 6: Create a function named MidCoordinatePair that calculates the midpoint between two points on a sphere. This task requires the prior completion of Tasks 2 and 3. Task 6a: Create a function MidCoordinatePair and add the following comment: ‘ Formula for the midpoint between two points on a sphere ‘ Ed Williams, “Aviation Formulary V1.46” ‘ at williams.best.vwh.net/avform.htm ‘ Bx = cos(lat2) ∙ cos(Δlong) ‘ By = cos(lat2) ∙ sin(Δlong) ‘ latm = atan2(sin(lat1) + sin(lat2), √((cos(lat1) + Bx)² + By²)) ‘ lonm = lon1 + atan2(By, cos(lat1) + Bx) ‘ (Note that angles need to be in radians to pass to trig functions).

Write the code for this function with input parameters index1 and index2 as type Integer, and a return value of type Coordinates. Use the function IndexToCoordinatePair to return the coordinates from the Hubs array for index1 and index2 and the function DegreesToRadians to convert the individual components of the two Coordinate pairs to Radians in order to do the calculation. After the calculation is complete, call the function RadiansToDegrees to convert the latitude and longitude back to degrees before returning the coordinate pair. Task6b: Right click anywhere within the MidCoordinatePair function in Airports.vb and add a unit test to the unit test framework. Add the line, target.LoadData(), to MidCoordinatePairTest immediately after the Dim statements. Modify the code to set index1 = 0, index2 = 1, expected.lat = 38.19098, and expected.lon=78.12139. You will need to test each component of the actual value separately. Set delta in each Assert.AreEqual call to 0.00001 to allow for rounding error. Task 6c: Run the unit tests to make sure they all run. Task 6d: Check out the master copy of the project and install your changes.

Task 7: Create a subroutine named Plot that plots a curved line on the US Map Form representing the shortest distance between two airport hubs. Task7a: Create a subroutine Plot and write code that plots a curved line on the US Map Form (Map) using the DrawCurve method of the CreateGraphics library. This will require the parameters Pen.Black and an array of points containing the xy coordinates of the starting point, midpoint, and ending point of the curve. No value for the third parameter, tension, is necessary. Task7b: In the same subroutine use the DrawRectangle method of the CreateGraphics library to draw small squares at the starting and ending points. Task 7c: Run the unit tests to make sure they all run. Task 7d: Check out the master copy of the project and install your changes.

Task 8: Add a button to the form Airports that plots a curved line on the US Map Form representing the shortest distance between two airport hubs. This task requires the prior completion of Task 7. Task8a: Create a button on the form Airports named ShowMapButton. Change the text property to “Show Map”. Task8b: In the event handler of the Click event for ShowMapButton, add code to build an array of points named XYPairs of type point that contains xy values for the starting point, midpoint, and ending point of the curve to be plotted on the US Map Form (Map). Be sure to Show Map before calling the subroutine Plot. Task 8c: Run the unit tests to make sure they all run. Task 8d: Check out the master copy of the project and install your changes.

Attachments