SQL半径搜索

时间:2018-02-16 13:03:18

标签: sql sql-server geospatial

假设我有一个由5个纬度/经度点组成的多边形地理区域,例如: -

51.314869, -0.497125
51.255586, 0.237066
51.684476, 0.244771
51.725210, -0.514339
51.314869, -0.497125
然后我从30英里的单点(例如51.728215,-1.209971)进行半径搜索。我希望能够找出半径搜索是否包含任何或所有多边形区域。

我知道SQL Server中提供了一种地理数据类型,如果需要,可以将数据更改为此,如果它可以更轻松地解决它

2 个答案:

答案 0 :(得分:0)

您可以通过计算lat / lon的最小值和最大值来计算边界框来优化搜索。然后,您可以通过与最小/最大纬度/长度进行比较来搜索数据库。最后,您可以通过检查lat / lon是否在多边形内部来过滤剩余数据。如果多边形是凸的,这并不难。您必须将其分解为三角形,并检查纬度/经度是否在其中一个内。

答案 1 :(得分:0)

以下应该可以解决问题:

declare @g geography =
    geography::STGeomFromText('POLYGON((
        51.314869 -0.497125 ,
        51.255586 0.237066  ,
        51.684476 0.244771  ,
        51.725210 -0.514339 ,
        51.314869 -0.497125 
    ))', 4326);

set @g=@g.ReorientObject();

declare @p geography =
    --geography::Point(-0.497125, 51.314869, 4326);
    geography::STPointFromText('POINT(51.314869 -0.497125)', 4326);

select @g.STIntersects(@p.STBuffer(48280.3))

作为解释,我正在使用地理数据类型,就像你的直觉所说应该是可能的。我首先构造一个代表你的区域的多边形。实际多边形的语法称为WKT(即众所周知的文本),是地理空间的标准。

下一步是我必须重新定位你的对象。为什么?具有地理多边形的问题是,它们可以定义边界内部区域或外部区域,具体取决于定义点的顺序。在这种情况下,你指定它们的顺序定义了区域的外部(即整个地球减去一个非常小的四边形),所以我假设你想要考虑该区域的内部(事实证明你有必要,如下所示。)

接下来,我构建一个观点。为方便起见,我选择了多边形的一个角。请注意,我提供了两种方法。我个人更喜欢使用Point()方法,但您也可以使用WKT来实现它!

最后,我测试你的多边形(@g)和一个以半径30英里(或48280.3米)为中心的圆盘之间的交叉点。测试返回一个布尔值。说到多边形中的点排序假设,如果以错误的顺序定义点,则交叉点测试将对甚至不接近多边形的事物返回true(因为它几乎定义了全局的全局)。乍一看,你认为你可以反转测试(即STIntersects()测试的逻辑否定),但我会把它作为练习留给读者,为什么这不是正确的做法