Сохранение допустимой формы геометрии в столбце географии Sql Server 2008

Я использую Spatial.NHibernate для сохранения некоторых геометрических фигур в столбце Geography в 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)}))

Я получаю то же самое

Указанные входные данные не представляют допустимый экземпляр географии.

Обратите внимание, что многоугольник отображается против часовой стрелки (так и должно быть по разным источникам). Но если я изменю свои координаты на по часовой стрелке:

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

Вроде бы нормально. Так действует ли по часовой стрелке что ли?


person James Allen    schedule 09.12.2009    source источник


Ответы (1)


Хорошо, я знаю, что происходит. Microsoft, в своей безграничной мудрости, похоже, пошла наперекор всему остальному миру и решила, что в своих представлениях географических координат WKT они ставят широту перед долготой (Y, X).

X, Y? Какого черта вы спросите ?! Ну, есть целая дискуссия об этом, очевидно, у них есть свои причины, но по общему мнению, это отстой, поэтому они собираюсь изменить его.

Это отстой, потому что полностью нарушает совместимость. Когда NHibernate Space сохраняет объекты NetTopologySuite, которые я использую для сохранения географии (типы IGeography), он записывает координаты как X, Y (естественный, ожидаемый способ, которым, как я полагаю, он должен работать). Когда это попадает на SQL-сервер, он пытается интерпретировать X как Y и Y как X, отсюда и все мои проблемы с недопустимыми типами.

Так что теперь мне нужно либо исправить NHibernate, либо поменять координаты в моем коде. Позор вам, Microsoft, за то, что причинили мне такую ​​боль!

person James Allen    schedule 11.12.2009