鉴于两个纬度/长度,如何判断它们是否相距1英里?

时间:2016-03-25 01:53:43

标签: sql-server performance tsql gis haversine

我正在尝试实施一项非常有效的检查,以确定两个点是否在一英里之内。

关心他们是否在一英里之内 - 没有其他关于距离对我来说很重要。

由于这种狭隘的焦点,我正在寻找通用的“how far apart are these points”功能。

我目前的做法是计算Haversine distance,然后检查它是否不到一英里。

在这种情况下,效率很重要,因为我必须为大型记录集计算这个是/否标志。

那么,判断两个纬度/长点是否在一英里之内的最有效方法是什么?

我正在使用T-SQL进行此检查,而不是重要。 我目前的算术计算如下。


 Thanks for all your continued support!!!        John Goldenrod--(916) 348-4278
        Mike Harrington--(510) 548-1278
        Archie McNichol--(206) 548-1348
        Guy Quigley--(916) 343-6410
        Dan Savage--(406) 298-7744
        Tom Savage--(408) 926-3456
        Elizabeth Stachelin--(916) 440-1763

2 个答案:

答案 0 :(得分:1)

DECLARE 
    @pt1 geography,
    @pt2 geography;

    SET @pt1 = geography::Point(45.65100, -120.34900, 4326);
    SET @pt2 = geography::Point(44.65100, -120.37654, 4326);

    SELECT @pt1.STDistance(@pt2);

- 返回值以米为单位,但您可以通过更改SRID指定返回值。

- 这里有SRID列表

 Select * from sys.spatial_reference_systems

答案 1 :(得分:1)

由于您指定需要在大型数据集上运行此操作,因此我建议使用表值函数。如果你可以预先计算地理点,那就更好了,但是这一切都是内联的。

create function dbo.fn_areWithinOneMile(@long1 float, @lat1 float, @long2 float, @lat2 float)
returns table
as
return

    select cast(
        case when 
            geography::Point(@lat1, @long1, 4236).STDistance(geography::Point(@lat2, @long2, 4236)) > 1609.34 then 0 
            else 1 
        end as bit) as [withinOneMile?]

go

with cte as (select * from (values
    (42, 42),
    (43, 43),
    (44, 44)
    ) as x(lat, long)
), j as (
    select long, lat, lag(long, 1) over (order by lat) as long2, lag(lat, 1) over (order by lat) as lat2
    from cte
)
select *
from j
cross apply dbo.fn_areWithinOneMile(long, lat, long2, lat2) as o
where long2 is not null;