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

我查看了网站上的post,但没有发现我的问题…正如头条说我试图从ecef转换为lla。

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

我在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; } 

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

先感谢您 !

我发现这篇文章并准备在我的应用程序的一部分中使用“已接受的答案”,但我决定先运行几个测试来validation算法。 我使用了在线转换计算器生成的样本数据( 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 

然后我使用以下post( 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 

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

 /* * * 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; } 

好的,所以我得到了这个工作。

问题是一个错位的变量,所以为了我们的未来,这里是工作的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; } 

注意ECEF XYZ的单位是

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

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