terrestres puntos metros medir longitud latitudes latitud entre distancias distancia coordenadas calcular sql sql-server tsql math sql-server-2008-r2

sql - metros - Cálculo de distancia entre dos puntos(Latitud, Longitud)



formula de haversine (6)

Estoy tratando de calcular la distancia entre dos posiciones en un mapa. He almacenado mis datos: longitud, latitud, X POS, Y POS.

He estado usando el fragmento de abajo a continuación.

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 confío en los datos que surgen de esto, parece dar resultados ligeramente inexactos.

Algunos datos de muestra en caso de que lo necesite

Latitude Longitude Distance 53.429108 -2.500953 85.2981833133896

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

Indique en qué unidad de medida se encuentran sus resultados.


Además de las respuestas anteriores, aquí hay una forma de calcular la distancia dentro de un SELECT:

CREATE FUNCTION Get_Distance ( @La1 float , @Lo1 float , @La2 float, @Lo2 float ) RETURNS TABLE AS RETURN -- Distance in Meters SELECT GEOGRAPHY::Point(@La1, @Lo1, 4326).STDistance(GEOGRAPHY::Point(@La2, @Lo2, 4326)) AS Distance GO

Uso:

select Distance from Place P1, Place P2, outer apply dbo.Get_Distance(P1.latitude, P1.longitude, P2.latitude, P2.longitude)

Las funciones escalares también funcionan pero son muy ineficientes cuando se computan grandes cantidades de datos.

Espero que esto pueda ayudar a alguien.


Como está utilizando SQL 2008 o posterior, le recomiendo consultar el tipo de datos geography . SQL ha incorporado soporte para consultas geoespaciales.

por ejemplo, tendría una columna en su tabla de tipo GEOGRAPHY que se llenaría con una representación geoespacial de las coordenadas (consulte la referencia de MSDN vinculada anteriormente para ver ejemplos). Este tipo de datos luego expone los métodos que le permiten realizar una gran cantidad de consultas geoespaciales (por ejemplo, encontrar la distancia entre 2 puntos)


Dado que está utilizando SQL Server 2008, tiene el tipo de datos de geography disponible, que está diseñado para exactamente 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)

Indicarnos que está a unos 538 km de (cerca de Londres) a (cerca) Edimburgo.

Naturalmente, habrá una cantidad de aprendizaje que hacer primero, pero una vez que lo sepa, es mucho más fácil que implementar su propio cálculo de Haversine; además obtienes MUCHA funcionalidad.

Si desea conservar su estructura de datos existente, aún puede usar STDistance , mediante la construcción de instancias de geography 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


La función siguiente proporciona la distancia entre dos coordenadas geográficas 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 función siguiente proporciona la distancia entre dos coordenadas geográficas 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 función siguiente proporciona la distancia entre dos coordenadas geográficas en kilómetros utilizando el tipo de datos geography que se introdujo en el servidor sql 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)

Referencia: Ref1 , Ref2


Parece que Microsoft invadió los cerebros de todos los demás encuestados y les hizo escribir soluciones tan complicadas como sea posible. Esta es la forma más simple sin ninguna función adicional / declaraciones declare:

SELECT geography::Point(LATITUDE_1, LONGITUDE_1, 4326).STDistance(geography::Point(LATITUDE_2, LONGITUDE_2, 4326))

Simplemente sustituya sus datos en lugar de LATITUDE_1 , LONGITUDE_1 , LATITUDE_2 , LONGITUDE_2 , por ejemplo:

SELECT geography::Point(53.429108, -2.500953, 4326).STDistance(geography::Point(c.Latitude, c.Longitude, 4326)) from coordinates c


Create Function [dbo].[DistanceKM] ( @Lat1 Float(18), @Lat2 Float(18), @Long1 Float(18), @Long2 Float(18) ) Returns Float(18) AS Begin Declare @R Float(8); Declare @dLat Float(18); Declare @dLon Float(18); Declare @a Float(18); Declare @c Float(18); Declare @d Float(18); Set @R = 6367.45 --Miles 3956.55 --Kilometers 6367.45 --Feet 20890584 --Meters 6367450 Set @dLat = Radians(@lat2 - @lat1); Set @dLon = Radians(@long2 - @long1); Set @a = Sin(@dLat / 2) * Sin(@dLat / 2) + Cos(Radians(@lat1)) * Cos(Radians(@lat2)) * Sin(@dLon / 2) * Sin(@dLon / 2); Set @c = 2 * Asin(Min(Sqrt(@a))); Set @d = @R * @c; Return @d; End GO

Uso:

seleccione dbo.DistanceKM (37.848832506474, 37.848732506474, 27.83935546875, 27.83905546875)

Productos:

0,02849639

Puede cambiar el parámetro @R con flotadores comentados.