我不熟悉SQL Server关于地理数据类型的功能以及如何使用它来计算两点之间的距离。但是,在YouTube视频的帮助下,我能够快速编写查询,以查找"位置"表中特定经纬度/经度点定义半径内的所有行。
DECLARE @Lat DECIMAL(12,9)
DECLARE @Long DECIMAL(12,9)
DECLARE @Miles INT
DECLARE @Meters FLOAT
-- Coordinates set to a reference point
SET @Lat = 29.761209
SET @Long = -95.383513
SET @Miles = 15
SET @Meters = @Miles * 1609.34
DECLARE @Orig GEOGRAPHY = GEOGRAPHY::Point(@Lat, @Long, 4326)
SELECT
@Orig.STDistance(GEOGRAPHY::Point(latitude, longitude, 4326)) / 1609.34 As MilesDistance,
*
FROM Locations
WHERE @Orig.STDistance(GEOGRAPHY::Point(latitude, longitude, 4326)) <= @Meters
AND latitude IS NOT NULL AND longitude IS NOT NULL
ORDER BY 1
但我现在需要更进一步。我需要将它们与一组多个点进行比较,而不是将位置与单个参考点进行比较。这基本上是一个笛卡尔连接,返回我从另一个表中提取的位置记录和经度/经度值的所有组合的距离,这可能取代了从单个点创建的@Orig变量。
好的,所以我能够想出一个有效的解决方案。我首先创建了一个 SQL 函数:
ALTER FUNCTION [dbo].[MilesBetweenTwoPoints]
(
@LatA DECIMAL(10,6),
@LongA DECIMAL(10,6),
@LatB DECIMAL(10,6),
@LongB DECIMAL(10,6)
)
RETURNS DECIMAL(10,6) AS
BEGIN
DECLARE @Miles DECIMAL(10,6)
DECLARE @PointA GEOGRAPHY = GEOGRAPHY::Point(@LatA, @LongA, 4326)
DECLARE @PointB GEOGRAPHY = GEOGRAPHY::Point(@LatB, @LongB, 4326)
SELECT @Miles = @PointA.STDistance(@PointB) / 1609.34
RETURN @Miles
END
然后我修改了我的查询,看起来像这样:
SELECT L1.latitude, L1.longitude, L2.latitude, L2.longitude,
dbo.MilesBetweenTwoPoints(L1.latitude, L1.longitude, L2.latitude, L2.longitude) As DistanceMiles
FROM Locations L1
INNER JOIN OtherLocations L2 ON 1=1
WHERE dbo.MilesBetweenTwoPoints(L1.latitude, L1.longitude, L2.latitude, L2.longitude) < @Miles