Cristiano
Cristiano

Reputation: 31

How to compute Direct and Inverse Conversion between geodetic coordinates (ECEF) to local reference (ENU)

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

Answers (2)

JeremyP
JeremyP

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

Abraham Avnisan
Abraham Avnisan

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

Related Questions