多个地理值之间的距离

时间:2014-07-09 08:39:51

标签: sql-server-2008 tsql sqlgeography

我们使用多个地理点的平均值来获得平均值并将其指定为项目位置。 我现在需要追踪这些数据并以某种方式识别任何与其余数据相距太远的原始点。 我认为我需要使用STDistance,但担心要做到正确我需要2个游标来循环并比较每个点与其他点。

如果示例有助于澄清:我们需要锁定项目的GPS坐标,因此我们要求用户在项目的大致区域内按下按钮,并记录GPS协议。然后,我们将其中的5个设置为AVG(Location.Lat)+ AVG(Location.Long)。 当其中一个用户按下完成数英里之外,抛出平均值时就会出现问题,因此现在需要识别其中任何一个。

关于在SQL中执行此操作的正确/有效方法的任何想法? (处理数以百万计的条目因此担心每个项目循环2个游标会使数据库瘫痪)

1 个答案:

答案 0 :(得分:2)

丢弃统计上无关紧要的数据对于人类来说很容易,但对于计算机来说可能有点麻烦。在您的情况下尤其如此,因为您处理的是两个维度(纬度和经度)。

我建议你看几年前写的这篇博客:Calculating Mean Median and Mode With SQL Server

使用纬度和经度,小数点后的每个数字代表一个距离。你能做的是将纬度和经度四舍五入到一定数量的小数位,找到模式。删除与模式不同的点,然后平均剩余的未接地项。

由于您在两个维度上工作,因此您需要分别针对纬度和经度值执行此操作,因为纬度可能会偏离而经度不是(这将代表北方或南部的实际位置)。同样地,经度可能会偏离,而纬度显然是正常的。如果任何一个值都是"坏",那么你应该完全丢弃这个点。

以下是我所说的一个例子:

Declare @Temp Table(Lat Decimal(9,6), Lon Decimal(9,6))

Insert Into @Temp Values(20.12341, 10.98731)
Insert Into @Temp Values(20.12342, 10.98732)
Insert Into @Temp Values(20.12343, 10.98733)
Insert Into @Temp Values(20.12344, 10.98734)
Insert Into @Temp Values(20.12344, 10.68734) -- Latitude OK, Longitude bad
Insert Into @Temp Values(20.32344, 10.98734) -- Longitude OK, Latitude bad
Insert Into @Temp Values(20.42340, 10.68730) -- Both are bad

Select  Avg(Lat), Avg(Lon)
From    @Temp

Select  Avg(T.Lat) As Latitude,
        Avg(T.Lon) As Longitude
From    @Temp T
        Inner Join (
            -- Calculate the mode for the latitude
            Select  Top 1 Convert(Decimal(9,4), Lat) As ModeOfLat
            From    @Temp
            Group By Convert(Decimal(9,4), Lat)
            Order By Count(*) DESC
            ) As Latitudes
            On Convert(Decimal(9,4), Lat) = Latitudes.ModeOfLat
        Inner Join (
            -- Calculate the mode for the longitude
            Select  Top 1 Convert(Decimal(9,4), Lon) As ModeOfLon
            From    @Temp
            Group By Convert(Decimal(9,4), Lon)
            Order By Count(*) DESC
            ) As Longitudes
            On Convert(Decimal(9,4), Lon) = Longitudes.ModeOfLon

如果在SQL Server Management Studio窗口中运行上面的查询,您将看到简单平均值与模式+平均值方法有很大不同。

由于这是一个基于集合的方法,因此它应该比循环/光标方法快得多。