00001 /** 00002 * \file PolarStereographic.hpp 00003 * \brief Header for GeographicLib::PolarStereographic class 00004 * 00005 * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> 00006 * and licensed under the LGPL. For more information, see 00007 * http://geographiclib.sourceforge.net/ 00008 **********************************************************************/ 00009 00010 #if !defined(GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP) 00011 #define GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP "$Id: PolarStereographic.hpp 6807 2010-02-01 11:26:34Z karney $" 00012 00013 #include "GeographicLib/Constants.hpp" 00014 00015 namespace GeographicLib { 00016 00017 /** 00018 * \brief Polar Stereographic Projection 00019 * 00020 * Implementation taken from the report, 00021 * - J. P. Snyder, 00022 * <a href="http://pubs.er.usgs.gov/usgspubs/pp/pp1395"> Map Projections: A 00023 * Working Manual</a>, USGS Professional Paper 1395 (1987), 00024 * pp. 160–163. 00025 * 00026 * This is a straightforward implementation of the equations in Snyder except 00027 * that Newton's method is used to invert the projection. 00028 **********************************************************************/ 00029 class PolarStereographic { 00030 private: 00031 typedef Math::real real; 00032 const real _a, _r, _f, _e2, _e, _e2m, _c; 00033 real _k0; 00034 static const real tol; 00035 static const int numit = 5; 00036 static inline real sq(real x) throw() { return x * x; } 00037 // Return e * atanh(e * x) for f >= 0, else return 00038 // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0 00039 inline real eatanhe(real x) const throw() { 00040 return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); 00041 } 00042 public: 00043 00044 /** 00045 * Constructor for a ellipsoid radius \e a (meters), reciprocal flattening 00046 * \e r, and central scale factor \e k0. Setting \e r <= 0 implies \e r = 00047 * inf or flattening = 0 (i.e., a sphere). An exception is thrown if \e a 00048 * or \e k0 is not positive. 00049 **********************************************************************/ 00050 PolarStereographic(real a, real r, real k0); 00051 00052 /** 00053 * Alter the scale for the projection so that on latitude \e lat, the scale 00054 * is \e k (default 1). \e lat is interpreted in the context a projection 00055 * centered at the north pole. The allows a "latitude of true scale" to be 00056 * specified. An exception is thrown if \e k is not positive. 00057 **********************************************************************/ 00058 void SetScale(real lat, real k = real(1)); 00059 00060 /** 00061 * Convert from latitude \e lat (degrees) and longitude \e lon (degrees) to 00062 * polar stereographic easting \e x (meters) and northing \e y (meters). 00063 * The projection is about the pole given by \e northp (false means south, 00064 * true means north). Also return the meridian convergence \e gamma 00065 * (degrees) and the scale \e k. No false easting or northing is added. 00066 * \e lat should be in the range (-90, 90] for \e northp = true and in the 00067 * range [-90, 90) for \e northp = false; \e lon should be in the range 00068 * [-180, 360]. 00069 **********************************************************************/ 00070 void Forward(bool northp, real lat, real lon, 00071 real& x, real& y, real& gamma, real& k) const throw(); 00072 00073 /** 00074 * Convert from polar stereogrphic easting \e x (meters) and northing \e y 00075 * (meters) to latitude \e lat (degrees) and longitude \e lon (degrees) . 00076 * The hemisphere is given by \e northp (false means south, true means 00077 * north). Also return the meridian convergence \e gamma (degrees) and the 00078 * scale \e k. No false easting or northing is added. The value of \e lon 00079 * returned is in the range [-180, 180). 00080 **********************************************************************/ 00081 void Reverse(bool northp, real x, real y, 00082 real& lat, real& lon, real& gamma, real& k) const throw(); 00083 00084 /** 00085 * The major radius of the ellipsoid (meters). This is that value of \e a 00086 * used in the constructor. 00087 **********************************************************************/ 00088 Math::real MajorRadius() const throw() { return _a; } 00089 00090 /** 00091 * The inverse flattening of the ellipsoid. This is that value of \e r 00092 * used in the constructor. A value of 0 is returned for a sphere 00093 * (infinite inverse flattening). 00094 **********************************************************************/ 00095 Math::real InverseFlattening() const throw() { return _r; } 00096 00097 /** 00098 * The central scale for the projection. This is that value of \e k0 used 00099 * in the constructor and is the scale at the pole. 00100 **********************************************************************/ 00101 Math::real CentralScale() const throw() { return _k0; } 00102 00103 /** 00104 * A global instantiation of PolarStereographic with the WGS84 ellipsoid 00105 * and the UPS scale factor. However, unlike UPS, no false easting or 00106 * northing is added. 00107 **********************************************************************/ 00108 const static PolarStereographic UPS; 00109 }; 00110 00111 } // namespace GeographicLib 00112 00113 #endif