假设我有一个由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中有一种可用的地理数据类型,如果需要,可以将数据更改为此类型,前提是这样可以更容易地解决问题
发布于 2018-02-16 23:58:26
下面的代码应该可以解决这个问题:
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()
测试的逻辑否定),但我将把它留给读者作为练习,为什么这不是正确的做法。
发布于 2018-02-16 21:10:42
您可以通过取经度/经度的最小和最大值来计算边界框来优化搜索。然后,您可以通过比较最小/最大经度/最小纬度来搜索数据库。最后,您可以通过检查经度/经度是否在多边形内来过滤剩余数据。如果多边形是凸的,这不是很难做到的。你必须将它分解成三角形,并检查经度/经度是否在其中之一。
https://stackoverflow.com/questions/48827415
复制相似问题