在 Java 中 ECEF 到 lla (lat,lon,alt)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18253546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:45:38  来源:igfitidea点击:

ECEF to lla (lat,lon,alt) in java

javamathgpslatitude-longitudecoordinate-systems

提问by dbkoren

Ive looked through the posts in the site and haven't found my problem ... as the head line says im trying to convert from ecef to lla .

我浏览了网站上的帖子,但没有发现我的问题......正如标题所说,我正在尝试从 ecef 转换为 lla 。

I'm using this document : Conversion articlein the direct formula , not the iterate formula and this site for result comparison : ECEF2LLA

我正在使用此文档: 直接公式中的转换文章,而不是迭代公式和此站点进行结果比较:ECEF2LLA

Im developing in java so my code is as follows :

我用java开发所以我的代码如下:

public static final double a = 6378137;
public static final double f = 1/298.257223563;
public static final double b = a*(1-f);
public static final double e = Math.sqrt((Math.pow(a, 2)-Math.pow(b, 2))/Math.pow(a, 2));
public static final double e2 = Math.sqrt((Math.pow(a, 2)-Math.pow(b, 2))/Math.pow(b, 2));
public static double[] ecef2lla(double x , double y , double z){
    double[] lla = {0,0,0};
    double lon,lat,height,N;
    double p = Math.sqrt(Math.pow(x, 2)+Math.pow(y, 2));
    double theta = Math.atan((z*a)/(p*b));
    lon = Math.atan(y/x);
    lon = lon*180/Math.PI;

    lat = Math.atan(((z+Math.pow(e2, 2)*b*Math.pow(Math.sin(theta), 3))/((p-Math.pow(e,2)*a*Math.pow(Math.cos(theta), 3)))));
    lat = (lat*180)/Math.PI;

    N= a/(Math.sqrt(1-Math.pow(e*Math.sin(lat), 2)));
    height = (p/Math.cos(theta)) - N;
    lla[0] = lon;
    lla[1] = lat;
    lla[2] = height;
    return lla;

}

I'm getting wrong height data. I've tried to move to radians and degrees and what not .

我得到错误的高度数据。我试图移动到弧度和度数,什么不是。

Thank you in advance !

先感谢您 !

采纳答案by dbkoren

OK so i got this working.

好的,所以我开始工作了。

The problem was a misplaced variable, so for the sake of our future here's the working JAVA implementation :

问题是一个错位的变量,所以为了我们的未来,这里是可用的 JAVA 实现:

public static final double a = 6378137;
public static final double f = 0.0034;
public static final double b = 6.3568e6;
public static final double e = Math.sqrt((Math.pow(a, 2) - Math.pow(b, 2)) / Math.pow(a, 2));
public static final double e2 = Math.sqrt((Math.pow(a, 2) - Math.pow(b, 2)) / Math.pow(b, 2));

public static double[] ecef2lla(double x, double y, double z) {

    double[] lla = { 0, 0, 0 };
    double lan, lon, height, N , theta, p;

    p = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));

    theta = Math.atan((z * a) / (p * b));

    lon = Math.atan(y / x);

    lat = Math.atan(((z + Math.pow(e2, 2) * b * Math.pow(Math.sin(theta), 3)) / ((p - Math.pow(e, 2) * a * Math.pow(Math.cos(theta), 3)))));
    N = a / (Math.sqrt(1 - (Math.pow(e, 2) * Math.pow(Math.sin(lat), 2))));

    double m = (p / Math.cos(lat));
    height = m - N;


    lon = lon * 180 / Math.PI;
    lat = lat * 180 / Math.PI; 
    lla[0] = lat;
    lla[1] = lon;
    lla[2] = height;
    return lla;
}

Note: The units for the ECEF X Y Zare in Meters!

注意ECEF XYZ的单位是

回答by Kyle Melton

I found this post and was ready to use the "accepted answer" in part of my application but I decided to run a couple of tests first to validate the algorithm. I used sample data generated by an online conversion calculator (http://www.sysense.com/products/ecef_lla_converter/index.html). I got less than stellar results as shown by the output below.

我找到了这篇文章,并准备在我的应用程序的一部分中使用“接受的答案”,但我决定先运行几个测试来验证算法。我使用了由在线转换计算器 ( http://www.sysense.com/products/ecef_lla_converter/index.html)生成的示例数据。如下面的输出所示,我得到的结果并不理想。

-----Test 1---------
Inputs:   -576793.17, -5376363.47, 3372298.51
Expected: 32.12345, -96.12345, 500.0
Actuals:  32.12306332822881, 83.87654999786477, 486.5472474489361
-----Test 2---------
Inputs:   2297292.91, 1016894.94, -5843939.62
Expected: -66.87654, 23.87654, 1000.0
Actuals:  -66.876230479461, 23.87653991401422, 959.6879360172898

Then I reran the same tests using the code from the following post (https://gist.github.com/klucar/1536194) and got much better results as shown by the output below.

然后我使用以下帖子(https://gist.github.com/klucar/1536194)中的代码重新运行相同的测试,并获得了更好的结果,如下面的输出所示。

-----Test 1---------
Inputs:   -576793.17, -5376363.47, 3372298.51
Expected: 32.12345, -96.12345, 500.0
Actuals:  32.12345004807767, -96.12345000213524, 499.997958839871
-----Test 2---------
Inputs:   2297292.91, 1016894.94, -5843939.62
Expected: -66.87654, 23.87654, 1000.0
Actuals:  -66.87654001741278, 23.87653991401422, 999.9983866894618

I didn't take the time to find the error in the solution provided in the "accepted answer" but my suggested answer: Use this code...

我没有花时间在“接受的答案”中提供的解决方案中找到错误,但我建议的答案是:使用此代码...

/*
*
*  ECEF - Earth Centered Earth Fixed
*   
*  LLA - Lat Lon Alt
*
*  ported from matlab code at
*  https://gist.github.com/1536054
*     and
*  https://gist.github.com/1536056
*/

// WGS84 ellipsoid constants
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;
}

回答by Graham S

If you are interested in using a published java library to convert between cartesian and geodetic coordinate systems, you can use the java orbit propagation library orekit.

如果您对使用已发布的 java 库在笛卡尔坐标系和大地坐标系之间进行转换感兴趣,可以使用 java 轨道传播库orekit

While Orekit provides some advanced features, it is not very easy to dive into. To help get you started I've written a sample code does some conversions. My code is in Scala but it uses the java library, so it should still be helpful. See the example code here.

虽然 Orekit 提供了一些高级功能,但并不容易深入研究。为了帮助您入门,我编写了一个示例代码进行了一些转换。我的代码在 Scala 中,但它使用了 java 库,所以它应该仍然有帮助。请参阅此处的示例代码。