左上角和右上角单元格的SQL视图

时间:2012-12-25 22:10:07

标签: sql sql-server

==> Referring to this Thread

参考显示为最佳解决方案的输出,我如何获得边界单元?即min(StartX),min(StartY)和max(EndX)和max(EndY)或者在某些情况下max(EndX + 1)或max(EndY + 1)如果错过了列或行,就像在这种情况下一样下图中的3,10(绿色边界是我的边界细胞)

[BoundingBox](http://tinypic.com/r/2moyvjo/6)

X Y PieceCells Boundary
11(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

2 个答案:

答案 0 :(得分: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轴位于下方);你也应该考虑做同样的事情。

答案 1 :(得分: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几何实例。从那里开始,我基本上将所有这些结合在一起,这将产生多边形。从那里,我遍历多面体中的各个多边形以获得各个聚类。信封免费提供。从这里开始,如果您愿意,您应该能够在视图中包装最终选择(或类似的东西)。