Reputation: 31
How to convert X,Y,Z from local reference (ENU) to world reference (ECEF) and reverse it ??
Input:
(lat,long) = center of the local reference system.
x,y,z = position of the point,in local system reference.
Output: (lat,long)= poistion of the point in WGS84. Also: reverse coordinate.
I suppose the step is:
1) convert Xlocal,Ylocal,Zlocal -> Xecef,Yecef,Zecef
2) convert Xecef,Yecef,Zecef -> Lat,Long (WGS84)
And than
1) convert Lat,Long(WGS84) -> Xecef,Yecef,Zecef
2) convert Xecef,Yecef,Zecef -> Xlocal,Ylocal,Zlocal
Upvotes: 2
Views: 5794
Reputation: 86661
The Ordnance Survey has published A Guide to Coordinate Systems in Great Britain. It's a PDF document that contains the mathematical algorithms for converting between lat/long and cartesian coordinates. Obviously it is oriented towards British systems, but the parameters needed for WGS84 are given in the guide.
Upvotes: 2
Reputation: 51
I'm working on a geospatial AR app and have just tackled this myself in objective-C / iOS (with quite a bit of help from this example code from Apple).
The three C functions to convert from lat lon to ecef to ENU and back are below. The mathematical formulas come from this wikipedia article.
#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))
#define DEGREES_TO_RADIANS(degrees)((M_PI * degrees)/180)
#define WGS84_A (6378137.0) // WGS 84 semi-major axis constant in meters
#define WGS84_E (8.1819190842622e-2) // WGS 84 eccentricity
// Converts latitude, longitude to ECEF coordinate system
void latLonToEcef(double lat, double lon, double alt, double *x, double *y, double *z)
{
double clat = cos(DEGREES_TO_RADIANS(lat));
double slat = sin(DEGREES_TO_RADIANS(lat));
double clon = cos(DEGREES_TO_RADIANS(lon));
double slon = sin(DEGREES_TO_RADIANS(lon));
double N = WGS84_A / sqrt(1.0 - WGS84_E * WGS84_E * slat * slat);
*x = (N + alt) * clat * clon;
*y = (N + alt) * clat * slon;
*z = (N * (1.0 - WGS84_E * WGS84_E) + alt) * slat;
}
// Converts ECEF to ENU coordinates centered at given lat, lon
void ecefToEnu(double lat, double lon, double xRef, double yRef, double zRef, double xPOI, double yPOI, double zPOI, double *e, double *n, double *u)
{
double clat = cos(DEGREES_TO_RADIANS(lat));
double slat = sin(DEGREES_TO_RADIANS(lat));
double clon = cos(DEGREES_TO_RADIANS(lon));
double slon = sin(DEGREES_TO_RADIANS(lon));
double dx = xPOI - xRef;
double dy = yPOI - yRef;
double dz = zPOI - zRef;
*e = -slon * dx + clon * dy;
*n = -slat * clon * dx - slat * slon * dy + clat * dz;
*u = clat * clon * dx + clat * slon * dy + slat * dz;
}
// Converts ENU of a POI (in realtion to a reference point) to ECEF coordinates
void enuToEcef(double lat, double lon, double xRef, double yRef, double zRef, double *xPOI, double *yPOI, double *zPOI, double e, double n, double u)
{
double clat = cos(DEGREES_TO_RADIANS(lat));
double slat = sin(DEGREES_TO_RADIANS(lat));
double clon = cos(DEGREES_TO_RADIANS(lon));
double slon = sin(DEGREES_TO_RADIANS(lon));
*xPOI = (-slon * e) + (-slat * clon * n) + (clat * clon * u) + xRef;
*yPOI = (clon * e) + (-slat * slon * n) + (clat * slon * u) + yRef;
*zPOI = (0 * e) + (clat * n) + (slat * u) + zRef;
}
Upvotes: 1