Функция для расчета расстояния между двумя координатами

В настоящее время я использую функцию ниже, и она не работает должным образом. Согласно Google 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/

Ответ 1

То, что вы используете, называется формулой 1,652 км между этими двумя точками.

Drive distance vs. straight line distance (red line mine).

Если вы ищете прямолинейное расстояние (как файлы ворона), ваша функция работает правильно. Если вам нужно дистанция (расстояние на велосипеде или расстояние общественного транспорта или расстояние пешком), вам придется использовать API сопоставления (Google или Bing является самым популярным), чтобы получить соответствующий маршрут, который будет включать в себя расстояние.

Кстати, API Карт Google предоставляет упакованный метод для сферического расстояния в google.maps.geometry.spherical namespace (ищите computeDistanceBetween). Вероятно, это лучше, чем катиться самостоятельно (для начала используется более точное значение радиуса Земли).

Для нас придирчивой, когда я говорю "прямолинейное расстояние", я имею в виду "прямую линию на сфере", которая на самом деле является криволинейной линией (т.е. расстоянием большого круга), конечно.

Ответ 2

Я написал аналогичное уравнение раньше - протестировал его, а также получил 1,6 км.

На ваших картах google показывалось расстояние DRIVING.

Ваша функция вычисляется по прямой (прямолинейное расстояние).

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

Ответ 3

Решение 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;
}

Ответ 4

Попробуйте это. Это в 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);  
    }

Ответ 5

Вычислить расстояние между двумя точками в javascript

function distance(lat1, lon1, lat2, lon2, unit) {
        var radlat1 = Math.PI * lat1/180
        var radlat2 = Math.PI * lat2/180
        var radlon1 = Math.PI * lon1/180
        var radlon2 = Math.PI * lon2/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);
        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
}

Для получения дополнительной информации см. Ссылку: Ссылка

Ответ 6

Кто-нибудь может объяснить мне, как это использовать? Я пытаюсь вычислить между 2 координатами (текстовое поле ввода lat.long1 1 и текстовое поле ввода lat.long2 2) с редактированием текста в Tasker и очень мало знаю о том, как использовать Java, но я пытаюсь учиться, и это отправная точка для меня. Я планирую поле для редактирования текста varordin1 &ordin2, и когда вы нажмете кнопку submit itll, разделите lat и long в обоих полях, укажите точное местоположение обоих, и вы получите координаты, основанные на расстоянии обоих блоков в км.