Python代码计算三个点(纬度经度坐标)之间的角度

7
有人能否建议如何计算三个点(纬度和经度坐标)之间的角度?
A : (12.92473, 77.6183)
B : (12.92512, 77.61923)
C : (12.92541, 77.61985)

1
可能是如何从三个点计算角度?的重复问题。 - Or East
这对经纬度也适用吗? - itsvks
4
您不能将这些数值视为平面点并计算角度。首先,地球并非平坦的,尽管在小范围内大致如此。更重要的是,经度和纬度的单位不相同。在赤道上,一度的纬度或经度是相同的。但是,离开赤道后,一度的经度覆盖的距离比一度的纬度少。在(非常接近)南北极,一度的经度覆盖距离,而一度的纬度仍然约为69英里。因此,这个问题与其他问题不是重复的。 - Rory Daulton
我赞同Rory的评论,他明确地表达了我在上面略带含蓄的评论中所说的话(使用地图投影)。 - gboffi
2
但这是现实生活中的情况吗?如果您需要真正的导航,您可以在15分钟内设置自己的OSRM实例,并且它将为您提供大型旅程的逐步转向指示(步行或驾车),每个指令只需1或2毫秒,没有任何限制并且免费。Graphhopper也类似。如果您正在谈论真实道路,那么您当前的方法没有希望(我的全职工作是车辆路径问题)。然后,您只需要使用“请求”与您的服务器通信。 - roganjosh
显示剩余12条评论
2个回答

5
我看到解决您的问题有两种主要方法,假设您想要角ABC(B是角的顶点)。由于您的三个点彼此靠近(纬度相差不到0.0007°,经度相差不到0.002°),我们可以将地球近似为平面,并使用二维向量计算。当我们离赤道远时,经度和纬度的距离不同,但我们可以进行调整。另一种解决方案是将您的点视为三维空间中的点,并使用三维向量计算。在这里,我们只需要将给定的球面坐标转换为3D笛卡尔坐标即可。
以下是我为您的问题编写的代码。我在这里使用numpy模块以方便操作,但是这也可以很容易地完成而不使用它。这段代码比较冗长,因此您可以更好地了解正在执行的操作。
import numpy as np
import math

def latlong_to_3d(latr, lonr):
    """Convert a point given latitude and longitude in radians to
    3-dimensional space, assuming a sphere radius of one."""
    return np.array((
        math.cos(latr) * math.cos(lonr),
        math.cos(latr) * math.sin(lonr),
        math.sin(latr)
    ))

def angle_between_vectors_degrees(u, v):
    """Return the angle between two vectors in any dimension space,
    in degrees."""
    return np.degrees(
        math.acos(np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v))))

# The points in tuple latitude/longitude degrees space
A = (12.92473, 77.6183)
B = (12.92512, 77.61923)
C = (12.92541, 77.61985)

# Convert the points to numpy latitude/longitude radians space
a = np.radians(np.array(A))
b = np.radians(np.array(B))
c = np.radians(np.array(C))

# Vectors in latitude/longitude space
avec = a - b
cvec = c - b

# Adjust vectors for changed longitude scale at given latitude into 2D space
lat = b[0]
avec[1] *= math.cos(lat)
cvec[1] *= math.cos(lat)

# Find the angle between the vectors in 2D space
angle2deg = angle_between_vectors_degrees(avec, cvec)


# The points in 3D space
a3 = latlong_to_3d(*a)
b3 = latlong_to_3d(*b)
c3 = latlong_to_3d(*c)

# Vectors in 3D space
a3vec = a3 - b3
c3vec = c3 - b3

# Find the angle between the vectors in 2D space
angle3deg = angle_between_vectors_degrees(a3vec, c3vec)


# Print the results
print('\nThe angle ABC in 2D space in degrees:', angle2deg)
print('\nThe angle ABC in 3D space in degrees:', angle3deg)

这将给出结果。
The angle ABC in 2D space in degrees: 177.64369006

The angle ABC in 3D space in degrees: 177.643487338

请注意,结果非常接近(偏差约为五千分之一度),这是三个非常接近的点所期望的。

0

要在经纬度系统中获取两个方向之间的角度,您可以使用两个方位角的差异(从此页面)

Formula:    
θ = atan2( sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ )
where   
φ11 is the start point, φ22 the end point (Δλ is the difference in longitude)

JavaScript:
(all angles in radians) 
var y = Math.sin(λ21) * Math.cos(φ2);
var x = Math.cos(φ1)*Math.sin(φ2) -
        Math.sin(φ1)*Math.cos(φ2)*Math.cos(λ21);
var brng = Math.atan2(y, x).toDegrees();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接