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 occured in function 00023 * GEOID_FILE_OPEN_ERROR : Geoid file opening error 00024 * GEOID_INITIALIZE_ERROR : Geoid seoaration 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 */ 00070 00071 #include "DtccApi.h" 00072 00073 namespace MSP 00074 { 00075 class CCSThreadMutex; 00076 namespace CCS 00077 { 00078 class MSP_DTCC_API GeoidLibrary 00079 { 00080 friend class GeoidLibraryCleaner; 00081 00082 public: 00083 00084 /* The function getInstance returns an instance of the GeoidLibrary 00085 */ 00086 00087 static GeoidLibrary* getInstance(); 00088 00089 00090 /* 00091 * The function removeInstance removes this GeoidLibrary 00092 * instance from the total number of instances. 00093 */ 00094 00095 static void removeInstance(); 00096 00097 00098 ~GeoidLibrary( void ); 00099 00100 00101 /* 00102 * The function convertEllipsoidToEGM96FifteenMinBilinearGeoidHeight 00103 * converts the specified WGS84 ellipsoid height at the specified 00104 * geodetic coordinates to the equivalent 00105 * geoid height, using the EGM96 gravity model and 00106 * the bilinear interpolation method. 00107 * 00108 * longitude : Geodetic longitude in radians (input) 00109 * latitude : Geodetic latitude in radians (input) 00110 * ellipsoidHeight : Ellipsoid height, in meters (input) 00111 * geoidHeight : Geoid height, in meters. (output) 00112 * 00113 */ 00114 00115 void convertEllipsoidToEGM96FifteenMinBilinearGeoidHeight( 00116 double longitude, 00117 double latitude, 00118 double ellipsoidHeight, 00119 double *geoidHeight ); 00120 00121 00122 /* 00123 * The function convertEllipsoidToEGM96VariableNaturalSplineHeight 00124 * converts the specified WGS84 ellipsoid height at the specified 00125 * geodetic coordinates to the equivalent geoid height, 00126 * using the EGM96 gravity model and 00127 * the natural spline interpolation method. 00128 * 00129 * longitude : Geodetic longitude in radians (input) 00130 * latitude : Geodetic latitude in radians (input) 00131 * ellipsoidHeight : Ellipsoid height, in meters (input) 00132 * geoidHeight : Geoid height, in meters. (output) 00133 * 00134 */ 00135 00136 void convertEllipsoidToEGM96VariableNaturalSplineHeight( 00137 double longitude, 00138 double latitude, 00139 double ellipsoidHeight, 00140 double *geoidHeight ); 00141 00142 /* 00143 * The function convertEllipsoidToEGM84TenDegBilinearHeight 00144 * converts the specified WGS84 ellipsoid height at the specified 00145 * geodetic coordinates to the equivalent geoid height, 00146 * using the EGM84 gravity model and 00147 * the bilinear interpolation method. 00148 * 00149 * longitude : Geodetic longitude in radians (input) 00150 * latitude : Geodetic latitude in radians (input) 00151 * ellipsoidHeight : Ellipsoid height, in meters (input) 00152 * geoidHeight : Geoid height, in meters. (output) 00153 * 00154 */ 00155 00156 void convertEllipsoidToEGM84TenDegBilinearHeight( 00157 double longitude, 00158 double latitude, 00159 double ellipsoidHeight, 00160 double *geoidHeight ); 00161 00162 /* 00163 * The function convertEllipsoidToEGM84TenDegNaturalSplineHeight 00164 * converts the specified WGS84 ellipsoid height at the specified 00165 * geodetic coordinates to the equivalent geoid height, 00166 * using the EGM84 gravity model and 00167 * the natural splineinterpolation method. 00168 * 00169 * longitude : Geodetic longitude in radians (input) 00170 * latitude : Geodetic latitude in radians (input) 00171 * ellipsoidHeight : Ellipsoid height, in meters (input) 00172 * geoidHeight : Geoid height, in meters. (output) 00173 * 00174 */ 00175 00176 void convertEllipsoidToEGM84TenDegNaturalSplineHeight( 00177 double longitude, 00178 double latitude, 00179 double ellipsoidHeight, 00180 double *geoidHeight ); 00181 00182 /* 00183 * The function convertEllipsoidToEGM84ThirtyMinBiLinearHeight 00184 * converts the specified WGS84 ellipsoid height at the specified 00185 * geodetic coordinates to the equivalent geoid height, 00186 * using the EGM84 gravity model and 00187 * the bilinear interpolation method. 00188 * 00189 * longitude : Geodetic longitude in radians (input) 00190 * latitude : Geodetic latitude in radians (input) 00191 * ellipsoidHeight : Ellipsoid height, in meters (input) 00192 * geoidHeight : Geoid height, in meters. (output) 00193 * 00194 */ 00195 00196 void convertEllipsoidToEGM84ThirtyMinBiLinearHeight( 00197 double longitude, 00198 double latitude, 00199 double ellipsoidHeight, 00200 double *geoidHeight ); 00201 00202 /* 00203 * The function convertEGM96FifteenMinBilinearGeoidToEllipsoidHeight 00204 * converts the specified WGS84 geoid height at the specified 00205 * geodetic coordinates to the equivalent ellipsoid height, 00206 * using the EGM96 gravity model and 00207 * the bilinear interpolation method. 00208 * 00209 * longitude : Geodetic longitude in radians (input) 00210 * latitude : Geodetic latitude in radians (input) 00211 * geoidHeight : Geoid height, in meters. (input) 00212 * ellipsoidHeight : Ellipsoid height, in meters (output) 00213 * 00214 */ 00215 00216 void convertEGM96FifteenMinBilinearGeoidToEllipsoidHeight( 00217 double longitude, 00218 double latitude, 00219 double geoidHeight, 00220 double *ellipsoidHeight ); 00221 00222 00223 /* 00224 * The function convertEGM96VariableNaturalSplineToEllipsoidHeight 00225 * converts the specified WGS84 geoid height at the specified 00226 * geodetic coordinates to the equivalent ellipsoid height, 00227 * using the EGM96 gravity model and 00228 * the natural spline interpolation method. 00229 * 00230 * longitude : Geodetic longitude in radians (input) 00231 * latitude : Geodetic latitude in radians (input) 00232 * geoidHeight : Geoid height, in meters. (input) 00233 * ellipsoidHeight : Ellipsoid height, in meters (output) 00234 * 00235 */ 00236 00237 void convertEGM96VariableNaturalSplineToEllipsoidHeight( 00238 double longitude, 00239 double latitude, 00240 double geoidHeight, 00241 double *ellipsoidHeight ); 00242 00243 00244 /* 00245 * The function convertEGM84TenDegBilinearToEllipsoidHeight 00246 * converts the specified WGS84 geoid height at the specified 00247 * geodetic coordinates to the equivalent ellipsoid height, using 00248 * the EGM84 gravity model and 00249 * the bilinear 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 convertEGM84TenDegBilinearToEllipsoidHeight( 00259 double longitude, 00260 double latitude, 00261 double geoidHeight, 00262 double *ellipsoidHeight ); 00263 00264 /* 00265 * The function convertEGM84TenDegNaturalSplineToEllipsoidHeight 00266 * converts the specified WGS84 geoid height at the specified 00267 * geodetic coordinates to the equivalent ellipsoid height, 00268 * using the EGM84 gravity model and 00269 * the natural spline interpolation method. 00270 * 00271 * longitude : Geodetic longitude in radians (input) 00272 * latitude : Geodetic latitude in radians (input) 00273 * geoidHeight : Geoid height, in meters. (input) 00274 * ellipsoidHeight : Ellipsoid height, in meters (output) 00275 * 00276 */ 00277 00278 void convertEGM84TenDegNaturalSplineToEllipsoidHeight( 00279 double longitude, 00280 double latitude, 00281 double geoidHeight, 00282 double *ellipsoidHeight ); 00283 00284 /* 00285 * The function convertEGM84ThirtyMinBiLinearToEllipsoidHeight 00286 * converts the specified WGS84 geoid height at the specified 00287 * geodetic coordinates to the equivalent ellipsoid height, using 00288 * the EGM84 gravity model and the bilinear interpolation method. 00289 * 00290 * longitude : Geodetic longitude in radians (input) 00291 * latitude : Geodetic latitude in radians (input) 00292 * geoidHeight : Geoid height, in meters. (input) 00293 * ellipsoidHeight : Ellipsoid height, in meters (output) 00294 * 00295 */ 00296 00297 void convertEGM84ThirtyMinBiLinearToEllipsoidHeight( 00298 double longitude, 00299 double latitude, 00300 double geoidHeight, 00301 double *ellipsoidHeight ); 00302 00303 protected: 00304 00305 /* 00306 * The constructor creates empty lists which are used 00307 * to store the geoid separation data 00308 * contained in the data files egm84.grd and egm96.grd 00309 */ 00310 00311 GeoidLibrary(); 00312 00313 00314 GeoidLibrary( const GeoidLibrary &gl ); 00315 00316 00317 GeoidLibrary& operator=( const GeoidLibrary &gl ); 00318 00319 00320 private: 00321 00322 static CCSThreadMutex mutex; 00323 static GeoidLibrary* instance; 00324 static int instanceCount; 00325 00326 /* List of EGM96 elevations */ 00327 float *egm96GeoidList; 00328 00329 /* List of EGM84 elevations */ 00330 float *egm84GeoidList; 00331 00332 /* List of EGM84 thirty minute elevations */ 00333 double *egm84ThirtyMinGeoidList; 00334 /* 00335 * The function loadGeoids reads geoid separation data from a file 00336 * in the current directory and builds the geoid separation table 00337 * from it. 00338 * If the separation file can not be found or accessed, an 00339 * error code of GEOID_FILE_OPEN_ERROR is returned, 00340 * If the separation file is incomplete or improperly formatted, 00341 * an error code of GEOID_INITIALIZE_ERROR is returned, 00342 * otherwise GEOID_NO_ERROR is returned. 00343 * This function must be called before 00344 * any of the other functions in this component. 00345 */ 00346 00347 void loadGeoids(); 00348 00349 /* 00350 * The function initializeEGM96Geoid reads geoid separation data 00351 * from the egm96.grd file in the current directory 00352 * and builds a geoid separation table from it. 00353 * If the separation file can not be found or accessed, 00354 * an error code of GEOID_FILE_OPEN_ERROR is returned, 00355 * If the separation file is incomplete or improperly formatted, 00356 * an error code of GEOID_INITIALIZE_ERROR is returned, 00357 * otherwise GEOID_NO_ERROR is returned. 00358 */ 00359 00360 void initializeEGM96Geoid(); 00361 00362 /* 00363 * The function initializeEGM84Geoid reads geoid separation data 00364 * from a file in the current directory and builds 00365 * the geoid separation table from it. 00366 * If the separation file can not be found or accessed, 00367 * an error code of GEOID_FILE_OPEN_ERROR is returned, 00368 * If the separation file is incomplete or improperly formatted, 00369 * an error code of GEOID_INITIALIZE_ERROR is returned, 00370 * otherwise GEOID_NO_ERROR is returned. 00371 */ 00372 00373 void initializeEGM84Geoid(); 00374 00375 /* 00376 * The function initializeEGM84ThirtyMinGeoid reads geoid 00377 * separation data from a file in the current directory and builds 00378 * the geoid separation table from it. 00379 * If the separation file can not be found or accessed, 00380 * an error code of GEOID_FILE_OPEN_ERROR is returned, 00381 * If the separation file is incomplete or improperly formatted, 00382 * an error code of GEOID_INITIALIZE_ERROR is returned, 00383 * otherwise GEOID_NO_ERROR is returned. 00384 */ 00385 00386 void initializeEGM84ThirtyMinGeoid(); 00387 00388 /* 00389 * The private function bilinearInterpolateDoubleHeights returns the 00390 * height of the WGS84 geoid above or below the WGS84 ellipsoid, 00391 * at the specified geodetic coordinates, 00392 * using a grid of height adjustments 00393 * and the bilinear interpolation method. 00394 * 00395 * longitude : Geodetic longitude in radians (input) 00396 * latitude : Geodetic latitude in radians (input) 00397 * scale_factor : Grid scale factor (input) 00398 * num_cols : Number of columns in grid (input) 00399 * num_rows : Number of rows in grid (input) 00400 * height_buffer : Grid of height adjustments, doubles (input) 00401 * delta_height : Height Adjustment, in meters. (output) 00402 * 00403 */ 00404 00405 void bilinearInterpolateDoubleHeights( 00406 double longitude, 00407 double latitude, 00408 double scale_factor, 00409 int num_cols, 00410 int num_rows, 00411 double *height_buffer, 00412 double *delta_height ); 00413 00414 /* 00415 * The private function bilinearInterpolate returns the height of 00416 * the WGS84 geoid above or below the WGS84 ellipsoid, at the 00417 * specified geodetic coordinates, using a grid of height 00418 * adjustments and the bilinear interpolation method. 00419 * 00420 * longitude : Geodetic longitude in radians (input) 00421 * latitude : Geodetic latitude in radians (input) 00422 * scale_factor : Grid scale factor (input) 00423 * num_cols : Number of columns in grid (input) 00424 * num_rows : Number of rows in grid (input) 00425 * height_buffer : Grid of height adjustments, floats (input) 00426 * delta_height : Height Adjustment, in meters. (output) 00427 * 00428 */ 00429 00430 void bilinearInterpolate( 00431 double longitude, 00432 double latitude, 00433 double scale_factor, 00434 int num_cols, 00435 int num_rows, 00436 float *height_buffer, 00437 double *delta_height ); 00438 00439 /* 00440 * The private function naturalSplineInterpolate returns the 00441 * height of the WGS84 geoid above or below the WGS84 ellipsoid, 00442 * at the specified geodetic coordinates, 00443 * using a grid of height adjustments 00444 * and the natural spline interpolation method. 00445 * 00446 * longitude : Geodetic longitude in radians (input) 00447 * latitude : Geodetic latitude in radians (input) 00448 * scale_factor : Grid scale factor (input) 00449 * num_cols : Number of columns in grid (input) 00450 * num_rows : Number of rows in grid (input) 00451 * height_buffer : Grid of height adjustments (input) 00452 * DeltaHeight : Height Adjustment, in meters. (output) 00453 * 00454 */ 00455 00456 void naturalSplineInterpolate( 00457 double longitude, 00458 double latitude, 00459 double scale_factor, 00460 int num_cols, 00461 int num_rows, 00462 int max_index, 00463 float *height_buffer, 00464 double *delta_height ); 00465 00466 /* 00467 * Delete the singleton. 00468 */ 00469 00470 static void deleteInstance(); 00471 }; 00472 } 00473 } 00474 00475 #endif 00476 00477 00478 // CLASSIFICATION: UNCLASSIFIED