计算两个点之间的距离(纬度,经度)(Calculating distance between two

2019-06-18 15:07发布

我试图计算地图上的两个位置之间的距离。 我已经保存在我的数据:经度,纬度,X POS,Y POS。

我以前已经使用下面的代码片段。

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

我不相信但数据出来的这一点,似乎给人略显不准确的结果。

在一些情况下,样本数据,你需要它

Latitude        Longitude     Distance 
53.429108       -2.500953     85.2981833133896

任何人可以帮助我与我的代码,如果你想解决什么我已经有了,如果你有实现这一目标的一种新的方式,这将是伟大的,我不介意。

请说出你的结果是什么计量单位。

Answer 1:

由于您使用SQL Server 2008中,您有geography可用的数据类型,这是专为正是这种类型的数据:

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

SELECT @source.STDistance(@target)

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

(1 row(s) affected)

告诉我们它是从(近)伦敦538公里(近)爱丁堡。

自然会有学习的第一个这样做的量,但一旦你知道它远比实现自己的半正矢计算容易得多; 再加上你的功能很多。


如果你想保留现有的数据结构,你仍然可以使用STDistance ,通过构建适当的geography使用的情况下, 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


Answer 2:

下面函数给出以英里2个地理坐标之间的距离

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 

下面的函数给出公里2个地理坐标之间的距离

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

下面函数给出使用公里2个地理坐标之间的距离 地理数据类型将其在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);

用法:

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

参考: Ref1至 , 至Ref2



Answer 3:

它看起来像微软入侵的其他所有受访者的大脑,让他们写的那样复杂的解决方案成为可能。 这是一个没有任何附加功能/声明语句最简单的方法:

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

简单地替换为您的数据,而不是LATITUDE_1LONGITUDE_1LATITUDE_2LONGITUDE_2例如:

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


Answer 4:

当你正在使用SQL 2008或更高版本,我建议你检查出的地理数据类型。 SQL具有内置的地理空间查询的支持。

例如,你必须在你的类型,地理这将与坐标的地理空间表示填充的表中的列(看看上面链接的例子参考MSDN)。 此数据类型则暴露了方法让您执行地理空间查询整个主机(例如寻找2点之间的距离)



Answer 5:

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

用法:

选择dbo.DistanceKM(37.848832506474,37.848732506474,27.83935546875,27.83905546875)

输出:

0,02849639

你可以评论花车改变@R参数。



Answer 6:

除了以前的答案,这里是计算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

用法:

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

标量函数也工作,但计算大量数据的时候都非常低效的。

我希望这可以帮助别人。



文章来源: Calculating distance between two points (Latitude, Longitude)