00001 #pragma once 00002 /** 00003 * \file NETGeographicLib/GravityModel.h 00004 * \brief Header for NETGeographicLib::GravityModel class 00005 * 00006 * NETGeographicLib is copyright (c) Scott Heiman (2013) 00007 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 00008 * <charles@karney.com> and licensed under the MIT/X11 License. 00009 * For more information, see 00010 * http://geographiclib.sourceforge.net/ 00011 **********************************************************************/ 00012 00013 namespace NETGeographicLib 00014 { 00015 ref class GravityCircle; 00016 ref class NormalGravity; 00017 /** 00018 * \brief .NET wrapper for GeographicLib::GravityModel. 00019 * 00020 * This class allows .NET applications to access GeographicLib::GravityModel. 00021 * 00022 * Evaluate the earth's gravity field according to a model. The supported 00023 * models treat only the gravitational field exterior to the mass of the 00024 * earth. When computing the field at points near (but above) the surface of 00025 * the earth a small correction can be applied to account for the mass of the 00026 * atomsphere above the point in question; see \ref gravityatmos. 00027 * Determining the geoid height entails correcting for the mass of the earth 00028 * above the geoid. The egm96 and egm2008 include separate correction terms 00029 * to account for this mass. 00030 * 00031 * Definitions and terminology (from Heiskanen and Moritz, Sec 2-13): 00032 * - \e V = gravitational potential; 00033 * - Φ = rotational potential; 00034 * - \e W = \e V + Φ = \e T + \e U = total potential; 00035 * - <i>V</i><sub>0</sub> = normal gravitation potential; 00036 * - \e U = <i>V</i><sub>0</sub> + Φ = total normal potential; 00037 * - \e T = \e W − \e U = \e V − <i>V</i><sub>0</sub> = anomalous 00038 * or disturbing potential; 00039 * - <b>g</b> = ∇\e W = <b>γ</b> + <b>δ</b>; 00040 * - <b>f</b> = ∇Φ; 00041 * - <b>Γ</b> = ∇<i>V</i><sub>0</sub>; 00042 * - <b>γ</b> = ∇\e U; 00043 * - <b>δ</b> = ∇\e T = gravity disturbance vector 00044 * = <b>g</b><sub><i>P</i></sub> − <b>γ</b><sub><i>P</i></sub>; 00045 * - δ\e g = gravity disturbance = \e g<sub><i>P</i></sub> − 00046 * γ<sub><i>P</i></sub>; 00047 * - Δ<b>g</b> = gravity anomaly vector = <b>g</b><sub><i>P</i></sub> 00048 * − <b>γ</b><sub><i>Q</i></sub>; here the line \e PQ is 00049 * perpendicular to ellipsoid and the potential at \e P equals the normal 00050 * potential at \e Q; 00051 * - Δ\e g = gravity anomaly = \e g<sub><i>P</i></sub> − 00052 * γ<sub><i>Q</i></sub>; 00053 * - (ξ, η) deflection of the vertical, the difference in 00054 * directions of <b>g</b><sub><i>P</i></sub> and 00055 * <b>γ</b><sub><i>Q</i></sub>, ξ = NS, η = EW. 00056 * - \e X, \e Y, \e Z, geocentric coordinates; 00057 * - \e x, \e y, \e z, local cartesian coordinates used to denote the east, 00058 * north and up directions. 00059 * 00060 * See \ref gravity for details of how to install the gravity model and the 00061 * data format. 00062 * 00063 * References: 00064 * - W. A. Heiskanen and H. Moritz, Physical Geodesy (Freeman, San 00065 * Francisco, 1967). 00066 * 00067 * C# Example: 00068 * \include example-GravityModel.cs 00069 * Managed C++ Example: 00070 * \include example-GravityModel.cpp 00071 * Visual Basic Example: 00072 * \include example-GravityModel.vb 00073 * 00074 * <B>INTERFACE DIFFERENCES:</B><BR> 00075 * The following functions are implemented as properties: 00076 * Description, DateTime, GravityFile, GravityModelName, 00077 * GravityModelDirectory, MajorRadius, MassConstant, 00078 * ReferenceMassConstant, AngularVelocity, and Flattening. 00079 * 00080 * The Circle function accepts the "capabilities mask" as a 00081 * NETGeographicLib::GravityModel::Mask rather than an unsigned. 00082 **********************************************************************/ 00083 public ref class GravityModel 00084 { 00085 private: 00086 // pointer to the unmanaged GeographicLib::GravityModel. 00087 const GeographicLib::GravityModel* m_pGravityModel; 00088 00089 // the finalizer frees the unmanaged memory when the object is destroyed. 00090 !GravityModel(void); 00091 00092 enum class CapType { 00093 CAP_NONE = 0U, 00094 CAP_G = 1U<<0, // implies potentials W and V 00095 CAP_T = 1U<<1, 00096 CAP_DELTA = 1U<<2 | CapType::CAP_T, // delta implies T? 00097 CAP_C = 1U<<3, 00098 CAP_GAMMA0 = 1U<<4, 00099 CAP_GAMMA = 1U<<5, 00100 CAP_ALL = 0x3FU, 00101 }; 00102 00103 public: 00104 00105 /** 00106 * Bit masks for the capabilities to be given to the GravityCircle object 00107 * produced by Circle. 00108 **********************************************************************/ 00109 enum class Mask { 00110 /** 00111 * No capabilities. 00112 * @hideinitializer 00113 **********************************************************************/ 00114 NONE = 0U, 00115 /** 00116 * Allow calls to GravityCircle::Gravity, GravityCircle::W, and 00117 * GravityCircle::V. 00118 * @hideinitializer 00119 **********************************************************************/ 00120 GRAVITY = CapType::CAP_G, 00121 /** 00122 * Allow calls to GravityCircle::Disturbance and GravityCircle::T. 00123 * @hideinitializer 00124 **********************************************************************/ 00125 DISTURBANCE = CapType::CAP_DELTA, 00126 /** 00127 * Allow calls to GravityCircle::T(double lon) (i.e., computing the 00128 * disturbing potential and not the gravity disturbance vector). 00129 * @hideinitializer 00130 **********************************************************************/ 00131 DISTURBING_POTENTIAL = CapType::CAP_T, 00132 /** 00133 * Allow calls to GravityCircle::SphericalAnomaly. 00134 * @hideinitializer 00135 **********************************************************************/ 00136 SPHERICAL_ANOMALY = CapType::CAP_DELTA | CapType::CAP_GAMMA, 00137 /** 00138 * Allow calls to GravityCircle::GeoidHeight. 00139 * @hideinitializer 00140 **********************************************************************/ 00141 GEOID_HEIGHT = CapType::CAP_T | CapType::CAP_C | CapType::CAP_GAMMA0, 00142 /** 00143 * All capabilities. 00144 * @hideinitializer 00145 **********************************************************************/ 00146 ALL = CapType::CAP_ALL, 00147 }; 00148 /** \name Setting up the gravity model 00149 **********************************************************************/ 00150 ///@{ 00151 /** 00152 * Construct a gravity model. 00153 * 00154 * @param[in] name the name of the model. 00155 * @param[in] path (optional) directory for data file. 00156 * @exception GeographicErr if the data file cannot be found, is 00157 * unreadable, or is corrupt. 00158 * @exception std::bad_alloc if the memory necessary for storing the model 00159 * can't be allocated. 00160 * 00161 * A filename is formed by appending ".egm" (World Gravity Model) to the 00162 * name. If \e path is specified (and is non-empty), then the file is 00163 * loaded from directory, \e path. Otherwise the path is given by 00164 * DefaultGravityPath(). 00165 * 00166 * This file contains the metadata which specifies the properties of the 00167 * model. The coefficients for the spherical harmonic sums are obtained 00168 * from a file obtained by appending ".cof" to metadata file (so the 00169 * filename ends in ".egm.cof"). 00170 **********************************************************************/ 00171 GravityModel(System::String^ name, System::String^ path); 00172 ///@} 00173 00174 /** 00175 * The destructor calls the finalizer. 00176 **********************************************************************/ 00177 ~GravityModel() 00178 { this->!GravityModel(); } 00179 00180 /** \name Compute gravity in geodetic coordinates 00181 **********************************************************************/ 00182 ///@{ 00183 /** 00184 * Evaluate the gravity at an arbitrary point above (or below) the 00185 * ellipsoid. 00186 * 00187 * @param[in] lat the geographic latitude (degrees). 00188 * @param[in] lon the geographic longitude (degrees). 00189 * @param[in] h the height above the ellipsoid (meters). 00190 * @param[out] gx the easterly component of the acceleration 00191 * (m s<sup>−2</sup>). 00192 * @param[out] gy the northerly component of the acceleration 00193 * (m s<sup>−2</sup>). 00194 * @param[out] gz the upward component of the acceleration 00195 * (m s<sup>−2</sup>); this is usually negative. 00196 * @return \e W the sum of the gravitational and centrifugal potentials. 00197 * 00198 * The function includes the effects of the earth's rotation. 00199 **********************************************************************/ 00200 double Gravity(double lat, double lon, double h, 00201 [System::Runtime::InteropServices::Out] double% gx, 00202 [System::Runtime::InteropServices::Out] double% gy, 00203 [System::Runtime::InteropServices::Out] double% gz); 00204 00205 /** 00206 * Evaluate the gravity disturbance vector at an arbitrary point above (or 00207 * below) the ellipsoid. 00208 * 00209 * @param[in] lat the geographic latitude (degrees). 00210 * @param[in] lon the geographic longitude (degrees). 00211 * @param[in] h the height above the ellipsoid (meters). 00212 * @param[out] deltax the easterly component of the disturbance vector 00213 * (m s<sup>−2</sup>). 00214 * @param[out] deltay the northerly component of the disturbance vector 00215 * (m s<sup>−2</sup>). 00216 * @param[out] deltaz the upward component of the disturbance vector 00217 * (m s<sup>−2</sup>). 00218 * @return \e T the corresponding disturbing potential. 00219 **********************************************************************/ 00220 double Disturbance(double lat, double lon, double h, 00221 [System::Runtime::InteropServices::Out] double% deltax, 00222 [System::Runtime::InteropServices::Out] double% deltay, 00223 [System::Runtime::InteropServices::Out] double% deltaz); 00224 00225 /** 00226 * Evaluate the geoid height. 00227 * 00228 * @param[in] lat the geographic latitude (degrees). 00229 * @param[in] lon the geographic longitude (degrees). 00230 * @return \e N the height of the geoid above the ReferenceEllipsoid() 00231 * (meters). 00232 * 00233 * This calls NormalGravity::U for ReferenceEllipsoid(). Some 00234 * approximations are made in computing the geoid height so that the 00235 * results of the NGA codes are reproduced accurately. Details are given 00236 * in \ref gravitygeoid. 00237 **********************************************************************/ 00238 double GeoidHeight(double lat, double lon); 00239 00240 /** 00241 * Evaluate the components of the gravity anomaly vector using the 00242 * spherical approximation. 00243 * 00244 * @param[in] lat the geographic latitude (degrees). 00245 * @param[in] lon the geographic longitude (degrees). 00246 * @param[in] h the height above the ellipsoid (meters). 00247 * @param[out] Dg01 the gravity anomaly (m s<sup>−2</sup>). 00248 * @param[out] xi the northerly component of the deflection of the vertical 00249 * (degrees). 00250 * @param[out] eta the easterly component of the deflection of the vertical 00251 * (degrees). 00252 * 00253 * The spherical approximation (see Heiskanen and Moritz, Sec 2-14) is used 00254 * so that the results of the NGA codes are reproduced accurately. 00255 * approximations used here. Details are given in \ref gravitygeoid. 00256 **********************************************************************/ 00257 void SphericalAnomaly(double lat, double lon, double h, 00258 [System::Runtime::InteropServices::Out] double% Dg01, 00259 [System::Runtime::InteropServices::Out] double% xi, 00260 [System::Runtime::InteropServices::Out] double% eta); 00261 ///@} 00262 00263 /** \name Compute gravity in geocentric coordinates 00264 **********************************************************************/ 00265 ///@{ 00266 /** 00267 * Evaluate the components of the acceleration due to gravity and the 00268 * centrifugal acceleration in geocentric coordinates. 00269 * 00270 * @param[in] X geocentric coordinate of point (meters). 00271 * @param[in] Y geocentric coordinate of point (meters). 00272 * @param[in] Z geocentric coordinate of point (meters). 00273 * @param[out] gX the \e X component of the acceleration 00274 * (m s<sup>−2</sup>). 00275 * @param[out] gY the \e Y component of the acceleration 00276 * (m s<sup>−2</sup>). 00277 * @param[out] gZ the \e Z component of the acceleration 00278 * (m s<sup>−2</sup>). 00279 * @return \e W = \e V + Φ the sum of the gravitational and 00280 * centrifugal potentials (m<sup>2</sup> s<sup>−2</sup>). 00281 * 00282 * This calls NormalGravity::U for ReferenceEllipsoid(). 00283 **********************************************************************/ 00284 double W(double X, double Y, double Z, 00285 [System::Runtime::InteropServices::Out] double% gX, 00286 [System::Runtime::InteropServices::Out] double% gY, 00287 [System::Runtime::InteropServices::Out] double% gZ); 00288 00289 /** 00290 * Evaluate the components of the acceleration due to gravity in geocentric 00291 * coordinates. 00292 * 00293 * @param[in] X geocentric coordinate of point (meters). 00294 * @param[in] Y geocentric coordinate of point (meters). 00295 * @param[in] Z geocentric coordinate of point (meters). 00296 * @param[out] GX the \e X component of the acceleration 00297 * (m s<sup>−2</sup>). 00298 * @param[out] GY the \e Y component of the acceleration 00299 * (m s<sup>−2</sup>). 00300 * @param[out] GZ the \e Z component of the acceleration 00301 * (m s<sup>−2</sup>). 00302 * @return \e V = \e W - Φ the gravitational potential 00303 * (m<sup>2</sup> s<sup>−2</sup>). 00304 **********************************************************************/ 00305 double V(double X, double Y, double Z, 00306 [System::Runtime::InteropServices::Out] double% GX, 00307 [System::Runtime::InteropServices::Out] double% GY, 00308 [System::Runtime::InteropServices::Out] double% GZ); 00309 00310 /** 00311 * Evaluate the components of the gravity disturbance in geocentric 00312 * coordinates. 00313 * 00314 * @param[in] X geocentric coordinate of point (meters). 00315 * @param[in] Y geocentric coordinate of point (meters). 00316 * @param[in] Z geocentric coordinate of point (meters). 00317 * @param[out] deltaX the \e X component of the gravity disturbance 00318 * (m s<sup>−2</sup>). 00319 * @param[out] deltaY the \e Y component of the gravity disturbance 00320 * (m s<sup>−2</sup>). 00321 * @param[out] deltaZ the \e Z component of the gravity disturbance 00322 * (m s<sup>−2</sup>). 00323 * @return \e T = \e W - \e U the disturbing potential (also called the 00324 * anomalous potential) (m<sup>2</sup> s<sup>−2</sup>). 00325 **********************************************************************/ 00326 double T(double X, double Y, double Z, 00327 [System::Runtime::InteropServices::Out] double% deltaX, 00328 [System::Runtime::InteropServices::Out] double% deltaY, 00329 [System::Runtime::InteropServices::Out] double% deltaZ); 00330 00331 /** 00332 * Evaluate disturbing potential in geocentric coordinates. 00333 * 00334 * @param[in] X geocentric coordinate of point (meters). 00335 * @param[in] Y geocentric coordinate of point (meters). 00336 * @param[in] Z geocentric coordinate of point (meters). 00337 * @return \e T = \e W - \e U the disturbing potential (also called the 00338 * anomalous potential) (m<sup>2</sup> s<sup>−2</sup>). 00339 **********************************************************************/ 00340 double T(double X, double Y, double Z); 00341 00342 /** 00343 * Evaluate the components of the acceleration due to normal gravity and 00344 * the centrifugal acceleration in geocentric coordinates. 00345 * 00346 * @param[in] X geocentric coordinate of point (meters). 00347 * @param[in] Y geocentric coordinate of point (meters). 00348 * @param[in] Z geocentric coordinate of point (meters). 00349 * @param[out] gammaX the \e X component of the normal acceleration 00350 * (m s<sup>−2</sup>). 00351 * @param[out] gammaY the \e Y component of the normal acceleration 00352 * (m s<sup>−2</sup>). 00353 * @param[out] gammaZ the \e Z component of the normal acceleration 00354 * (m s<sup>−2</sup>). 00355 * @return \e U = <i>V</i><sub>0</sub> + Φ the sum of the 00356 * normal gravitational and centrifugal potentials 00357 * (m<sup>2</sup> s<sup>−2</sup>). 00358 * 00359 * This calls NormalGravity::U for ReferenceEllipsoid(). 00360 **********************************************************************/ 00361 double U(double X, double Y, double Z, 00362 [System::Runtime::InteropServices::Out] double% gammaX, 00363 [System::Runtime::InteropServices::Out] double% gammaY, 00364 [System::Runtime::InteropServices::Out] double% gammaZ); 00365 00366 /** 00367 * Evaluate the centrifugal acceleration in geocentric coordinates. 00368 * 00369 * @param[in] X geocentric coordinate of point (meters). 00370 * @param[in] Y geocentric coordinate of point (meters). 00371 * @param[out] fX the \e X component of the centrifugal acceleration 00372 * (m s<sup>−2</sup>). 00373 * @param[out] fY the \e Y component of the centrifugal acceleration 00374 * (m s<sup>−2</sup>). 00375 * @return Φ the centrifugal potential (m<sup>2</sup> 00376 * s<sup>−2</sup>). 00377 * 00378 * This calls NormalGravity::Phi for ReferenceEllipsoid(). 00379 **********************************************************************/ 00380 double Phi(double X, double Y, 00381 [System::Runtime::InteropServices::Out] double% fX, 00382 [System::Runtime::InteropServices::Out] double% fY); 00383 ///@} 00384 00385 /** \name Compute gravity on a circle of constant latitude 00386 **********************************************************************/ 00387 ///@{ 00388 /** 00389 * Create a GravityCircle object to allow the gravity field at many points 00390 * with constant \e lat and \e h and varying \e lon to be computed 00391 * efficiently. 00392 * 00393 * @param[in] lat latitude of the point (degrees). 00394 * @param[in] h the height of the point above the ellipsoid (meters). 00395 * @param[in] caps bitor'ed combination of GravityModel::mask values 00396 * specifying the capabilities of the resulting GravityCircle object. 00397 * @exception std::bad_alloc if the memory necessary for creating a 00398 * GravityCircle can't be allocated. 00399 * @return a GravityCircle object whose member functions computes the 00400 * gravitational field at a particular values of \e lon. 00401 * 00402 * The GravityModel::mask values are 00403 * - \e caps |= GravityModel::GRAVITY 00404 * - \e caps |= GravityModel::DISTURBANCE 00405 * - \e caps |= GravityModel::DISTURBING_POTENTIAL 00406 * - \e caps |= GravityModel::SPHERICAL_ANOMALY 00407 * - \e caps |= GravityModel::GEOID_HEIGHT 00408 * . 00409 * The default value of \e caps is GravityModel::ALL which turns on all the 00410 * capabilities. If an unsupported function is invoked, it will return 00411 * NaNs. Note that GravityModel::GEOID_HEIGHT will only be honored if \e h 00412 * = 0. 00413 * 00414 * If the field at several points on a circle of latitude need to be 00415 * calculated then creating a GravityCircle object and using its member 00416 * functions will be substantially faster, especially for high-degree 00417 * models. See \ref gravityparallel for an example of using GravityCircle 00418 * (together with OpenMP) to speed up the computation of geoid heights. 00419 **********************************************************************/ 00420 GravityCircle^ Circle(double lat, double h, Mask caps ); 00421 ///@} 00422 00423 /** \name Inspector functions 00424 **********************************************************************/ 00425 ///@{ 00426 00427 /** 00428 * @return the NormalGravity object for the reference ellipsoid. 00429 **********************************************************************/ 00430 NormalGravity^ ReferenceEllipsoid(); 00431 00432 /** 00433 * @return the description of the gravity model, if available, in the data 00434 * file; if absent, return "NONE". 00435 **********************************************************************/ 00436 property System::String^ Description { System::String^ get(); } 00437 00438 /** 00439 * @return date of the model; if absent, return "UNKNOWN". 00440 **********************************************************************/ 00441 property System::String^ DateTime { System::String^ get(); } 00442 00443 /** 00444 * @return full file name used to load the gravity model. 00445 **********************************************************************/ 00446 property System::String^ GravityFile { System::String^ get(); } 00447 00448 /** 00449 * @return "name" used to load the gravity model (from the first argument 00450 * of the constructor, but this may be overridden by the model file). 00451 **********************************************************************/ 00452 property System::String^ GravityModelName { System::String^ get(); } 00453 00454 /** 00455 * @return directory used to load the gravity model. 00456 **********************************************************************/ 00457 property System::String^ GravityModelDirectory 00458 { System::String^ get(); } 00459 00460 /** 00461 * @return \e a the equatorial radius of the ellipsoid (meters). 00462 **********************************************************************/ 00463 property double MajorRadius { double get(); } 00464 00465 /** 00466 * @return \e GM the mass constant of the model (m<sup>3</sup> 00467 * s<sup>−2</sup>); this is the product of \e G the gravitational 00468 * constant and \e M the mass of the earth (usually including the mass of 00469 * the earth's atmosphere). 00470 **********************************************************************/ 00471 property double MassConstant { double get(); } 00472 00473 /** 00474 * @return \e GM the mass constant of the ReferenceEllipsoid() 00475 * (m<sup>3</sup> s<sup>−2</sup>). 00476 **********************************************************************/ 00477 property double ReferenceMassConstant { double get(); } 00478 00479 /** 00480 * @return ω the angular velocity of the model and the 00481 * ReferenceEllipsoid() (rad s<sup>−1</sup>). 00482 **********************************************************************/ 00483 property double AngularVelocity { double get(); } 00484 00485 /** 00486 * @return \e f the flattening of the ellipsoid. 00487 **********************************************************************/ 00488 property double Flattening { double get(); } 00489 ///@} 00490 00491 /** 00492 * @return the default path for gravity model data files. 00493 * 00494 * This is the value of the environment variable GEOGRAPHICLIB_GRAVITY_PATH, if set; 00495 * otherwise, it is $GEOGRAPHICLIB_DATA/gravity if the environment variable 00496 * GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default 00497 * (/usr/local/share/GeographicLib/gravity on non-Windows systems and 00498 * C:/ProgramData/GeographicLib/gravity on Windows systems). 00499 **********************************************************************/ 00500 static System::String^ DefaultGravityPath(); 00501 00502 /** 00503 * @return the default name for the gravity model. 00504 * 00505 * This is the value of the environment variable GEOGRAPHICLIB_GRAVITY_NAME, if set, 00506 * otherwise, it is "egm96". The GravityModel class does not use 00507 * this function; it is just provided as a convenience for a calling 00508 * program when constructing a GravityModel object. 00509 **********************************************************************/ 00510 static System::String^ DefaultGravityName(); 00511 }; 00512 } //namespace NETGeographicLib