22

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

Equirectangular坐标来自openflights.org 我尝试了几种cossin的组合,但结果看起来不像我们心爱的小地球。


在下文中,您可以看到应用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

在此处输入图像描述

红色: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

在此处输入图像描述


这是没有转换值的结果。

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

在此处输入图像描述


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


解决方案

感谢 TreyA,我在 mathworks.com 上找到了这个页面。执行它的代码如下:

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因为那时地球是旋转的,但是,它起作用了!结果是这样的:

在此处输入图像描述

4

3 回答 3

15

我已经重新格式化了之前提到的代码here,但更重要的是,您遗漏了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 公里
Y = -4653003.08089 米或-4653.003 公里
Z = 3551245.35929 米或3551.245 公里

您的代码:
X = -2514072.72181 米或-2514.072 公里
Y = -4648117.26458 米或-4648.117 公里
Z = 3571424.90261 米或3571.424 公里

尽管在您的地球自转环境中,您的函数将生成正确的地理区域以供显示,但它不会给出正确的 ECEF 等效坐标。正如你所看到的,一些参数相差多达20 公里,这是一个相当大的误差。

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

就个人而言,我喜欢使用这个指向海军研究生院的链接来检查我的转换情况。

于 2013-12-03T19:34:26.423 回答
14

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

他们说:

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

进而:

theta == latitude
phi == longitude

并且,在您的情况下, r = 半径 + 高度

所以你应该使用:

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

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

于 2012-05-06T23:48:34.200 回答
4

正如TreyA所说,LLA to ECEF是解决方案。见http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html

于 2012-05-28T17:13:48.553 回答