65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 SQL Server 计算地理距离

2017 年 5 月 6 日

CPOL

1分钟阅读

viewsIcon

79454

如何使用 SQL Server 计算两个地理位置之间的距离,或在特定半径范围内查找距离

引言

在本技巧中,我将解释如何使用 SQL Server 计算两个地理位置之间的地理距离。

背景

地理位置半径搜索是当今大多数应用程序中的一项常见功能。
您可以计算两个地理位置之间的距离,也可以在指定半径内找到附近的地理位置。

Using the Code

您可以使用空间类型 - SQL Server 中的 **geography** 数据类型来计算地理距离。
这种类型以圆地球坐标系中表示数据。您可以在 Spatial type: Geography 处找到详细信息。

我知道更详细的描述会让你感到厌烦。

假设我们有一个表,其中包含位置名称及其经度和纬度地理位置,如下所示

Location tag

现在假设我想从我的当前位置计算出所有显示位置的距离,那么您可以使用当前的经度和纬度来计算,如下所示。

目前我的位置是:23.012034, 72.510754

DECLARE
@GEO1 GEOGRAPHY,
@LAT VARCHAR(10),
@LONG VARCHAR(10)

SET @LAT='23.012034'
SET @LONG='72.510754'


SET @geo1= geography::Point(@LAT, @LONG, 4326)

SELECT LOC_ID,LOC_NAME,(@geo1.STDistance(geography::Point(ISNULL(LAT,0), _
ISNULL(LONG,0), 4326))) as DISTANCE  FROM LOCATION_MASTER

location

这些距离以米为单位计算。您可以根据您的要求进行计算。

我将其转换为公里,如下所示

SELECT LOC_ID,LOC_NAME,LEFT(CONVERT(VARCHAR,_
(@geo1.STDistance(geography::Point(ISNULL(LAT,0), _
ISNULL(LONG,0), 4326))/1000)),5)+' Km' as DISTANCE FROM LOCATION_MASTER

location

您还可以按半径计算位置。

假设您只想找到附近半径为 7 公里的位置。

DECLARE
@GEO1 GEOGRAPHY,
@LAT VARCHAR(10),
@LONG VARCHAR(10)

SET @LAT='23.012034'
SET @LONG='72.510754'

SET @geo1= geography::Point(@LAT, @LONG, 4326)

SELECT LOC_ID,LOC_NAME,LEFT(CONVERT(VARCHAR,_
(@geo1.STDistance(geography::Point(ISNULL(LAT,0), _
ISNULL(LONG,0), 4326)))/1000),5)+' Km' _
as DISTANCE from LOCATION_MASTER
WHERE (@geo1.STDistance(geography::Point(ISNULL(LAT,0), _
ISNULL(LONG,0), 4326)))/1000 < 7

LOCATIONS

通过使用 geography 数据类型,地理距离计算变得非常容易。

关注点

您可以创建一个存储过程,只需传递当前经度、纬度和半径,它将返回半径内的位置记录。

CREATE PROCEDURE calculateDistance
    @RADIUS INT=0,
    @LAT VARCHAR(10)='',
    @LONG VARCHAR(10)='',
    @GEO1 GEOGRAPHY = NULL,
AS
BEGIN        
    
    SET @geo1= geography::Point(@LAT, @LONG, 4326)        
    
    SELECT TOP 10 LOC_ID,LOC_NAME,LEFT(CONVERT(VARCHAR,_
    (@geo1.STDistance(geography::Point(ISNULL(LAT,0), _
    ISNULL(LONG,0), 4326)))/1000),5)+' Km' as DISTANCE from LOCATION_MASTER
    WHERE (@geo1.STDistance(geography::Point(ISNULL(LAT,0), _
    ISNULL(LONG,0), 4326)))/1000 < @RADIUS
    
END
GO

注意:此距离是点到点的直线距离,不会像道路路线那样计算。

历史

  • 2017 年 5 月 6 日:初始发布
© . All rights reserved.