Javascript 在两个GPS坐标之间计算罗盘方位的问题

Javascript 在两个GPS坐标之间计算罗盘方位的问题,javascript,geolocation,Javascript,Geolocation,在我的webapp中,有一个来自数据库查询的JSON数据响应,其中包括1到n个位置的lat/long坐标。我想计算从数据[I]位置到当前位置的轴承 我一直在修改代码,但返回的轴承不正确 //starting lat/long along with converting lat to rads var endLat = toRad(location.lat()); var endLong = location.lng(); //loop over response, calcul

在我的webapp中,有一个来自数据库查询的JSON数据响应,其中包括1到n个位置的lat/long坐标。我想计算从
数据[I]
位置到当前位置的轴承

我一直在修改代码,但返回的轴承不正确

//starting lat/long along with converting lat to rads
var endLat = toRad(location.lat());        
var endLong = location.lng();

//loop over response, calculate new headings for links and add link to array
for(var i=0; i<data.length; i++){

  //this link's lat/long coordinates, convert lat to rads
  var startLat = toRad(data[i].lat);
  var startLong = data[i].lon;

  //get the delta values between start and end coordinates in rads
  var dLong = toRad(endLong - startLong);

  //calculate 
  var y = Math.sin(dLong)*Math.cos(endLong);
  var x = Math.cos(startLat)*Math.sin(endLat)-Math.sin(startLat)*Math.cos(endLat)*Math.cos(dLong);
  var bearing = Math.atan(y, x);
  bearing = (toDeg(bearing) + 360) % 360;

  panoLinks.push({'heading': bearing, 'description': data[i].description, 'pano': data[i].description});
}

//radian/degree conversions
function toRad(convert){
  return convert * Math.PI/180;
}

function toDeg(convert){
  return convert * 180/Math.PI;
}
结果是罗盘角度为

bearing= 0.000014910023935499339

这绝对是错的。我哪里出错了?

试试看,我一辈子都记不起是从哪里弄来的

    /**
     * Calculate the bearing between two positions as a value from 0-360
     *
     * @param lat1 - The latitude of the first position
     * @param lng1 - The longitude of the first position
     * @param lat2 - The latitude of the second position
     * @param lng2 - The longitude of the second position
     *
     * @return int - The bearing between 0 and 360
     */
    bearing : function (lat1,lng1,lat2,lng2) {
        var dLon = (lng2-lng1);
        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 = this._toDeg(Math.atan2(y, x));
        return 360 - ((brng + 360) % 360);
    },

   /**
     * Since not all browsers implement this we have our own utility that will
     * convert from degrees into radians
     *
     * @param deg - The degrees to be converted into radians
     * @return radians
     */
    _toRad : function(deg) {
         return deg * Math.PI / 180;
    },

    /**
     * Since not all browsers implement this we have our own utility that will
     * convert from radians into degrees
     *
     * @param rad - The radians to be converted into degrees
     * @return degrees
     */
    _toDeg : function(rad) {
        return rad * 180 / Math.PI;
    },

如果您想要一种非常粗略的短距离方法,可以使用6378137m的地球半径(WGS84球体半长轴的长度)根据经纬度差计算三角形的边。然后计算适当的轴承。这将是一个真正的方位,但可能在短距离内足够近

你需要让用户自己计算出局部磁偏角

e、 g.举个例子:

startLat  = 43.6822
startLong = -70.450769

endLat  = 43.682211
endLong = -70.45070

diff lat  = 0.000011 = 1.22m
diff long = 0.000069 = 7.68m
终点位于起点的北面和东面,因此可以通过以下方式找到轴承:

tan a = 7.68 / 1.22
    a = 81°
所以方向是关于

这可能应该在测绘线程中进行。一旦你算出了数学题,就来这里找答案

编辑 要将纬度转换为米,首先计算赤道(或任何大圆)处的地球周长:

然后得到360°的周长比:

dist = c * deg / 360
     = 40,075,000m * 0.000011° / 360°
     = 1.223m
对于经度,随着纬度接近极点,距离变窄,因此使用相同的公式,结果乘以纬度的余弦:

     = 40,075,000m * 0.000069° / 360° * cos(0.000011°)
     = 7.681m

