我目前正在使用下面的功能,它不能正常工作。根据谷歌Maps,这些坐标之间的距离(从59.3293371,13.4877472到59.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/


当前回答

谷歌的答案

https://cloud.google.com/blog/products/maps-platform/how-calculate-distances-map-maps-javascript-api

支票由三部分组成。

https://www.distancefromto.net/

static distance({ x: x1, y: y1 }, { x: x2, y: y2 }) {
    function toRadians(value) {
        return value * Math.PI / 180
    }

    var R = 6371.0710
    var rlat1 = toRadians(x1) // Convert degrees to radians
    var rlat2 = toRadians(x2) // Convert degrees to radians
    var difflat = rlat2 - rlat1 // Radian difference (latitudes)
    var difflon = toRadians(y2 - y1) // Radian difference (longitudes)
    return 2 * R * Math.asin(Math.sqrt(Math.sin(difflat / 2) * Math.sin(difflat / 2) + Math.cos(rlat1) * Math.cos(rlat2) * Math.sin(difflon / 2) * Math.sin(difflon / 2)))
}

其他回答

试试这个。它在VB.net中,您需要将其转换为Javascript。此函数接受十进制分钟的参数。

    Private Function calculateDistance(ByVal long1 As String, ByVal lat1 As String, ByVal long2 As String, ByVal lat2 As String) As Double
    long1 = Double.Parse(long1)
    lat1 = Double.Parse(lat1)
    long2 = Double.Parse(long2)
    lat2 = Double.Parse(lat2)

    'conversion to radian
    lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0
    long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0
    lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0
    long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0

    ' use to different earth axis length
    Dim a As Double = 6378137.0        ' Earth Major Axis (WGS84)
    Dim b As Double = 6356752.3142     ' Minor Axis
    Dim f As Double = (a - b) / a        ' "Flattening"
    Dim e As Double = 2.0 * f - f * f      ' "Eccentricity"

    Dim beta As Double = (a / Math.Sqrt(1.0 - e * Math.Sin(lat1) * Math.Sin(lat1)))
    Dim cos As Double = Math.Cos(lat1)
    Dim x As Double = beta * cos * Math.Cos(long1)
    Dim y As Double = beta * cos * Math.Sin(long1)
    Dim z As Double = beta * (1 - e) * Math.Sin(lat1)

    beta = (a / Math.Sqrt(1.0 - e * Math.Sin(lat2) * Math.Sin(lat2)))
    cos = Math.Cos(lat2)
    x -= (beta * cos * Math.Cos(long2))
    y -= (beta * cos * Math.Sin(long2))
    z -= (beta * (1 - e) * Math.Sin(lat2))

    Return Math.Sqrt((x * x) + (y * y) + (z * z))
End Function

编辑 javascript中的转换函数

function calculateDistance(lat1, long1, lat2, long2)
  {    

      //radians
      lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0;      
      long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0;    
      lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0;   
      long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0;       


      // use to different earth axis length    
      var a = 6378137.0;        // Earth Major Axis (WGS84)    
      var b = 6356752.3142;     // Minor Axis    
      var f = (a-b) / a;        // "Flattening"    
      var e = 2.0*f - f*f;      // "Eccentricity"      

      var beta = (a / Math.sqrt( 1.0 - e * Math.sin( lat1 ) * Math.sin( lat1 )));    
      var cos = Math.cos( lat1 );    
      var x = beta * cos * Math.cos( long1 );    
      var y = beta * cos * Math.sin( long1 );    
      var z = beta * ( 1 - e ) * Math.sin( lat1 );      

      beta = ( a / Math.sqrt( 1.0 -  e * Math.sin( lat2 ) * Math.sin( lat2 )));    
      cos = Math.cos( lat2 );   
      x -= (beta * cos * Math.cos( long2 ));    
      y -= (beta * cos * Math.sin( long2 ));    
      z -= (beta * (1 - e) * Math.sin( lat2 ));       

      return (Math.sqrt( (x*x) + (y*y) + (z*z) )/1000);  
    }

你使用的是哈弗辛公式,它计算了当乌鸦飞行时球面上两点之间的距离。您提供的谷歌Maps链接显示距离为2.2公里,因为它不是一条直线。

Wolfram Alpha是进行地理计算的一个很好的资源,它还显示了这两点之间的距离为1.652公里。

如果您正在寻找直线距离(如crow文件),则您的函数工作正常。如果你想要的是开车距离(或骑自行车距离、公共交通距离或步行距离),你必须使用一个映射API(谷歌或Bing是最流行的)来获得适当的路线,其中将包括距离。

顺便提一下,谷歌Maps API在其Google . Maps .geometry.spherical命名空间(查找computeDistanceBetween)中提供了一个打包的球面距离方法。这可能比你自己卷更好(首先,它使用了更精确的地球半径值)。

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

我在typescript和ES6中实现了这个算法

export type Coordinate = {
  lat: number;
  lon: number;
};

求两点之间的距离:

function getDistanceBetweenTwoPoints(cord1: Coordinate, cord2: Coordinate) {
  if (cord1.lat == cord2.lat && cord1.lon == cord2.lon) {
    return 0;
  }

  const radlat1 = (Math.PI * cord1.lat) / 180;
  const radlat2 = (Math.PI * cord2.lat) / 180;

  const theta = cord1.lon - cord2.lon;
  const radtheta = (Math.PI * theta) / 180;

  let 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;
  dist = dist * 1.609344; //convert miles to km
  
  return dist;
}

获取坐标数组之间的距离

export function getTotalDistance(coordinates: Coordinate[]) {
  coordinates = coordinates.filter((cord) => {
    if (cord.lat && cord.lon) {
      return true;
    }
  });
  
  let totalDistance = 0;

  if (!coordinates) {
    return 0;
  }

  if (coordinates.length < 2) {
    return 0;
  }

  for (let i = 0; i < coordinates.length - 2; i++) {
    if (
      !coordinates[i].lon ||
      !coordinates[i].lat ||
      !coordinates[i + 1].lon ||
      !coordinates[i + 1].lat
    ) {
      totalDistance = totalDistance;
    }
    totalDistance =
      totalDistance +
      getDistanceBetweenTwoPoints(coordinates[i], coordinates[i + 1]);
  }

  return totalDistance.toFixed(2);
}

访问这个地址。 https://www.movable-type.co.uk/scripts/latlong.html 你可以使用下面的代码:

JavaScript:     

const R = 6371e3; // metres
const φ1 = lat1 * Math.PI/180; // φ, λ in radians
const φ2 = lat2 * Math.PI/180;
const Δφ = (lat2-lat1) * Math.PI/180;
const Δλ = (lon2-lon1) * Math.PI/180;

const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
          Math.cos(φ1) * Math.cos(φ2) *
          Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

const d = R * c; // in metres

我试着通过命名变量让代码更容易理解, 我希望这能有所帮助

function getDistanceFromLatLonInKm(point1, point2) {

  const [lat1, lon1] = point1;
  const [lat2, lon2] = point2;
  const earthRadius = 6371;
  const dLat = convertDegToRad(lat2 - lat1);
  const dLon = convertDegToRad(lon2 - lon1);
  const squarehalfChordLength =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(convertDegToRad(lat1)) * Math.cos(convertDegToRad(lat2)) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);

  const angularDistance = 2 * Math.atan2(Math.sqrt(squarehalfChordLength), Math.sqrt(1 - squarehalfChordLength));
  const distance = earthRadius * angularDistance;
  return distance;

}