You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
6.3 KiB
206 lines
6.3 KiB
// 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 |
|
|
|
|