NETGeographicLib  1.38
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Pages
GeodesicLine.h
Go to the documentation of this file.
1 #pragma once
2 /**
3  * \file NETGeographicLib/GeodesicLine.h
4  * \brief Header for NETGeographicLib::GeodesicLine 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 #include "NETGeographicLib.h"
13 
14 namespace NETGeographicLib
15 {
16  /**
17  * \brief .NET wrapper for GeographicLib::GeodesicLine.
18  *
19  * This class allows .NET applications to access GeographicLib::GeodesicLine.
20  *
21  * GeodesicLine facilitates the determination of a series of points on a
22  * single geodesic. The starting point (\e lat1, \e lon1) and the azimuth \e
23  * azi1 are specified in the constructor. GeodesicLine.Position returns the
24  * location of point 2 a distance \e s12 along the geodesic. Alternatively
25  * GeodesicLine.ArcPosition gives the position of point 2 an arc length \e
26  * a12 along the geodesic.
27  *
28  * The default copy constructor and assignment operators work with this
29  * class. Similarly, a vector can be used to hold GeodesicLine objects.
30  *
31  * The calculations are accurate to better than 15 nm (15 nanometers). See
32  * Sec. 9 of
33  * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for
34  * details. The algorithms used by this class are based on series expansions
35  * using the flattening \e f as a small parameter. These are only accurate
36  * for |<i>f</i>| &lt; 0.02; however reasonably accurate results will be
37  * obtained for |<i>f</i>| &lt; 0.2. For very eccentric ellipsoids, use
38  * GeodesicLineExact instead.
39  *
40  * The algorithms are described in
41  * - C. F. F. Karney,
42  * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
43  * Algorithms for geodesics</a>,
44  * J. Geodesy <b>87</b>, 43--55 (2013);
45  * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
46  * 10.1007/s00190-012-0578-z</a>;
47  * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html">
48  * geod-addenda.html</a>.
49  * .
50  * For more information on geodesics see \ref geodesic.
51  *
52  * C# Example:
53  * \include example-GeodesicLine.cs
54  * Managed C++ Example:
55  * \include example-GeodesicLine.cpp
56  * Visual Basic Example:
57  * \include example-GeodesicLine.vb
58  *
59  * <B>INTERFACE DIFFERENCES:</B><BR>
60  * A constructor has been provided which assumes WGS84 parameters.
61  *
62  * The following functions are implemented as properties:
63  * Latitude, Longitude, Azimuth, EquatorialAzimuth, EquatorialArc,
64  * MajorRadius, and Flattening.
65  *
66  * The constructors, Capabilities, and GenPosition functions accept the
67  * "capabilities mask" as a NETGeographicLib::Mask rather than an
68  * unsigned. The Capabilities function returns a NETGeographicLib::Mask
69  * rather than an unsigned.
70  **********************************************************************/
71  public ref class GeodesicLine
72  {
73  private:
74  // pointer to the unmanaged GeographicLib::GeodesicLine.
75  const GeographicLib::GeodesicLine* m_pGeodesicLine;
76 
77  // The finalizer frees the unmanaged memory when this object is destroyed.
78  !GeodesicLine(void);
79  public:
80  /** \name Constructors
81  **********************************************************************/
82  ///@{
83 
84  /**
85  * Constructor for a geodesic line staring at latitude \e lat1, longitude
86  * \e lon1, and azimuth \e azi1 (all in degrees).
87  *
88  * @param[in] g A Geodesic object used to compute the necessary information
89  * about the GeodesicLine.
90  * @param[in] lat1 latitude of point 1 (degrees).
91  * @param[in] lon1 longitude of point 1 (degrees).
92  * @param[in] azi1 azimuth at point 1 (degrees).
93  * @param[in] caps bitor'ed combination of NETGeographicLib::Mask values
94  * specifying the capabilities the GeodesicLine object should possess,
95  * i.e., which quantities can be returned in calls to
96  * GeodesicLine::Position.
97  *
98  * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 and \e
99  * azi1 should be in the range [&minus;540&deg;, 540&deg;).
100  *
101  * The NETGeographicLib::Mask values are
102  * - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this is
103  * added automatically;
104  * - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2;
105  * - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is
106  * added automatically;
107  * - \e caps |= GeodesicLine::DISTANCE for the distance \e s12;
108  * - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m12;
109  * - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12
110  * and \e M21;
111  * - \e caps |= GeodesicLine::AREA for the area \e S12;
112  * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the
113  * geodesic to be given in terms of \e s12; without this capability the
114  * length can only be specified in terms of arc length;
115  * - \e caps |= GeodesicLine::ALL for all of the above.
116  * .
117  * The default value of \e caps is GeodesicLine::ALL.
118  *
119  * If the point is at a pole, the azimuth is defined by keeping \e lon1
120  * fixed, writing \e lat1 = &plusmn;(90&deg; &minus; &epsilon;), and taking
121  * the limit &epsilon; &rarr; 0+.
122  **********************************************************************/
123  GeodesicLine( Geodesic^ g, double lat1, double lon1, double azi1,
124  NETGeographicLib::Mask caps );
125 
126  /**
127  * A constructor which assumes the WGS84 ellipsoid.
128  **********************************************************************/
129  GeodesicLine(double lat1, double lon1, double azi1,
131  ///@}
132 
133  /**
134  * The destructor calls the finalizer.
135  **********************************************************************/
137  { this->!GeodesicLine(); }
138 
139  /** \name Position in terms of distance
140  **********************************************************************/
141  ///@{
142 
143  /**
144  * Compute the position of point 2 which is a distance \e s12 (meters) from
145  * point 1.
146  *
147  * @param[in] s12 distance between point 1 and point 2 (meters); it can be
148  * negative.
149  * @param[out] lat2 latitude of point 2 (degrees).
150  * @param[out] lon2 longitude of point 2 (degrees); requires that the
151  * GeodesicLine object was constructed with \e caps |=
152  * GeodesicLine::LONGITUDE.
153  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
154  * @param[out] m12 reduced length of geodesic (meters); requires that the
155  * GeodesicLine object was constructed with \e caps |=
156  * GeodesicLine::REDUCEDLENGTH.
157  * @param[out] M12 geodesic scale of point 2 relative to point 1
158  * (dimensionless); requires that the GeodesicLine object was constructed
159  * with \e caps |= GeodesicLine::GEODESICSCALE.
160  * @param[out] M21 geodesic scale of point 1 relative to point 2
161  * (dimensionless); requires that the GeodesicLine object was constructed
162  * with \e caps |= GeodesicLine::GEODESICSCALE.
163  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
164  * that the GeodesicLine object was constructed with \e caps |=
165  * GeodesicLine::AREA.
166  * @return \e a12 arc length of between point 1 and point 2 (degrees).
167  *
168  * The values of \e lon2 and \e azi2 returned are in the range
169  * [&minus;180&deg;, 180&deg;).
170  *
171  * The GeodesicLine object \e must have been constructed with \e caps |=
172  * GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no
173  * parameters are set. Requesting a value which the GeodesicLine object is
174  * not capable of computing is not an error; the corresponding argument
175  * will not be altered.
176  *
177  * The following functions are overloaded versions of
178  * GeodesicLine::Position which omit some of the output parameters. Note,
179  * however, that the arc length is always computed and returned as the
180  * function value.
181  **********************************************************************/
182  double Position(double s12,
183  [System::Runtime::InteropServices::Out] double% lat2,
184  [System::Runtime::InteropServices::Out] double% lon2,
185  [System::Runtime::InteropServices::Out] double% azi2,
186  [System::Runtime::InteropServices::Out] double% m12,
187  [System::Runtime::InteropServices::Out] double% M12,
188  [System::Runtime::InteropServices::Out] double% M21,
189  [System::Runtime::InteropServices::Out] double% S12);
190 
191  /**
192  * See the documentation for GeodesicLine::Position.
193  **********************************************************************/
194  double Position(double s12,
195  [System::Runtime::InteropServices::Out] double% lat2,
196  [System::Runtime::InteropServices::Out] double% lon2);
197 
198  /**
199  * See the documentation for GeodesicLine::Position.
200  **********************************************************************/
201  double Position(double s12,
202  [System::Runtime::InteropServices::Out] double% lat2,
203  [System::Runtime::InteropServices::Out] double% lon2,
204  [System::Runtime::InteropServices::Out] double% azi2);
205 
206  /**
207  * See the documentation for GeodesicLine::Position.
208  **********************************************************************/
209  double Position(double s12,
210  [System::Runtime::InteropServices::Out] double% lat2,
211  [System::Runtime::InteropServices::Out] double% lon2,
212  [System::Runtime::InteropServices::Out] double% azi2,
213  [System::Runtime::InteropServices::Out] double% m12);
214 
215  /**
216  * See the documentation for GeodesicLine::Position.
217  **********************************************************************/
218  double Position(double s12,
219  [System::Runtime::InteropServices::Out] double% lat2,
220  [System::Runtime::InteropServices::Out] double% lon2,
221  [System::Runtime::InteropServices::Out] double% azi2,
222  [System::Runtime::InteropServices::Out] double% M12,
223  [System::Runtime::InteropServices::Out] double% M21);
224 
225  /**
226  * See the documentation for GeodesicLine::Position.
227  **********************************************************************/
228  double Position(double s12,
229  [System::Runtime::InteropServices::Out] double% lat2,
230  [System::Runtime::InteropServices::Out] double% lon2,
231  [System::Runtime::InteropServices::Out] double% azi2,
232  [System::Runtime::InteropServices::Out] double% m12,
233  [System::Runtime::InteropServices::Out] double% M12,
234  [System::Runtime::InteropServices::Out] double% M21);
235 
236  ///@}
237 
238  /** \name Position in terms of arc length
239  **********************************************************************/
240  ///@{
241 
242  /**
243  * Compute the position of point 2 which is an arc length \e a12 (degrees)
244  * from point 1.
245  *
246  * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
247  * be negative.
248  * @param[out] lat2 latitude of point 2 (degrees).
249  * @param[out] lon2 longitude of point 2 (degrees); requires that the
250  * GeodesicLine object was constructed with \e caps |=
251  * NETGeographicLib::Mask::LONGITUDE.
252  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
253  * @param[out] s12 distance between point 1 and point 2 (meters); requires
254  * that the GeodesicLine object was constructed with \e caps |=
255  * NETGeographicLib::Mask::DISTANCE.
256  * @param[out] m12 reduced length of geodesic (meters); requires that the
257  * GeodesicLine object was constructed with \e caps |=
258  * NETGeographicLib::Mask::REDUCEDLENGTH.
259  * @param[out] M12 geodesic scale of point 2 relative to point 1
260  * (dimensionless); requires that the GeodesicLine object was constructed
261  * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE.
262  * @param[out] M21 geodesic scale of point 1 relative to point 2
263  * (dimensionless); requires that the GeodesicLine object was constructed
264  * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE.
265  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
266  * that the GeodesicLine object was constructed with \e caps |=
267  * NETGeographicLib::Mask::AREA.
268  *
269  * The values of \e lon2 and \e azi2 returned are in the range
270  * [&minus;180&deg;, 180&deg;).
271  *
272  * Requesting a value which the GeodesicLine object is not capable of
273  * computing is not an error; the corresponding argument will not be
274  * altered.
275  *
276  * The following functions are overloaded versions of
277  * GeodesicLine::ArcPosition which omit some of the output parameters.
278  **********************************************************************/
279  void ArcPosition(double a12,
280  [System::Runtime::InteropServices::Out] double% lat2,
281  [System::Runtime::InteropServices::Out] double% lon2,
282  [System::Runtime::InteropServices::Out] double% azi2,
283  [System::Runtime::InteropServices::Out] double% s12,
284  [System::Runtime::InteropServices::Out] double% m12,
285  [System::Runtime::InteropServices::Out] double% M12,
286  [System::Runtime::InteropServices::Out] double% M21,
287  [System::Runtime::InteropServices::Out] double% S12);
288 
289  /**
290  * See the documentation for GeodesicLine::ArcPosition.
291  **********************************************************************/
292  void ArcPosition(double a12,
293  [System::Runtime::InteropServices::Out] double% lat2,
294  [System::Runtime::InteropServices::Out] double% lon2);
295 
296  /**
297  * See the documentation for GeodesicLine::ArcPosition.
298  **********************************************************************/
299  void ArcPosition(double a12,
300  [System::Runtime::InteropServices::Out] double% lat2,
301  [System::Runtime::InteropServices::Out] double% lon2,
302  [System::Runtime::InteropServices::Out] double% azi2);
303 
304  /**
305  * See the documentation for GeodesicLine::ArcPosition.
306  **********************************************************************/
307  void ArcPosition(double a12,
308  [System::Runtime::InteropServices::Out] double% lat2,
309  [System::Runtime::InteropServices::Out] double% lon2,
310  [System::Runtime::InteropServices::Out] double% azi2,
311  [System::Runtime::InteropServices::Out] double% s12);
312 
313  /**
314  * See the documentation for GeodesicLine::ArcPosition.
315  **********************************************************************/
316  void ArcPosition(double a12,
317  [System::Runtime::InteropServices::Out] double% lat2,
318  [System::Runtime::InteropServices::Out] double% lon2,
319  [System::Runtime::InteropServices::Out] double% azi2,
320  [System::Runtime::InteropServices::Out] double% s12,
321  [System::Runtime::InteropServices::Out] double% m12);
322 
323  /**
324  * See the documentation for GeodesicLine::ArcPosition.
325  **********************************************************************/
326  void ArcPosition(double a12,
327  [System::Runtime::InteropServices::Out] double% lat2,
328  [System::Runtime::InteropServices::Out] double% lon2,
329  [System::Runtime::InteropServices::Out] double% azi2,
330  [System::Runtime::InteropServices::Out] double% s12,
331  [System::Runtime::InteropServices::Out] double% M12,
332  [System::Runtime::InteropServices::Out] double% M21);
333 
334  /**
335  * See the documentation for GeodesicLine::ArcPosition.
336  **********************************************************************/
337  void ArcPosition(double a12,
338  [System::Runtime::InteropServices::Out] double% lat2,
339  [System::Runtime::InteropServices::Out] double% lon2,
340  [System::Runtime::InteropServices::Out] double% azi2,
341  [System::Runtime::InteropServices::Out] double% s12,
342  [System::Runtime::InteropServices::Out] double% m12,
343  [System::Runtime::InteropServices::Out] double% M12,
344  [System::Runtime::InteropServices::Out] double% M21);
345  ///@}
346 
347  /** \name The general position function.
348  **********************************************************************/
349  ///@{
350 
351  /**
352  * The general position function. GeodesicLine::Position and
353  * GeodesicLine::ArcPosition are defined in terms of this function.
354  *
355  * @param[in] arcmode boolean flag determining the meaning of the second
356  * parameter; if arcmode is false, then the GeodesicLine object must have
357  * been constructed with \e caps |= GeodesicLine::DISTANCE_IN.
358  * @param[in] s12_a12 if \e arcmode is false, this is the distance between
359  * point 1 and point 2 (meters); otherwise it is the arc length between
360  * point 1 and point 2 (degrees); it can be negative.
361  * @param[in] outmask a bitor'ed combination of NETGeographicLib::Mask values
362  * specifying which of the following parameters should be set.
363  * @param[out] lat2 latitude of point 2 (degrees).
364  * @param[out] lon2 longitude of point 2 (degrees); requires that the
365  * GeodesicLine object was constructed with \e caps |=
366  * NETGeographicLib::Mask::LONGITUDE.
367  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
368  * @param[out] s12 distance between point 1 and point 2 (meters); requires
369  * that the GeodesicLine object was constructed with \e caps |=
370  * NETGeographicLib::Mask::DISTANCE.
371  * @param[out] m12 reduced length of geodesic (meters); requires that the
372  * GeodesicLine object was constructed with \e caps |=
373  * NETGeographicLib::Mask::REDUCEDLENGTH.
374  * @param[out] M12 geodesic scale of point 2 relative to point 1
375  * (dimensionless); requires that the GeodesicLine object was constructed
376  * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE.
377  * @param[out] M21 geodesic scale of point 1 relative to point 2
378  * (dimensionless); requires that the GeodesicLine object was constructed
379  * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE.
380  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
381  * that the GeodesicLine object was constructed with \e caps |=
382  * NETGeographicLib::Mask::AREA.
383  * @return \e a12 arc length of between point 1 and point 2 (degrees).
384  *
385  * The GeodesicLine::mask values possible for \e outmask are
386  * - \e outmask |= NETGeographicLib::Mask::LATITUDE for the latitude \e lat2;
387  * - \e outmask |= NETGeographicLib::Mask::LONGITUDE for the latitude \e lon2;
388  * - \e outmask |= NETGeographicLib::Mask::AZIMUTH for the latitude \e azi2;
389  * - \e outmask |= NETGeographicLib::Mask::DISTANCE for the distance \e s12;
390  * - \e outmask |= NETGeographicLib::Mask::REDUCEDLENGTH for the reduced length \e
391  * m12;
392  * - \e outmask |= NETGeographicLib::Mask::GEODESICSCALE for the geodesic scales \e
393  * M12 and \e M21;
394  * - \e outmask |= NETGeographicLib::Mask::AREA for the area \e S12;
395  * - \e outmask |= NETGeographicLib::Mask::ALL for all of the above.
396  * .
397  * Requesting a value which the GeodesicLine object is not capable of
398  * computing is not an error; the corresponding argument will not be
399  * altered. Note, however, that the arc length is always computed and
400  * returned as the function value.
401  **********************************************************************/
402  double GenPosition(bool arcmode, double s12_a12,
403  NETGeographicLib::Mask outmask,
404  [System::Runtime::InteropServices::Out] double% lat2,
405  [System::Runtime::InteropServices::Out] double% lon2,
406  [System::Runtime::InteropServices::Out] double% azi2,
407  [System::Runtime::InteropServices::Out] double% s12,
408  [System::Runtime::InteropServices::Out] double% m12,
409  [System::Runtime::InteropServices::Out] double% M12,
410  [System::Runtime::InteropServices::Out] double% M21,
411  [System::Runtime::InteropServices::Out] double% S12);
412 
413  ///@}
414 
415  /** \name Inspector functions
416  **********************************************************************/
417  ///@{
418 
419  /**
420  * @return \e lat1 the latitude of point 1 (degrees).
421  **********************************************************************/
422  property double Latitude { double get(); }
423 
424  /**
425  * @return \e lon1 the longitude of point 1 (degrees).
426  **********************************************************************/
427  property double Longitude { double get(); }
428 
429  /**
430  * @return \e azi1 the azimuth (degrees) of the geodesic line at point 1.
431  **********************************************************************/
432  property double Azimuth { double get(); }
433 
434  /**
435  * @return \e azi0 the azimuth (degrees) of the geodesic line as it crosses
436  * the equator in a northward direction.
437  **********************************************************************/
438  property double EquatorialAzimuth { double get(); }
439 
440  /**
441  * @return \e a1 the arc length (degrees) between the northward equatorial
442  * crossing and point 1.
443  **********************************************************************/
444  property double EquatorialArc { double get(); }
445 
446  /**
447  * @return \e a the equatorial radius of the ellipsoid (meters). This is
448  * the value inherited from the Geodesic object used in the constructor.
449  **********************************************************************/
450  property double MajorRadius { double get(); }
451 
452  /**
453  * @return \e f the flattening of the ellipsoid. This is the value
454  * inherited from the Geodesic object used in the constructor.
455  **********************************************************************/
456  property double Flattening { double get(); }
457 
458  /**
459  * @return \e caps the computational capabilities that this object was
460  * constructed with. LATITUDE and AZIMUTH are always included.
461  **********************************************************************/
463 
464  /**
465  * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values.
466  * @return true if the GeodesicLine object has all these capabilities.
467  **********************************************************************/
468  bool Capabilities(NETGeographicLib::Mask testcaps);
469  ///@}
470  };
471 } // namespace NETGeographicLib