如何使用 Haversine 公式计算行进的距离(不是位移)?

How to calculate distance (NOT DISPLACEMENT) travelled using Haversine Formula?

我正在尝试编写一些 JS,使用 Haversine 公式计算用户移动的距离。

现在 Haversine 公式接受起始坐标和当前坐标,并给出这两个坐标之间的间隔。然而,这只是 DISPLACEMENT 而不是用户可能已经到达终点的距离。

我需要有人帮助我编写下面的代码(提供位移)并建议我应该做些什么才能计算距离。

//Geolocation
var startPos;
var watchId;
//Start Tracking Position
function startTracking() {
    if(navigator.geolocation) {
        if (document.getElementById('startBtn').innerHTML === " Stop Tracking?")
        {
            stopTracking();
            stopClock();
            return;
        }
        document.getElementById('startBtn').innerHTML = " Stop Tracking?";
        //Get Position
        navigator.geolocation.getCurrentPosition(showPosition, showError);
        //Watch Position
        watchId = navigator.geolocation.watchPosition(showPositionUpdate, showError);
    }
    else {
        alert('Geolocation is not supported by your browser');
    }
}
//Show Start Position
function showPosition(position) {
    startPos = position;
    document.getElementById('startLat').innerHTML = startPos.coords.latitude;
    document.getElementById('startLon').innerHTML = startPos.coords.longitude;
}
//Updated Position
function showPositionUpdate(position) {
    document.getElementById('currentLat').innerHTML = position.coords.latitude;
    document.getElementById('currentLon').innerHTML = position.coords.longitude;
    var distance = calculateDistance(startPos.coords.latitude, startPos.coords.longitude, position.coords.latitude, position.coords.longitude);
    if (distance < 1) {
        document.getElementById('distance').innerHTML = (Math.round(distance * 1000)) + "m";
    } else {
        document.getElementById('distance').innerHTML = (Math.round(distance * 100) / 100) + "Km";
    }
}
//Error Handler
function showError(error) {
    switch(error.code) {
        case error.PERMISSION_DENIED:
            alert('User denied the request for Geolocation');
            break;
        case error.POSITION_UNAVAILABLE:
            alert('Location Not Available');
            break;
        case error.TIMEOUT:
            alert('The request has timed-out');
            break;
        case error.UNKNOWN_ERROR:
            alert('There was an unknown error');
            break;
    }
}
//Calculate the distance between start and updated, Haversine Formula
function calculateDistance(lat1, lon1, lat2, lon2) {
    var R = 6371; // km  
    var dLat = (lat2-lat1).toRad();  
    var dLon = (lon2-lon1).toRad();   
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +  
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *   
            Math.sin(dLon/2) * Math.sin(dLon/2);   
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));   
    var d = R * c;
    return d;
}
Number.prototype.toRad = function() {
    return this * Math.PI / 180;
}
//Stop Tracking
function stopTracking() {
    navigator.geolocation.clearWatch(watchId);
    alert('Tracking has stopped');
    document.getElementById('startBtn').innerHTML = "Start Tracking?";
}

每隔x秒左右记录一次位移,然后求和。你将有一个相当好的近似值。或者先记录不同时刻的点,最后再计算。

var checkpoints = [],
    interval = null;

function record() {
  checkpoints.push( /* current position */ )
}

function distance(a, b) {
  return /* your distance calculation */
}

function start() {
  checkpoints = [];
  interval = setInterval(record, 1000); // record current pos every second
}

function end() {
  clearInterval(interval);

  var distanceTravelled = checkpoints.reduce(function(x, current, i, checkpoints){
    return x + distance(current, checkpoints[i-1]);
  }, 0);

  // do something nice with the distance
}

更新

我刚刚意识到您使用 watch 回调。您可以使用以下方法,

var lastPoint = null,
    travelled = 0;

function update(point) {
  if (lastPoint != null)
    travelled += calculateDistance(lastPoint.long, lastPoint.lat, point.long, point.lat);      

  lastPoint = point;
}

更新 2 工作解决方案:http://jsfiddle.net/ymz3a5pb/