00001 00003 // // 00004 // UNCLASSIFIED UNCLASSIFIED UNCLASSIFIED UNCLASSIFIED // 00005 // // 00006 // Description of this module: // 00007 // // 00008 // Utility software that interpolates EGM 2008 // 00009 // geoid heights from one of NGA's geoid height grids. // 00010 // // 00011 // This base class supports two geoid height interpolators: // 00012 // // 00013 // 1) the first one reads the entire worldwide EGM2008 grid // 00014 // before interpolating any geoid heights from the worldwide grid; // 00015 // 2) the second one does not read geoid height data from // 00016 // file until a user requests that a geoid height be computed; // 00017 // the 2nd interpolator then reads an Area of Interest // 00018 // (AOI) grid from file before interpolating from the AOI grid; // 00019 // the Area of Interest grid is refreshed, if needed, // 00020 // when users submit subsequent geoid height requests. // 00021 // // 00022 // Revision History: // 00023 // Date Name Description // 00024 // ----------- ------------ ----------------------------------------------// 00025 // 19 Nov 2010 RD Craig Release // 00026 // 11 Feg 2011 RD Craig Upgrades following code review // 00027 // // 00029 00030 #ifndef EGM2008_GEOID_GRID_H 00031 #define EGM2008_GEOID_GRID_H 00032 00033 // This file declares a base C++ class 00034 // that supports geoid height interpolation 00035 // from one of NGA's EGM 2008 geoid height files. 00036 00037 // EGM2008_GEOID_GRID IS A PURE VIRTUAL CLASS. 00038 00039 // Note: Following common usage, this class uses the term 00040 // "geoid height" to mean heights of the geoid above or 00041 // below the earth ellipsoid. The GeoidLibrary class confuses 00042 // the term "geoid height" with height of a point above or below 00043 // the geoid: these heights are properly called "orthometric heights". 00044 00045 #include <string> 00046 00047 #include "CCSThreadMutex.h" 00048 00049 namespace MSP 00050 { 00051 00052 class Egm2008GeoidGrid { 00053 00054 protected: 00055 00056 // MAX_WSIZE: The maximum number of rows and 00057 // columns in a local interpolation window. 00058 00059 int MAX_WSIZE; 00060 00061 // gridFname: A string containing 00062 // the file name for one of 00063 // NGA's reformatted geoid height grids. 00064 00065 std::string _gridFname; 00066 00067 // nGridPad: The number of grid cells added to 00068 // the left, right, top, and bottom sides 00069 // of the worldwide EGM2008 geoid height grid; 00070 // interpolation window size is related to _nGridPad; 00071 // an ExE grid, where E is an even number, requires at 00072 // least _nGridPad = int( E - 2 ) / 2 ) rows/cols of pad; 00073 // an OxO grid, where O is an odd number, requires at 00074 // least _nGridPad = int( O / 2 ) rows/cols of pad on each edge. 00075 00076 int _nGridPad; 00077 00078 // nGridRows: The number of latitude rows contained in 00079 // the padded, memory-resident world-wide grid. 00080 00081 int _nGridRows; 00082 00083 // nGridCols: The number of longitude entries per 00084 // row in the padded, memory-resident grid. 00085 00086 int _nGridCols; 00087 00088 // nOrigRows: The number of latitude rows 00089 // contained in the world-wide grid file. 00090 00091 int _nOrigRows; 00092 00093 // nOrigCols: The number of longitude entries per 00094 // latitude row in the world-wide grid file. 00095 00096 int _nOrigCols; 00097 00098 // baseLatitude: The padded grid's base latitude 00099 // (radians); baseLatitude will be less than 00100 // -PI/2 radians for the world-wide EGM 2008 grid. 00101 00102 double _baseLatitude; 00103 00104 // baseLongitude: The padded grid's base longitude 00105 // (radians); baseLongitude will be less than 00106 // zero radians for the world-wide EGM 2008 grid. 00107 00108 double _baseLongitude; 00109 00110 // dLat: Grid's latitude spacing (radians). 00111 00112 double _dLat; 00113 00114 // dLon: Grid's longitude spacing (radians). 00115 00116 double _dLon; 00117 00118 // mutex: A CCSThreadMutex object used to ensure thread safety. 00119 00120 MSP::CCSThreadMutex _mutex; 00121 00122 public: 00123 00124 // Basic functions ..... 00125 00126 Egm2008GeoidGrid ( void ); 00127 00128 Egm2008GeoidGrid( const Egm2008GeoidGrid& oldGrid ); 00129 00130 virtual 00131 ~Egm2008GeoidGrid( void ); 00132 00133 Egm2008GeoidGrid& 00134 operator = ( const Egm2008GeoidGrid& oldGrid ); 00135 00136 // User functions ..... 00137 00138 /* 00139 * Public function geoidHeight implements 00140 * a bicubic spline geoid separation interpolator. 00141 * 00142 * wSize : Number of rows (= # columns) ( input ) 00143 * in the local interpolation window; 00144 * the function supports 2 <= wSize <= 20, 00145 * but EGM 2008 interpolations use wSize = 6. 00146 * latitude : Geodetic latitude ( input - radians ) 00147 * longitude : Geodetic longitude ( input - radians ) 00148 * gHeight : Geoid height ( output - meters ) 00149 * 00150 * return value : The function's error flag; 00151 * errors = 0 ..... no errors encountered, 00152 * errors = 1 ..... at least one error encountered. 00153 * 00154 */ 00155 00156 virtual int 00157 geoidHeight( 00158 int wSize, // input 00159 double latitude, // input 00160 double longitude, // input 00161 double& gHeight ) = 0; // output 00162 00163 protected: 00164 00165 /* 00166 * Protected function geoidHeight 00167 * implements a bilinear geoid separation interpolator. 00168 * Exercise this function when the requested interpolation 00169 * window size is too small to support bicubic spline interpolation. 00170 * 00171 * latitude : Geodetic latitude ( input - radians ) 00172 * longitude : Geodetic longitude ( input - radians ) 00173 * gHeight : Geoid height ( output - meters ) 00174 * 00175 * return value : The function's error flag; 00176 * errors = 0 ..... no errors encountered, 00177 * errors = 1 ..... at least one error encountered. 00178 */ 00179 00180 virtual int 00181 geoidHeight( 00182 double latitude, // input 00183 double longitude, // input 00184 double& gHeight ) = 0; // output 00185 00186 /* 00187 * Protected function loadGridCoords finds 00188 * horizontal coordinates corresponding to 00189 * grid row and column indices. The indices must 00190 * be referenced to the worldwide geoid height grid. 00191 * 00192 * i : An index to a worldwide grid ( input ) 00193 * intersection's row of interest. 00194 * j : An index to a worldwide grid ( input ) 00195 * intersection's column of interest. 00196 * latitude : Geodetic latitude ( output - radians ) 00197 * longitude : Geodetic longitude ( output - radians ) 00198 * 00199 * return value : The function's error flag; 00200 * errors = 0 ..... no errors encountered, 00201 * errors = 1 ..... at least one error encountered. 00202 */ 00203 00204 int 00205 loadGridCoords( 00206 int i, // input 00207 int j, // input 00208 double& latitude, // output 00209 double& longitude ); // output 00210 00211 /* 00212 * Protected function initSpline computes the 00213 * geoid separation posts' 2nd derivatives. This 00214 * function assumes the posts are arranged in a row, 00215 * it assumes the posts are equally spaced, and it also 00216 * assumes the spline's 2nd derivatives are zero at the endpoints. 00217 * The computed 2nd derivatives support the 1D spline interpolator. 00218 * 00219 * n : Number of geoid height posts for ( input ) 00220 * which 2nd derivatives are computed. 00221 * posts[] : An array containing ( input ) 00222 * geoid height posts' ordinates. 00223 * moments[] : An array containing geoid 00224 * height posts' 2nd derivatives. ( output ) 00225 * 00226 * return value : The function's error flag; 00227 * errors = 0 ..... no errors encountered, 00228 * errors = 1 ..... at least one error encountered. 00229 */ 00230 00231 int 00232 initSpline( 00233 int n, // input 00234 const double posts[], // input 00235 double moments[] ); // output 00236 00237 /* 00238 * Protected function spline implements a 00239 * low-level one-dimensional spline interpolator. 00240 * 00241 * n : Number of geoid height posts for ( input ) 00242 * which 2nd derivatives are computed. 00243 * x : Abscissa at which ( input ) 00244 * interpolation is to occur; 00245 * x is measured in grid intervals, 00246 * and it is measured relative to the 00247 * first geoid separation post's position. 00248 * posts[] : An array containing ( input ) 00249 * geoid separation posts' ordinates. 00250 * moments[] : An array containing geoid 00251 * separation posts' 2nd derivatives.( input ) 00252 * 00253 * return value : The interpolated geoid height ( meters ). 00254 */ 00255 00256 double 00257 spline( 00258 int n, // input 00259 double x, // input 00260 const double posts[], // input 00261 const double moments[] ); // input 00262 00263 /* 00264 * Protected function swapBytes swaps 00265 * bytes when transforming binary numbers 00266 * between BIG-ENDIAN and LITTLE-ENDIAN formats. 00267 * 00268 * buffer : Pointer to binary data item(s) ( input & output ) 00269 * size : Size of each binary number ( input - bytes ) 00270 * count : Number of binary numbers ( input ) 00271 */ 00272 00273 void 00274 swapBytes( 00275 void* buffer, // input & output 00276 size_t size, // input 00277 size_t count ); // input 00278 00279 /* 00280 * Protected function swGridIndices computes 00281 * grid row & column indices for the intersection 00282 * immediately to the SOUTHWEST of the input point. 00283 * The indices refer to the worldwide geoid height grid. 00284 * 00285 * latitude : Geodetic latitude ( input - radians ) 00286 * longitude : Geodetic longitude ( input - radians ) 00287 * i : Row number for the ( output ) 00288 * worldwide grid intersection 00289 * Southwest of the point of interest. 00290 * j : Column number for the ( output ) 00291 * worldwide grid intersection 00292 * Southwest of the point of interest. 00293 * 00294 * return value : The function's error flag; 00295 * errors = 0 ..... no errors encountered, 00296 * errors = 1 ..... at least one error encountered. 00297 */ 00298 00299 int 00300 swGridIndices( 00301 double latitude, // input 00302 double longitude, // input 00303 int& i, // output 00304 int& j ); // output 00305 00306 }; // End of Egm2008GeoidGrid class declaration 00307 00308 } // End of namespace block 00309 00310 #endif 00311 00313 // UNCLASSIFIED UNCLASSIFIED UNCLASSIFIED UNCLASSIFIED // 00315