我正在寻找一种从lat,lon和height数据计算ECEF坐标的书面方法。我找到了这个java方法但我的编码技巧不允许我将其转移到swift。
private final double a = 6378137; // radius
private final double e = 8.1819190842622e-2; // eccentricity
private final double asq = Math.pow(a,2);
private final double esq = Math.pow(e,2);
private double[] ecef2lla(double[] ecef){
double x = ecef[0];
double y = ecef[1];
double z = ecef[2];
double b = Math.sqrt( asq * (1-esq) );
double bsq = Math.pow(b,2);
double ep = Math.sqrt( (asq - bsq)/bsq);
double p = Math.sqrt( Math.pow(x,2) + Math.pow(y,2) );
double th = Math.atan2(a*z, b*p);
double lon = Math.atan2(y,x);
double lat = Math.atan2( (z + Math.pow(ep,2)*b*Math.pow(Math.sin(th),3) ), (p - esq*a*Math.pow(Math.cos(th),3)) );
double N = a/( Math.sqrt(1-esq*Math.pow(Math.sin(lat),2)) );
double alt = p / Math.cos(lat) - N;
// mod lat to 0-2pi
lon = lon % (2*Math.PI);
// correction for altitude near poles left out.
double[] ret = {lat, lon, alt};
return ret;
}
谢谢你的帮助。
答案 0 :(得分:1)
这是直接翻译,(除了对%输出的小修正):
let a:Double = 6378137 // radius
let e:Double = 8.1819190842622e-2 // eccentricity
let asq = pow(a,2)
let esq = pow(e,2)
func ecef2lla(ecef:[Double]) -> [Double] {
let x = ecef[0]
let y = ecef[1]
let z = ecef[2]
let b = sqrt( asq * (1-esq) )
let bsq = pow(b,2)
let ep = sqrt( (asq - bsq)/bsq)
let p = sqrt( pow(x,2) + pow(y,2) )
let th = atan2(a*z, b*p)
var lon = atan2(y,x)
let lat = atan2( (z + pow(ep,2)*b*pow(sin(th),3) ), (p - esq*a*pow(cos(th),3)) )
let N = a/( sqrt(1-esq*pow(sin(lat),2)) )
let alt = p / cos(lat) - N
// mod lat to 0-2pi
lon = lon % (2*M_PI)
if lon < 0 {
lon += 2*M_PI
}
// correction for altitude near poles left out.
let ret = [lat, lon, alt]
return ret
}
对于反向功能,请看这个答案: ECEF to LLA in Python
转换为Swift:
func lla2ecef(lat lat: Double, lon: Double, alt: Double) -> [Double] {
// see http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html
let rad = 6378137.0 // Radius of the Earth (in meters)
let f = 1.0/298.257223563 // Flattening factor WGS84 Model
let cosLat = cos(lat)
let sinLat = sin(lat)
let FF = pow((1.0-f), 2)
let C = 1/sqrt(pow(cosLat, 2) + FF * pow(sinLat,2))
let S = C * FF
let x = (rad * C + alt)*cosLat * cos(lon)
let y = (rad * C + alt)*cosLat * sin(lon)
let z = (rad * S + alt)*sinLat
return [x, y, z]
}
lla2ecef(lat: 42.0 / 180.0 * M_PI, lon: 28.0 / 180.0 * M_PI, alt: 0.0)
答案 1 :(得分:1)
func toECEF(lat:Double,lon:Double, h: Double) -> [Double]{
let a : Double = 6378137 // radius
let e : Double = 8.1819190842622e-2 // eccentricity
let lat = lat / 180 * M_PI
let lon = lon / 180 * M_PI
let h = h
let e2 = pow(e, 2)
let slat = sin(lat)
let clat = cos(lat)
let N = a / sqrt(1-e2 * slat * slat)
let x = (N + h) * clat * cos(lon)
let y = (N + h) * clat * sin(lon)
let z = (N * (1 - e2) + h) * slat
return [x,y,z]
}
toECEF(42,lon:28,h:0)
结果:[4191342.320476103,2228582.38702054,4245611.943048043]