假设我有一个由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中提供了一种地理数据类型,如果需要,可以将数据更改为此,如果它可以更轻松地解决它
答案 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()
测试的逻辑否定),但我会把它作为练习留给读者,为什么这不是正确的做法