计算点之间的距离时不一致
Posted
技术标签:
【中文标题】计算点之间的距离时不一致【英文标题】:Incosistency when Calculating Distance Between Points 【发布时间】:2015-07-28 15:53:14 【问题描述】:我在 SQL Server 中有一个函数可以计算两个指定点之间的距离。
该函数使用在 T-SQL 中编写为函数的 Haversine 公式的实现:
CREATE FUNCTION dbo.mpl_geo_distance
(
@LAT1 FLOAT ,
@LON1 FLOAT ,
@LAT2 FLOAT ,
@LON2 FLOAT
)
RETURNS FLOAT
WITH ENCRYPTION
AS
BEGIN
DECLARE @A AS FLOAT
DECLARE @C AS FLOAT
DECLARE @L1 AS FLOAT
DECLARE @L2 AS FLOAT
DECLARE @R1 AS FLOAT
DECLARE @R2 AS FLOAT
SET @R1 = RADIANS(@LAT1)
SET @R2 = RADIANS(@LAT2)
SET @L1 = RADIANS(@LAT2 - @LAT1)
SET @L2 = RADIANS(@LON2 - @LON1)
SET @A = SIN(@L1 / 2) * SIN(@L1 / 2) + COS(@R1) * COS(@R2) * SIN(@L2 / 2) * SIN(@L2 / 2)
SET @C = 2 * ATN2(SQRT(@A), SQRT(1 - @A))
RETURN 6371000 * @C
END
根据我在 SO 上阅读的一些答案,我决定尝试使用 GEOGRAPHY
类型和 STDistance
。然而,这两种方法的结果是不同的(虽然差别不大):
-- Distance between London and Eiffel Tower
DECLARE @X GEOGRAPHY = 'POINT(51.5000 -0.1300)'
DECLARE @Y GEOGRAPHY = 'POINT(48.858093 2.294694)'
PRINT @X.STDistance(@Y)
PRINT dbo.mpl_geo_distance (51.5000, -0.1300, 48.858093, 2.294694)
产量:
397909
340704
哪个值更准确,我应该使用哪个?
【问题讨论】:
我认为你的纬度和经度倒数了。打印 dbo.mpl_geo_distance(-0.1300, 51.5000, 2.294694, 48.858093) 【参考方案1】:Haversine 公式是一个估计值。如果您查看this site,它会显示各种计算,但请注意:
所有这些公式都是基于球形地球的计算(忽略椭球体效应)——对于大多数用途来说,这已经足够准确*了……[事实上,地球是非常轻微的椭球体;使用球形模型通常会产生高达 0.3% 的误差 - 请参阅注释了解更多详细信息]。
Wikipedia 声称错误可能更高:
当应用于地球时,这两个公式都只是一个近似值,它不是一个完美的球体:“地球半径”R 从两极的 6356.752 公里到赤道的 6378.137 公里不等。更重要的是,地球表面南北线的曲率半径在两极(≈6399.594 公里)比在赤道(≈6335.439 公里)大 1%——所以半正弦公式和余弦定律不能保证正确率优于0.5%
经过一番挖掘,我不完全确定 STDistance 是如何计算的,但 Microsoft say 这个:
STDistance() 返回两种地理类型之间最短的 LineString。这是测地线距离的近似值。普通地球模型上的 STDistance() 与精确测地线距离的偏差不超过 0.25%。这样可以避免混淆测地线类型中长度和距离之间的细微差别。
如果要相信各种来源,那么似乎 STDistance 可能比 Haversine 公式更准确。
【讨论】:
以上是关于计算点之间的距离时不一致的主要内容,如果未能解决你的问题,请参考以下文章