140 using namespace MSP::CCS;
 
  150 const double PI = 3.14159265358979323e0; 
 
  183                    {{74.5, 75.5, 273.5, 280.0},
 
  184                     {66.5, 67.5, 293.5, 295.0},
 
  185                     {62.5, 64.0, 133.0, 136.5},
 
  186                     {60.5, 61.5, 208.5, 210.0},
 
  187                     {60.5, 61.0, 219.0, 220.5},
 
  188                     {51.0, 53.0, 172.0, 174.5},
 
  189                     {52.0, 53.0, 192.5, 194.0},
 
  190                     {51.0, 52.0, 188.5, 191.0},
 
  191                     {50.0, 52.0, 178.0, 182.5},
 
  192                     {43.0, 46.0, 148.0, 153.5},
 
  193                     {43.0, 45.0, 84.0, 89.5},
 
  194                     {40.0, 41.0, 70.5, 72.0},
 
  195                     {36.5, 37.0, 78.5, 79.0},
 
  196                     {36.0, 37.0, 348.0, 349.5},
 
  197                     {35.0, 36.0, 171.0, 172.5},
 
  198                     {34.0, 35.0, 140.5, 142.0},
 
  199                     {29.5, 31.0, 78.5, 81.0},
 
  200                     {28.5, 30.0, 81.5, 83.0},
 
  201                     {26.5, 30.0, 142.0, 143.5},
 
  202                     {26.0, 29.0, 91.5, 96.0},
 
  203                     {27.5, 29.0, 84.0, 86.5},
 
  204                     {28.0, 29.0, 342.5, 344.0},
 
  205                     {26.5, 28.0, 88.5, 90.0},
 
  206                     {25.0, 26.0, 189.0, 190.5},
 
  207                     {23.0, 24.0, 195.0, 196.5},
 
  208                     {21.0, 21.5, 204.0, 204.5},
 
  209                     {20.0, 21.0, 283.5, 288.0},
 
  210                     {18.5, 20.5, 204.0, 205.5},
 
  211                     {18.0, 20.0, 291.0, 296.5},
 
  212                     {17.0, 18.0, 298.0, 299.5},
 
  213                     {15.0, 16.0, 122.0, 123.5},
 
  214                     {12.0, 14.0, 144.5, 147.0},
 
  215                     {11.0, 12.0, 141.5, 144.0},
 
  216                     {9.5, 11.5, 125.0, 127.5},
 
  217                     {10.0, 11.0, 286.0, 287.5},
 
  218                     {6.0, 9.5, 287.0, 289.5},
 
  219                     {5.0, 7.0, 124.0, 128.5},
 
  220                     {-1.0, 1.0, 125.0, 128.5},
 
  221                     {-3.0, -1.5, 281.0, 282.5},
 
  222                     {-7.0, -5.0, 150.5, 155.0},
 
  223                     {-8.0, -7.0, 107.0, 108.5},
 
  224                     {-9.0, -7.0, 147.0, 149.5},
 
  225                     {-11.0, -10.0, 161.5, 163.0},
 
  226                     {-14.5, -13.5, 166.0, 167.5},
 
  227                     {-18.5, -17.0, 186.5, 188.0},
 
  228                     {-20.5, -20.0, 168.0, 169.5},
 
  229                     {-23.0, -20.0, 184.5, 187.0},
 
  230                     {-27.0, -24.0, 288.0, 290.5},
 
  231                     {-53.0, -52.0, 312.0, 313.5},
 
  232                     {-56.0, -55.0, 333.0, 334.5},
 
  233                     {-61.5, -60.0, 312.5, 317.0},
 
  234                     {-61.5, -60.5, 300.5, 303.0},
 
  235                     {-73.0, -72.0, 24.5, 26.0}};
 
  248    char *b = (
char *) buffer;
 
  250    for (
size_t c = 0; c < count; c ++)
 
  252       for (
size_t s = 0; s < size / 2; s ++)
 
  254          temp = b[c*size + s];
 
  255          b[c*size + s] = b[c*size + size - s - 1];
 
  256          b[c*size + size - s - 1] = temp;
 
  268    size_t actual_count = fread(buffer, size, count, stream);
 
  270    if(ferror(stream) || actual_count < count )
 
  272       char message[256] = 