地球半径的值不一定精确,地球不是一个完美的球体(它是一个扁球体,有点像梨形)。在不同的地方使用不同的近似值以获得更高的精度,但我使用的应该足够好。

这是对已接受答案的编辑,经过一些修改,使其适用于我(主要是在lat、lng值上使用toRad函数)


找到理论和在线计算器:

好的,我找到了参考资料:发现这个网站非常方便!这与我正在运行的代码几乎完全相同。问题是,两个完全相反的位置之间只有0.00001度的差异。一个应该是230度,第二个应该是70度。很好的尝试,但是你的函数是基于数学方位的。在数学中,0°沿+X轴,角度沿逆时针方向前进,因此90°沿+Y轴,180°沿-X轴,依此类推。在绘图中,0°(正北)位于+Y轴上方,轴承顺时针方向运行,因此90°(正东)位于+X轴上,180°(正南)位于-Y轴上,依此类推。我会帮忙的,但我的球形三角架生锈了,现在再查规则已经太晚了。这是我能找到的最接近的答案。。最大的区别是使用atan2功能而不是atan。指南针方位是基于,从一个地方到另一个地方,在正北以东和以西都可能有10°到20°的变化。你们计算的轴承将是基于,或多或少是正北的球面轴承。我知道这一点。然而,我试图计算两个相距约10米的位置之间的方位。在这个距离上,从磁场到正北的偏差是无关紧要的。20°是无关紧要的吗?超过10米,你将指向3.6米以外的地方。呃,也许我应该编辑一下。刚刚检查了我所在区域的磁偏角差异,磁北在正北以东18度。然而,这些指南针方位是基于GPS坐标的,这是方向不可知的。你需要上一堂导航课!请参阅我的第一条评论并点击链接。:-)GPS设备生成的纬度和经度(即“GPS坐标”)基于与其他大地测量系统完全相同的坐标系。它们是地球的数学近似值,它们在同一点上的坐标和点与点之间的方位都略有不同。拜托,你是怎么得到0.000011=1.22米的?提前谢谢!为什么要将差异纬度和差异长度转换为米?如果你想知道角度a,你可以使用以度为单位的差值或者你正在使用的任何东西(我甚至更喜欢用rad来计算这些类型的计算),当你以角度计算起点和终点之间的距离时,如果你想知道以米为单位,你可以将其转换为米。这在很大程度上取决于您的应用程序,这正是海里的意义所在。。。。我更喜欢从一个角度到海里,然后把它们转换成米(当谈论地球时…)@RemyNL,Manatok已经给出了球面三角的答案。这只是一个简单的方法,在短距离内使用平面触发器。纬度和经度在呈现给用户时通常以度表示,OP使用的就是纬度和经度
dist = c * deg / 360
     = 40,075,000m * 0.000011° / 360°
     = 1.223m
     = 40,075,000m * 0.000069° / 360° * cos(0.000011°)
     = 7.681m
    var geo = {
        /**
         * Calculate the bearing between two positions as a value from 0-360
         *
         * @param lat1 - The latitude of the first position
         * @param lng1 - The longitude of the first position
         * @param lat2 - The latitude of the second position
         * @param lng2 - The longitude of the second position
         *
         * @return int - The bearing between 0 and 360
         */
        bearing : function (lat1,lng1,lat2,lng2) {
            var dLon = this._toRad(lng2-lng1);
            var y = Math.sin(dLon) * Math.cos(this._toRad(lat2));
            var x = Math.cos(this._toRad(lat1))*Math.sin(this._toRad(lat2)) - Math.sin(this._toRad(lat1))*Math.cos(this._toRad(lat2))*Math.cos(dLon);
            var brng = this._toDeg(Math.atan2(y, x));
            return ((brng + 360) % 360);
        },

       /**
         * Since not all browsers implement this we have our own utility that will
         * convert from degrees into radians
         *
         * @param deg - The degrees to be converted into radians
         * @return radians
         */
        _toRad : function(deg) {
             return deg * Math.PI / 180;
        },

        /**
         * Since not all browsers implement this we have our own utility that will
         * convert from radians into degrees
         *
         * @param rad - The radians to be converted into degrees
         * @return degrees
         */
        _toDeg : function(rad) {
            return rad * 180 / Math.PI;
        },
    };

    /** Usage **/
    var myInitialBearing = geo.bearing(0,0,45,45);