SQL几何查找半径内的所有点

编程入门 行业动态 更新时间:2024-10-26 17:21:29
本文介绍了SQL几何查找半径内的所有点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我精通SQL,但不熟悉使用SQL几何特性。我有一个可能是非常基本的问题要解决,但我还没有在网上找到任何好的资源来解释如何使用几何对象。(TechNet是一种学习新事物的糟糕方式...)

我在笛卡尔平面上有一个二维点的集合,我正在尝试查找半径集合内的所有点。

我使用如下语法创建并填充了一个表:

更新[事物]set[位置]=几何::Point(@X,@Y,0)

(@X,@Y只是x和y值,0是所有对象共享的任意数字,如果我理解正确的话,它允许集合筛选)

这就是我偏离轨道的地方……我是尝试使用它来构建某种多边形集合和查询,还是有某种简单的方法来检查多个半径的交集,而不需要构建一堆圆形多边形?

附录:如果没有人知道多半径问题的答案,那么单半径解决方案是什么?

更新

以下是我使用虚构的恒星数据库制作的一些例子,其中恒星以点的形式存储在x-y网格上:

选择框中的所有点:

DECLARE @polygon geometry = geometry::STGeomFromText('POLYGON((' + CAST(@MinX AS VARCHAR(10)) + ' ' + CAST(@MinY AS VARCHAR(10)) + ',' + CAST(@MaxX AS VARCHAR(10)) + ' ' + CAST(@MinY AS VARCHAR(10)) + ', ' + CAST(@MaxX AS VARCHAR(10)) + ' ' + CAST(@MaxY AS VARCHAR(10)) + ',' + CAST(@MinX AS VARCHAR(10)) + ' ' + CAST(@MaxY AS VARCHAR(10)) + ',' + CAST(@MinX AS VARCHAR(10)) + ' ' + CAST(@MinY AS VARCHAR(10)) + '))', 0); SELECT [Star].[Name] AS [StarName], [Star].[StarTypeId] AS [StarTypeId], FROM [Star] WHERE @polygon.STContains([Star].[Location]) = 1 将其用作模式,您可以做各种有趣的事情,例如 定义多个面:

WHERE @polygon1.STContains([Star].[Location]) = 1 OR @polygon2.STContains([Star].[Location]) = 1 OR @polygon3.STContains([Star].[Location]) = 1

或检查距离:

WHERE [Star].[Location].STDistance(@polygon1) < @SomeDistance

INSERT语句示例

INSERT [Star] ( [Name], [StarTypeId], [Location], ) VALUES ( @Name, @StarTypeId, GEOMETRY::Point(@LocationX, @LocationY, 0), ) 推荐答案

这是一个令人难以置信的迟来的答案,但也许我可以解释一些解决方案。您所指的"设置"数字是空间参考识别符或SRID。对于经度/经度计算,您应该考虑将其设置为4326,这将确保将米用作测量单位。您还应该考虑切换到SqlGegraph,而不是SqlGeometry,但我们现在将继续使用SqlGeometry。要批量设置SRID,您可以按如下方式更新表:

UPDATE [YourTable] SET [SpatialColumn] = GEOMETRY.STPointFromText([SpatialColumn].STAsText(), 4326);

对于单个半径,您需要创建一个半径作为空间对象。例如:

DECLARE @radiusInMeters FLOAT = 1000; -- Set to a number in meters DECLARE @radius GEOMETRY = GEOMETRY::Point(@x, @y, 4326).STBuffer(@radiusInMeters);

STBuffer()获取空间点并从它创建一个圆(现在是Polygon类型)。然后您可以按如下方式查询您的数据集:

SELECT * FROM [YourTable] WHERE [SpatialColumn].STIntersects(@radius);

以上现在将使用您在其查询计划中为[SpatialColumn]创建的任何空间索引。

还有一个更简单的选项可以工作(仍然使用空间索引)。STDistance方法允许您执行以下操作:

DECLARE @radius GEOMETRY = GEOMETRY::Point(@x, @y, 4326); DECLARE @distance FLOAT = 1000; -- A distance in metres SELECT * FROM [YourTable] WHERE [SpatialColumn].STDistance(@radius) <= @distance;

最后,使用半径集合。你有几个选择。第一种方法是为每个半径依次运行上面的命令,但我会考虑以下几种方法:

DECLARE #radiiCollection TABLE ( [RadiusInMetres] FLOAT, [Radius] GEOMETRY ) INSERT INTO #radiiCollection ([RadiusInMetres], [Radius]) VALUES (1000, GEOMETRY::Point(@xValue, @yValue, 4326).STBuffer(1000)); -- Repeat for other radii SELECT X.[Id], MIN(R.[RadiusInMetres]) AS [WithinRadiusDistance] FROM [YourTable] X JOIN #radiiCollection RC ON RC.[Radius].STIntersects(X.[SpatialColumn]) GROUP BY X.[IdColumn], R.[RadiusInMetres] DROP TABLE @radiiCollection;

上面的最终版本还没有经过测试,但我99%肯定它就在那里,可能会有一些小的调整。在选择中采用最小半径距离的理想方式是,如果多个半径源于单个位置,则如果一个点在第一个半径内,则它自然也在所有其他半径内。因此,您将复制该记录,但通过分组,然后选择最小值,您只会得到一个(并且是最接近的)。

希望这对你有所帮助,尽管你问这个问题已经4周了。对不起,我没有早点看到它,如果问题只有一个空间标签就好了!

更多推荐

SQL几何查找半径内的所有点

本文发布于:2023-10-13 14:27:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1488208.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:半径   几何   SQL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!