text: // UTM.h
  
  // Original Javascript by Chuck Taylor
  // Port to C++ by Alex Hajnal
  //
  // *** THIS CODE USES 32-BIT FLOATS BY DEFAULT ***
  // *** For 64-bit double-precision edit this file: undefine FLOAT_32 and define FLOAT_64 (see below)
  // 
  // This is a simple port of the code on the Geographic/UTM Coordinate Converter (1) page from Javascript to C++.
  // Using this you can easily convert between UTM and WGS84 (latitude and longitude).
  // Accuracy seems to be around 50cm (I suspect rounding errors are limiting precision).
  // This code is provided as-is and has been minimally tested; enjoy but use at your own risk!
  // The license for UTM.cpp and UTM.h is the same as the original Javascript: 
  // "The C++ source code in UTM.cpp and UTM.h may be copied and reused without restriction."
  // 
  // 1) http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html
  
  #ifndef UTM_H
  #define UTM_H
  
  // Choose floating point precision:
  
  // 32-bit (for Teensy 3.5/3.6 ARM boards, etc.)
  #define FLOAT_64
  
  // 64-bit (for desktop/server use)
  //#define FLOAT_64
  
  #ifdef FLOAT_64
  #define FLOAT double
  #define SIN sin
  #define COS cos
  #define TAN tan
  #define POW pow
  #define SQRT sqrt
  #define FLOOR floor
  
  #else
  #ifdef FLOAT_32
  #define FLOAT float
  #define SIN sinf
  #define COS cosf
  #define TAN tanf
  #define POW powf
  #define SQRT sqrtf
  #define FLOOR floorf
  
  #endif
  #endif
  
  
  #include <math.h>
  
  #define pi 3.14159265358979
  
  /* Ellipsoid model constants (actual values here are for WGS84) */
  #define sm_a 6378137.0
  #define sm_b 6356752.314
  #define sm_EccSquared 6.69437999013e-03
  
  #define UTMScaleFactor 0.9996
  
  // DegToRad
  // Converts degrees to radians.
  FLOAT DegToRad(FLOAT deg);
  
  // RadToDeg
  // Converts radians to degrees.
  FLOAT RadToDeg(FLOAT rad);
  
  // ArcLengthOfMeridian
  // Computes the ellipsoidal distance from the equator to a point at a
  // given latitude.
  // 
  // Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
  // GPS: Theory and Practice, 3rd ed.  New York: Springer-Verlag Wien, 1994.
  // 
  // Inputs:
  //     phi - Latitude of the point, in radians.
  // 
  // Globals:
  //     sm_a - Ellipsoid model major axis.
  //     sm_b - Ellipsoid model minor axis.
  // 
  // Returns:
  //     The ellipsoidal distance of the point from the equator, in meters.
  FLOAT ArcLengthOfMeridian (FLOAT phi);
  
  // UTMCentralMeridian
  // Determines the central meridian for the given UTM zone.
  //
  // Inputs:
  //     zone - An integer value designating the UTM zone, range [1,60].
  //
  // Returns:
  //   The central meridian for the given UTM zone, in radians
  //   Range of the central meridian is the radian equivalent of [-177,+177].
  FLOAT UTMCentralMeridian(int zone);
  
  // FootpointLatitude
  //
  // Computes the footpoint latitude for use in converting transverse
  // Mercator coordinates to ellipsoidal coordinates.
  //
  // Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
  //   GPS: Theory and Practice, 3rd ed.  New York: Springer-Verlag Wien, 1994.
  //
  // Inputs:
  //   y - The UTM northing coordinate, in meters.
  //
  // Returns:
  //   The footpoint latitude, in radians.
  FLOAT FootpointLatitude(FLOAT y);
  
  // MapLatLonToXY
  // Converts a latitude/longitude pair to x and y coordinates in the
  // Transverse Mercator projection.  Note that Transverse Mercator is not
  // the same as UTM; a scale factor is required to convert between them.
  //
  // Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
  // GPS: Theory and Practice, 3rd ed.  New York: Springer-Verlag Wien, 1994.
  //
  // Inputs:
  //    phi - Latitude of the point, in radians.
  //    lambda - Longitude of the point, in radians.
  //    lambda0 - Longitude of the central meridian to be used, in radians.
  //
  // Outputs:
  //    x - The x coordinate of the computed point.
  //    y - The y coordinate of the computed point.
  //
  // Returns:
  //    The function does not return a value.
  void MapLatLonToXY (FLOAT phi, FLOAT lambda, FLOAT lambda0, FLOAT &x, FLOAT &y);
  
  // MapXYToLatLon
  // Converts x and y coordinates in the Transverse Mercator projection to
  // a latitude/longitude pair.  Note that Transverse Mercator is not
  // the same as UTM; a scale factor is required to convert between them.
  //
  // Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
  //   GPS: Theory and Practice, 3rd ed.  New York: Springer-Verlag Wien, 1994.
  //
  // Inputs:
  //   x - The easting of the point, in meters.
  //   y - The northing of the point, in meters.
  //   lambda0 - Longitude of the central meridian to be used, in radians.
  //
  // Outputs:
  //   phi    - Latitude in radians.
  //   lambda - Longitude in radians.
  //
  // Returns:
  //   The function does not return a value.
  //
  // Remarks:
  //   The local variables Nf, nuf2, tf, and tf2 serve the same purpose as
  //   N, nu2, t, and t2 in MapLatLonToXY, but they are computed with respect
  //   to the footpoint latitude phif.
  //
  //   x1frac, x2frac, x2poly, x3poly, etc. are to enhance readability and
  //   to optimize computations.
  void MapXYToLatLon (FLOAT x, FLOAT y, FLOAT lambda0, FLOAT& phi, FLOAT& lambda);
  
  // LatLonToUTMXY
  // Converts a latitude/longitude pair to x and y coordinates in the
  // Universal Transverse Mercator projection.
  //
  // Inputs:
  //   lat - Latitude of the point, in radians.
  //   lon - Longitude of the point, in radians.
  //   zone - UTM zone to be used for calculating values for x and y.
  //          If zone is less than 1 or greater than 60, the routine
  //          will determine the appropriate zone from the value of lon.
  //
  // Outputs:
  //   x - The x coordinate (easting) of the computed point. (in meters)
  //   y - The y coordinate (northing) of the computed point. (in meters)
  //
  // Returns:
  //   The UTM zone used for calculating the values of x and y.
  int LatLonToUTMXY (FLOAT lat, FLOAT lon, int zone, FLOAT& x, FLOAT& y);
  
  // UTMXYToLatLon
  //
  // Converts x and y coordinates in the Universal Transverse Mercator//   The UTM zone parameter should be in the range [1,60].
  
  // projection to a latitude/longitude pair.
  //
  // Inputs:
  // x - The easting of the point, in meters.
  // y - The northing of the point, in meters.
  // zone - The UTM zone in which the point lies.
  // southhemi - True if the point is in the southern hemisphere;
  //               false otherwise.
  //
  // Outputs:
  // lat - The latitude of the point, in radians.
  // lon - The longitude of the point, in radians.
  // 
  // Returns:
  // The function does not return a value.
  void UTMXYToLatLon (FLOAT x, FLOAT y, int zone, bool southhemi, FLOAT& lat, FLOAT& lon);
  
  #endif
  
  