如何在 SQL 服务器中按优先顺序拆分重叠环多边形
how to split overlapping ring polygons by priority order in SQL Server
我有一个 SQL 服务器空间层,其中包含 750 个圆形多边形。每个多边形都有一个优先级编号“siteorder”)并且一些多边形重叠(在某些情况下,与多个其他多边形重叠)。我想拆分重叠区域以仅保留具有最高站点顺序的圆圈。
我最好在 SQL 服务器中执行此操作,因为在此之后我还有几个步骤要执行。
我在 QGIS 中生成了下面的图像,但它不能轻松地重新加入。
有人可以帮忙吗?
谢谢
抢
我的想法是执行以下算法:
- 从最高排序顺序到最低排序顺序循环所有圆圈。这简化了重叠的生成,因为多边形不能与排序顺序较低的多边形重叠
- 通过生成一个“巨型多边形”来跟踪所有以前的多边形,它是所有以前的并集。这简化了“较低”排序多边形的重叠。
- 当前的多边形将是圆与“巨型多边形”的差异,即圆的其余部分不重叠。
现在对于代码,我首先在#t-table中创建一些测试数据,然后进行递归cte来生成多边形。如果更简单,您也可以使用 while 循环或游标
-- Generate some test data
create table #t_polygons (id int identity, sortorder INT, geomPoint geometry)
declare @i int = 0
, @geom GEOMETRY
, @str NVARCHAR(30)
while @i < 700
begin
set @str = 'POINT (' + CAST(RAND() * 200 AS VARCHAR(10)) + ' '
set @str = @str + CAST(RAND() * 200 AS VARCHAR(10)) + ')'
set @geom = @str
insert into #t_polygons (
sortorder, geomPoint
)
select rand() * 5
, @geom.STBuffer(RAND() * 10)
set @i = @i + 1
end
select *
from #t_polygons
-- Loop through polygons one by one
;with cte as (
select row_number() OVER(ORDER BY sortorder DESC, id) AS sort
, *
FROM #t_polygons
)
, cte2 AS (
select id
, geomPoint as mergedPoint
, geomPoint AS thisPoint
, sort
from cte
WHERE sort = 1
union all
select c.id
, mergedPoint.STUnion(geomPoint)
, geomPoint.STDifference(mergedPoint) AS newPoint
, c.sort
from cte2 c2
inner join cte c
ON c.sort = c2.sort + 1
)
select id, thisPoint, sort
from cte2
option (maxrecursion 0)
我有一个 SQL 服务器空间层,其中包含 750 个圆形多边形。每个多边形都有一个优先级编号“siteorder”)并且一些多边形重叠(在某些情况下,与多个其他多边形重叠)。我想拆分重叠区域以仅保留具有最高站点顺序的圆圈。
我最好在 SQL 服务器中执行此操作,因为在此之后我还有几个步骤要执行。
我在 QGIS 中生成了下面的图像,但它不能轻松地重新加入。
有人可以帮忙吗?
谢谢
抢
我的想法是执行以下算法:
- 从最高排序顺序到最低排序顺序循环所有圆圈。这简化了重叠的生成,因为多边形不能与排序顺序较低的多边形重叠
- 通过生成一个“巨型多边形”来跟踪所有以前的多边形,它是所有以前的并集。这简化了“较低”排序多边形的重叠。
- 当前的多边形将是圆与“巨型多边形”的差异,即圆的其余部分不重叠。
现在对于代码,我首先在#t-table中创建一些测试数据,然后进行递归cte来生成多边形。如果更简单,您也可以使用 while 循环或游标
-- Generate some test data
create table #t_polygons (id int identity, sortorder INT, geomPoint geometry)
declare @i int = 0
, @geom GEOMETRY
, @str NVARCHAR(30)
while @i < 700
begin
set @str = 'POINT (' + CAST(RAND() * 200 AS VARCHAR(10)) + ' '
set @str = @str + CAST(RAND() * 200 AS VARCHAR(10)) + ')'
set @geom = @str
insert into #t_polygons (
sortorder, geomPoint
)
select rand() * 5
, @geom.STBuffer(RAND() * 10)
set @i = @i + 1
end
select *
from #t_polygons
-- Loop through polygons one by one
;with cte as (
select row_number() OVER(ORDER BY sortorder DESC, id) AS sort
, *
FROM #t_polygons
)
, cte2 AS (
select id
, geomPoint as mergedPoint
, geomPoint AS thisPoint
, sort
from cte
WHERE sort = 1
union all
select c.id
, mergedPoint.STUnion(geomPoint)
, geomPoint.STDifference(mergedPoint) AS newPoint
, c.sort
from cte2 c2
inner join cte c
ON c.sort = c2.sort + 1
)
select id, thisPoint, sort
from cte2
option (maxrecursion 0)