Javascript 在地球上移动后找到最终的经纬度

Javascript 在地球上移动后找到最终的经纬度,javascript,math,geolocation,haversine,earthdistance,Javascript,Math,Geolocation,Haversine,Earthdistance,我用哈弗森公式计算两个经纬度对之间的距离 function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) { var R = 6371; // Radius of the earth in km var dLat = deg2rad(lat2-lat1); var dLon = deg2rad(lon2-lon1); var lat1 = deg2rad(lat1); var lat2 = deg2rad(

我用哈弗森公式计算两个经纬度对之间的距离

function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
    var R = 6371; // Radius of the earth in km
    var dLat = deg2rad(lat2-lat1);
    var dLon = deg2rad(lon2-lon1); 
    var lat1 = deg2rad(lat1);
    var lat2 = deg2rad(lat2);

    var a = 
        Math.sin(dLat/2) * Math.sin(dLat/2) + 
        Math.sin(dLon/2) * Math.sin(dLon/2) * 
        Math.cos(lat1) * Math.cos(lat2);

    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    var d = R * c;
    return d;
}
给定一个起点(lat1,lat2),直线上移动所需的距离和角度,我需要确定端点(如lat2和lon2)

请参阅下面我的尝试:

function getFinalLatLon(lat1, lon1, distance, angle) {
    var R = 6371; // Radius of the earth in km
    var c = distance/R;
    // Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) = c/2
    var a = // stuck here

    // looking for this part of the code

    return [lat2, lon2];
}

如果水平移动,可以将经度增加
距离/(R*cos(lat))
。不需要
atan


<>编辑:既然你想要一个通用的公式,请考虑下面的几何推导:

  • 前视图:

  • 侧视图:

  • 整个设置:

注:

  • r
    是起始位置的单位向量,
    s
    是终点

  • a、b、c
    是辅助计算的中间向量

  • (θ,φ)
    是(横向,纵向)坐标
  • γ
    是您将要行驶方向的方位角
  • δ
    是通过的角度(距离/半径
    R=6400000m
我们需要
a,b
r
垂直,并且
a
与北对齐。这使得:

c
由(简单三角学)给出:

因此我们得到了
s
(通过一些非常繁琐的代数):

现在,我们可以使用以下公式计算
s
的最终(横向、纵向)坐标:


代码:

测试用例:

  • 输入
    (横向,纵向)=(45,0)
    角度=0
    距离=半径*deg2rad(90)
    =>
    (45,180)
    (如我前面所说)

  • 输入
    (横向,纵向)=(0,0)
    角度=90
    距离=半径*deg2rad(90)
    =>
    (0,90)
    (按预期-从赤道开始,向东移动90度)

  • 输入
    (横向,纵向)=(54,29)
    角度=36
    距离=半径*deg2rad(360)
    =>
    (54,29)
    (如预期的那样-从任意位置开始,在任意方向整圈)

  • 有趣的例子:输入
    (lat,long)=(30,0)
    ,其他都一样。=><代码>(0,90)(我们预期的是
    (30,90)
    ?-不是从赤道开始,向北移动90度)

    原因是北纬90度不是东(如果你不在赤道上)!此图应显示原因:

    如你所见,向北90度的移动路径不是向东


  • 我刚刚发现了一个类似的问题,然后我按照解决方案提出了一个适用于我的案例的函数

    希望它能帮助其他人:

    function getFinalLatLon(lat1, lon1, distance, angle){ 
        function deg2rad(deg) {
            return deg * (Math.PI/180)
        }
        // dy = R*sin(theta) 
        var dy = distance * Math.sin(deg2rad(angle)) 
        var delta_latitude = dy/110574
        // One degree of latitude on the Earth's surface equals (110574 meters
        delta_latitude = parseFloat(delta_latitude.toFixed(6));
    
        // final latitude = start_latitude + delta_latitude
        var lat2 = lat1 + delta_latitude
    
        // dx = R*cos(theta) 
        var dx = distance * Math.cos(deg2rad(angle)) 
        // One degree of longitude equals 111321 meters (at the equator)
        var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1))) 
        delta_longitude = parseFloat(delta_longitude.toFixed(6));
    
        // final longitude = start_longitude + delta_longitude
        var lon2 = lon1 + delta_longitude
    
        return [lat2, lon2];
    }
    

    水平移动的角度为0度。你可以随意切换。如果有人向北移动,那么西北方向将是90度135度,以此类推……

    数学.atan2
    相反?你是说<代码>数学.tan?不。。。它是Math.atan2所以你的意思是数学的倒数。atan2本身就是吗?我不想在这里开玩笑,但你的问题陈述(和标题)有点让人困惑。我只想要一个算法,在[lat1,lat2]和水平距离移动的情况下,让我到达[lat2,lon2]。这有点相似,在我接受之前让我证明一下。。。听起来很简单,让我大吃一惊。@TechyTimo-oops等等,对不起,有点missing@meowgoesthedog乘以180/Pi得到以度为单位的经度增量很好的解释。虽然第一个测试用例通过了,但似乎失败了-取地球半径=6371000米,距离=半径*deg2rad(90)和getFinalLatLong(45,0,距离,90,半径)返回[4.96..90]@TechyTimo您没有显示该
    lat
    值的其余部分,尽管-4.961562726608714e-15-即接近预期值零的非常小的数字。这是这类计算中典型的浮点错误,近似于双精度数字的机器ε。不确定这是否有效。假设你正北移动
    2*(90-lat)
    。你应该再次回到
    lat
    ,但是你得到了
    180-lat
    ,这是不正确的。我认为它是固定的-我缺少了一个非常需要的角度到弧度的转换。虽然这是必要的,但它不能解决我上面指出的问题。我不理解你的问题。。你向北移动什么?你能用实际数字吗…比如说你在纬度=45。如果你向北移动距离(地球半径)*90,你仍然应该到达纬度45(就在地球的另一边,即你的经度变化180)。但是,如果运行代码,纬度变为135,经度一点也不改变;我认为这是一个错误的结果。
    function getFinalLatLon(lat1, lon1, distance, angle){ 
        function deg2rad(deg) {
            return deg * (Math.PI/180)
        }
        // dy = R*sin(theta) 
        var dy = distance * Math.sin(deg2rad(angle)) 
        var delta_latitude = dy/110574
        // One degree of latitude on the Earth's surface equals (110574 meters
        delta_latitude = parseFloat(delta_latitude.toFixed(6));
    
        // final latitude = start_latitude + delta_latitude
        var lat2 = lat1 + delta_latitude
    
        // dx = R*cos(theta) 
        var dx = distance * Math.cos(deg2rad(angle)) 
        // One degree of longitude equals 111321 meters (at the equator)
        var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1))) 
        delta_longitude = parseFloat(delta_longitude.toFixed(6));
    
        // final longitude = start_longitude + delta_longitude
        var lon2 = lon1 + delta_longitude
    
        return [lat2, lon2];
    }