2009-12-09 33 views
1

我使用Spatial.NHibernate一些几何形状保存到SQL Server中的地理列2008年这里是我的映射:坚持有效的几何形状到SQL Server 2008地理列

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); 

我收到以下错误:

The specified input does not represent a valid geography instance.

Type: System.ArgumentException Source: Microsoft.SqlServer.Types TargetSite: Microsoft.SqlServer.Types.SqlGeography ConstructGeographyFromUserInput(Microsoft.SqlServer.Types.GeoData, Int32) ...etc.

我明白,一个有效的多边形的地理类型必须逆时针绘制,并且必须关闭,并且不能重叠。我很确定我正在履行所有这些限制(虽然如果我错了,请纠正我),所以我在这里有点难住。要么我的多边形出现问题,要么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)})) 

我得到同样的

The specified input does not represent a valid geography instance.

注意,多边形绘制逆时针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)})) 

这似乎是好的。那么顺时针有效还是什么?

回答

2

好的,我知道发生了什么事。微软以其无尽的智慧,似乎违背了整个世界其他国家的政策,并决定在他们的WKT地理坐标表示中,他们将Latitiude放在Longitude(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,要么在我的代码中交换坐标。耻辱你,微软,让我如此痛苦!