GeographicLib  1.35
GeodesicLine.hpp
Go to the documentation of this file.
1 /**
2  * \file GeodesicLine.hpp
3  * \brief Header for GeographicLib::GeodesicLine class
4  *
5  * Copyright (c) Charles Karney (2009-2012) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * http://geographiclib.sourceforge.net/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP)
11 #define GEOGRAPHICLIB_GEODESICLINE_HPP 1
12 
15 
16 namespace GeographicLib {
17 
18  /**
19  * \brief A geodesic line
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  * Example of use:
53  * \include example-GeodesicLine.cpp
54  *
55  * <a href="GeodSolve.1.html">GeodSolve</a> is a command-line utility
56  * providing access to the functionality of Geodesic and GeodesicLine.
57  **********************************************************************/
58 
60  private:
61  typedef Math::real real;
62  friend class Geodesic;
63  static const int nC1_ = Geodesic::nC1_;
64  static const int nC1p_ = Geodesic::nC1p_;
65  static const int nC2_ = Geodesic::nC2_;
66  static const int nC3_ = Geodesic::nC3_;
67  static const int nC4_ = Geodesic::nC4_;
68 
69  real _lat1, _lon1, _azi1;
70  real _a, _f, _b, _c2, _f1, _salp0, _calp0, _k2,
71  _salp1, _calp1, _ssig1, _csig1, _dn1, _stau1, _ctau1, _somg1, _comg1,
72  _A1m1, _A2m1, _A3c, _B11, _B21, _B31, _A4, _B41;
73  // index zero elements of _C1a, _C1pa, _C2a, _C3a are unused
74  real _C1a[nC1_ + 1], _C1pa[nC1p_ + 1], _C2a[nC2_ + 1], _C3a[nC3_],
75  _C4a[nC4_]; // all the elements of _C4a are used
76  unsigned _caps;
77 
78  enum captype {
79  CAP_NONE = Geodesic::CAP_NONE,
80  CAP_C1 = Geodesic::CAP_C1,
81  CAP_C1p = Geodesic::CAP_C1p,
82  CAP_C2 = Geodesic::CAP_C2,
83  CAP_C3 = Geodesic::CAP_C3,
84  CAP_C4 = Geodesic::CAP_C4,
85  CAP_ALL = Geodesic::CAP_ALL,
86  OUT_ALL = Geodesic::OUT_ALL,
87  };
88  public:
89 
90  /**
91  * Bit masks for what calculations to do. They signify to the
92  * GeodesicLine::GeodesicLine constructor and to Geodesic::Line what
93  * capabilities should be included in the GeodesicLine object. This is
94  * merely a duplication of Geodesic::mask.
95  **********************************************************************/
96  enum mask {
97  /**
98  * No capabilities, no output.
99  * @hideinitializer
100  **********************************************************************/
102  /**
103  * Calculate latitude \e lat2. (It's not necessary to include this as a
104  * capability to GeodesicLine because this is included by default.)
105  * @hideinitializer
106  **********************************************************************/
107  LATITUDE = Geodesic::LATITUDE,
108  /**
109  * Calculate longitude \e lon2.
110  * @hideinitializer
111  **********************************************************************/
112  LONGITUDE = Geodesic::LONGITUDE,
113  /**
114  * Calculate azimuths \e azi1 and \e azi2. (It's not necessary to
115  * include this as a capability to GeodesicLine because this is included
116  * by default.)
117  * @hideinitializer
118  **********************************************************************/
119  AZIMUTH = Geodesic::AZIMUTH,
120  /**
121  * Calculate distance \e s12.
122  * @hideinitializer
123  **********************************************************************/
124  DISTANCE = Geodesic::DISTANCE,
125  /**
126  * Allow distance \e s12 to be used as input in the direct geodesic
127  * problem.
128  * @hideinitializer
129  **********************************************************************/
130  DISTANCE_IN = Geodesic::DISTANCE_IN,
131  /**
132  * Calculate reduced length \e m12.
133  * @hideinitializer
134  **********************************************************************/
135  REDUCEDLENGTH = Geodesic::REDUCEDLENGTH,
136  /**
137  * Calculate geodesic scales \e M12 and \e M21.
138  * @hideinitializer
139  **********************************************************************/
140  GEODESICSCALE = Geodesic::GEODESICSCALE,
141  /**
142  * Calculate area \e S12.
143  * @hideinitializer
144  **********************************************************************/
146  /**
147  * All capabilities, calculate everything.
148  * @hideinitializer
149  **********************************************************************/
151  };
152 
153  /** \name Constructors
154  **********************************************************************/
155  ///@{
156 
157  /**
158  * Constructor for a geodesic line staring at latitude \e lat1, longitude
159  * \e lon1, and azimuth \e azi1 (all in degrees).
160  *
161  * @param[in] g A Geodesic object used to compute the necessary information
162  * about the GeodesicLine.
163  * @param[in] lat1 latitude of point 1 (degrees).
164  * @param[in] lon1 longitude of point 1 (degrees).
165  * @param[in] azi1 azimuth at point 1 (degrees).
166  * @param[in] caps bitor'ed combination of GeodesicLine::mask values
167  * specifying the capabilities the GeodesicLine object should possess,
168  * i.e., which quantities can be returned in calls to
169  * GeodesicLine::Position.
170  *
171  * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 and \e
172  * azi1 should be in the range [&minus;540&deg;, 540&deg;).
173  *
174  * The GeodesicLine::mask values are
175  * - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this is
176  * added automatically;
177  * - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2;
178  * - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is
179  * added automatically;
180  * - \e caps |= GeodesicLine::DISTANCE for the distance \e s12;
181  * - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m12;
182  * - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12
183  * and \e M21;
184  * - \e caps |= GeodesicLine::AREA for the area \e S12;
185  * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the
186  * geodesic to be given in terms of \e s12; without this capability the
187  * length can only be specified in terms of arc length;
188  * - \e caps |= GeodesicLine::ALL for all of the above.
189  * .
190  * The default value of \e caps is GeodesicLine::ALL.
191  *
192  * If the point is at a pole, the azimuth is defined by keeping \e lon1
193  * fixed, writing \e lat1 = &plusmn;(90&deg; &minus; &epsilon;), and taking
194  * the limit &epsilon; &rarr; 0+.
195  **********************************************************************/
196  GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1,
197  unsigned caps = ALL)
198  throw();
199 
200  /**
201  * A default constructor. If GeodesicLine::Position is called on the
202  * resulting object, it returns immediately (without doing any
203  * calculations). The object can be set with a call to Geodesic::Line.
204  * Use Init() to test whether object is still in this uninitialized state.
205  **********************************************************************/
206  GeodesicLine() throw() : _caps(0U) {}
207  ///@}
208 
209  /** \name Position in terms of distance
210  **********************************************************************/
211  ///@{
212 
213  /**
214  * Compute the position of point 2 which is a distance \e s12 (meters) from
215  * point 1.
216  *
217  * @param[in] s12 distance between point 1 and point 2 (meters); it can be
218  * negative.
219  * @param[out] lat2 latitude of point 2 (degrees).
220  * @param[out] lon2 longitude of point 2 (degrees); requires that the
221  * GeodesicLine object was constructed with \e caps |=
222  * GeodesicLine::LONGITUDE.
223  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
224  * @param[out] m12 reduced length of geodesic (meters); requires that the
225  * GeodesicLine object was constructed with \e caps |=
226  * GeodesicLine::REDUCEDLENGTH.
227  * @param[out] M12 geodesic scale of point 2 relative to point 1
228  * (dimensionless); requires that the GeodesicLine object was constructed
229  * with \e caps |= GeodesicLine::GEODESICSCALE.
230  * @param[out] M21 geodesic scale of point 1 relative to point 2
231  * (dimensionless); requires that the GeodesicLine object was constructed
232  * with \e caps |= GeodesicLine::GEODESICSCALE.
233  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
234  * that the GeodesicLine object was constructed with \e caps |=
235  * GeodesicLine::AREA.
236  * @return \e a12 arc length of between point 1 and point 2 (degrees).
237  *
238  * The values of \e lon2 and \e azi2 returned are in the range
239  * [&minus;180&deg;, 180&deg;).
240  *
241  * The GeodesicLine object \e must have been constructed with \e caps |=
242  * GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no
243  * parameters are set. Requesting a value which the GeodesicLine object is
244  * not capable of computing is not an error; the corresponding argument
245  * will not be altered.
246  *
247  * The following functions are overloaded versions of
248  * GeodesicLine::Position which omit some of the output parameters. Note,
249  * however, that the arc length is always computed and returned as the
250  * function value.
251  **********************************************************************/
252  Math::real Position(real s12,
253  real& lat2, real& lon2, real& azi2,
254  real& m12, real& M12, real& M21,
255  real& S12) const throw() {
256  real t;
257  return GenPosition(false, s12,
258  LATITUDE | LONGITUDE | AZIMUTH |
259  REDUCEDLENGTH | GEODESICSCALE | AREA,
260  lat2, lon2, azi2, t, m12, M12, M21, S12);
261  }
262 
263  /**
264  * See the documentation for GeodesicLine::Position.
265  **********************************************************************/
266  Math::real Position(real s12, real& lat2, real& lon2) const throw() {
267  real t;
268  return GenPosition(false, s12,
269  LATITUDE | LONGITUDE,
270  lat2, lon2, t, t, t, t, t, t);
271  }
272 
273  /**
274  * See the documentation for GeodesicLine::Position.
275  **********************************************************************/
276  Math::real Position(real s12, real& lat2, real& lon2,
277  real& azi2) const throw() {
278  real t;
279  return GenPosition(false, s12,
280  LATITUDE | LONGITUDE | AZIMUTH,
281  lat2, lon2, azi2, t, t, t, t, t);
282  }
283 
284  /**
285  * See the documentation for GeodesicLine::Position.
286  **********************************************************************/
287  Math::real Position(real s12, real& lat2, real& lon2,
288  real& azi2, real& m12) const throw() {
289  real t;
290  return GenPosition(false, s12,
291  LATITUDE | LONGITUDE |
292  AZIMUTH | REDUCEDLENGTH,
293  lat2, lon2, azi2, t, m12, t, t, t);
294  }
295 
296  /**
297  * See the documentation for GeodesicLine::Position.
298  **********************************************************************/
299  Math::real Position(real s12, real& lat2, real& lon2,
300  real& azi2, real& M12, real& M21)
301  const throw() {
302  real t;
303  return GenPosition(false, s12,
304  LATITUDE | LONGITUDE |
305  AZIMUTH | GEODESICSCALE,
306  lat2, lon2, azi2, t, t, M12, M21, t);
307  }
308 
309  /**
310  * See the documentation for GeodesicLine::Position.
311  **********************************************************************/
312  Math::real Position(real s12,
313  real& lat2, real& lon2, real& azi2,
314  real& m12, real& M12, real& M21)
315  const throw() {
316  real t;
317  return GenPosition(false, s12,
318  LATITUDE | LONGITUDE | AZIMUTH |
319  REDUCEDLENGTH | GEODESICSCALE,
320  lat2, lon2, azi2, t, m12, M12, M21, t);
321  }
322 
323  ///@}
324 
325  /** \name Position in terms of arc length
326  **********************************************************************/
327  ///@{
328 
329  /**
330  * Compute the position of point 2 which is an arc length \e a12 (degrees)
331  * from point 1.
332  *
333  * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
334  * be negative.
335  * @param[out] lat2 latitude of point 2 (degrees).
336  * @param[out] lon2 longitude of point 2 (degrees); requires that the
337  * GeodesicLine object was constructed with \e caps |=
338  * GeodesicLine::LONGITUDE.
339  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
340  * @param[out] s12 distance between point 1 and point 2 (meters); requires
341  * that the GeodesicLine object was constructed with \e caps |=
342  * GeodesicLine::DISTANCE.
343  * @param[out] m12 reduced length of geodesic (meters); requires that the
344  * GeodesicLine object was constructed with \e caps |=
345  * GeodesicLine::REDUCEDLENGTH.
346  * @param[out] M12 geodesic scale of point 2 relative to point 1
347  * (dimensionless); requires that the GeodesicLine object was constructed
348  * with \e caps |= GeodesicLine::GEODESICSCALE.
349  * @param[out] M21 geodesic scale of point 1 relative to point 2
350  * (dimensionless); requires that the GeodesicLine object was constructed
351  * with \e caps |= GeodesicLine::GEODESICSCALE.
352  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
353  * that the GeodesicLine object was constructed with \e caps |=
354  * GeodesicLine::AREA.
355  *
356  * The values of \e lon2 and \e azi2 returned are in the range
357  * [&minus;180&deg;, 180&deg;).
358  *
359  * Requesting a value which the GeodesicLine object is not capable of
360  * computing is not an error; the corresponding argument will not be
361  * altered.
362  *
363  * The following functions are overloaded versions of
364  * GeodesicLine::ArcPosition which omit some of the output parameters.
365  **********************************************************************/
366  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
367  real& s12, real& m12, real& M12, real& M21,
368  real& S12) const throw() {
369  GenPosition(true, a12,
370  LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
371  REDUCEDLENGTH | GEODESICSCALE | AREA,
372  lat2, lon2, azi2, s12, m12, M12, M21, S12);
373  }
374 
375  /**
376  * See the documentation for GeodesicLine::ArcPosition.
377  **********************************************************************/
378  void ArcPosition(real a12, real& lat2, real& lon2)
379  const throw() {
380  real t;
381  GenPosition(true, a12,
382  LATITUDE | LONGITUDE,
383  lat2, lon2, t, t, t, t, t, t);
384  }
385 
386  /**
387  * See the documentation for GeodesicLine::ArcPosition.
388  **********************************************************************/
389  void ArcPosition(real a12,
390  real& lat2, real& lon2, real& azi2)
391  const throw() {
392  real t;
393  GenPosition(true, a12,
394  LATITUDE | LONGITUDE | AZIMUTH,
395  lat2, lon2, azi2, t, t, t, t, t);
396  }
397 
398  /**
399  * See the documentation for GeodesicLine::ArcPosition.
400  **********************************************************************/
401  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
402  real& s12) const throw() {
403  real t;
404  GenPosition(true, a12,
405  LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
406  lat2, lon2, azi2, s12, t, t, t, t);
407  }
408 
409  /**
410  * See the documentation for GeodesicLine::ArcPosition.
411  **********************************************************************/
412  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
413  real& s12, real& m12) const throw() {
414  real t;
415  GenPosition(true, a12,
416  LATITUDE | LONGITUDE | AZIMUTH |
417  DISTANCE | REDUCEDLENGTH,
418  lat2, lon2, azi2, s12, m12, t, t, t);
419  }
420 
421  /**
422  * See the documentation for GeodesicLine::ArcPosition.
423  **********************************************************************/
424  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
425  real& s12, real& M12, real& M21)
426  const throw() {
427  real t;
428  GenPosition(true, a12,
429  LATITUDE | LONGITUDE | AZIMUTH |
430  DISTANCE | GEODESICSCALE,
431  lat2, lon2, azi2, s12, t, M12, M21, t);
432  }
433 
434  /**
435  * See the documentation for GeodesicLine::ArcPosition.
436  **********************************************************************/
437  void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
438  real& s12, real& m12, real& M12, real& M21)
439  const throw() {
440  real t;
441  GenPosition(true, a12,
442  LATITUDE | LONGITUDE | AZIMUTH |
443  DISTANCE | REDUCEDLENGTH | GEODESICSCALE,
444  lat2, lon2, azi2, s12, m12, M12, M21, t);
445  }
446  ///@}
447 
448  /** \name The general position function.
449  **********************************************************************/
450  ///@{
451 
452  /**
453  * The general position function. GeodesicLine::Position and
454  * GeodesicLine::ArcPosition are defined in terms of this function.
455  *
456  * @param[in] arcmode boolean flag determining the meaning of the second
457  * parameter; if arcmode is false, then the GeodesicLine object must have
458  * been constructed with \e caps |= GeodesicLine::DISTANCE_IN.
459  * @param[in] s12_a12 if \e arcmode is false, this is the distance between
460  * point 1 and point 2 (meters); otherwise it is the arc length between
461  * point 1 and point 2 (degrees); it can be negative.
462  * @param[in] outmask a bitor'ed combination of GeodesicLine::mask values
463  * specifying which of the following parameters should be set.
464  * @param[out] lat2 latitude of point 2 (degrees).
465  * @param[out] lon2 longitude of point 2 (degrees); requires that the
466  * GeodesicLine object was constructed with \e caps |=
467  * GeodesicLine::LONGITUDE.
468  * @param[out] azi2 (forward) azimuth at point 2 (degrees).
469  * @param[out] s12 distance between point 1 and point 2 (meters); requires
470  * that the GeodesicLine object was constructed with \e caps |=
471  * GeodesicLine::DISTANCE.
472  * @param[out] m12 reduced length of geodesic (meters); requires that the
473  * GeodesicLine object was constructed with \e caps |=
474  * GeodesicLine::REDUCEDLENGTH.
475  * @param[out] M12 geodesic scale of point 2 relative to point 1
476  * (dimensionless); requires that the GeodesicLine object was constructed
477  * with \e caps |= GeodesicLine::GEODESICSCALE.
478  * @param[out] M21 geodesic scale of point 1 relative to point 2
479  * (dimensionless); requires that the GeodesicLine object was constructed
480  * with \e caps |= GeodesicLine::GEODESICSCALE.
481  * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
482  * that the GeodesicLine object was constructed with \e caps |=
483  * GeodesicLine::AREA.
484  * @return \e a12 arc length of between point 1 and point 2 (degrees).
485  *
486  * The GeodesicLine::mask values possible for \e outmask are
487  * - \e outmask |= GeodesicLine::LATITUDE for the latitude \e lat2;
488  * - \e outmask |= GeodesicLine::LONGITUDE for the latitude \e lon2;
489  * - \e outmask |= GeodesicLine::AZIMUTH for the latitude \e azi2;
490  * - \e outmask |= GeodesicLine::DISTANCE for the distance \e s12;
491  * - \e outmask |= GeodesicLine::REDUCEDLENGTH for the reduced length \e
492  * m12;
493  * - \e outmask |= GeodesicLine::GEODESICSCALE for the geodesic scales \e
494  * M12 and \e M21;
495  * - \e outmask |= GeodesicLine::AREA for the area \e S12;
496  * - \e outmask |= GeodesicLine::ALL for all of the above.
497  * .
498  * Requesting a value which the GeodesicLine object is not capable of
499  * computing is not an error; the corresponding argument will not be
500  * altered. Note, however, that the arc length is always computed and
501  * returned as the function value.
502  **********************************************************************/
503  Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask,
504  real& lat2, real& lon2, real& azi2,
505  real& s12, real& m12, real& M12, real& M21,
506  real& S12) const throw();
507 
508  ///@}
509 
510  /** \name Inspector functions
511  **********************************************************************/
512  ///@{
513 
514  /**
515  * @return true if the object has been initialized.
516  **********************************************************************/
517  bool Init() const throw() { return _caps != 0U; }
518 
519  /**
520  * @return \e lat1 the latitude of point 1 (degrees).
521  **********************************************************************/
522  Math::real Latitude() const throw()
523  { return Init() ? _lat1 : Math::NaN<real>(); }
524 
525  /**
526  * @return \e lon1 the longitude of point 1 (degrees).
527  **********************************************************************/
528  Math::real Longitude() const throw()
529  { return Init() ? _lon1 : Math::NaN<real>(); }
530 
531  /**
532  * @return \e azi1 the azimuth (degrees) of the geodesic line at point 1.
533  **********************************************************************/
534  Math::real Azimuth() const throw()
535  { return Init() ? _azi1 : Math::NaN<real>(); }
536 
537  /**
538  * @return \e azi0 the azimuth (degrees) of the geodesic line as it crosses
539  * the equator in a northward direction.
540  **********************************************************************/
541  Math::real EquatorialAzimuth() const throw() {
542  return Init() ?
543  atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>();
544  }
545 
546  /**
547  * @return \e a1 the arc length (degrees) between the northward equatorial
548  * crossing and point 1.
549  **********************************************************************/
550  Math::real EquatorialArc() const throw() {
551  return Init() ?
552  atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>();
553  }
554 
555  /**
556  * @return \e a the equatorial radius of the ellipsoid (meters). This is
557  * the value inherited from the Geodesic object used in the constructor.
558  **********************************************************************/
559  Math::real MajorRadius() const throw()
560  { return Init() ? _a : Math::NaN<real>(); }
561 
562  /**
563  * @return \e f the flattening of the ellipsoid. This is the value
564  * inherited from the Geodesic object used in the constructor.
565  **********************************************************************/
566  Math::real Flattening() const throw()
567  { return Init() ? _f : Math::NaN<real>(); }
568 
569  /// \cond SKIP
570  /**
571  * <b>DEPRECATED</b>
572  * @return \e r the inverse flattening of the ellipsoid.
573  **********************************************************************/
574  Math::real InverseFlattening() const throw()
575  { return Init() ? 1/_f : Math::NaN<real>(); }
576  /// \endcond
577 
578  /**
579  * @return \e caps the computational capabilities that this object was
580  * constructed with. LATITUDE and AZIMUTH are always included.
581  **********************************************************************/
582  unsigned Capabilities() const throw() { return _caps; }
583 
584  /**
585  * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values.
586  * @return true if the GeodesicLine object has all these capabilities.
587  **********************************************************************/
588  bool Capabilities(unsigned testcaps) const throw() {
589  testcaps &= OUT_ALL;
590  return (_caps & testcaps) == testcaps;
591  }
592  ///@}
593 
594  };
595 
596 } // namespace GeographicLib
597 
598 #endif // GEOGRAPHICLIB_GEODESICLINE_HPP