GeographicLib  1.35
PolarStereographic.hpp
Go to the documentation of this file.
1 /**
2  * \file PolarStereographic.hpp
3  * \brief Header for GeographicLib::PolarStereographic class
4  *
5  * Copyright (c) Charles Karney (2008-2011) <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_POLARSTEREOGRAPHIC_HPP)
11 #define GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP 1
12 
14 
15 namespace GeographicLib {
16 
17  /**
18  * \brief Polar stereographic projection
19  *
20  * Implementation taken from the report,
21  * - J. P. Snyder,
22  * <a href="http://pubs.er.usgs.gov/usgspubs/pp/pp1395"> Map Projections: A
23  * Working Manual</a>, USGS Professional Paper 1395 (1987),
24  * pp. 160--163.
25  *
26  * This is a straightforward implementation of the equations in Snyder except
27  * that Newton's method is used to invert the projection.
28  *
29  * Example of use:
30  * \include example-PolarStereographic.cpp
31  **********************************************************************/
33  private:
34  typedef Math::real real;
35  // _Cx used to be _C but g++ 3.4 has a macro of that name
36  real _a, _f, _e2, _e, _e2m, _Cx, _c;
37  real _k0;
38  static const real tol_;
39  static const real overflow_;
40  static const int numit_ = 5;
41  // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
42  static inline real tanx(real x) throw() {
43  real t = std::tan(x);
44  // Write the tests this way to ensure that tanx(NaN()) is NaN()
45  return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overflow_);
46  }
47  // Return e * atanh(e * x) for f >= 0, else return
48  // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
49  inline real eatanhe(real x) const throw()
50  { return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); }
51  public:
52 
53  /**
54  * Constructor for a ellipsoid with
55  *
56  * @param[in] a equatorial radius (meters).
57  * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
58  * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flattening
59  * to 1/\e f.
60  * @param[in] k0 central scale factor.
61  * @exception GeographicErr if \e a, (1 &minus; \e f ) \e a, or \e k0 is
62  * not positive.
63  **********************************************************************/
64  PolarStereographic(real a, real f, real k0);
65 
66  /**
67  * Set the scale for the projection.
68  *
69  * @param[in] lat (degrees) assuming \e northp = true.
70  * @param[in] k scale at latitude \e lat (default 1).
71  * @exception GeographicErr \e k is not positive.
72  * @exception GeographicErr if \e lat is not in (&minus;90&deg;,
73  * 90&deg;].
74  **********************************************************************/
75  void SetScale(real lat, real k = real(1));
76 
77  /**
78  * Forward projection, from geographic to polar stereographic.
79  *
80  * @param[in] northp the pole which is the center of projection (true means
81  * north, false means south).
82  * @param[in] lat latitude of point (degrees).
83  * @param[in] lon longitude of point (degrees).
84  * @param[out] x easting of point (meters).
85  * @param[out] y northing of point (meters).
86  * @param[out] gamma meridian convergence at point (degrees).
87  * @param[out] k scale of projection at point.
88  *
89  * No false easting or northing is added. \e lat should be in the range
90  * (&minus;90&deg;, 90&deg;] for \e northp = true and in the range
91  * [&minus;90&deg;, 90&deg;) for \e northp = false; \e lon should
92  * be in the range [&minus;540&deg;, 540&deg;).
93  **********************************************************************/
94  void Forward(bool northp, real lat, real lon,
95  real& x, real& y, real& gamma, real& k) const throw();
96 
97  /**
98  * Reverse projection, from polar stereographic to geographic.
99  *
100  * @param[in] northp the pole which is the center of projection (true means
101  * north, false means south).
102  * @param[in] x easting of point (meters).
103  * @param[in] y northing of point (meters).
104  * @param[out] lat latitude of point (degrees).
105  * @param[out] lon longitude of point (degrees).
106  * @param[out] gamma meridian convergence at point (degrees).
107  * @param[out] k scale of projection at point.
108  *
109  * No false easting or northing is added. The value of \e lon returned is
110  * in the range [&minus;180&deg;, 180&deg;).
111  **********************************************************************/
112  void Reverse(bool northp, real x, real y,
113  real& lat, real& lon, real& gamma, real& k) const throw();
114 
115  /**
116  * PolarStereographic::Forward without returning the convergence and scale.
117  **********************************************************************/
118  void Forward(bool northp, real lat, real lon,
119  real& x, real& y) const throw() {
120  real gamma, k;
121  Forward(northp, lat, lon, x, y, gamma, k);
122  }
123 
124  /**
125  * PolarStereographic::Reverse without returning the convergence and scale.
126  **********************************************************************/
127  void Reverse(bool northp, real x, real y,
128  real& lat, real& lon) const throw() {
129  real gamma, k;
130  Reverse(northp, x, y, lat, lon, gamma, k);
131  }
132 
133  /** \name Inspector functions
134  **********************************************************************/
135  ///@{
136  /**
137  * @return \e a the equatorial radius of the ellipsoid (meters). This is
138  * the value used in the constructor.
139  **********************************************************************/
140  Math::real MajorRadius() const throw() { return _a; }
141 
142  /**
143  * @return \e f the flattening of the ellipsoid. This is the value used in
144  * the constructor.
145  **********************************************************************/
146  Math::real Flattening() const throw() { return _f; }
147 
148  /// \cond SKIP
149  /**
150  * <b>DEPRECATED</b>
151  * @return \e r the inverse flattening of the ellipsoid.
152  **********************************************************************/
153  Math::real InverseFlattening() const throw() { return 1/_f; }
154  /// \endcond
155 
156  /**
157  * The central scale for the projection. This is the value of \e k0 used
158  * in the constructor and is the scale at the pole unless overridden by
159  * PolarStereographic::SetScale.
160  **********************************************************************/
161  Math::real CentralScale() const throw() { return _k0; }
162  ///@}
163 
164  /**
165  * A global instantiation of PolarStereographic with the WGS84 ellipsoid
166  * and the UPS scale factor. However, unlike UPS, no false easting or
167  * northing is added.
168  **********************************************************************/
169  static const PolarStereographic UPS;
170  };
171 
172 } // namespace GeographicLib
173 
174 #endif // GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP
void Reverse(bool northp, real x, real y, real &lat, real &lon) const
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:52
GeographicLib::Math::real real
Definition: GeodSolve.cpp:40
static T atanh(T x)
Definition: Math.hpp:315
static const PolarStereographic UPS
void Forward(bool northp, real lat, real lon, real &x, real &y) const
Polar stereographic projection.
Header for GeographicLib::Constants class.