将有效的几何形状保存到 Sql Server 2008 地理列中

Posted

技术标签:

【中文标题】将有效的几何形状保存到 Sql Server 2008 地理列中【英文标题】:Persisting a valid Geometry shape into Sql Server 2008 Geography column 【发布时间】:2009-12-09 15:56:24 【问题描述】:

我正在使用 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 目标站点: 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】:

好的,我知道发生了什么。微软以其无穷的智慧似乎违背了整个世界其他地区的原则,并已决定在其 WKT 地理坐标表示中,他们将纬度置于经度 (Y,X) 之前。

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

这很糟糕,因为它完全破坏了互操作性。当 NHibernate 空间持久化我用来持久化地理(IGeography 类型)的 NetTopologySuite 对象时,它会将坐标写为 X、Y(我认为它应该工作的自然、预期的方式)。当这遇到 SQL 服务器时,它会尝试将 X 解释为 Y 并将 Y 解释为 X,因此我的所有问题都与无效类型有关。

所以现在我要么必须修复 NHibernate,要么在我的代码中交换坐标。微软,你让我这么痛苦,真丢脸!

【讨论】:

以上是关于将有效的几何形状保存到 Sql Server 2008 地理列中的主要内容,如果未能解决你的问题,请参考以下文章

使用 Chilkat 和 SQL Server 将单个电子邮件附件保存到 BLOB

经纬度坐标上的几何运算

MongoDB 2dsphere 索引失败(几何形状错误?)

如何将简单的几何形状写入 numpy 数组

C# 将字符串作为几何图形保存到数据库

OpenCV中BLOB特征提取与几何形状分类