Как вычислить прямое и обратное преобразование между геодезическими координатами (ECEF) в локальную привязку (ENU) - PullRequest
2 голосов
/ 08 июня 2011

Как преобразовать X, Y, Z из локального эталона (ENU) в мировой эталон (ECEF) и обратить его обратно?

Ввод:

(lat,long) = center of the local reference system.
       x,y,z = position of the point,in local system reference.

Выход: (лат,long) = точка в WGS84.Также: обратная координата.

Я полагаю, шаг:

1) convert Xlocal,Ylocal,Zlocal  -> Xecef,Yecef,Zecef

2) convert Xecef,Yecef,Zecef     -> Lat,Long (WGS84)

И чем

1) convert Lat,Long(WGS84)       -> Xecef,Yecef,Zecef

2) convert Xecef,Yecef,Zecef     -> Xlocal,Ylocal,Zlocal

Ответы [ 2 ]

2 голосов
/ 08 июня 2011

В Обзоре артиллерии опубликовано Руководство по системам координат в Великобритании .Это PDF-документ, содержащий математические алгоритмы для преобразования между широтой / долготой и декартовыми координатами.Очевидно, что он ориентирован на британские системы, но параметры, необходимые для WGS84, приведены в руководстве.

0 голосов
/ 17 июня 2016

Я работаю над геопространственным AR-приложением и только что занялся этим в target-C / iOS (с небольшой помощью этого примера кода от Apple).

Ниже приведены три функции C для преобразования из латинского в ecef в ENU и обратно. Математические формулы взяты из этой статьи в Википедии.

#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;

}
...