地理坐标系学习与GPS经纬度坐标WGS84到东北天坐标系ENU的转换(附代码)
地理坐标系学习与GPS经纬度坐标WGS84到东北天坐标系ENU的转换(附代码)
一、简介
1.1 ECEF坐标系
也叫地心地固直角坐标系。其原点为地球的质心,x轴延伸通过本初子午线(0度经度)和赤道(0deglatitude)的交点。 z轴延伸通过的北极(即,与地球旋转轴重合)。 y轴完成右手坐标系,穿过赤道和90度经度。
1.2 WGS-84坐标
也叫经纬高坐标系(经度(longitude),纬度(latitude)和高度(altitude)LLA坐标系)。,全球地理坐标系、大地坐标系。可以说是最为广泛应用的一个地球坐标系,它给出一点的大地纬度、大地经度和大地高程而更加直观地告诉我们该点在地球中的位置,故又被称作纬经高坐标系。WGS-84坐标系的X轴指向BIH(国际时间服务机构)1984.0定义的零子午面(Greenwich)和协议地球极(CTP)赤道的交点。Z轴指向CTP方向。Y轴与X、Z轴构成右手坐标系。
一句话解释就是:把前面提到的ECEF坐标系用在GPS中,就是WGS-84坐标系。
其中:
(1):大地纬度是过用户点P的基准椭球面法线与赤道面的夹角。纬度值在-90°到+90°之间。北半球为正,南半球为负。
(2):大地经度是过用户点P的子午面与本初子午线之间的夹角。经度值在-180°到+180°之间。
(3):大地高度h是过用户点P到基准椭球面的法线距离,基准椭球面以内为负,以外为正。
1.3 东北天坐标系(ENU)
也叫站心坐标系以用户所在位置P为坐标原点。
坐标系定义为: X轴:指向东边 Y轴:指向北边 Z轴:指向天顶
ENU局部坐标系采用三维直角坐标系来描述地球表面,实际应用较为困难,因此一般使用简化后的二维投影坐标系来描述。在众多二维投影坐标系中,统一横轴墨卡托(The Universal Transverse Mercator ,UTM)坐标系是一种应用较为广泛的一种。UTM 坐标系统使用基于网格的方法表示坐标,它将地球分为 60 个经度区,每个区包含6度的经度范围,每个区内的坐标均基于横轴墨卡托投影,如下图所示:
2.1 LLA坐标系转ECEF坐标系
(1)LLA坐标系下的(lon,lat,alt)转换为ECEF坐标系下点(X,Y,Z)
(2)其中e为椭球偏心率,N为基准椭球体的曲率半径
(3) 坐标转换公式也可以为
function enuToEcef(x, y, z, refLat, refLon, refAlt) {
var refEcef = geodeticToEcef(refLat, refLon, refAlt);
refLat = (refLat * Math.PI) / 180.0;
refLon = (refLon * Math.PI) / 180.0;
var cosLat = Math.cos(refLat);
var sinLat = Math.sin(refLat);
var cosLon = Math.cos(refLon);
var sinLon = Math.sin(refLon);
var X = -sinLon * x - sinLat * cosLon * y + cosLat * cosLon * z + refEcef[0];
var Y = cosLon * x - sinLat * sinLon * y + cosLat * sinLon * z + refEcef[1];
var Z = cosLat * y + sinLat * z + refEcef[2];
return [X, Y, Z];
}
function geodeticToEcef(lat, lon, alt) {
var a = 6378137.0;
var b = 6356752.31424518;
lat = (lat * Math.PI) / 180.0;
lon = (lon * Math.PI) / 180.0;
var cosLat = Math.cos(lat);
var sinLat = Math.sin(lat);
var cosLon = Math.cos(lon);
var sinLon = Math.sin(lon);
var a2 = a * a;
var b2 = b * b;
var L = 1.0 / Math.sqrt(a2 * cosLat * cosLat + b2 * sinLat * sinLat);
var nhcl = (a2 * L + alt) * cosLat;
var X = nhcl * cosLon;
var Y = nhcl * sinLon;
var Z = (b2 * L + alt) * sinLat;
return [X, Y, Z];
}
2.2 ECEF坐标系转LLA坐标系
ECEF坐标系下点(X,Y,Z)转换为LLA坐标系下的(lon,lat,alt)
一开始lon是未知的,可以假设为0,经过几次迭代之后就能收敛
function ecefToGeodetic(X, Y, Z) {
var a = 6378137.0;
var b = 6356752.31424518;
var a2 = a * a;
var b2 = b * b;
var a2mb2 = a2 - b2;
var ea = Math.sqrt(a2mb2 / a2);
var eb = Math.sqrt(a2mb2 / b2);
var p = Math.sqrt(X * X + Y * Y);
var theta = Math.atan2(Z * a, p * b);
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
var lon = Math.atan2(Y, X);
var lat = Math.atan2(Z + eb * eb * b * sinTheta * sinTheta * sinTheta, p - ea * ea * a * cosTheta * cosTheta * cosTheta);
var sinLat = Math.sin(lat);
var cosLat = Math.cos(lat);
var N = a / Math.sqrt(1 - ea * ea * sinLat * sinLat);
var alt = p / cosLat - N;
return [(lat * 180.0) / Math.PI, (lon * 180.0) / Math.PI, alt];
}
2.3 ECEF坐标系转ENU坐标系
用户所在坐标原点(P_0=(x_0,y_0,z_0)),,计算点(P=(x,y,z))在以点(P_0)为坐标原点的ENU坐标系位置(e,n,u)这里需要用到LLA坐标系的数据,(P_0)的LLA坐标点为(LLA_0=(lon_0,lat_0,alt_0))
function ecefToEnu(X, Y, Z, refLat, refLon, refAlt) {
var refEcef = geodeticToEcef(refLat, refLon, refAlt);
var V = [X - refEcef[0], Y - refEcef[1], Z - refEcef[2]];
refLat = (refLat * Math.PI) / 180.0;
refLon = (refLon * Math.PI) / 180.0;
var cosLat = Math.cos(refLat);
var sinLat = Math.sin(refLat);
var cosLon = Math.cos(refLon);
var sinLon = Math.sin(refLon);
var x = -sinLon * V[0] + cosLon * V[1];
var y = -sinLat * cosLon * V[0] - sinLat * sinLon * V[1] + cosLat * V[2];
var z = cosLat * cosLon * V[0] + cosLat * sinLon * V[1] + sinLat * V[2];
return [x, y, z];
}