Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Terrain Analysis Background Aircraft frequently rely on terrain elevation data t

ID: 3776954 • Letter: T

Question

Terrain Analysis

Background

Aircraft frequently rely on terrain elevation data to help navigate in low visibility conditions, to reduce pilot workload, to help closely follow terrain at low altitude to avoid radar detection (sometimes called ground-hugging or terrain-following flight), and to plot a course to avoid extreme sudden altitude changes (e.g., flying around a mountain, rather than over it). Terrain elevation data is gathered through terrain-following radar, lidar, satellites, and existing terrain map

elevation information. Elevation data is especially useful radar or communication services are not operating.

Elevation data is typically broken down into a grid, where each grid cell represents a square physical area of uniform size. Because elevation varies

within a cell, the highest elevation in the cell is usually used as the elevation value for that cell on the grid.

To navigate using elevation data, it’s useful to compute locations of peaks (high points), valleys (low points), and flat areas (which might be at high or low elevations). To

a specific location is a peak, we're interested in discovering whether that

location is a local maximum. To do this, we must examine its eight adjacent locations: left, right, above, below, and the four diagonal neighbors. If the location we’re analyzing has a higher elevation than all eight surrounding locations, then the location is clearly a peak. We might choose to loosen our definition of a peak by saying, for example, that a location is a peak if more than five of the eight surrounding locations have a lower elevation.

Similarly, to decide if a location is a valley, we determine if it's a local minimum by checking to see if all eight neighboring locations are higher than the location we’re analyzing. If all eight are higher, we clearly have a valley. Again, we might choose to loosen our valley definition to identify a valley if more than five surrounding locations are higher than the location we’re analyzing.

Determining if a location is part of a relatively flat area (a plain for our purposes, but it might also be a plateau in the real world), we would again examine all eight neighboring locations. If they are all within a small tolerance in elevation, then we would declare the location to be part of a plain. Once again, we might choose to loosen our definition of a plain, so that a location surrounded by more than five locations that have a similar elevation is considered a plain.

Your Assignment

You will develop a C program that creates a two-dimensional array of doubles representing an elevation grid, populates the array it with elevation data read from an instructor-supplied binary data file, displays the elevation data numerically, analyzes the data in the array to find the peaks, valleys, and plains, and displays strings indicating where these peaks, valleys, and plains are. Terrain elevation values are all assumed to be expressed in meters.

