两个 gps 坐标之间的距离 - javascript

Distance between two gps coordinates - javascript

从上个月开始我就在寻找这背后的概念,直到现在我得到了这些资源

  1. How do I calculate distance between two latitude-longitude points?
  2. geolib.js
  3. Function to calculate distance between two coordinates shows wrong
  4. Calculate distance, bearing and more between Latitude/Longitude points

但我还是想不出指定坐标之间的正确距离

例如,我有两个坐标

起始纬度:26.26594 开始长:78.2095508 目的地纬度:21.24386 目标多头:81.611

我得到的结果是 655.358 公里,但实际上(我用自行车的里程表测量了它)距离只有 ~3 公里,这就是为什么我得到这个答案。

我什至检查了我在 geolib.js 上的实现(我在列表项中指定的第二项),它也显示相同的结果 (655.358)。

想不通

JS

// initialising the distance calculation

function geoLocationInit() {
        $('.fd-loc-err').html(''); // empty the error shown, if there is any already
        $('.fd-dist-rest-user').html('<img src="/images/loader.gif" alt="loading"/>'); // loader
        var options = {timeout:120000};
        if (navigator.geolocation) {
            navigator.geolocation.watchPosition(getLocation, gotError, options);
        }
        else {
            locationError = 'Your Browser does not support geolocation';
            showLocationError(locationError);
        }
    }



//finding the coordinates of user

function getLocation(current) {
        var userLat = current.coords.latitude, userLong = current.coords.longitude;
        var distance = getDistance(userLat, userLong, restLatitude, restLongitude);
        $('.fd-dist-rest-user').html('~' + (distance/1000).toFixed(2) + ' km away'); // fd-dist-rest-user is the <div> tag where i have show the distance calculated
    }


    function toRad(value) {
        return value * Math.PI / 180;
    }


    // calculating distance using Vincenty Formula
    function getDistance(lat1, lon1, lat2, lon2) {
        var a = 6378137, b = 6356752.314245,  f = 1/298.257223563;
        var L = toRad(lon2-lon1);
        var U1 = Math.atan((1-f) * Math.tan(toRad(lat1)));
        var U2 = Math.atan((1-f) * Math.tan(toRad(lat2)));
        var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
        var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);

        var lambda = L, lambdaP, iterLimit = 100;
        do 
        {
            var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
            var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) + (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda));
            if (sinSigma==0) return 0;

            var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
            var sigma = Math.atan2(sinSigma, cosSigma);
            var sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
            var cosSqAlpha = 1 - sinAlpha*sinAlpha;
            var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha;
            if (isNaN(cos2SigmaM)) cos2SigmaM = 0;
            var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
            lambdaP = lambda;
            lambda = L + (1-C) * f * sinAlpha * (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
        } while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0);

        if (iterLimit==0) return NaN

        var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
        var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
        var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
        var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
        var s = b*A*(sigma-deltaSigma);
        return s;
    }


// Error handling for the geolocation

    function gotError(error) {
        switch(error.code) {
            case 1: 
                locationError = 'You need to give the permission to use your location to calculate the distances between this restaurant and you <button class="btn btn-danger fd-detect-lctn-try-agn">Please try again</button>';
                break;
            case 2:
                locationError = 'TIME OUT - You need to give permission to use your location to show the distance of this restaurant from your current position <button class="btn btn-danger fd-detect-lctn-try-agn">Please try again</button>';
                break;
            case 3:
                locationError = 'It took to long getting your position, <button class="btn btn-danger fd-detect-lctn">Please try again</button>';
                break;
            default:
                locationError = 'An unknown error has occurred, <button class="btn btn-danger fd-detect-lctn">Please try again</button>';
        }
        showLocationError(locationError);
    }

    function showLocationError(msg) {
        $('.fd-loc-err').html(msg);
        $('.fd-dist-rest-user').html('');
    }

我从我的数据库中获取纬度和经度,然后在单击按钮时调用 geoLocationInit 函数(下面是以下代码)

restLongitude = response['longitude'];
restLatitude = response['latitude'];
geoLocationInit(); /* getting location initialisation */

Patrick Evans 的评论帮助下进行更多研究后,我发现,由于桌面上缺少 gps 设备,我遇到了问题,因此,坐标不准确导致距离计算错误。

根据 Firefox - 位置感知浏览

Accuracy varies greatly from location to location. In some places, our service providers may be able to provide a location to within a few meters. However, in other areas it might be much more than that. All locations returned by our service providers are estimates only and we do not guarantee the accuracy of the locations provided. Please do not use this information for emergencies. Always use common sense.

来源Location-Aware Browsing - How Accurate are the locations

因此,如果想找到几乎准确的 gps 坐标,则应使用 GPS 设备或 移动设备 中的 HTML5 geolocation API,后者通常安装有 GPS 硬件, 所以会得到精确的坐标

我尝试修改方法的选项:'geoLocationInit' 以尝试访问最佳位置,但如果它是智能的 phone 应该启用 wifi 和 gps。

会是这样的:

var options = {timeout:120000, enableHighAccuracy: true};