"";
 
  273       strcpy( message, 
"Error reading binary file." );
 
  303         GeoidLibrary::deleteInstance();
 
  314 int GeoidLibrary::instanceCount = 0;
 
  336   if ( --instanceCount < 1 )
 
  343 void GeoidLibrary::deleteInstance()
 
  371   delete [] egm96GeoidList;
 
  372   delete [] egm84GeoidList;
 
  373   delete [] egm84ThirtyMinGeoidList;
 
  390      egm96GeoidList[i] = gl.egm96GeoidList[i];
 
  395      egm84GeoidList[j] = gl.egm84GeoidList[j];
 
  400      egm84ThirtyMinGeoidList[k] = gl.egm84ThirtyMinGeoidList[k];
 
  403   *( this->egm2008Geoid ) = *( gl.egm2008Geoid );  
 
  409 void GeoidLibrary::loadGeoids()
 
  423    egm96GeoidList          = NULL;
 
  424    egm84GeoidList          = NULL;
 
  425    egm84ThirtyMinGeoidList = NULL;
 
  432       initializeEGM96Geoid();
 
  436       delete egm96GeoidList;
 
  437       egm96GeoidList = NULL;
 
  441       initializeEGM84Geoid();
 
  445       delete egm84GeoidList;
 
  446       egm84GeoidList = NULL;
 
  450       initializeEGM84ThirtyMinGeoid();
 
  454       delete egm84ThirtyMinGeoidList;
 
  455       egm84ThirtyMinGeoidList = NULL;
 
  462       initializeEGM2008Geoid();
 
  470       if (egm96GeoidList          == NULL &&
 
  471           egm84GeoidList          == NULL &&
 
  472           egm84ThirtyMinGeoidList == NULL)
 
  475             "Error: GeoidLibrary::LoadGeoids: All geoid height buffer initialization failed.");
 
  485    double ellipsoidHeight,
 
  486    double *geoidHeight )
 
  500   if (egm96GeoidList == NULL)
 
  503       "Error: EGM96 Geoid height buffer is NULL");
 
  513   *geoidHeight = ellipsoidHeight - delta_height;
 
  520    double ellipsoidHeight,
 
  521    double *geoidHeight )
 
  535   if (egm96GeoidList == NULL)
 
  538       "Error: EGM96 Geoid height buffer is NULL");
 
  550   if( longitude_degrees < 0.0 )
 
  551     longitude_degrees += 360.0;
 
  571     if( latitude_degrees >= -60.0 && latitude_degrees < 60.0 )
 
  585   naturalSplineInterpolate(
 
  590   *geoidHeight = ellipsoidHeight - delta_height;
 
  597    double ellipsoidHeight,
 
  598    double *geoidHeight )
 
  612    if (egm84GeoidList == NULL)
 
  615          "Error: EGM84 Geoid height buffer is NULL");
 
  625    *geoidHeight = ellipsoidHeight - delta_height;
 
  632    double ellipsoidHeight,
 
  633    double *geoidHeight )
 
  647   if (egm84GeoidList == NULL)
 
  650       "Error: EGM84 Geoid height buffer is NULL");
 
  655   naturalSplineInterpolate(
 
  658      egm84GeoidList, &delta_height );
 
  660   *geoidHeight = ellipsoidHeight - delta_height;
 
  665     double longitude, 
double latitude, 
double ellipsoidHeight, 
 
  666     double *geoidHeight )
 
  681   if (egm84GeoidList == NULL)
 
  684       "Error: EGM84 Geoid height buffer is NULL");
 
  689   bilinearInterpolateDoubleHeights(
 
  692      egm84ThirtyMinGeoidList, &delta_height );
 
  694   *geoidHeight = ellipsoidHeight - delta_height;
 
  701    double ellipsoidHeight,
 
  702    double *geoidHeight )
 
  722    if (this->egm2008Geoid == NULL)
 
  725          "Error: EGM2008 geoid buffer is NULL" );
 
  734       double     geoidSeparation;
 
  738             ( WSIZE, latitude, longitude, geoidSeparation );
 
  740       if ( error != 0 )                                    