When defining your C functions in this program, you may either define the functions before they are used by any other functions, or place function prototypes near the top of your code (after all #include directives), and then define the functions in any order.

Part 1 – Creating and Populating the Elevation Array

Create a new Visual Studio Win32 Console project named terrainmap. Create a new C source file named project6.c within that project. At the top of the source file, #define _CRT_SECURE_NO_WARNINGS, and then #include stdio.h and math.h.

Define your main function as usual. Inside the main function, define a local two-dimensional array of doubles, with 20 rows and 10 columns, initializing it to contain all 0.0 elevation values. Initialize the array using the initialization list { 0.0 } as discussed in class.

Define two local unsigned integer variables in main, one for the total number of rows, and one for the total number of columns. Initialize these two variables as follows (where myArray must be replaced by the actual name of your array of doubles):

Your rows variable must be set to sizeof(myArray) / sizeof(myArray[0]). This is the size of the array divided by the size of the first column, which yields the number of rows in the array.

Your columns variable must be set to sizeof(myArray[0]) / sizeof(myArray[0][0]). This is the size of one row of the array divided by the size of one element of the array, which yields the number of columns in the array.

Add the const keyword to the beginning of these two unsigned integer variable definitions, to prevent them from being accidentally changed later on. Use these variables in your main function whenever you need to specify the number of rows or columns in the array, or when you need to compute the total number of elements in the array (rows times columns).

The data file that you will use to populate this array is a binary file, not a human-readable text file. Download and extract the instructor-supplied data file for this project and place it into a known location on your computer or flash drive. Take note of the exact path name of this data file, including the drive letter, folder(s), and file name. Note that this data file ends with a .RFD extension, which may or may not appear in your File Explorer, depending on the configuration of your system.

Still inside the main function, define a FILE pointer variable. Then open the instructor-supplied data file for reading in binary mode by calling the fopen function, storing the result of fopen into your FILE pointer variable. When specifying the full path name string in the first parameter to fopen, don't forget to specify the drive letter, to double each backslash in the path name, and to specify the .RFD extension.

Using an if statement, check to see if the file failed to open. If the FILE pointer returned by fopen was NULL, display an appropriate error message and return -1 from main.

Otherwise, if the file opened successfully, make just ONE call to the fread function, to read all the data from the file directly into your array of doubles. You will need to store the result of the fread call into a local unsigned integer variable, which will be the number of doubles successfully read from the file.

Pass the following parameters into the fread function:

The address (i.e., the name) of your two-dimensional array, which you defined earlier.

The size of one element of the array (i.e. the number of bytes occupied by one array element). The total number of elements in the array (number of rows times number of columns).

The FILE pointer you got back from the call to fopen earlier.

Note: The values in the input file are stored in row-major order, the same order in which values in a C two-dimensional array are stored in memory. This is why it's possible to read the entire array of values using only a single call to fread. If the values were stored in a different order in the input file, this approach would not work.

Using an if statement, check to see if the number of doubles successfully read from the file is not equal to the total number of elements in your array (rows times columns). If the correct number of elements was not read, print an appropriate error message, close the file using fclose (passing in the FILE pointer you received from fopen), and return -1 from main.

Part 2 – Displaying Elevation Data

Define a separate C function named PrintMapElevations, which has the following function prototype:

void PrintMapElevations(const double terrain[][10], const unsigned rows, const unsigned cols);

The goal of this function is to print out the contents of the two-dimensional array. Once inside this function definition, you will refer to the array by this function's parameter name, terrain. The function must behave as follows:

Print the heading as shown in the sample output below. Be sure to get the numeric information in the heading from the rows and cols parameters that were passed into this function.

Start a for loop that runs through all the rows of the array (starting at index 0). This outer loop will need its own loop variable. Inside the outer loop:

o Start a nested for loop that runs through all the columns (starting at index 0). This inner loop will need its own loop variable. Inside the inner loop:

There should only be one line of code inside the inner loop, to print one value from the array. Use a %7.1f format, and be sure to print a newline at the end of each row of data. You may use array notation or pointer arithmetic to access the array element here.

After the end of the inner loop, print a newline to ensure that the next row will appear on a new line of output.

Print another newline after the end of the outer loop.

In the main function, add a call to the PrintMapElevations function, passing in the address of (the name of) your two-dimensional array, and the number of rows and number of columns (the local const integer variables you defined and initialized earlier). Now, build and test your program so far. Here is the sample output you should see, assuming you are using the instructor-supplied data file:

Map Elevations (20 x 10):

299.3 332.2 481.1 595.6 622.1 742.9 845.4 1222.1 948.2 1112.3

334.9 335.2 336.1 582.5 793.4 985.5 1342.3 1188.2 1242.1

335.1 336.7 334.8 488.1 694.2 1111.9 1499.5 1542.1 1412.4

336.2 337.3 335.3 524.2 849.9 1341.7 1412.8 1501.7 1398.6

336.2 336.2 336.2 421.1 906.2 1341.6 1341.5 1342.1 1342.5

336.2 336.2 337.9 589.3 984.5 999.9 1298.2 1341.2 1343.1

336.2 336.2 662.2 799.9 1001.2 978.2 1026.4 1342.8 1342.3

337.1 336.5 493.9 1106.4 1307.7 1287.1 989.1 1222.3 1341.1

338.3 985.9 722.6 2049.3 1583.5 1392.9 876.2 1005.4 1298.6

339.4 2166.6 3999.2 3721.1 2684.1 2084.2 1008.3 722.8 1241.3

488.5 3874.3 4033.2 3997.1 3042.6 1788.4 1186.2 865.9 881.1

921.1

891.5

2998.5

4392.2

3721.4

3548.7

1598.2

1243.6

998.3

722.5

1242.7

1563.8

2925.8

2884.7

3121.6

2766.3

1488.7

942.1

777.9

509.9

1333.3

2900.6

2901.2

2902.3

2999.4

2622.7

1163.3

867.2

602.3

421.4

1998.2

2901.1

2902.9

2903.4

2560.3

2263.5

985.4

734.4

358.1

226.5

1575.5

2900.1

2903.1

2903.8

2450.2

1996.5

862.1

627.8

199.7

183.2

471.8

1569.4

2904.9

1855.3

1812.4

1251.6

746.3

253.3

230.2

150.1

3.3

0.9

3.1

1766.2

1410.3

1108.3

622.1

242.5

292.3

149.4

4.1

5.4

0.4

1208.8

877.6

923.5

542.8

231.8

228.7

198.3

-0.3

-0.2

-0.1

555.3

421.5

398.1

231.2

232.1

230.8

229.1

Verify that your program is working correctly before proceeding to the next part.

Part 3 – Detecting and Displaying Elevation Features

Define a separate C function named PrintMapFeatures, which has the following function prototype:

void PrintMapFeatures(const double terrain[][10], const unsigned rows, const unsigned cols);

The goal of this function is to analyze elements of the two-dimensional array and display information indicating areas of peaks, valleys, and plains. Once inside this function definition, you will refer to the array by this function's parameter name, terrain. This function must display an elevation map, but instead of displaying elevation values, it must display one of the following strings for each element of the array:

??????? (7 question mark characters), if the element is in the first row, first column, last row, or last column of the array (i.e., an edge).

^^^^^^^ (7 carat characters), if the element is considered a peak.

vvvvvvv (7 lowercase v characters), if the location is considered a valley. _______ (7 underscore characters), if the location is considered a plain.

....... (7 period characters), if the location is none of the above (i.e., unknown).

The function must behave as follows. (You may use array notation or pointer arithmetic to access array elements.)

Print the heading as shown in the sample output below. Be sure to get the numeric information in the heading from the rows and cols parameters that were passed into this function.

Start a for loop that runs through all the rows of the array (starting at index 0). This outer loop will need its own loop variable. Inside the outer loop:

o Start a nested for loop that runs through all the columns (starting at index 0). This inner loop will need its own loop variable. Inside the inner loop:

If the row is either the first row or last row, or the column is either the first column or last column, print the edge indicator discussed earlier.

Otherwise, examine each of the neighboring elevations as follows.

Define three new integer variables: peakCount, valleyCount, and plainCount, and set them all to 0.

Start a for loop that runs from the current row – 1 to the current row + 1. This loop will need its own loop variable. Inside this loop:

o Start a nested for loop that runs from the current column – 1 to the current column + 1. This loop will need its own loop variable. Inside this loop, use three independent if statements:

If the center elevation is greater than the neighboring elevation, increment peakCount.

If the center elevation is less than the neighboring elevation, increment valleyCount.

If the center elevation is within 4.5 meters (higher or lower) of the neighboring elevation, increment plainCount. (You can use the abs function, absolute value, to simplify this conditional test.)

After both of these loops have completed, subtract 1 from the plainCount, so that the center element is not part of the count.

Use an if-else-if ladder to do the following:

If more than 5 of the 8 surrounding elements have a lower elevation, print the peak indicator discussed earlier.

Otherwise, if more than 5 of the 8 surrounding elements have a higher elevation, print the valley indicator discussed earlier.

o    Otherwise, if plainCount is greater than 5, print the plain indicator discussed earlier.

o    Otherwise, print the unknown indicator discussed earlier.

After the end of the inner loop, print a newline to ensure that the next row will appear on a new line of output.

Print another newline after the end of the outer loop.

In your main function, add a call to PrintMapFeatures, after all the other calls already present in the main function. Pass in the address of (name of) your two-dimensional array, and the number of rows and number of columns.

Here is an example of the output of PrintMapFeatures:

Map Features (20 x 10):

??????????????????????????????????????????????????????????????????????

???????vvvvvvv_______vvvvvvv

.....................

^^^^^^^vvvvvvv???????

???????vvvvvvv^^^^^^^vvvvvvv

.....................

^^^^^^^^^^^^^^???????

???????_______^^^^^^^vvvvvvv

..............

^^^^^^^.......

^^^^^^^???????

???????______________.....................

^^^^^^^..............

???????

???????______________...................................

vvvvvvv???????

???????______________^^^^^^^

..............

vvvvvvv.......

^^^^^^^???????

???????^^^^^^^vvvvvvvvvvvvvv

.....................

vvvvvvv

.......???????

???????_______^^^^^^^vvvvvvv

.....................

vvvvvvv

.......???????

???????..............

^^^^^^^

..............

^^^^^^^.......

vvvvvvv???????

???????..............

^^^^^^^

............................

vvvvvvv???????

???????vvvvvvv

.......^^^^^^^

.......^^^^^^^

..............

^^^^^^^???????

???????.......

^^^^^^^vvvvvvv

...................................

???????

???????.....................

^^^^^^^............................

???????

???????.......

_______^^^^^^^

...................................

???????

???????.......

_______^^^^^^^

............................

vvvvvvv???????

???????.......

^^^^^^^..........................................

???????

???????vvvvvvvvvvvvvv...................................

^^^^^^^???????

???????^^^^^^^vvvvvvv^^^^^^^

.......^^^^^^^

..............

vvvvvvv???????

??????????????????????????????????????????????????????????????????????

Note that we might have an official peak that also happens to be less than 4.5 meters higher than its surrounding locations. If we find a peak or valley, that must be printed in the output. If a peak or valley also happens to qualify as a plain, we just ignore that fact (using the if-else-if ladder, where peak and valley detection appears before plain detection). In other words, once we have detected a peak or a valley, we don’t even bother to check if it is a plain.

Verify that the elevation values are printed correctly (in Part 2), and that peaks, valleys, and plains are correctly identified by your program (in Part 3). Before submitting your project, verify that your program’s output is correct. Also, be sure to make whatever additions are necessary to meet all of the requirements listed in the Project Submission Requirements document.

921.1

891.5

2998.5

4392.2

3721.4

3548.7

1598.2

1243.6

998.3

722.5

1242.7

1563.8

2925.8

2884.7

3121.6

2766.3

1488.7

942.1

777.9

509.9

1333.3

2900.6

2901.2

2902.3

2999.4

2622.7

1163.3

867.2

602.3

421.4

1998.2

2901.1

2902.9

2903.4

2560.3

2263.5

985.4

734.4

358.1

226.5

1575.5

2900.1

2903.1

2903.8

2450.2

1996.5

862.1

627.8

199.7

183.2

471.8

1569.4

2904.9

1855.3

1812.4

1251.6

746.3

253.3

230.2

150.1

3.3

0.9

3.1

1766.2

1410.3

1108.3

622.1

242.5

292.3

149.4

4.1

5.4

0.4

1208.8

877.6

923.5

542.8

231.8

228.7

198.3

-0.3

-0.2

-0.1

555.3

421.5

398.1

231.2

232.1

230.8

229.1

Explanation / Answer

part1:

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote