0

==>参考这个线程

参考那里显示为最佳解决方案的输出,我怎样才能获得边界单元格?即 min(StartX)、min(StartY) 和 max(EndX) 和 max(EndY) 或者在某些情况下 max(EndX+1) 或 max(EndY+1) 如果列或行被遗漏,例如这种情况下图中的 3,10 个(绿色边框是我的边界单元格)

[边界框](http://tinypic.com/r/2moyvjo/6)

X Y PieceCells 边界
1 1 (1,1)(2,1)(2,2)(3,2) (1,1)(3,2)
8 1 (10,1)(8,1)(8, 2)(9,1)(9,2)(9,3) (8,1)(10,1)

那么我想要这样:
BoundaryStartX, BoundaryStartY, BoundaryEndX, BoundaryEndY
1 1 3 2
8 1 10 3

4

2 回答 2

0

我可以使用几何数据类型非常简单地做到这一点。

declare @g geometry;
set @g = geometry::STGeomFromText(
   'POLYGON( (1 -1, 1 -2, 2 -2, 2 -3, 4 -3, 4 -2, 3 -2, 3 -1, 1 -1) )'
   , 0);

select @g, @g.STEnvelope();

几何从 SQL2008 开始可用。另请注意,我将您的坐标系转换为标准笛卡尔坐标系(原点右侧的正 x 轴,下方的负 y 轴);你最好考虑做同样的事情。

于 2012-12-26T03:07:12.570 回答
0
use tempdb;
if exists (select 1 from sys.tables where name = 'grid')
    drop table grid;

if not exists (select 1 from sys.tables where name = 'tally')
begin
    create table tally (i int not null);
    with 
        a as (select 1 as [i] union select 0),
        b as (select 1 as [i] from a as [a1] cross join a as [a2]),
        c as (select 1 as [i] from b as [a1] cross join b as [a2]),
        d as (select 1 as [i] from c as [a1] cross join c as [a2]),
        e as (select 1 as [i] from d as [a1] cross join d as [a2])
    insert into tally
    select row_number() over (order by i) from e
    create unique clustered index [CI_Tally] on tally (i)
end

create table grid (
    x tinyint, 
    y tinyint, 
    cell as geometry::STGeomFromText(
    'POLYGON( (' + 
        cast(x as varchar) + ' ' + cast(-1*y as varchar) + ', ' +
        cast(x+1 as varchar) + ' ' + cast(-1*y as varchar) + ', ' +
        cast(x+1 as varchar) + ' ' + cast(-1*(y+1) as varchar) + ', ' +
        cast(x as varchar) + ' ' + cast(-1*(y+1) as varchar) + ', ' +
        cast(x as varchar) + ' ' + cast(-1*y as varchar) +
        ') )'
        , 0)
);

insert into grid (x, y) 
    values 
    (1,1),
    (2,1),
    (2,2),
    (3,2),

    (8,1),
    (9,1),
    (8,2),
    (9,2),
    (9,3),
    (10,1);

with cte as (
    select cell, row_number() over (order by x, y) as [rn]
    from grid
),
cte2 as (
    select cell, [rn]
    from cte
    where [rn] = 1

    union all

    select a.cell.STUnion(b.cell) as [cell], b.rn
    from cte2 as a
    inner join cte as b
        on a.rn + 1 = b.[rn]
), cte3 as (
    select cell
    from cte2
    where [rn] = (select count(*) from grid)
), clusters as (
    select i, cell.STGeometryN(t.i) as c
    from cte3 as [a]
    cross join tally as [t]
    where t.i <= cell.STNumGeometries()
)
select *, c.STEnvelope() from clusters

此解决方案解决了您的原始问题和这个问题。我喜欢这个,因为你仍然可以使用你想要的任何奇怪的坐标系,它会做你想做的事。您所要做的就是相应地修改网格表上的计算列。我将把信封角的计算留给读者作为练习。:)

作为解释,计算列根据给定的 x 和 y 坐标创建一个 1x1 几何实例。从那里,我基本上将所有这些结合在一起,这将产生一个多面体。从那里,我遍历多面体中的各个多边形以获得各个簇。信封免费提供。从这里,如果您愿意,您应该能够将最终选择(或非常类似的东西)包装在视图中。

于 2013-01-04T04:52:13.140 回答