throw;
 
  742       *geoidHeight = ellipsoidHeight - geoidSeparation;
 
  749          "Error: Could not convert ellipsoid height to EGM2008 geoid height" );
 
  769   if (egm96GeoidList == NULL)
 
  772       "Error: EGM96 Geoid height buffer is NULL");
 
  782   *ellipsoidHeight = geoidHeight + delta_height;
 
  790    double *ellipsoidHeight )
 
  804   if (egm96GeoidList == NULL)
 
  807       "Error: EGM96 Geoid height buffer is NULL");
 
  819   if( longitude_degrees < 0.0 )
 
  820     longitude_degrees += 360.0;
 
  840     if( latitude_degrees >= -60.0 && latitude_degrees < 60.0 )
 
  854   naturalSplineInterpolate(
 
  859   *ellipsoidHeight = geoidHeight + delta_height;
 
  877   if (egm84GeoidList == NULL)
 
  880       "Error: EGM84 Geoid height buffer is NULL");
 
  890   *ellipsoidHeight = geoidHeight + delta_height;
 
  898    double *ellipsoidHeight )
 
  912   if (egm84GeoidList == NULL)
 
  915       "Error: EGM84 Geoid height buffer is NULL");
 
  920   naturalSplineInterpolate(
 
  923      egm84GeoidList, &delta_height );
 
  925   *ellipsoidHeight = geoidHeight + delta_height;
 
  930     double longitude, 
double latitude, 
double geoidHeight, 
 
  931     double *ellipsoidHeight )
 
  946   if (egm84GeoidList == NULL)
 
  949       "Error: EGM84 Geoid height buffer is NULL");
 
  957   *ellipsoidHeight = geoidHeight + delta_height;
 
  965    double *ellipsoidHeight )
 
  985    if (this->egm2008Geoid == NULL)
 
  988          "Error: EGM2008 geoid buffer is NULL");
 
  997       double     geoidSeparation;
 
 1001             ( WSIZE, latitude, longitude, geoidSeparation );
 
 1003       if ( error != 0 )                                    
throw;
 
 1005       *ellipsoidHeight = geoidHeight + geoidSeparation;
 
 1012          "Error: Could not convert EGM2008 geoid height to ellipsoid height" );
 
 1023 void GeoidLibrary::initializeEGM96Geoid()
 
 1035   char* file_name = 0;
 
 1036   char* path_name = NULL;
 
 1037   long elevations_read = 0;
 
 1038   long items_discarded = 0;
 
 1040   FILE*  geoid_height_file;
 
 1048   path_name = 
"/data/data/com.baesystems.msp.geotrans/lib/";
 
 1049   file_name = 
new char[ 80 ];
 
 1050   strcpy( file_name, path_name );
 
 1051   strcat( file_name, 
"libegm96grd.so" );
 
 1053   path_name = getenv( 
"MSPCCS_DATA" );;
 
 1054   if (path_name != NULL)
 
 1056     file_name = 
new char[ strlen( path_name ) + 11 ];
 
 1057     strcpy( file_name, path_name );
 
 1058     strcat( file_name, 
"/" );
 
 1062     file_name = 
new char[ 21 ];
 
 1063     strcpy( file_name, 
"../../data/" );
 
 1065   strcat( file_name, 
"egm96.grd" );
 
 1070   if ( ( geoid_height_file = fopen( file_name, 
"rb" ) ) == NULL )
 
 1072     delete [] file_name;
 
 1075     char message[256] = 
