00001 // CLASSIFICATION: UNCLASSIFIED 00002 00003 #ifndef GeoidLibrary_H 00004 #define GeoidLibrary_H 00005 00006 /***************************************************************************/ 00007 /* RSC IDENTIFIER: Geoid Library 00008 * 00009 * ABSTRACT 00010 * 00011 * The purpose of GEOID is to support conversions between WGS84 ellipsoid 00012 * heights and WGS84 geoid heights. 00013 * 00014 * 00015 * ERROR HANDLING 00016 * 00017 * This component checks parameters for valid values. If an invalid value 00018 * is found, the error code is combined with the current error code using 00019 * the bitwise or. This combining allows multiple error codes to be 00020 * returned. The possible error codes are: 00021 * 00022 * GEOID_NO_ERROR : No errors occurred in function 00023 * GEOID_FILE_OPEN_ERROR : Geoid file opening error 00024 * GEOID_INITIALIZE_ERROR : Geoid separation database can not initialize 00025 * GEOID_LAT_ERROR : Latitude out of valid range 00026 * (-90 to 90 degrees) 00027 * GEOID_LON_ERROR : Longitude out of valid range 00028 * (-180 to 360 degrees) 00029 * 00030 * REUSE NOTES 00031 * 00032 * Geoid is intended for reuse by any application that requires conversion 00033 * between WGS84 ellipsoid heights and WGS84 geoid heights. 00034 * 00035 * REFERENCES 00036 * 00037 * Further information on Geoid can be found in the Reuse Manual. 00038 * 00039 * Geoid originated from : U.S. Army Topographic Engineering Center 00040 * Geospatial Information Division 00041 * 7701 Telegraph Road 00042 * Alexandria, VA 22310-3864 00043 * 00044 * LICENSES 00045 * 00046 * None apply to this component. 00047 * 00048 * RESTRICTIONS 00049 * 00050 * Geoid has no restrictions. 00051 * 00052 * ENVIRONMENT 00053 * 00054 * Geoid was tested and certified in the following environments 00055 * 00056 * 1. Solaris 2.5 with GCC 2.8.1 00057 * 2. MS Windows XP with MS Visual C++ 6.0 00058 * 00059 * 00060 * MODIFICATIONS 00061 * 00062 * Date Description 00063 * ---- ----------- 00064 * 24-May-99 Original Code 00065 * 09-Jan-06 Added new geoid height interpolation methods 00066 * 03-14-07 Original C++ Code 00067 * 05-12-10 S. Gillis, BAEts26542, MSL-HAE for 30 minute grid added 00068 * 07-21-10 Read in full file at once instead of one post at a time 00069 * 12-17-10 RD Craig added pointer to EGM2008 interpolator (BAEts26267). 00070 * 00071 */ 00072 00073 #include "egm2008_geoid_grid.h" 00074 00075 #include "DtccApi.h" 00076 00077 namespace MSP 00078 { 00079 class CCSThreadMutex; 00080 namespace CCS 00081 { 00082 class MSP_DTCC_API GeoidLibrary 00083 { 00084 friend class GeoidLibraryCleaner; 00085 00086 public: 00087 00088 /* The function getInstance returns an instance of the GeoidLibrary 00089 */ 00090 00091 static GeoidLibrary* getInstance(); 00092 00093 00094 /* 00095 * The function removeInstance removes this GeoidLibrary 00096 * instance from the total number of instances. 00097 */ 00098 00099 static void removeInstance(); 00100 00101 00102 ~GeoidLibrary( void ); 00103 00104 00105 /* 00106 * The function convertEllipsoidToEGM96FifteenMinBilinearGeoidHeight 00107 * converts the specified WGS84 ellipsoid height at the specified 00108 * geodetic coordinates to the equivalent 00109 * geoid height, using the EGM96 gravity model and 00110 * the bilinear interpolation method. 00111 * 00112 * longitude : Geodetic longitude in radians (input) 00113 * latitude : Geodetic latitude in radians (input) 00114 * ellipsoidHeight : Ellipsoid height, in meters (input) 00115 * geoidHeight : Geoid height, in meters. (output) 00116 * 00117 */ 00118 00119 void convertEllipsoidToEGM96FifteenMinBilinearGeoidHeight( 00120 double longitude, 00121 double latitude, 00122 double ellipsoidHeight, 00123 double *geoidHeight ); 00124 00125 00126 /* 00127 * The function convertEllipsoidToEGM96VariableNaturalSplineHeight 00128 * converts the specified WGS84 ellipsoid height at the specified 00129 * geodetic coordinates to the equivalent geoid height, 00130 * using the EGM96 gravity model and 00131 * the natural spline interpolation method. 00132 * 00133 * longitude : Geodetic longitude in radians (input) 00134 * latitude : Geodetic latitude in radians (input) 00135 * ellipsoidHeight : Ellipsoid height, in meters (input) 00136 * geoidHeight : Geoid height, in meters. (output) 00137 * 00138 */ 00139 00140 void convertEllipsoidToEGM96VariableNaturalSplineHeight( 00141 double longitude, 00142 double latitude, 00143 double ellipsoidHeight, 00144 double *geoidHeight ); 00145 00146 /* 00147 * The function convertEllipsoidToEGM84TenDegBilinearHeight 00148 * converts the specified WGS84 ellipsoid height at the specified 00149 * geodetic coordinates to the equivalent geoid height, 00150 * using the EGM84 gravity model and 00151 * the bilinear interpolation method. 00152 * 00153 * longitude : Geodetic longitude in radians (input) 00154 * latitude : Geodetic latitude in radians (input) 00155 * ellipsoidHeight : Ellipsoid height, in meters (input) 00156 * geoidHeight : Geoid height, in meters. (output) 00157 * 00158 */ 00159 00160 void convertEllipsoidToEGM84TenDegBilinearHeight( 00161 double longitude, 00162 double latitude, 00163 double ellipsoidHeight, 00164 double *geoidHeight ); 00165 00166 /* 00167 * The function convertEllipsoidToEGM84TenDegNaturalSplineHeight 00168 * converts the specified WGS84 ellipsoid height at the specified 00169 * geodetic coordinates to the equivalent geoid height, 00170 * using the EGM84 gravity model and 00171 * the natural splineinterpolation method. 00172 * 00173 * longitude : Geodetic longitude in radians (input) 00174 * latitude : Geodetic latitude in radians (input) 00175 * ellipsoidHeight : Ellipsoid height, in meters (input) 00176 * geoidHeight : Geoid height, in meters. (output) 00177 * 00178 */ 00179 00180 void convertEllipsoidToEGM84TenDegNaturalSplineHeight( 00181 double longitude, 00182 double latitude, 00183 double ellipsoidHeight, 00184 double *geoidHeight ); 00185 00186 /* 00187 * The function convertEllipsoidToEGM84ThirtyMinBiLinearHeight 00188 * converts the specified WGS84 ellipsoid height at the specified 00189 * geodetic coordinates to the equivalent geoid height, 00190 * using the EGM84 gravity model and 00191 * the bilinear interpolation method. 00192 * 00193 * longitude : Geodetic longitude in radians (input) 00194 * latitude : Geodetic latitude in radians (input) 00195 * ellipsoidHeight : Ellipsoid height, in meters (input) 00196 * geoidHeight : Geoid height, in meters. (output) 00197 */ 00198 00199 void convertEllipsoidToEGM84ThirtyMinBiLinearHeight( 00200 double longitude, 00201 double latitude, 00202 double ellipsoidHeight, 00203 double *geoidHeight ); 00204 00205 /* 00206 * The function convertEllipsoidHeightToEGM2008GeoidHeight 00207 * converts the specified WGS84 ellipsoid height at the specified 00208 * geodetic coordinates to the equivalent height above the geoid. This function 00209 * uses the EGM2008 gravity model, plus the bicubic spline interpolation method. 00210 * 00211 * longitude : Geodetic longitude in radians (input) 00212 * latitude : Geodetic latitude in radians (input) 00213 * ellipsoidHeight : Ellipsoid height, in meters (input) 00214 * geoidHeight : Height above the geoid, meters (output) 00215 */ 00216 00217 void 00218 convertEllipsoidHeightToEGM2008GeoidHeight( 00219 double longitude, 00220 double latitude, 00221 double ellipsoidHeight, 00222 double *geoidHeight ); 00223 00224 /* 00225 * The function convertEGM96FifteenMinBilinearGeoidToEllipsoidHeight 00226 * converts the specified WGS84 geoid height at the specified 00227 * geodetic coordinates to the equivalent ellipsoid height, 00228 * using the EGM96 gravity model and 00229 * the bilinear interpolation method. 00230 * 00231 * longitude : Geodetic longitude in radians (input) 00232 * latitude : Geodetic latitude in radians (input) 00233 * geoidHeight : Geoid height, in meters. (input) 00234 * ellipsoidHeight : Ellipsoid height, in meters (output) 00235 * 00236 */ 00237 00238 void convertEGM96FifteenMinBilinearGeoidToEllipsoidHeight( 00239 double longitude, 00240 double latitude, 00241 double geoidHeight, 00242 double *ellipsoidHeight ); 00243 00244 /* 00245 * The function convertEGM96VariableNaturalSplineToEllipsoidHeight 00246 * converts the specified WGS84 geoid height at the specified 00247 * geodetic coordinates to the equivalent ellipsoid height, 00248 * using the EGM96 gravity model and 00249 * the natural spline interpolation method. 00250 * 00251 * longitude : Geodetic longitude in radians (input) 00252 * latitude : Geodetic latitude in radians (input) 00253 * geoidHeight : Geoid height, in meters. (input) 00254 * ellipsoidHeight : Ellipsoid height, in meters (output) 00255 * 00256 */ 00257 00258 void convertEGM96VariableNaturalSplineToEllipsoidHeight( 00259 double longitude, 00260 double latitude, 00261 double geoidHeight, 00262 double *ellipsoidHeight ); 00263 00264 00265 /* 00266 * The function convertEGM84TenDegBilinearToEllipsoidHeight 00267 * converts the specified WGS84 geoid height at the specified 00268 * geodetic coordinates to the equivalent ellipsoid height, using 00269 * the EGM84 gravity model and 00270 * the bilinear interpolation method. 00271 * 00272 * longitude : Geodetic longitude in radians (input) 00273 * latitude : Geodetic latitude in radians (input) 00274 * geoidHeight : Geoid height, in meters. (input) 00275 * ellipsoidHeight : Ellipsoid height, in meters (output) 00276 * 00277 */ 00278 00279 void convertEGM84TenDegBilinearToEllipsoidHeight( 00280 double longitude, 00281 double latitude, 00282 double geoidHeight, 00283 double *ellipsoidHeight ); 00284 00285 /* 00286 * The function convertEGM84TenDegNaturalSplineToEllipsoidHeight 00287 * converts the specified WGS84 geoid height at the specified 00288 * geodetic coordinates to the equivalent ellipsoid height, 00289 * using the EGM84 gravity model and 00290 * the natural spline interpolation method. 00291 * 00292 * longitude : Geodetic longitude in radians (input) 00293 * latitude : Geodetic latitude in radians (input) 00294 * geoidHeight : Geoid height, in meters. (input) 00295 * ellipsoidHeight : Ellipsoid height, in meters (output) 00296 * 00297 */ 00298 00299 void convertEGM84TenDegNaturalSplineToEllipsoidHeight( 00300 double longitude, 00301 double latitude, 00302 double geoidHeight, 00303 double *ellipsoidHeight ); 00304 00305 /* 00306 * The function convertEGM84ThirtyMinBiLinearToEllipsoidHeight 00307 * converts the specified WGS84 geoid height at the specified 00308 * geodetic coordinates to the equivalent ellipsoid height, using 00309 * the EGM84 gravity model and the bilinear interpolation method. 00310 * 00311 * longitude : Geodetic longitude in radians (input) 00312 * latitude : Geodetic latitude in radians (input) 00313 * geoidHeight : Geoid height, in meters. (input) 00314 * ellipsoidHeight : Ellipsoid height, in meters (output) 00315 * 00316 */ 00317 00318 void convertEGM84ThirtyMinBiLinearToEllipsoidHeight( 00319 double longitude, 00320 double latitude, 00321 double geoidHeight, 00322 double *ellipsoidHeight ); 00323 00324 /* 00325 * The function convertEGM2008GeoidHeightToEllipsoidHeight( 00326 * converts the specified EGM2008 geoid height at the specified 00327 * geodetic coordinates to the equivalent ellipsoid height. It uses 00328 * the EGM2008 gravity model, plus the bicubic spline interpolation method. 00329 * 00330 * longitude : Geodetic longitude in radians (input) 00331 * latitude : Geodetic latitude in radians (input) 00332 * geoidHeight : Height above the geoid, meters (input) 00333 * ellipsoidHeight : Ellipsoid height, in meters (output) 00334 */ 00335 00336 void convertEGM2008GeoidHeightToEllipsoidHeight( 00337 double longitude, 00338 double latitude, 00339 double geoidHeight, 00340 double *ellipsoidHeight ); 00341 00342 protected: 00343 00344 /* 00345 * The constructor creates empty lists which are used 00346 * to store the geoid separation data 00347 * contained in the data files egm84.grd and egm96.grd. 00348 * 00349 * The constructor now also instantiates the 00350 * appropriate EGM2008 geoid separation interpolator. 00351 */ 00352 00353 GeoidLibrary(); 00354 00355 00356 GeoidLibrary( const GeoidLibrary &gl ); 00357 00358 00359 GeoidLibrary& operator=( const GeoidLibrary &gl ); 00360 00361 00362 private: 00363 00364 static CCSThreadMutex mutex; 00365 static GeoidLibrary* instance; 00366 static int instanceCount; 00367 00368 /* List of EGM96 elevations */ 00369 float *egm96GeoidList; 00370 00371 /* List of EGM84 elevations */ 00372 float *egm84GeoidList; 00373 00374 /* List of EGM84 thirty minute elevations */ 00375 double *egm84ThirtyMinGeoidList; 00376 00377 /* Pointer to EGM2008 interpolator object */ 00378 00379 Egm2008GeoidGrid* egm2008Geoid; 00380 00381 /* 00382 * The function loadGeoids reads geoid separation data from a file 00383 * in the current directory and builds the geoid separation table 00384 * from it. 00385 * If the separation file can not be found or accessed, an 00386 * error code of GEOID_FILE_OPEN_ERROR is returned, 00387 * If the separation file is incomplete or improperly formatted, 00388 * an error code of GEOID_INITIALIZE_ERROR is returned, 00389 * otherwise GEOID_NO_ERROR is returned. 00390 * This function must be called before 00391 * any of the other functions in this component. 00392 */ 00393 00394 void loadGeoids(); 00395 00396 /* 00397 * The function initializeEGM96Geoid reads geoid separation data 00398 * from the egm96.grd file in the current directory 00399 * and builds a geoid separation table from it. 00400 * If the separation file can not be found or accessed, 00401 * an error code of GEOID_FILE_OPEN_ERROR is returned, 00402 * If the separation file is incomplete or improperly formatted, 00403 * an error code of GEOID_INITIALIZE_ERROR is returned, 00404 * otherwise GEOID_NO_ERROR is returned. 00405 */ 00406 00407 void initializeEGM96Geoid(); 00408 00409 /* 00410 * The function initializeEGM84Geoid reads geoid separation data 00411 * from a file in the current directory and builds 00412 * the geoid separation table from it. 00413 * If the separation file can not be found or accessed, 00414 * an error code of GEOID_FILE_OPEN_ERROR is returned, 00415 * If the separation file is incomplete or improperly formatted, 00416 * an error code of GEOID_INITIALIZE_ERROR is returned, 00417 * otherwise GEOID_NO_ERROR is returned. 00418 */ 00419 00420 void initializeEGM84Geoid(); 00421 00422 /* 00423 * The function initializeEGM84ThirtyMinGeoid reads geoid 00424 * separation data from a file in the current directory and builds 00425 * the geoid separation table from it. 00426 * If the separation file can not be found or accessed, 00427 * an error code of GEOID_FILE_OPEN_ERROR is returned, 00428 * If the separation file is incomplete or improperly formatted, 00429 * an error code of GEOID_INITIALIZE_ERROR is returned, 00430 * otherwise GEOID_NO_ERROR is returned. 00431 */ 00432 00433 void initializeEGM84ThirtyMinGeoid(); 00434 00435 /* 00436 * The function initializeEGM2008Geoid 00437 * instantiates one of two geoid-separation objects. 00438 * The FULL_GRID interpolator reads the entire 00439 * geoid-separation file into memory upon instantiation, 00440 * while the AOI_GRID interpolator only reads the 00441 * grid file's header into memory upon instantiation. 00442 * 00443 * The FULL_GRID interpolator builds its local interpolation 00444 * windows from data contained in the worldwide, memory-resident, 00445 * geoid separation grid. The AOI_GRID interpolator reads intermediate 00446 * Area of Interest grids into memory before populating local interpolation 00447 * windows. These AOI grids are much smaller than the EGM2008 worldwide grid, 00448 * so they load quickly, and they permit high-resolution geoid separations to be 00449 * computed even on small computer systems. AOI grids do not need to be reloaded 00450 * into computer memory if all requested geoid separations are spatially localized. 00451 * AOI grid reloads are automatic, and they require no action by GeoidLibrary users. 00452 */ 00453 00454 void initializeEGM2008Geoid(); 00455 00456 /* 00457 * The private function bilinearInterpolateDoubleHeights returns the 00458 * height of the WGS84 geoid above or below the WGS84 ellipsoid, 00459 * at the specified geodetic coordinates, 00460 * using a grid of height adjustments 00461 * and the bilinear interpolation method. 00462 * 00463 * longitude : Geodetic longitude in radians (input) 00464 * latitude : Geodetic latitude in radians (input) 00465 * scale_factor : Grid scale factor (input) 00466 * num_cols : Number of columns in grid (input) 00467 * num_rows : Number of rows in grid (input) 00468 * height_buffer : Grid of height adjustments, doubles (input) 00469 * delta_height : Height Adjustment, in meters. (output) 00470 * 00471 */ 00472 00473 void bilinearInterpolateDoubleHeights( 00474 double longitude, 00475 double latitude, 00476 double scale_factor, 00477 int num_cols, 00478 int num_rows, 00479 double *height_buffer, 00480 double *delta_height ); 00481 00482 /* 00483 * The private function bilinearInterpolate returns the height of 00484 * the WGS84 geoid above or below the WGS84 ellipsoid, at the 00485 * specified geodetic coordinates, using a grid of height 00486 * adjustments and the bilinear interpolation method. 00487 * 00488 * longitude : Geodetic longitude in radians (input) 00489 * latitude : Geodetic latitude in radians (input) 00490 * scale_factor : Grid scale factor (input) 00491 * num_cols : Number of columns in grid (input) 00492 * num_rows : Number of rows in grid (input) 00493 * height_buffer : Grid of height adjustments, floats (input) 00494 * delta_height : Height Adjustment, in meters. (output) 00495 * 00496 */ 00497 00498 void bilinearInterpolate( 00499 double longitude, 00500 double latitude, 00501 double scale_factor, 00502 int num_cols, 00503 int num_rows, 00504 float *height_buffer, 00505 double *delta_height ); 00506 00507 /* 00508 * The private function naturalSplineInterpolate returns the 00509 * height of the WGS84 geoid above or below the WGS84 ellipsoid, 00510 * at the specified geodetic coordinates, 00511 * using a grid of height adjustments 00512 * and the natural spline interpolation method. 00513 * 00514 * longitude : Geodetic longitude in radians (input) 00515 * latitude : Geodetic latitude in radians (input) 00516 * scale_factor : Grid scale factor (input) 00517 * num_cols : Number of columns in grid (input) 00518 * num_rows : Number of rows in grid (input) 00519 * height_buffer : Grid of height adjustments (input) 00520 * DeltaHeight : Height Adjustment, in meters. (output) 00521 * 00522 */ 00523 00524 void naturalSplineInterpolate( 00525 double longitude, 00526 double latitude, 00527 double scale_factor, 00528 int num_cols, 00529 int num_rows, 00530 int max_index, 00531 float *height_buffer, 00532 double *delta_height ); 00533 00534 /* 00535 * Delete the singleton. 00536 */ 00537 00538 static void deleteInstance(); 00539 }; 00540 } 00541 } 00542 00543 #endif 00544 00545 00546 // CLASSIFICATION: UNCLASSIFIED