javascript - puntos - La función para calcular la distancia entre dos coordenadas muestra un error
formula de haversine (4)
He escrito una ecuación similar antes: la probé y también obtuve 1.6 km.
Tus google maps mostraban la distancia de CONDUCCIÓN.
Su función es calcular a vuelo de pájaro (distancia en línea recta).
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;
}
Actualmente estoy usando la función a continuación y muestra un poco mal. Según Google Maps, la distancia entre estas coordenadas (de 59.3293371,13.4877472 a 59.3225525,13.4619422) es de 2,2 kilómetros mientras que la función muestra 1,6 kilómetros. ¿Cómo puedo hacer que la función de Chuck muestre la distancia correcta?
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/
La solución de Derek funcionó bien para mí, y simplemente la convertí a PHP, ¡espero que ayude a alguien allá afuera!
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;
}
Lo que estás usando se llama la fórmula de haversine , que calcula la distancia entre dos puntos en una esfera en línea recta . El enlace de Google Maps que proporcionó muestra la distancia como 2.2 km porque no es una línea recta.
Wolphram Alpha es un gran recurso para hacer cálculos geográficos, y también muestra una distancia de 1.652 km entre estos dos puntos .
Si está buscando una distancia en línea recta (como los archivos crow), su función está funcionando correctamente. Si lo que quieres es distancia de manejo (o distancia en bicicleta o distancia de transporte público o distancia recorrida), tendrás que usar una API de mapeo ( Google o Bing son los más populares) para obtener la ruta apropiada, que incluirá la distancia.
A propósito, la API de Google Maps proporciona un método empaquetado para la distancia esférica, en su espacio de nombres google.maps.geometry.spherical
(busque computeDistanceBetween
). Probablemente sea mejor que rodar el suyo (para empezar, usa un valor más preciso para el radio de la Tierra).
Para el exigente de nosotros, cuando digo "distancia en línea recta", me refiero a una "línea recta en una esfera", que en realidad es una línea curva (es decir, la distancia del círculo máximo), por supuesto.
Prueba esto. Está en VB.net y necesitas convertirlo a Javascript. Esta función acepta parámetros en minutos decimales.
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
Editar la función convertida en 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);
}