Calcular la distancia entre dos puntos (Latitud, Longitud)

Estoy intentando calcular la distancia entre dos posiciones en un mapa. He almacenado en mis datos Longitud, Latitud, X POS, Y POS.

He estado utilizando previamente el siguiente fragmento.

DECLARE @orig_lat DECIMAL
DECLARE @orig_lng DECIMAL
SET @orig_lat=53.381538 set @orig_lng=-1.463526
SELECT *,
    3956 * 2 * ASIN(
          SQRT( POWER(SIN((@orig_lat - abs(dest.Latitude)) * pi()/180 / 2), 2) 
              + COS(@orig_lng * pi()/180 ) * COS(abs(dest.Latitude) * pi()/180)  
              * POWER(SIN((@orig_lng - dest.Longitude) * pi()/180 / 2), 2) )) 
          AS distance
--INTO #includeDistances
FROM #orig dest

Sin embargo, no me fío de los datos que salen de esto, parece que da resultados ligeramente inexactos.

Algunos datos de muestra en caso de que los necesite

Latitude        Longitude     Distance 
53.429108       -2.500953     85.2981833133896

Podría alguien ayudarme con mi código, no me importa si quieres arreglar lo que ya tengo si tienes una nueva forma de lograr esto sería genial.

Por favor, indique en qué unidad de medida están sus resultados.

Solución

Dado que utiliza SQL Server 2008, dispone del tipo de datos geography, que está diseñado exactamente para este tipo de datos:

DECLARE @source geography = 'POINT(0 51.5)'
DECLARE @target geography = 'POINT(-3 56)'

SELECT @source.STDistance(@target)

Da

----------------------
538404.100197555

(1 row(s) affected)

Nos dice que hay unos 538 km desde (cerca de) Londres hasta (cerca de) Edimburgo.

Naturalmente, habrá que aprender primero, pero una vez que lo conozcas es mucho más fácil que implementar tu propio cálculo de Haversine; además, obtienes MUCHAS funcionalidades.


Si quieres mantener tu estructura de datos existente, puedes seguir utilizando STDistance, construyendo instancias de geografía adecuadas utilizando el método Point:

DECLARE @orig_lat DECIMAL(12, 9)
DECLARE @orig_lng DECIMAL(12, 9)
SET @orig_lat=53.381538 set @orig_lng=-1.463526

DECLARE @orig geography = geography::Point(@orig_lat, @orig_lng, 4326);

SELECT *,
    @orig.STDistance(geography::Point(dest.Latitude, dest.Longitude, 4326)) 
       AS distance
--INTO #includeDistances
FROM #orig dest
Comentarios (11)

La siguiente función da distancia entre dos geocoordenadas en millas

create function [dbo].[fnCalcDistanceMiles] (@Lat1 decimal(8,4), @Long1 decimal(8,4), @Lat2 decimal(8,4), @Long2 decimal(8,4))
returns decimal (8,4) as
begin
declare @d decimal(28,10)
-- Convert to radians
set @Lat1 = @Lat1 / 57.2958
set @Long1 = @Long1 / 57.2958
set @Lat2 = @Lat2 / 57.2958
set @Long2 = @Long2 / 57.2958
-- Calc distance
set @d = (Sin(@Lat1) * Sin(@Lat2)) + (Cos(@Lat1) * Cos(@Lat2) * Cos(@Long2 - @Long1))
-- Convert to miles
if @d  0
begin
set @d = 3958.75 * Atan(Sqrt(1 - power(@d, 2)) / @d);
end
return @d
end 

La siguiente función da distancia entre dos geocoordenadas en kilómetros

CREATE FUNCTION dbo.fnCalcDistanceKM(@lat1 FLOAT, @lat2 FLOAT, @lon1 FLOAT, @lon2 FLOAT)
RETURNS FLOAT 
AS
BEGIN

    RETURN ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+COS(PI()*@lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0))*6371
END

La siguiente función da distancia entre dos geocoordenadas en kilómetros utilizando el tipo de datos Geography que se introdujo en sql server 2008

DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
SELECT @g.STDistance(@h);

Uso:

select [dbo].[fnCalcDistanceKM](13.077085,80.262675,13.065701,80.258916)

Reference: Ref1,Ref2

Comentarios (6)

Si utiliza SQL 2008 o una versión posterior, le recomiendo que compruebe el tipo de datos GEOGRAPHY. SQL ha construido en el apoyo a las consultas geoespaciales.

Por ejemplo, usted tendría una columna en su tabla de tipo GEOGRAPHY que se rellenaría con una representación geoespacial de las coordenadas (consulte la referencia de MSDN enlazada anteriormente para ver ejemplos). Este tipo de datos expone métodos que permiten realizar toda una serie de consultas geoespaciales (por ejemplo, encontrar la distancia entre 2 puntos)

Comentarios (1)