确定从一个纬度/经度到另一个的指南针方向

时间:2010-07-09 04:44:55

标签: algorithm geospatial pseudocode

有没有人有算法来确定从一个纬度/经度到另一个的方向(伪代码):

CalculateHeading( lat1, lon1, lat2, long2 ) returns string heading

标题是例如NW,SW,E等

基本上,我在地图上有两个点我希望得到一个方向的概念,考虑到东50英里和北一英里只是东方而不是东北。

3 个答案:

答案 0 :(得分:17)

This site有基本算法:

// in javascript, not hard to translate...
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1)*Math.sin(lat2) -
        Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
var brng = Math.atan2(y, x).toDeg();

更新:请参阅此处以获取完整的算法Mapping Math and Javascript

那会给你一个0到360之间的数字,然后只需要进行简单的查找:

var bearings = ["NE", "E", "SE", "S", "SW", "W", "NW", "N"];

var index = brng - 22.5;
if (index < 0)
    index += 360;
index = parseInt(index / 45);

return(bearings[index]);

重要的是要注意,当你在地球上移动时,你的方位实际上会发生变化。上面的算法显示初始方位,但是如果你长途旅行,当你到达目的地时你的方位会有很大差异(如果你只是短途旅行[&a; a几百公里]然后它可能不会改变到足以引起关注)。

答案 1 :(得分:2)

你还记得你的三角函数吗?即SOHCAHTOA:

  • SOH :罪(θ)=与斜边相反
  • CAH :Cos(θ)=与斜边相邻
  • TOA :Tan(θ)=与相邻
  • 相对

在伪代码中:

function getDir(lat1, long1, lat2, long2) {
    margin = π/90; // 2 degree tolerance for cardinal directions
    o = lat1 - lat2;
    a = long1 - long2;
    angle = atan2(o,a);

    if (angle > -margin && angle < margin):
            return "E";
    elseif (angle > π/2 - margin && angle < π/2 + margin):
            return "N";
    elseif (angle > π - margin && angle < -π + margin):
            return "W";
    elseif (angle > -π/2 - margin && angle < -π/2 + margin):
            return "S";
    }
    if (angle > 0 && angle < π/2) {
        return "NE";
    } elseif (angle > π/2 && angle < π) {
        return "NW";
    } elseif (angle > -π/2 && angle < 0) {
        return "SE";
    } else {
        return "SW";
    }
}

编辑1: 正如皮特和迪恩指出的那样,这并没有考虑到地球的曲率。为了更准确地计算远离赤道的点,你需要使用spherical triangle formulas,就像Dean的回答一样。

编辑2: 另一个纠正;正如Pete所说,arctan()没有给出正确的角度,因为-1 / -1和1/1是相同的(-1/1和1 / -1)。 arctan2(y, x)arctan()的两个参数变体,旨在弥补这一点。 arctan()的范围为(-π,π),y >= 0为正,y < 0为负。

答案 2 :(得分:0)

转换为数字角度并使用结果查找文本。例如,-22.5 .. + 22.5 = N. + 22.5..67.5 = NE,67.5..112.5 = E等。当然,假设您只使用N,NE,E,SE,S,SW ,W,NW - 如果您决定(例如)使用旧的“指南针的32个点”,则每个文本字符串显然代表较小的范围。