计算两个坐标之间距离的函数

IT技术 javascript coordinates distance
2021-02-07 04:22:20

我目前正在使用下面的功能,但它无法正常工作。根据谷歌地图,这些坐标(从59.3293371,13.487747259.3225525,13.4619422之间的距离2.2公里,而函数返回1.6公里。我怎样才能让这个函数返回正确的距离?

function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI/180)
}

jsFiddle:http : //jsfiddle.net/edgren/gAHJB/

6个回答

您使用的是所谓的半正弦公式,它计算乌鸦飞行时球体上两点之间的距离您提供的 Google 地图链接显示距离为 2.2 公里,因为它不是直线。

Wolfram Alpha 是进行地理计算的绝佳资源,并且还显示这两个点之间的距离为1.652 公里

行驶距离与直线距离(我的红线)。

如果您正在寻找直线距离(如乌鸦文件),则您的函数工作正常。如果您想要的是行驶距离(或骑车距离或公共交通距离或步行距离),则必须使用地图 API(GoogleBing是最受欢迎的)来获取适当的路线,其中包括距离。

顺便说一句,Google Maps API 在其google.maps.geometry.spherical命名空间(查找computeDistanceBetween)中提供了球面距离的封装方法它可能比滚动你自己的更好(对于初学者来说,它使用更精确的地球半径值)。

对于我们中挑剔的人,当我说“直线距离”时,我指的是“球面上的直线”,当然,它实际上是一条曲线(即大圆距离)。

这是一个美丽的答案。我说漂亮是因为提供的细节对于理解差异来说太好了,即使对于像我这样的新手也是如此。
2021-03-20 04:22:20
我的荣幸!回答起来很有趣。
2021-03-23 04:22:20

我之前写过一个类似的方程 - 测试它,也得到了 1.6 公里。

您的谷歌地图显示了行驶距离。

您的函数正在计算乌鸦飞行(直线距离)。

alert(calcCrow(59.3293371,13.4877472,59.3225525,13.4619422).toFixed(1));



    //This function takes in latitude and longitude of two location and returns the distance between them as the crow flies (in km)
    function calcCrow(lat1, lon1, lat2, lon2) 
    {
      var R = 6371; // km
      var dLat = toRad(lat2-lat1);
      var dLon = toRad(lon2-lon1);
      var lat1 = toRad(lat1);
      var lat2 = toRad(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;
    }

    // Converts numeric degrees to radians
    function toRad(Value) 
    {
        return Value * Math.PI / 180;
    }
你为什么要添加代码?它是否解决了问题代码中的任何问题?
2021-03-22 04:22:20
我认为你的变量名太具有描述性了:)
2021-03-28 04:22:20

Derek 的解决方案对我来说效果很好,我只是简单地将它转换为 PHP,希望它可以帮助那里的人!

function calcCrow($lat1, $lon1, $lat2, $lon2){
        $R = 6371; // km
        $dLat = toRad($lat2-$lat1);
        $dLon = toRad($lon2-$lon1);
        $lat1 = toRad($lat1);
        $lat2 = toRad($lat2);

        $a = sin($dLat/2) * sin($dLat/2) +sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2); 
        $c = 2 * atan2(sqrt($a), sqrt(1-$a)); 
        $d = $R * $c;
        return $d;
}

// Converts numeric degrees to radians
function toRad($Value) 
{
    return $Value * pi() / 180;
}

使用Haversine公式,代码来源

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//:::                                                                         :::
//:::  This routine calculates the distance between two points (given the     :::
//:::  latitude/longitude of those points). It is being used to calculate     :::
//:::  the distance between two locations using GeoDataSource (TM) prodducts  :::
//:::                                                                         :::
//:::  Definitions:                                                           :::
//:::    South latitudes are negative, east longitudes are positive           :::
//:::                                                                         :::
//:::  Passed to function:                                                    :::
//:::    lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)  :::
//:::    lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)  :::
//:::    unit = the unit you desire for results                               :::
//:::           where: 'M' is statute miles (default)                         :::
//:::                  'K' is kilometers                                      :::
//:::                  'N' is nautical miles                                  :::
//:::                                                                         :::
//:::  Worldwide cities and other features databases with latitude longitude  :::
//:::  are available at https://www.geodatasource.com                         :::
//:::                                                                         :::
//:::  For enquiries, please contact sales@geodatasource.com                  :::
//:::                                                                         :::
//:::  Official Web site: https://www.geodatasource.com                       :::
//:::                                                                         :::
//:::               GeoDataSource.com (C) All Rights Reserved 2018            :::
//:::                                                                         :::
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

function distance(lat1, lon1, lat2, lon2, unit) {
    if ((lat1 == lat2) && (lon1 == lon2)) {
        return 0;
    }
    else {
        var radlat1 = Math.PI * lat1/180;
        var radlat2 = Math.PI * lat2/180;
        var theta = lon1-lon2;
        var radtheta = Math.PI * theta/180;
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        if (dist > 1) {
            dist = 1;
        }
        dist = Math.acos(dist);
        dist = dist * 180/Math.PI;
        dist = dist * 60 * 1.1515;
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="N") { dist = dist * 0.8684 }
        return dist;
    }
}

示例代码在 LGPLv3 下获得许可。

你为什么要这样做?如果 (dist > 1) { dist = 1; }
2021-03-24 04:22:20

为 Node.JS 用户添加这个。您可以使用该haversine-distancemodule来执行此操作,因此您无需自行处理计算。有关更多信息,请参阅npm 页面

安装:

npm install --save hasrsine-distance

您可以按如下方式使用该module:

var haversine = require("haversine-distance");

//First point in your haversine calculation
var point1 = { lat: 6.1754, lng: 106.8272 }

//Second point in your haversine calculation
var point2 = { lat: 6.1352, lng: 106.8133 }

var haversine_m = haversine(point1, point2); //Results in meters (default)
var haversine_km = haversine_m /1000; //Results in kilometers

console.log("distance (in meters): " + haversine_m + "m");
console.log("distance (in kilometers): " + haversine_km + "km");