/usr/include/GeographicLib/TransverseMercator.hpp is in libgeographiclib-dev 1.8-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | /**
* \file TransverseMercator.hpp
* \brief Header for GeographicLib::TransverseMercator class
*
* Copyright (c) Charles Karney (2008, 2009, 2010, 2011) <charles@karney.com>
* and licensed under the LGPL. For more information, see
* http://geographiclib.sourceforge.net/
**********************************************************************/
#if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP)
#define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP "$Id: TransverseMercator.hpp 6950 2011-02-11 04:09:24Z karney $"
#include "GeographicLib/Constants.hpp"
#if !defined(TM_TX_MAXPOW)
/**
* The order of the series approximation used in TransverseMercator.
* TM_TX_MAXPOW can be set to any integer in [4, 8].
**********************************************************************/
#define TM_TX_MAXPOW \
(GEOGRAPHICLIB_PREC == 1 ? 6 : GEOGRAPHICLIB_PREC == 0 ? 4 : 8)
#endif
namespace GeographicLib {
/**
* \brief Transverse Mercator Projection
*
* This uses Krüger's method which evaluates the projection and its
* inverse in terms of a series. See
* - L. Krüger,
* <a href="http://dx.doi.org/10.2312/GFZ.b103-krueger28"> Konforme
* Abbildung des Erdellipsoids in der Ebene</a> (Conformal mapping of the
* ellipsoidal earth to the plane), Royal Prussian Geodetic Institute, New
* Series 52, 172 pp. (1912).
* - C. F. F. Karney,
* <a href="http://dx.doi.org/10.1007/s00190-011-0445-3">
* Transverse Mercator with an accuracy of a few nanometers,</a>
* J. Geodesy (2011);
* preprint
* <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>.
*
* Krüger's method has been extended from 4th to 6th order. The maximum
* errors is 5 nm (ground distance) for all positions within 35 degrees of
* the central meridian. The error in the convergence is 2e-15" and the
* relative error in the scale is 6e-12%%. See Sec. 4 of
* <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for details.
* The speed penalty in going to 6th order is only about 1%.
* TransverseMercatorExact is an alternative implementation of the projection
* using exact formulas which yield accurate (to 8 nm) results over the
* entire ellipsoid.
*
* The ellipsoid parameters and the central scale are set in the constructor.
* The central meridian (which is a trivial shift of the longitude) is
* specified as the \e lon0 argument of the TransverseMercator::Forward and
* TransverseMercator::Reverse functions. The latitude of origin is taken to
* be the equator. There is no provision in this class for specifying a
* false easting or false northing or a different latitude of origin.
* However these are can be simply included by the calling funtcion. For
* example, the UTMUPS class applies the false easting and false northing for
* the UTM projections. A more complicated example is the British National
* Grid (<a href="http://www.spatialreference.org/ref/epsg/7405/">
* EPSG:7405</a>) which requires the use of a latitude of origin. This is
* implemented by the GeographicLib::OSGB class.
*
* See TransverseMercator.cpp for more information on the implementation.
*
* See \ref transversemercator for a discussion of this projection.
**********************************************************************/
class TransverseMercator {
private:
typedef Math::real real;
static const int maxpow = TM_TX_MAXPOW;
static const real tol, overflow;
static const int numit = 5;
const real _a, _r, _f, _k0, _e2, _e, _e2m, _c, _n;
// _alp[0] and _bet[0] unused
real _a1, _b1, _alp[maxpow + 1], _bet[maxpow + 1];
static inline real sq(real x) throw() { return x * x; }
// tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
static inline real tanx(real x) throw() {
real t = std::tan(x);
// Write the tests this way to ensure that tanx(NaN()) is NaN()
return x >= 0 ? (!(t < 0) ? t : overflow) : (!(t >= 0) ? t : -overflow);
}
// Return e * atanh(e * x) for f >= 0, else return
// - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
inline real eatanhe(real x) const throw() {
return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x);
}
public:
/**
* Constructor for a ellipsoid with
*
* @param[in] a equatorial radius (meters)
* @param[in] r reciprocal flattening. Setting \e r = 0 implies \e r = inf
* or flattening = 0 (i.e., a sphere). Negative \e r indicates a prolate
* ellipsoid.
* @param[in] k0 central scale factor.
*
* An exception is thrown if either of the axes of the ellipsoid or \e k0
* is not positive.
**********************************************************************/
TransverseMercator(real a, real r, real k0);
/**
* Forward projection, from geographic to transverse Mercator.
*
* @param[in] lon0 central meridian of the projection (degrees).
* @param[in] lat latitude of point (degrees).
* @param[in] lon longitude of point (degrees).
* @param[out] x easting of point (meters).
* @param[out] y northing of point (meters).
* @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point.
*
* No false easting or northing is added. \e lat should be in the range
* [-90, 90]; \e lon and \e lon0 should be in the range [-180, 360].
**********************************************************************/
void Forward(real lon0, real lat, real lon,
real& x, real& y, real& gamma, real& k) const throw();
/**
* Reverse projection, from transverse Mercator to geographic.
*
* @param[in] lon0 central meridian of the projection (degrees).
* @param[in] x easting of point (meters).
* @param[in] y northing of point (meters).
* @param[out] lat latitude of point (degrees).
* @param[out] lon longitude of point (degrees).
* @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point.
*
* No false easting or northing is added. \e lon0 should be in the range
* [-180, 360]. The value of \e lon returned is in the range [-180, 180).
**********************************************************************/
void Reverse(real lon0, real x, real y,
real& lat, real& lon, real& gamma, real& k) const throw();
/**
* TransverseMercator::Forward without returning the convergence and scale.
**********************************************************************/
void Forward(real lon0, real lat, real lon,
real& x, real& y) const throw() {
real gamma, k;
Forward(lon0, lat, lon, x, y, gamma, k);
}
/**
* TransverseMercator::Reverse without returning the convergence and scale.
**********************************************************************/
void Reverse(real lon0, real x, real y,
real& lat, real& lon) const throw() {
real gamma, k;
Reverse(lon0, x, y, lat, lon, gamma, k);
}
/** \name Inspector functions
**********************************************************************/
///@{
/**
* @return \e a the equatorial radius of the ellipsoid (meters). This is
* the value used in the constructor.
**********************************************************************/
Math::real MajorRadius() const throw() { return _a; }
/**
* @return \e r the inverse flattening of the ellipsoid. This is the
* value used in the constructor. A value of 0 is returned for a sphere
* (infinite inverse flattening).
**********************************************************************/
Math::real InverseFlattening() const throw() { return _r; }
/**
* @return \e k0 central scale for the projection. This is the value of \e
* k0 used in the constructor and is the scale on the central meridian.
**********************************************************************/
Math::real CentralScale() const throw() { return _k0; }
///@}
/**
* A global instantiation of TransverseMercator with the WGS84 ellipsoid
* and the UTM scale factor. However, unlike UTM, no false easting or
* northing is added.
**********************************************************************/
static const TransverseMercator UTM;
};
} // namespace GeographicLib
#endif
|