将纬度和经度转换为3D空间中的点

时间:2012-05-06 20:07:34

标签: python math 3d latitude-longitude data-conversion

我需要将纬度和经度值转换为三维空间中的一个点。我现在已经尝试了大约2个小时,但是我没有得到正确的结果。

Equirectangular 坐标来自openflights.org。我已经尝试过几种 cos sin 的组合,但结果看起来从来都不像我们心爱的小地球。


在下文中,您可以看到应用转化Wikipedia建议的结果。我想可以从上下文中猜出c4d.Vector是什么。

def llarToWorld(latit, longit, altid, rad):
    x = math.sin(longit) * math.cos(latit)
    z = math.sin(longit) * math.sin(latit)
    y = math.cos(longit)
    v = c4d.Vector(x, y, z)
    v = v * altid + v * rad
    return v

enter image description here

红色:X,绿色:Y,蓝色:Z

确实可以识别出北美和南美,尤其是墨西哥湾周围的土地。然而,它看起来有点挤压,有点在错误的地方..


结果看起来有些旋转,我想,我尝试了交换纬度和经度。但结果有点尴尬。

def llarToWorld(latit, longit, altid, rad):
    temp = latit
    latit = longit
    longit = temp
    x = math.sin(longit) * math.cos(latit)
    z = math.sin(longit) * math.sin(latit)
    y = math.cos(longit)
    v = c4d.Vector(x, y, z)
    v = v * altid + v * rad
    return v

enter image description here


这是没有转换值的结果。

def llarToWorld(latit, longit, altid, rad):
    return c4d.Vector(math.degrees(latit), math.degrees(longit), altid)

enter image description here


问题:如何正确转换经度和纬度?


解决方案

感谢TreyA,我在mathworks.com上找到了this页面。执行此操作的代码如下:

def llarToWorld(lat, lon, alt, rad):
    # see: http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html
    f  = 0                              # flattening
    ls = atan((1 - f)**2 * tan(lat))    # lambda

    x = rad * cos(ls) * cos(lon) + alt * cos(lat) * cos(lon)
    y = rad * cos(ls) * sin(lon) + alt * cos(lat) * sin(lon)
    z = rad * sin(ls) + alt * sin(lat)

    return c4d.Vector(x, y, z)

实际上,我切换了yz,因为地球已经旋转了,但是,它有效!这就是结果:

enter image description here

3 个答案:

答案 0 :(得分:12)

你没有按照维基百科的建议去做。仔细阅读。

他们说:

x = r cos(phi) sin(theta)
y = r sin(phi) sin(theta)
z = r cos(theta)

然后:

theta == latitude
phi == longitude

,在您的情况下,r = radius + altitude

所以你应该使用:

r = radius + altitude
x = r cos(long) sin(lat)
y = r sin(long) sin(lat)
z = r cos(lat)

请注意,最后一个条目是cos(lat)(您使用的是经度)。

答案 1 :(得分:12)

我已经重新格式化了之前提到的代码,但更重要的是,你遗漏了 Niklas R 提供的链接中提到的一些方程式

def LLHtoECEF(lat, lon, alt):
    # see http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html

    rad = np.float64(6378137.0)        # Radius of the Earth (in meters)
    f = np.float64(1.0/298.257223563)  # Flattening factor WGS84 Model
    cosLat = np.cos(lat)
    sinLat = np.sin(lat)
    FF     = (1.0-f)**2
    C      = 1/np.sqrt(cosLat**2 + FF * sinLat**2)
    S      = C * FF

    x = (rad * C + alt)*cosLat * np.cos(lon)
    y = (rad * C + alt)*cosLat * np.sin(lon)
    z = (rad * S + alt)*sinLat

    return (x, y, z)

比较输出:为洛杉矶,加利福尼亚州找到ECEF(34.0522,-118.40806,0海拔)
我的代码:
X = -2516715.36114米或 -2516.715 km
Y = -4653003.08089米或 -4653.003 km
Z = 3551245.35929米或 3551.245 km

您的密码:
X = -2514072.72181米或 -2514.072 km
Y = -4648117.26458米或 -4648.117 km
Z = 3571424.90261米或 3571.424 km

虽然在你的地球自转环境中你的功能会产生正确的地理区域以供显示,但 NOT 会给出正确的ECEF等效坐标。正如您所看到的,某些参数的变化范围为 20 KM ,这是一个很大的错误。

展平系数f取决于您为转化假设的模型。典型的模型是WGS 84;但是,还有其他型号。

就个人而言,我喜欢使用this link海军研究生院对我的转换进行健全性检查。

答案 2 :(得分:4)

作为 TreyA statet,LLA to ECEF是解决方案。见http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html