"";
 
 1076     if (NULL == path_name)
 
 1078       strcpy( message, 
"Environment variable undefined: MSPCCS_DATA." );
 
 1083       strcat( message, 
": egm96.grd\n" );
 
 1096   if( egm96GeoidHeaderList[0] !=  -90.0 ||
 
 1097       egm96GeoidHeaderList[1] !=   90.0 ||
 
 1098       egm96GeoidHeaderList[2] !=    0.0 ||
 
 1099       egm96GeoidHeaderList[3] !=  360.0 ||
 
 1104     fclose( geoid_height_file );
 
 1105     delete [] file_name;
 
 1108     char message[256] = 
"";
 
 1110     strcat( message, 
": egm96.grd\n" );
 
 1119   fclose( geoid_height_file );
 
 1120   geoid_height_file = 0;
 
 1122   delete [] file_name;
 
 1127 void GeoidLibrary::initializeEGM84Geoid()
 
 1139   char* file_name = 0;
 
 1140   char* path_name = NULL;
 
 1141   long elevations_read = 0;
 
 1143   FILE*  geoid_height_file;
 
 1151   path_name = 
"/data/data/com.baesystems.msp.geotrans/lib/";
 
 1152   file_name = 
new char[ 80 ];
 
 1153   strcpy( file_name, path_name );
 
 1154   strcat( file_name, 
"libegm84grd.so" );
 
 1156   path_name = getenv( 
"MSPCCS_DATA" );
 
 1157   if (path_name != NULL)
 
 1159     file_name = 
new char[ strlen( path_name ) + 11 ];
 
 1160     strcpy( file_name, path_name );
 
 1161     strcat( file_name, 
"/" );
 
 1165     file_name =
new char[ 21 ];
 
 1166     strcpy( file_name, 
"../../data/" );
 
 1168   strcat( file_name, 
"egm84.grd" );
 
 1173   if( ( geoid_height_file = fopen( file_name, 
"rb" ) ) == NULL )
 
 1175     delete [] file_name;
 
 1178     char message[256] = 
"";
 
 1179     if (NULL == path_name)
 
 1181       strcpy( message, 
"Environment variable undefined: MSPCCS_DATA." );
 
 1186       strcat( message, 
": egm84.grd\n" );
 
 1197   fclose( geoid_height_file );
 
 1199   delete [] file_name;
 
 1203 void GeoidLibrary::initializeEGM84ThirtyMinGeoid()
 
 1215   char* file_name = 0;
 
 1216   char* path_name = NULL;
 
 1217   long elevations_read = 0;
 
 1219   FILE*  geoid_height_file;
 
 1227   path_name = 
"/data/data/com.baesystems.msp.geotrans/lib/";
 
 1228   file_name = 
new char[ 80 ];
 
 1229   strcpy( file_name, path_name );
 
 1230   strcat( file_name, 
"libwwgridbin.so" );
 
 1232   path_name = getenv( 
"MSPCCS_DATA" );
 
 1233   if (path_name != NULL)
 
 1235     file_name = 
new char[ strlen( path_name ) + 12 ]; 
 
 1236     strcpy( file_name, path_name );
 
 1237     strcat( file_name, 
"/" );
 
 1241     file_name =
new char[ 22 ]; 
 
 1242     strcpy( file_name, 
"../../data/" );
 
 1244   strcat( file_name, 
"wwgrid.bin" );
 
 1249   if( ( geoid_height_file = fopen( file_name, 
"rb" ) ) == NULL )
 
 1251     delete [] file_name;
 
 1254     char message[256] = 
"";
 
 1255     if (NULL == path_name)
 
 1257       strcpy( message, 
"Environment variable undefined: MSPCCS_DATA." );
 
 1262       strcat( message, 
": wwgrid.bin\n" );
 
 1274   fclose( geoid_height_file );
 
 1276   delete [] file_name;
 
 1281 void GeoidLibrary::initializeEGM2008Geoid( 
void )
 
 1301    char   message[256] = 
"";
 
 1302    char*  gridUsage    = NULL;
 
 1304    gridUsage = getenv( 
"EGM2008_GRID_USAGE" );
 
 1306    if ( NULL == gridUsage ) 
 
 1312       this->egm2008Geoid = 
new Egm2008AoiGrid;
 
 1316       if ( strcmp( gridUsage, 
"FULL" ) == 0 )
 
 1322          this->egm2008Geoid = 
new Egm2008FullGrid;
 
 1330          this->egm2008Geoid = 
new Egm2008AoiGrid;
 
 1337 void GeoidLibrary::bilinearInterpolateDoubleHeights(
 
 1340    double scale_factor,
 
 1343    double *height_buffer,
 
 1344    double *delta_height )
 
 1364   double offset_x, offset_y;
 
 1365   double delta_x, delta_y;
 
 1366   double _1_minus_delta_x, _1_minus_delta_y;
 
 1367   double latitude_dd, longitude_dd;
 
 1368   double height_se, height_sw, height_ne, height_nw;
 
 1369   double w_sw, w_se, w_ne, w_nw;
 
 1370   double south_lat, west_lon;
 
 1372   int max_index = num_rows * num_cols - 1;
 
 1378   if( ( longitude < -
PI ) || ( longitude > 
TWO_PI ) )
 
 1388   if( longitude_dd < 0.0 )
 
 1390     offset_x = ( longitude_dd + 360.0 ) / scale_factor;
 
 1394     offset_x = longitude_dd / scale_factor;
 
 1396   offset_y = ( 90 - latitude_dd ) / scale_factor;
 
 1401   post_x = ( int )( offset_x );
 
 1402   if( ( post_x + 1 ) == num_cols )
 
 1404   post_y = ( int )( offset_y + 1.0e-11 );
 
 1405   if( ( post_y + 1 ) == num_rows )
 
 1409   index = post_y * num_cols + post_x;
 
 1411     height_nw = height_buffer[ 0 ];
 
 1412   else if( index > max_index )
 
 1413     height_nw = height_buffer[ max_index ];
 
 1415     height_nw = height_buffer[ index ];
 
 1417   end_index = index + 1;
 
 1418   if( end_index > max_index )
 
 1419     height_ne  = height_buffer[ max_index ];
 
 1421     height_ne  = height_buffer[ end_index ];
 
 1424   index = ( post_y + 1 ) * num_cols + post_x;  
 
 1426     height_sw = height_buffer[ 0 ];
 
 1427   else if( index > max_index )
 
 1428     height_sw = height_buffer[ max_index ];
 
 1430     height_sw = height_buffer[ index ];
 
 1433   end_index = index + 1;
 
 1434   if( end_index > max_index )
 
 1435     height_se  = height_buffer[ max_index ];
 
 1437     height_se  = height_buffer[ end_index ];
 
 1439   west_lon = post_x * scale_factor;
 
 1442   south_lat = ( 90 - ( post_y * scale_factor ) ) - scale_factor;
 
 1446   if( longitude_dd < 0.0 )
 
 1447     delta_x = ( longitude_dd + 360.0 - west_lon ) / scale_factor;
 
 1449     delta_x = ( longitude_dd - west_lon ) / scale_factor;
 
 1450   delta_y = ( latitude_dd - south_lat ) / scale_factor;
 
 1452   _1_minus_delta_x = 1 - delta_x;
 
 1453   _1_minus_delta_y = 1 - delta_y;
 
 1455   w_sw = _1_minus_delta_x * _1_minus_delta_y;
 
 1456   w_se = delta_x * _1_minus_delta_y;
 
 1457   w_ne = delta_x * delta_y;
 
 1458   w_nw = _1_minus_delta_x * delta_y;
 
 1461      height_sw * w_sw + height_se * w_se + height_ne * w_ne + height_nw * w_nw;
 
 1465 void GeoidLibrary::bilinearInterpolate(
 
 1468    double  scale_factor,
 
 1471    float  *height_buffer,
 
 1472    double *delta_height )
 
 1492   double offset_x, offset_y;
 
 1493   double delta_x, delta_y;
 
 1494   double _1_minus_delta_x, _1_minus_delta_y;
 
 1495   double latitude_dd, longitude_dd;
 
 1496   double height_se, height_sw, height_ne, height_nw;
 
 1497   double w_sw, w_se, w_ne, w_nw;
 
 1498   double south_lat, west_lon;
 
 1500   int max_index = num_rows * num_cols - 1;
 
 1506   if( ( longitude < -
PI ) || ( longitude > 
TWO_PI ) )
 
 1515   if( longitude_dd < 0.0 )
 
 1517     offset_x = ( longitude_dd + 360.0 ) / scale_factor;
 
 1521     offset_x = longitude_dd / scale_factor;
 
 1523   offset_y = ( 90 - latitude_dd ) / scale_factor;
 
 1528   post_x = ( int )( offset_x );
 
 1529   if( ( post_x + 1 ) == num_cols )
 
 1531   post_y = ( int )( offset_y + 1.0e-11 );
 
 1532   if( ( post_y + 1 ) == num_rows )
 
 1536   index = post_y * num_cols + post_x;
 
 1538     height_nw = height_buffer[ 0 ];
 
 1539   else if( index > max_index )
 
 1540     height_nw = height_buffer[ max_index ];
 
 1542     height_nw = height_buffer[ index ];
 
 1544   end_index = index + 1;
 
 1545   if( end_index > max_index )
 
 1546     height_ne  = height_buffer[ max_index ];
 
 1548     height_ne  = height_buffer[ end_index ];
 
 1551   index = ( post_y + 1 ) * num_cols + post_x;  
 
 1553     height_sw = height_buffer[ 0 ];
 
 1554   else if( index > max_index )
 
 1555     height_sw = height_buffer[ max_index ];
 
 1557     height_sw = height_buffer[ index ];
 
 1560   end_index = index + 1;
 
 1561   if( end_index > max_index )
 
 1562     height_se  = height_buffer[ max_index ];
 
 1564     height_se  = height_buffer[ end_index ];
 
 1566   west_lon = post_x * scale_factor;
 
 1569   south_lat = ( 90 - ( post_y * scale_factor ) ) - scale_factor;
 
 1573   if( longitude_dd < 0.0 )
 
 1574     delta_x = ( longitude_dd + 360.0 - west_lon ) / scale_factor;
 
 1576     delta_x = ( longitude_dd - west_lon ) / scale_factor;
 
 1577   delta_y = ( latitude_dd - south_lat ) / scale_factor;
 
 1579   _1_minus_delta_x = 1 - delta_x;
 
 1580   _1_minus_delta_y = 1 - delta_y;
 
 1582   w_sw = _1_minus_delta_x * _1_minus_delta_y;
 
 1583   w_se = delta_x * _1_minus_delta_y;
 
 1584   w_ne = delta_x * delta_y;
 
 1585   w_nw = _1_minus_delta_x * delta_y;
 
 1588      height_sw * w_sw + height_se * w_se + height_ne * w_ne + height_nw * w_nw;
 
 1592 void GeoidLibrary::naturalSplineInterpolate(
 
 1595    double scale_factor,
 
 1599    float  *height_buffer,
 
 1600    double *delta_height )
 
 1620   int temp_offset_x, temp_offset_y;
 
 1621   double offset_x, offset_y;
 
 1622   double delta_x, delta_y;
 
 1623   double delta_x2, delta_y2;
 
 1624   double _1_minus_delta_x, _1_minus_delta_y;
 
 1625   double _1_minus_delta_x2, _1_minus_delta_y2;
 
 1626   double  _3_minus_2_times_1_minus_delta_x, _3_minus_2_times_1_minus_delta_y;
 
 1627   double _3_minus_2_times_delta_x, _3_minus_2_times_delta_y;
 
 1628   double latitude_dd, longitude_dd;
 
 1629   double height_se, height_sw, height_ne, height_nw;
 
 1630   double w_sw, w_se, w_ne, w_nw;
 
 1631   double south_lat, west_lon;
 
 1633   double skip_factor = 1.0;
 
 1639   if( ( longitude < -
PI ) || ( longitude > 
TWO_PI ) )
 
 1649   if( longitude_dd < 0.0 )
 
 1651     offset_x = ( longitude_dd + 360.0 ) / scale_factor;
 
 1655     offset_x = longitude_dd / scale_factor;
 
 1657   offset_y = ( 90.0 - latitude_dd ) / scale_factor;
 
 1662   post_x = ( int ) offset_x;
 
 1663   if ( ( post_x + 1 ) == num_cols)
 
 1665   post_y = ( int )( offset_y + 1.0e-11 );
 
 1666   if ( ( post_y + 1 ) == num_rows)
 
 1688   temp_offset_x = ( int )( post_x * skip_factor );
 
 1689   temp_offset_y = ( int )( post_y * skip_factor + 1.0e-11 );
 
 1690   if ( ( temp_offset_x + 1 ) == num_cols )
 
 1692   if ( ( temp_offset_y + 1 ) == num_rows )
 
 1696   index = ( int )( temp_offset_y * num_cols + temp_offset_x );
 
 1698     height_nw = height_buffer[ 0 ];
 
 1699   else if( index > max_index )
 
 1700     height_nw = height_buffer[ max_index ];
 
 1702     height_nw = height_buffer[ index ];
 
 1704   end_index = index + (int)skip_factor;
 
 1706     height_ne = height_buffer[ 0 ];
 
 1707   else if( end_index > max_index )
 
 1708     height_ne = height_buffer[ max_index ];
 
 1710     height_ne = height_buffer[ end_index ];
 
 1713   index = ( int )( ( temp_offset_y + skip_factor ) * num_cols + temp_offset_x );
 
 1715     height_sw = height_buffer[ 0 ];
 
 1716   else if( index > max_index )
 
 1717     height_sw = height_buffer[ max_index ];
 
 1719     height_sw = height_buffer[ index ];
 
 1721   end_index = index + (int)skip_factor;
 
 1723     height_se = height_buffer[ 0 ];
 
 1724   else if( end_index > max_index )
 
 1725     height_se = height_buffer[ max_index ];
 
 1727     height_se = height_buffer[ end_index ];
 
 1729   west_lon = post_x * scale_factor;
 
 1732   south_lat = ( 90 - ( post_y * scale_factor ) ) - scale_factor;   
 
 1736   if( longitude_dd < 0.0 )
 
 1737     delta_x = ( longitude_dd + 360.0 - west_lon ) / scale_factor;
 
 1739     delta_x = ( longitude_dd - west_lon ) / scale_factor;
 
 1740   delta_y = ( latitude_dd - south_lat ) / scale_factor;
 
 1742   delta_x2 = delta_x * delta_x;
 
 1743   delta_y2 = delta_y * delta_y;
 
 1745   _1_minus_delta_x = 1 - delta_x;
 
 1746   _1_minus_delta_y = 1 - delta_y;
 
 1748   _1_minus_delta_x2 = _1_minus_delta_x * _1_minus_delta_x;
 
 1749   _1_minus_delta_y2 = _1_minus_delta_y * _1_minus_delta_y;
 
 1751   _3_minus_2_times_1_minus_delta_x = 3 - 2 * _1_minus_delta_x;
 
 1752   _3_minus_2_times_1_minus_delta_y = 3 - 2 * _1_minus_delta_y;
 
 1754   _3_minus_2_times_delta_x = 3 - 2 * delta_x;
 
 1755   _3_minus_2_times_delta_y = 3 - 2 * delta_y;
 
 1757   w_sw = _1_minus_delta_x2 * _1_minus_delta_y2 * 
 
 1758      ( _3_minus_2_times_1_minus_delta_x * _3_minus_2_times_1_minus_delta_y );
 
 1760   w_se = delta_x2 * _1_minus_delta_y2 * 
 
 1761      ( _3_minus_2_times_delta_x * _3_minus_2_times_1_minus_delta_y );
 
 1763   w_ne = delta_x2 * delta_y2 * 
 
 1764      ( _3_minus_2_times_delta_x * _3_minus_2_times_delta_y );
 
 1766   w_nw = _1_minus_delta_x2 * delta_y2 * 
 
 1767      (  _3_minus_2_times_1_minus_delta_x * _3_minus_2_times_delta_y );
 
 1770      height_sw * w_sw + height_se * w_se + height_ne * w_ne + height_nw * w_nw;