将有效的几何形状保留到Sql Server 2008 Geography列中

时间:2009-12-09 15:56:25

标签: nhibernate sql-server-2008 geometry validation geography

我使用Spatial.NHibernate将一些几何形状保存到Sql Server 2008中的Geography列。这是我的映射:

public class AreaMapping : ClassMap<Area>
{
    public AreaMapping()
    {
        Id(c => c.Id).GeneratedBy.HiLo(100.ToString());
        Map(c => c.Name).Not.Nullable();
        Map(x => x.Boundary)
            .CustomTypeIs<MsSql2008GeographyType>()
            .Not.Nullable()
            .CustomSqlTypeIs("GEOGRAPHY");
    }
}

映射似乎有效。这是班级:

public class Area
{
    public virtual Guid Id { get; set; }
    public virtual Polygon Boundary { get; set; }
    public virtual string Name { get; set; }
}

然而,当我去保存这样的区域时:

Area area = new Area{ Boundary = new Polygon(new LinearRing(new ICoordinate[]{
                    new Coordinate(-1.911524, 55.136334),
                    new Coordinate(-1.912679, 55.136293),
                    new Coordinate(-1.912689, 55.136178),
                    new Coordinate(-1.911507, 55.136194),
                    new Coordinate(-1.911524, 55.136334)}))
Session.Save(area);

我收到以下错误:

  

指定的输入不代表   一个有效的地理实例。

     

类型:System.ArgumentException   来源:Microsoft.SqlServer.Types   TargetSite:   Microsoft.SqlServer.Types.SqlGeography   ConstructGeographyFromUserInput(Microsoft.SqlServer.Types.GeoData,   Int32)......等等。

据我所知,地理类型的有效多边形必须逆时针绘制,并且必须关闭,并且不得重叠。我很确定我正在履行所有这些限制(如果我错了请纠正我)所以我有点难过。我的多边形有问题,或者NHibernate没有正确地保持它 - 欢迎任何帮助!

修改 好吧,我现在很困惑。

为简化起见,我将多边形更改为:

Area area = new Area{ Boundary = new Polygon(new LinearRing(new ICoordinate[]{
                    new Coordinate(10,15),
                    new Coordinate(10,5),
                    new Coordinate(20,5),
                    new Coordinate(20,15),
                    new Coordinate(10,15)}))

我得到了相同的

  

指定的输入不代表   一个有效的地理实例。

请注意,多边形绘制为逆时针as it should be according to various sources)。但如果我将坐标改为顺时针:

Area area = new Area{ Boundary = new Polygon(new LinearRing(new ICoordinate[]{
                    new Coordinate(10,15),
                    new Coordinate(20,15),
                    new Coordinate(20,5),
                    new Coordinate(10,5),
                    new Coordinate(10,15)}))

似乎没关系。顺便说一下有效还是什么?

1 个答案:

答案 0 :(得分:2)

好的,我知道发生了什么事。微软凭借其无限的智慧,似乎违背了整个世界其他地区,并决定在他们的WKT地理坐标表示中,他们将Latitiude放在经度(Y,X)之前。

X,Y?你可能会问WTF?!好吧a whole debate about it,显然他们有他们的理由,但普遍的共识是它很糟糕,所以他们是going to change it

它太糟糕了,因为它完全打破了互操作性。当NHibernate空间持久存在NetTopologySuite对象时,我用它来保持地理(IGeography类型),它将坐标写为X,Y(我认为它应该工作的自然,预期的方式)。当它击中SQL服务器时,它试图将X解释为Y和Y作为X,因此我的所有问题都是无效类型。

所以现在我要么修复NHibernate,要么交换代码中的坐标。微软感到羞耻,因为给我带来了这样的痛苦!