【问题标题】:SQL Server 2008+ : Best method for detecting if two polygons overlap?SQL Server 2008+:检测两个多边形是否重叠的最佳方法?
【发布时间】:2012-02-06 22:48:10
【问题描述】:

我们有一个应用程序,它的数据库中充满了多边形(当前存储为点),一个 .net 应用程序会提取这些多边形并检查它们是否重叠。

我想到将这些点数组转换为数据库中的多边形/折线对象并使用 sql 来获取它们是否重叠的天气会更好。

我已经看到建议使用不同的方法来执行此操作,但给出的示例中没有一个完全符合我的需求。

我很高兴收到那些愿意提供他们经验的人的意见。

补充:

回答问题:确实是2D。是的,两者的任何交叉都被认为是正确的。多边形有 n 个点并且可以是凹的。多边形将保存为每行 1 个(在数据转换任务之后)作为多边形(即多边形类型..它可能被称为其他空间/几何我的记忆现在不在我身边)

【问题讨论】:

  • 您能否更具体地说明多边形的数据存储? (每个多边形 3 个点,还是每个多边形 n 个点?每个点一行,还是每个多边形一行?) 带有示例数据的表定义会很棒。
  • 哦,如果一个多边形完全在另一个多边形内,我假设您认为这是重叠?
  • 您想知道如何将现有数据转换为几何数据类型吗?这是一次性转换,还是您需要一个程序在每次您想要检查重叠时即时转换它们?或者您想知道在将它们转换为原生几何数据类型后如何检查重叠?

标签: sql sql-server-2008 sql-server-2008-r2 polygon polyline


【解决方案1】:

您可以使用 .STIntersection 和 .STAsText() 来测试重叠的多边形。 (我真的很讨厌微软使用的术语(或任何设定标准术语的人)。在我看来,“触摸”应该是测试两个几何/地理形状是否完全重叠,而不仅仅是共享边界。)

无论如何....

如果@RadiusGeom 是一个几何图形,表示从一个点开始的半径,下面将返回一个任意两个多边形的列表,其中交点(表示两个几何图形重叠区域的几何图形)不为空。

SELECT CT.ID AS CTID, CT.[Geom] AS CensusTractGeom
FROM CensusTracts CT
WHERE CT.[Geom].STIntersection(@RadiusGeom).STAsText() <> 'GEOMETRYCOLLECTION EMPTY'

如果您的几何字段是空间索引的,则运行速度非常快。我在大约 3 秒内对 66,000 条美国 CT 记录运行了此程序。可能有更好的方法,但由于没有其他人有答案,这是我试图为你解答的问题。希望对您有所帮助!

【讨论】:

  • 谢谢杰森,这太棒了:o)
【解决方案2】:

计算每个多边形的边界矩形并将其存储在与该多边形关联的行内的一组新字段中。 (我假设您有一个;如果没有,请创建一个。)当您的 dotnet 应用程序有一个多边形并正在寻找重叠的多边形时,它可以使用相对简单的 SQL SELECT 语句从数据库中仅获取边界矩形重叠的多边形。这些多边形应该相对较少,所以这将是有效的。然后,您的 dotnet 应用可以执行更精细的多边形重叠计算,以确定其中哪些真正重叠。

【讨论】:

  • OP 包含单词“Polyline”,它暗示 2-D 而不是 3-D。没有?
  • database full of polygons, convert these point arrays to polygon / polyline objects。而且,即使是一条线也可以存在于三维空间中。
  • 不幸的是,Mike,边界框系统在这种情况下并没有真正的帮助,因为大多数多边形都非常紧密,因此边界框相交。如果你看到墙上的程序洞?如果您将玩家想象成一个多边形,而墙壁也是如此......这就是我们正在谈论的那种复杂性和紧密度。
  • 在这种情况下,优化它的唯一方法是将多边形重叠计算代码从您的 dotnet 应用程序移动到数据库中的存储过程中,这意味着您必须在 TSQL 中重写它,这将非常符合我对噩梦的定义。
【解决方案3】:

好的,我有另一个想法,所以我将其发布为不同的答案。我认为我之前对边界多边形的回答可能有其本身的一些优点,即使它是将从数据库中获取的多边形数量减少一小部分,但这个可能更好。

MSSQL 从 2005 版开始支持与 CLR 的集成。这意味着您可以在程序集中定义自己的数据类型,向 MSSQL 注册程序集,从那一刻起,MSSQL 将接受您的用户定义数据类型作为列的有效类型,它将调用您的程序集以使用您的用户定义的数据类型执行操作。

CodeProject 上有关此技术的示例文章:Creating User-Defined Data Types in SQL Server 2005

我从来没有使用过这种机制,所以我不知道它的细节,但我认为你应该能够对你的数据类型定义一个新的操作,或者可能重载一些现有的操作,比如“小于” ,以便您可以检查一个多边形是否与另一个多边形相交。这可能会大大加快速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多