在几何数据类型中插入一个圆

Daw*_*awn 1 t-sql geometry geospatial sql-server-2008-r2 computational-geometry

我现在第一次开始使用几何或地理数据类型,因为我们有一个2008R2的开发基线(!)我正在努力找到如何存储圆的表示.我们目前有圆的中心和长度的纬度,类似于: -

[Lat] [float] NOT NULL,
[Long] [float] NOT NULL,
[Radius] [decimal](9, 4) NOT NULL,
Run Code Online (Sandbox Code Playgroud)

有没有人知道使用STGeomFromText方法存储它的等效方法,即使用哪个Well-Known Text(WKT)表示?我看过圆形字符串(LINESTRING)和曲线,但找不到任何例子....

谢谢.

Joh*_*ell 6

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

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

这输出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) 
Run Code Online (Sandbox Code Playgroud)

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

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

编辑1:正如Jon Bellamy所指出的,如果您选择使用Reduce函数,则参数需要与圆/缓冲半径成比例缩放,因为它是基于Ramer-Douglas-的去除点的灵敏度因子 Peucker算法

编辑2:还有一个功能,BufferWithTolerance可用于近似带有多边形的圆.第二个参数,容差会影响此近似值的接近程度:值越低,点越多,逼近越好.第三个参数是一个位,表示公差相对于缓冲半径是相对的还是绝对的.这个功能可以用来代替STBuffer,Reduce组合,创造更多点的圆.

以下查询生成,

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

一个321点的"圆",面积为3.1424,即在PI的真实值的0.02%之内(但现在更大)并且实际上不如上面的简单缓冲区精确.进一步增加公差不会导致准确性的任何显着改善,这表明这种方法存在上限.

正如MvG所说,CircularString or CompoundCurve直到SQL Server 2012,才能通过构建CompoundCurve由两个半圆构成的两个半圆,即使用两个半圆来更紧凑和准确地存储圆CircularStrings.