弧/顶点到MultiPolygon

时间:2015-07-11 08:52:32

标签: c# sql-server gis geojson

我有一个以这种形式的Arcs(顶点)列表:

public class Arc
{
    public Guid Id { get; set; }
    public double X1 { get; set; }
    public double Y1 { get; set; }
    public double X2 { get; set; }
    public double Y2 { get; set; }
}

我可以在2个Arcs的情况下序列化为MultiLineString GeoJSON

{ "type": "MultiLineString",
    "coordinates": [
    [ [100.0, 0.0], [101.0, 1.0] ],
    [ [102.0, 2.0], [103.0, 3.0] ]
    ]
}

我的基础数据实际上代表多边形。更准确地说是MultiPolygon

{ "type": "MultiPolygon",
    "coordinates": [
      [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],
      [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
       [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]
      ]
    }

好奇,是否可以将原始Arc转换为MultiPolygon?我也在考虑通过SQL Server的GIS功能来实现它。有没有人遇到类似的问题?任何指针都将非常感激。非常感谢。

PS:

弧线目前是不相交的,当组合时应形成一个闭合的多边形。下图显示了潜在多边形的一部分。

enter image description here

1 个答案:

答案 0 :(得分:1)

你走了。我提出了一个巨大的警告,我非常反复地写它,如果我从生产代码中的其他人那里看到这个,我就和他们谈谈。 :)

declare @g geography = geography::STGeomFromText('MULTILINESTRING((100 0, 101 1), (102 2, 103 3))', 4236);
declare @multiPoly geography;

with cte as (
    select *
    from dbo.Numbers as n
    cross apply (
        select *
        from (values 
            (@g.STGeometryN(number).STStartPoint().Lat, @g.STGeometryN(number).STStartPoint().Long, 1),
            (@g.STGeometryN(number).STEndPoint().Lat, @g.STGeometryN(number).STStartPoint().Long, 2),
            (@g.STGeometryN(number).STEndPoint().Lat, @g.STGeometryN(number).STEndPoint().Long, 3),
            (@g.STGeometryN(number).STStartPoint().Lat, @g.STGeometryN(number).STEndPoint().Long, 4),
            (@g.STGeometryN(number).STStartPoint().Lat, @g.STGeometryN(number).STStartPoint().Long, 5)
        ) as x(Lat, Long, n)
    ) as decomp
    where n.Number <= @g.STNumGeometries()
)
select @multiPoly = geography::STGeomFromText(
    'MULTIPOLYGON (' + stuff((
        select ', ((' + stuff((
            select ', ' + cast(cte.Long as varchar(10)) + ' ' + cast(cte.Lat as varchar(10))
            from cte
            where Number = n.Number
            order by cte.n
            for xml path('')
        ), 1, 2, '') + '))'
        from dbo.Numbers as n
        where n.Number <= @g.STNumGeometries()
        for xml path('')
        ), 1, 2, '') + ')'
    , 4236);


select @multiPoly;