【问题标题】:Insert a circle into geometry data type将圆插入几何数据类型
【发布时间】:2014-09-12 21:06:43
【问题描述】:

我即将开始第一次使用几何或地理数据类型,因为我们的开发基线是 2008R2(!) 我正在努力寻找如何存储一个圆圈的表示。我们目前有圆心的纬度和经度以及半径,例如:-

[Lat] [float] NOT NULL,
[Long] [float] NOT NULL,
[Radius] [decimal](9, 4) NOT NULL,

有谁知道使用 STGeomFromText 方法存储它的等效方法,即使用哪种众所周知的文本 (WKT) 表示?我查看了圆形字符串(LINESTRING)和曲线,但找不到任何示例....

谢谢。

【问题讨论】:

    标签: tsql sql-server-2008-r2 geometry geospatial computational-geometry


    【解决方案1】:

    如果您使用的是 SQL Server 2008,您可以做的一件事是缓冲一个点并存储生成的多边形(内部众所周知的二进制文件)。例如,

    declare @g geometry
    set @g=geometry::STGeomFromText('POINT(0 0)', 4326).STBuffer(1)
    select @g.ToString()
    select @g.STNumPoints()
    select @g.STArea()
    

    这个输出,WKT,

    POLYGON ((0 -1, 0.051459848880767822 -0.99869883060455322, 0.10224419832229614 -0.99483710527420044, 0.15229016542434692 -0.98847776651382446, 0.20153486728668213 -0.97968357801437378, 0.24991559982299805 -0.96851736307144165,... , 0 -1))

    点数,129,从中可以看出缓冲一个圆用了128个点加上一个重复的起点和面积,3.1412,精确到小数点后3位,与实际值相差0.01%,这对于许多用例来说是可以接受的。

    如果你想要更少的精度(即更少的点),你可以使用Reduce函数来减少点的数量,例如,

    declare @g geometry
    set @g=geometry::STGeomFromText('POINT(0 0)', 4326).STBuffer(1).Reduce(0.01) 
    

    现在生成一个具有 33 个点和 3.122 面积的近似圆(现在比 PI 的实际值小 0.6%)。

    更少的点将减少存储空间,并使 STIntersects 和 STIntersection 等查询更快,但显然是以准确性为代价的。

    编辑 1: 正如 Jon Bellamy 指出的那样,如果您选择使用 Reduce 函数,则该参数需要与圆/缓冲区半径成比例缩放,因为它是删除点,基于Ramer-Douglas-Peucker algorithm

    编辑 2: 还有一个函数,BufferWithTolerance,可用于用多边形近似圆。第二个参数,公差影响这个近似值的接近程度:值越低,点越多,近似值越好。第三个参数是位,表示公差相对于缓冲区半径是相对的还是绝对的。这个函数可以用来代替STBufferReduce的组合来创建一个有更多点的圆。

    以下查询产生,

    declare @g geometry
    set @g=geometry::STGeomFromText('POINT(0 0)', 4326).BufferWithTolerance(1,0.0001,1)
    select @g.STNumPoints()
    select @g.STArea()
    

    一个由 321 个点组成的“圆”,面积为 3.1424,即在 PI 真实值的 0.02% 以内(但现在更大),实际上不如上面的简单缓冲区准确。进一步增加容差并不会显着提高准确性,这表明这种方法存在上限。

    正如 MvG 所说,在 SQL Server 2012 之前没有CircularString or CompoundCurve,通过构建由两个半圆组成的CompoundCurve,即使用两个@ 987654339@.

    【讨论】:

    • 很好的答案 John,我唯一要补充的是传​​递给“Reduce()”(如果使用)的值需要与半径成比例增加,以尝试保持结果相同.例如,对于 STBuffer 值为 1,Reduce 示例将点从 129 减少到 33,但对于 STBuffer 值为 100 没有任何区别。本质上,请记住将 Reduce 的值与 STBuffer 成比例地增加。 1 缓冲到 0.01 减少,100 缓冲到 1 减少,502 到 5.02 等等。
    • 谢谢乔恩,我忘了把它放进去。将编辑我的答案
    • 非常感谢小伙子们,尽管有一个叫做“STBuffer”的东西可以用于椭球体?看起来我也可以使用“.BufferWithTolerance”来改变准确性。再次感谢您及时回复我的第一个 StackOverflow 问题 :)
    • 黎明,BufferWithTolerance 看起来比 Buffer 加 Reduce 更好。一旦我有机会正确查看它,我将更新答案。干杯。
    • 您可能希望包含BufferWithToleranceSTBufferReduce 的链接。
    【解决方案2】:

    据我从文档中得知,CircularString 只是为 SQL Server 2012 添加的。唯一的另一个 instantiable curve 似乎是 LineString,顾名思义,它对一系列线段进行编码。所以你最好的选择是将圆近似为具有足够数量的角的(可能是规则的)多边形。如果这不可接受,您可能必须保留当前的数据结构,单独或除了空间数据类型之外,以验证那里的匹配确实与圆匹配。

    这个答案纯粹是从文档中写出来的,没有经验来支持它。

    【讨论】:

      猜你喜欢
      • 2021-11-20
      • 1970-01-01
      • 2020-08-15
      • 2015-06-27
      • 1970-01-01
      • 2012-04-09
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多