NETGeographicLib  1.38
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Pages
Geoid.h
Go to the documentation of this file.
1 #pragma once
2 /**
3  * \file NETGeographicLib/Geoid.h
4  * \brief Header for NETGeographicLib::Geoid class
5  *
6  * NETGeographicLib is copyright (c) Scott Heiman (2013)
7  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
8  * <charles@karney.com> and licensed under the MIT/X11 License.
9  * For more information, see
10  * http://geographiclib.sourceforge.net/
11  **********************************************************************/
12 
13 namespace NETGeographicLib
14 {
15  /**
16  * \brief .NET wrapper for GeographicLib::Geoid.
17  *
18  * This class allows .NET applications to access GeographicLib::Geoid.
19  *
20  * This class evaluated the height of one of the standard geoids, EGM84,
21  * EGM96, or EGM2008 by bilinear or cubic interpolation into a rectangular
22  * grid of data. These geoid models are documented in
23  * - EGM84:
24  * http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/wgs84_180.html
25  * - EGM96:
26  * http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/egm96.html
27  * - EGM2008:
28  * http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008
29  *
30  * The geoids are defined in terms of spherical harmonics. However in order
31  * to provide a quick and flexible method of evaluating the geoid heights,
32  * this class evaluates the height by interpolation into a grid of
33  * precomputed values.
34  *
35  * See \ref geoid for details of how to install the data sets, the data
36  * format, estimates of the interpolation errors, and how to use caching.
37  *
38  * In addition to returning the geoid height, the gradient of the geoid can
39  * be calculated. The gradient is defined as the rate of change of the geoid
40  * as a function of position on the ellipsoid. This uses the parameters for
41  * the WGS84 ellipsoid. The gradient defined in terms of the interpolated
42  * heights. As a result of the way that the geoid data is stored, the
43  * calculation of gradients can result in large quantization errors. This is
44  * particularly acute for fine grids, at high latitudes, and for the easterly
45  * gradient.
46  *
47  * This class is typically \e not thread safe in that a single instantiation
48  * cannot be safely used by multiple threads because of the way the object
49  * reads the data set and because it maintains a single-cell cache. If
50  * multiple threads need to calculate geoid heights they should all construct
51  * thread-local instantiations. Alternatively, set the optional \e
52  * threadsafe parameter to true in the constructor. This causes the
53  * constructor to read all the data into memory and to turn off the
54  * single-cell caching which results in a Geoid object which \e is thread
55  * safe.
56  *
57  * C# Example:
58  * \include example-Geoid.cs
59  * Managed C++ Example:
60  * \include example-Geoid.cpp
61  * Visual Basic Example:
62  * \include example-Geoid.vb
63  *
64  * <B>INTERFACE DIFFERENCES:</B><BR>
65  * The () operator has been replaced with Height method.
66  *
67  * The following functions are implemented as properties:
68  * Description, DateTime, GeoidFile, GeoidName, GeoidDirectory,
69  * Interpolation, MaxError, RMSError, Offset, Scale, ThreadSafe,
70  * Cache, CacheWest, CacheEast, CacheNorth, CacheSouth, MajorRadius,
71  * and Flattening.
72  **********************************************************************/
73  public ref class Geoid
74  {
75  private:
76  // a pointer to the unmanaged GeographicLib::Geoid.
77  const GeographicLib::Geoid* m_pGeoid;
78 
79  // the finalizer frees hthe unmanaged memory when the object is destroyed.
80  !Geoid(void);
81  public:
82  /**
83  * Flags indicating conversions between heights above the geoid and heights
84  * above the ellipsoid.
85  **********************************************************************/
86  enum class ConvertFlag {
87  /**
88  * The multiplier for converting from heights above the geoid to heights
89  * above the ellipsoid.
90  **********************************************************************/
91  ELLIPSOIDTOGEOID = -1,
92  /**
93  * No conversion.
94  **********************************************************************/
95  NONE = 0,
96  /**
97  * The multiplier for converting from heights above the ellipsoid to
98  * heights above the geoid.
99  **********************************************************************/
100  GEOIDTOELLIPSOID = 1,
101  };
102 
103  /** \name Setting up the geoid
104  **********************************************************************/
105  ///@{
106  /**
107  * Construct a geoid.
108  *
109  * @param[in] name the name of the geoid.
110  * @param[in] path (optional) directory for data file.
111  * @param[in] cubic (optional) interpolation method; false means bilinear,
112  * true (the default) means cubic.
113  * @param[in] threadsafe (optional), if true, construct a thread safe
114  * object. The default is false
115  * @exception GeographicErr if the data file cannot be found, is
116  * unreadable, or is corrupt.
117  * @exception GeographicErr if \e threadsafe is true but the memory
118  * necessary for caching the data can't be allocated.
119  *
120  * The data file is formed by appending ".pgm" to the name. If \e path is
121  * specified (and is non-empty), then the file is loaded from directory, \e
122  * path. Otherwise the path is given by DefaultGeoidPath(). If the \e
123  * threadsafe parameter is true, the data set is read into memory, the data
124  * file is closed, and single-cell caching is turned off; this results in a
125  * Geoid object which \e is thread safe.
126  **********************************************************************/
127  Geoid(System::String^ name, System::String^ path,
128  bool cubic, bool threadsafe);
129  /**
130  * The destructor calls the finalizer.
131  **********************************************************************/
133  { this->!Geoid(); }
134 
135  /**
136  * Set up a cache.
137  *
138  * @param[in] south latitude (degrees) of the south edge of the cached area.
139  * @param[in] west longitude (degrees) of the west edge of the cached area.
140  * @param[in] north latitude (degrees) of the north edge of the cached area.
141  * @param[in] east longitude (degrees) of the east edge of the cached area.
142  * @exception GeographicErr if the memory necessary for caching the data
143  * can't be allocated (in this case, you will have no cache and can try
144  * again with a smaller area).
145  * @exception GeographicErr if there's a problem reading the data.
146  * @exception GeographicErr if this is called on a threadsafe Geoid.
147  *
148  * Cache the data for the specified "rectangular" area bounded by the
149  * parallels \e south and \e north and the meridians \e west and \e east.
150  * \e east is always interpreted as being east of \e west, if necessary by
151  * adding 360&deg; to its value. \e south and \e north should be in
152  * the range [&minus;90&deg;, 90&deg;]; \e west and \e east should
153  * be in the range [&minus;540&deg;, 540&deg;).
154  **********************************************************************/
155  void CacheArea(double south, double west, double north, double east);
156 
157  /**
158  * Cache all the data.
159  *
160  * @exception GeographicErr if the memory necessary for caching the data
161  * can't be allocated (in this case, you will have no cache and can try
162  * again with a smaller area).
163  * @exception GeographicErr if there's a problem reading the data.
164  * @exception GeographicErr if this is called on a threadsafe Geoid.
165  *
166  * On most computers, this is fast for data sets with grid resolution of 5'
167  * or coarser. For a 1' grid, the required RAM is 450MB; a 2.5' grid needs
168  * 72MB; and a 5' grid needs 18MB.
169  **********************************************************************/
170  void CacheAll();
171 
172  /**
173  * Clear the cache. This never throws an error. (This does nothing with a
174  * thread safe Geoid.)
175  **********************************************************************/
176  void CacheClear();
177 
178  ///@}
179 
180  /** \name Compute geoid heights
181  **********************************************************************/
182  ///@{
183  /**
184  * Compute the geoid height at a point
185  *
186  * @param[in] lat latitude of the point (degrees).
187  * @param[in] lon longitude of the point (degrees).
188  * @exception GeographicErr if there's a problem reading the data; this
189  * never happens if (\e lat, \e lon) is within a successfully cached area.
190  * @return geoid height (meters).
191  *
192  * The latitude should be in [&minus;90&deg;, 90&deg;] and
193  * longitude should be in [&minus;540&deg;, 540&deg;).
194  **********************************************************************/
195  double Height(double lat, double lon);
196 
197  /**
198  * Compute the geoid height and gradient at a point
199  *
200  * @param[in] lat latitude of the point (degrees).
201  * @param[in] lon longitude of the point (degrees).
202  * @param[out] gradn northerly gradient (dimensionless).
203  * @param[out] grade easterly gradient (dimensionless).
204  * @exception GeographicErr if there's a problem reading the data; this
205  * never happens if (\e lat, \e lon) is within a successfully cached area.
206  * @return geoid height (meters).
207  *
208  * The latitude should be in [&minus;90&deg;, 90&deg;] and
209  * longitude should be in [&minus;540&deg;, 540&deg;). As a result
210  * of the way that the geoid data is stored, the calculation of gradients
211  * can result in large quantization errors. This is particularly acute for
212  * fine grids, at high latitudes, and for the easterly gradient. If you
213  * need to compute the direction of the acceleration due to gravity
214  * accurately, you should use GravityModel::Gravity.
215  **********************************************************************/
216  double Height(double lat, double lon,
217  [System::Runtime::InteropServices::Out] double% gradn,
218  [System::Runtime::InteropServices::Out] double% grade);
219 
220  /**
221  * Convert a height above the geoid to a height above the ellipsoid and
222  * vice versa.
223  *
224  * @param[in] lat latitude of the point (degrees).
225  * @param[in] lon longitude of the point (degrees).
226  * @param[in] h height of the point (degrees).
227  * @param[in] d a Geoid::convertflag specifying the direction of the
228  * conversion; Geoid::GEOIDTOELLIPSOID means convert a height above the
229  * geoid to a height above the ellipsoid; Geoid::ELLIPSOIDTOGEOID means
230  * convert a height above the ellipsoid to a height above the geoid.
231  * @exception GeographicErr if there's a problem reading the data; this
232  * never happens if (\e lat, \e lon) is within a successfully cached area.
233  * @return converted height (meters).
234  **********************************************************************/
235  double ConvertHeight(double lat, double lon, double h,
236  ConvertFlag d);
237 
238  ///@}
239 
240  /** \name Inspector functions
241  **********************************************************************/
242  ///@{
243  /**
244  * @return geoid description, if available, in the data file; if
245  * absent, return "NONE".
246  **********************************************************************/
247  property System::String^ Description { System::String^ get(); }
248 
249  /**
250  * @return date of the data file; if absent, return "UNKNOWN".
251  **********************************************************************/
252  property System::String^ DateTime { System::String^ get(); }
253 
254  /**
255  * @return full file name used to load the geoid data.
256  **********************************************************************/
257  property System::String^ GeoidFile { System::String^ get(); }
258 
259  /**
260  * @return "name" used to load the geoid data (from the first argument of
261  * the constructor).
262  **********************************************************************/
263  property System::String^ GeoidName { System::String^ get(); }
264 
265  /**
266  * @return directory used to load the geoid data.
267  **********************************************************************/
268  property System::String^ GeoidDirectory { System::String^ get(); }
269 
270  /**
271  * @return interpolation method ("cubic" or "bilinear").
272  **********************************************************************/
273  property System::String^ Interpolation { System::String^ get(); }
274 
275  /**
276  * @return estimate of the maximum interpolation and quantization error
277  * (meters).
278  *
279  * This relies on the value being stored in the data file. If the value is
280  * absent, return &minus;1.
281  **********************************************************************/
282  property double MaxError { double get(); }
283 
284  /**
285  * @return estimate of the RMS interpolation and quantization error
286  * (meters).
287  *
288  * This relies on the value being stored in the data file. If the value is
289  * absent, return &minus;1.
290  **********************************************************************/
291  property double RMSError { double get(); }
292 
293  /**
294  * @return offset (meters).
295  *
296  * This in used in converting from the pixel values in the data file to
297  * geoid heights.
298  **********************************************************************/
299  property double Offset { double get(); }
300 
301  /**
302  * @return scale (meters).
303  *
304  * This in used in converting from the pixel values in the data file to
305  * geoid heights.
306  **********************************************************************/
307  property double Scale { double get(); }
308 
309  /**
310  * @return true if the object is constructed to be thread safe.
311  **********************************************************************/
312  property bool ThreadSafe { bool get(); }
313 
314  /**
315  * @return true if a data cache is active.
316  **********************************************************************/
317  property bool Cache { bool get(); }
318 
319  /**
320  * @return west edge of the cached area; the cache includes this edge.
321  **********************************************************************/
322  property double CacheWest { double get(); }
323 
324  /**
325  * @return east edge of the cached area; the cache excludes this edge.
326  **********************************************************************/
327  property double CacheEast { double get(); }
328 
329  /**
330  * @return north edge of the cached area; the cache includes this edge.
331  **********************************************************************/
332  property double CacheNorth { double get(); }
333 
334  /**
335  * @return south edge of the cached area; the cache excludes this edge
336  * unless it's the south pole.
337  **********************************************************************/
338  property double CacheSouth { double get(); }
339 
340  /**
341  * @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
342  *
343  * (The WGS84 value is returned because the supported geoid models are all
344  * based on this ellipsoid.)
345  **********************************************************************/
346  property double MajorRadius { double get(); }
347 
348  /**
349  * @return \e f the flattening of the WGS84 ellipsoid.
350  *
351  * (The WGS84 value is returned because the supported geoid models are all
352  * based on this ellipsoid.)
353  **********************************************************************/
354  property double Flattening { double get(); }
355  ///@}
356 
357  /**
358  * @return the default path for geoid data files.
359  *
360  * This is the value of the environment variable
361  * GEOGRAPHICLIB_GEOID_PATH, if set; otherwise, it is
362  * $GEOGRAPHICLIB_DATA/geoids if the environment variable
363  * GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default
364  * (/usr/local/share/GeographicLib/geoids on non-Windows systems and
365  * C:/ProgramData/GeographicLib/geoids on Windows systems).
366  **********************************************************************/
367  static System::String^ DefaultGeoidPath();
368 
369  /**
370  * @return the default name for the geoid.
371  *
372  * This is the value of the environment variable
373  * GEOGRAPHICLIB_GEOID_NAME, if set, otherwise, it is "egm96-5". The
374  * Geoid class does not use this function; it is just provided as a
375  * convenience for a calling program when constructing a Geoid object.
376  **********************************************************************/
377  static System::String^ DefaultGeoidName();
378  };
379 } // namespace NETGeographicLib
System::String^ GeoidDirectory
Definition: Geoid.h:268
void CacheArea(double south, double west, double north, double east)
System::String^ DateTime
Definition: Geoid.h:252
System::String^ GeoidName
Definition: Geoid.h:263
Geoid(System::String^ name, System::String^ path, bool cubic, bool threadsafe)
static System::String^ DefaultGeoidPath()
System::String^ Interpolation
Definition: Geoid.h:273
static System::String^ DefaultGeoidName()
double ConvertHeight(double lat, double lon, double h, ConvertFlag d)
System::String^ GeoidFile
Definition: Geoid.h:257
System::String^ Description
Definition: Geoid.h:247
double Height(double lat, double lon)
.NET wrapper for GeographicLib::Geoid.
Definition: Geoid.h:73