00001 /** 00002 * \file PolarStereographic.hpp 00003 * \brief Header for GeographicLib::PolarStereographic class 00004 * 00005 * Copyright (c) Charles Karney (2008) <charles@karney.com> 00006 * and licensed under the LGPL. 00007 **********************************************************************/ 00008 00009 #if !defined(POLARSTEREOGRAPHIC_HPP) 00010 #define POLARSTEREOGRAPHIC_HPP "$Id: PolarStereographic.hpp 6537 2009-02-14 13:41:47Z ckarney $" 00011 00012 #include <cmath> 00013 00014 namespace GeographicLib { 00015 00016 /** 00017 * \brief Polar Stereographic Projection 00018 * 00019 * Implementation taken from the report, 00020 * - J. P. Snyder, 00021 * <a href="http://pubs.er.usgs.gov/usgspubs/pp/pp1395"> Map Projections: A 00022 * Working Manual</a>, USGS Professional Paper 1395 (1987), 00023 * pp. 160–163. 00024 * 00025 * This is a straightforward implementation of the equations in Snyder except 00026 * that Newton's method is used to invert the projection. 00027 **********************************************************************/ 00028 class PolarStereographic { 00029 private: 00030 const double _a, _f, _k0, _e, _e2m, _c, _tol; 00031 const int _numit; 00032 static inline double sq(double x) throw() { return x * x; } 00033 #if defined(_MSC_VER) 00034 static inline double hypot(double x, double y) throw() 00035 { return _hypot(x, y); } 00036 #else 00037 static inline double hypot(double x, double y) throw() 00038 { return ::hypot(x, y); } 00039 #endif 00040 public: 00041 00042 /** 00043 * Constructor for a ellipsoid radius \e a (meters), inverse flattening \e 00044 * invf, and central scale factor \e k0. Setting \e invf <= 0 implies \e 00045 * invf = inf or flattening = 0 (i.e., a sphere). 00046 **********************************************************************/ 00047 PolarStereographic(double a, double invf, double k0) throw(); 00048 00049 /** 00050 * Convert from latitude \e lat (degrees) and longitude \e lon (degrees) to 00051 * polar stereographic easting \e x (meters) and northing \e y (meters). 00052 * The projection is about the pole given by \e northp (false means south, 00053 * true means north). Also return the meridian convergence \e gamma 00054 * (degrees) and the scale \e k. No false easting or northing is added. 00055 * \e lat should be in the range (-90, 90] for \e northp = true and in the 00056 * range [-90, 90) for \e northp = false; \e lon should be in the range 00057 * [-180, 360]. 00058 **********************************************************************/ 00059 void Forward(bool northp, double lat, double lon, 00060 double& x, double& y, 00061 double& gamma, double& k) const throw(); 00062 00063 /** 00064 * Convert from polar stereogrphic easting \e x (meters) and northing \e y 00065 * (meters) to latitude \e lat (degrees) and longitude \e lon (degrees) . 00066 * The hemisphere is given by \e northp (false means south, true means 00067 * north). Also return the meridian convergence \e gamma (degrees) and the 00068 * scale \e k. No false easting or northing is added. The value of \e lon 00069 * returned is in the range [-180, 180). 00070 **********************************************************************/ 00071 void Reverse(bool northp, double x, double y, 00072 double& lat, double& lon, 00073 double& gamma, double& k) const throw(); 00074 00075 /** 00076 * A global instantiation of PolarStereographic with the WGS84 ellipsoid 00077 * and the UPS scale factor. However, unlike UPS, no false easting or 00078 * northing is added. 00079 **********************************************************************/ 00080 const static PolarStereographic UPS; 00081 }; 00082 00083 } // namespace GeographicLib 00084 00085 #endif