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