2016-03-03 7 views
0

我正在尋找一種書面方法來計算經度,緯度和高度數據的ECEF座標。我已經找到了這個java方法,但是我的編碼技巧不允許我將其轉換爲swift。Lat Lon以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

您是否看着[OpenMap](https://github.com/OpenMap-java/openmap)? – bradimus

+0

@bradimus我想在Swift中做到這一點。 –

回答

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) 
+0

它工作!但是我需要相反的計算方法...(LCE LON HEIGHT to ECEF:( –

+0

)對不起,對於eef到lat lon的高度也沒有計算正確。 –

+0

什麼部分是不正確的?我只是修復了'lon'。 – vacawama

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,經度:28,H:0)

結果:[4191342.320476103,2228582.38702054,4245611.943048043]

+1

您應該使用'M_PI'而不是'3.1416'。 – vacawama

+0

我剛剛意識到:) –

+0

改變了它。謝謝 –

相關問題