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

时间:2012-07-10 14:06:58

标签: javascript geolocation

在我的webapp中,从数据库查询中获取JSON数据响应,其中包括1到n个位置的纬度/经度坐标。我想计算从data[i]位置到当前位置的方位。

我一直在调整代码here,但返回的方法不正确。

//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;
}

使用上述功能和值

startLat= 43.6822, converts to 0.7623982145146669 radians
startLong= -70.450769

endLat= 43.682211, converts to 0.7623984065008848 radians
endLong= -70.45070

dLong = startLong - endLong, converts to 0.0000011170107216805305 radians

导致罗盘度

bearing= 0.000014910023935499339

绝对是关闭的。我哪里出错?

3 个答案:

答案 0 :(得分:17)

尝试一下,我不能为我的生活记住我得到它的地方......

    /**
     * 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;
    },

答案 1 :(得分:6)

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

    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);

http://www.movable-type.co.uk/scripts/latlong.html

找到理论和在线计算器

答案 2 :(得分:3)

如果你想要一个非常粗略的短距离方法,你可以使用6,378,137米的地球半径(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°

所以方向是East by North

这应该是一个映射和测量线程。一旦你完成了数学计算,就来这里寻求解决方案。

修改

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

c = 2πR where r = 6378137m
  = 40,075,000 (approx)

然后得到360°周长的比率:

dist = c * deg / 360
     = 40,075,000m * 0.000011° / 360°
     = 1.223m

对于经度,当纬度接近极点时,距离变窄,因此使用相同的公式,结果乘以纬度的余弦:

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

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