快速固定在地球中心地球的Lat Lon高度

时间:2016-03-03 23:54:59

标签: java swift gps

我正在寻找一种从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;
        }

谢谢你的帮助。

2 个答案:

答案 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]