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

发布于 2024-08-14 06:40:02 字数 2501 浏览 11 评论 0原文

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

我得到相同的结果

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

请注意,多边形是逆时针绘制的(因为根据各种来源应该是这样)。但如果我将坐标更改为顺时针:

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

似乎没问题。那么顺时针有效还是什么?

I am using Spatial.NHibernate to save some geometry shapes to a Geography column in Sql Server 2008. Here is my mapping:

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

The mapping appears to be valid. Here is the class:

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

However when I go to save an area like this:

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

I get the following error:

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.

I understand that a valid Polygon for a geography type must be plotted anti-clockwise, and it must be closed, and it must not overlap itself. I'm pretty sure I'm fulfilling all these restrictions (although please correct me if I'm wrong) so I'm a bit stumped here. Either there is something wrong with my polygon, or NHibernate is not persisting it correctly - any help welcome!

Edit
Okay I'm confused now.

To simplify things, I changed my polygon to this:

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

I get the same

The specified input does not represent
a valid geography instance.

Note that the polygon is plotted anti-clockwise (as it should be according to various sources). But if I change my coordinates to clockwise:

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

It seems to be okay. So is clockwise valid or what?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╰つ倒转 2024-08-21 06:40:02

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

X,Y?你可能会问 WTF?!好吧,有一场完整的辩论关于它,显然他们有他们的理由,但普遍的共识是它很糟糕,所以他们要更改它

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

所以现在我要么必须修复 NHibernate,要么交换代码中的坐标。微软,你让我感到如此痛苦,真是可耻!

Okay, I know what's going on. Microsoft, in their infinate wisdom, appear to have gone against the grain of the whole of the rest of the world and have decided that in their WKT representations of geography coordinates, they put Latitiude before Longitude (Y,X).

X,Y? WTF you might ask?! Well there's a whole debate about it, apparently they have their reasons, but the general consensus is that it sucks and so they're going to change it.

It sucks because it totally screws interoperablity. When NHibernate spatial persists the NetTopologySuite objects I am using to persist geography (IGeography types) it writes coordinates out as X,Y (the natural, expected way i would assume it should work). When this hits SQL server, it's trying to interpret the X as a Y and Y as an X, hence all my issues with invalid types.

So now I either have to fix NHibernate, or swap the coordinates in my code. Shame on you, Microsoft, for causing me such pain!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文