我正在从单个点进行最近的点查询。这是顺序。我在MSSQLServer中存储了多个POI,并且该表dbo.Place
。第二个表是dbo.Position
,它将存储收集的GPS点。
我正在使用存储过程,并且位置的纬度已定义且可用。如何根据以下示例进行查询?
德博。地方
Id | Name | Lat | Long
1 POI1 1.735 4.73225
2 POI2 1.5665 3.9983
3 Tim2 1.4344 3.1282
Lat Long 变量在存储过程中定义。我想使用以下公式来查找最近的点,我只会从 3 个查询中获取最接近的值(假设示例数据为 3 行(
SQRT(POW(X(`POI.Lat`) - 49.843317 , 2) + POW(Y(`POI.Long`) - 24.026642, 2)) * 100
谢谢。
为此,您可以使用 SQL Server 的地理函数。
DECLARE @InputLatitude FLOAT = 1.64
DECLARE @InputLongitude FLOAT = 4.25
DECLARE @GPS GEOGRAPHY = GEOGRAPHY::Point(@InputLatitude, @InputLongitude, 4326)
SELECT TOP 1
P.*,
Distance = @GPS.STDistance(GEOGRAPHY::Point(P.Lat, P.Long, 4326))
FROM
dbo.Place AS P
ORDER BY
@GPS.STDistance(GEOGRAPHY::Point(P.Lat, P.Long, 4326)) ASC
您应该考虑在表上添加一个GEOGRAPHY
列,其中 GPS 点已经转换,并添加一个SPATIAL INDEX
以加快查询速度。
除了推荐的地理类型外,您还可以使用常规数据类型(如 float(获得类似的结果。
DECLARE @latitude FLOAT = 4.5678; -- Latitude of the place to search around
DECLARE @longitude FLOAT = 51.234; -- Longitude of the place to search around
DECLARE @range FLOAT = 100000; -- Max range in meters
SELECT TOP(1000)
[place].[Lat],
[place].[Long],
((((ACOS((SIN((PI() * [place].[Lat]) / 180.0) * SIN((PI() * @latitude) / 180.0)) + ((COS((PI() * [place].[Lat]) / 180.0) * COS((PI() * @latitude) / 180.0)) * COS((PI() * ([place].[Long] - @longitude)) / 180.0))) * 180.0) * 60.0) * 1.1515) * 1609.344) / PI() AS [Distance]
FROM [dbo].[Place] AS [place]
WHERE (((((ACOS((SIN((PI() * [place].[Lat]) / 180.0) * SIN((PI() * @latitude) / 180.0)) + ((COS((PI() * [place].[Lat]) / 180.0) * COS((PI() * @latitude) / 180.0)) * COS((PI() * ([place].[Long] - @longitude)) / 180.0))) * 180.0) * 60.0) * 1.1515) * 1609.344) / PI()) <= @range
ORDER BY [Distance]