代码之家  ›  专栏  ›  技术社区  ›  James Allen

将有效的几何图形持久化到SQL Server 2008地理列中

  •  1
  • James Allen  · 技术社区  · 16 年前

    我正在使用spatial.nhibernate将一些几何图形保存到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);
    

    我得到以下错误:

    指定的输入不表示 有效的地理实例。

    类型: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 回复  |  直到 16 年前
        1
  •  2
  •   James Allen    16 年前

    好吧,我知道怎么回事。微软,在他们的内讧智慧,似乎已经违背了整个世界的粮食,并决定在他们的地理坐标WKT表示,他们把纬度放在经度(Y,X)之前。

    x,y?你会问吗?!嗯 a whole debate about it ,显然他们有他们的理由,但普遍的共识是,这很糟糕,所以他们 going to change it .

    这很糟糕,因为它完全扭曲了互操作性。当nhibernate spatial持久化nettopologysuite对象时,我使用它来持久化地理(i geography类型),它将坐标写为x,y(我认为它应该工作的自然的、预期的方式)。当它命中sql server时,它试图将x解释为y,将y解释为x,因此我的所有问题都与无效类型有关。

    所以现在我要么修复nhibernate,要么交换代码中的坐标。你真可耻,微软,给我带来这么大的痛苦!

    推荐文章