Изменить «вручаемость» полигонов для SQL 2008 (обратный порядок вершин полигонов)

11

У меня есть несколько сотен фигур ( polygonс и multipolygonя) каждый из которых состоит из десятков тысяч точек , которые я пытаюсь войти в SQL 2008.

К сожалению, фигуры, которые я попытался импортировать, являются «правосторонними» (периметр каждой из них нарисован по часовой стрелке вокруг точек, которые она содержит). SQL-сервер принимает «левосторонние» формы (против часовой стрелки внутри), по крайней мере, для geographyтипов. Это означает, что SQL предполагает, что я пытаюсь выбрать всю землю, кроме моей формы. Некоторые люди описывают это как "наизнанку" формы.

Из MSDN , который, к сожалению, не говорит, какую ориентацию кольца следует использовать:

Если мы используем geographyтип данных для хранения пространственного экземпляра, мы должны указать ориентацию кольца и точно описать местоположение экземпляра.

Если вы используете неправильную ориентацию кольца в SQL 2008, он вылетает со следующей ошибкой (выделено мной):

Ошибка .NET Framework произошла во время выполнения пользовательской подпрограммы или совокупной «географии»: Microsoft.SqlServer.Types.GLArgumentException: 24205: указанный ввод не представляет допустимый экземпляр географии, поскольку он превышает одно полушарие. Каждый экземпляр географии должен помещаться в одном полушарии. Распространенной причиной этой ошибки является неправильная ориентация кольца.

Импортирование фигур geometryвместо geographyработы нормально, но я бы хотел использовать, geographyесли смогу.

В SQL 2012 исправить эту проблему довольно просто , но я привязан к 2008 году.

Как мне преобразовать фигуры?

Майкл - Где Клэй Ширки
источник
1
+1 отличный вопрос ... у вас есть ссылка, где говорится, что сервер Sql принимает формы для левшей?
Кирк Куйкендалл
@ Кирк Спасибо. У меня возникают проблемы с поиском официальной документации, но я могу связаться с MSDN, где говорится, что «ориентация кольца» имеет значение (хотя там не указано, какой способ использования). Я также добавлю ошибку, которая возникает при сбое.
Майкл - Где Клэй Ширки

Ответы:

14

В блоге Spatial Ed было краткое решение. Вот некоторый SQL, демонстрирующий преобразование:

DECLARE @geom GEOMETRY = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))';
DECLARE @geog GEOGRAPHY = @geom.MakeValid().STUnion(@geom.STStartPoint()).STAsText()

И выдержка из поста Эда:

Ключом к этому поведению является STUnion()метод. Поскольку это метод на основе OGC, работающий со всей геометрией для данного объекта, он заставляет полигоны ориентироваться в требуемом для метода направлении, которое, как правило, используется для Geographyтипа [...]. Этот метод иллюстрируется довольно эффективно, сохраняя небольшие накладные расходы [...].

Майкл - Где Клэй Ширки
источник
2
На SQL Server 2008 r2 мне нужно было также поместить .MakeValid () внутри STUnion (), чтобы это работало: .STUnion (@ geom.MakeValid (). STStartPoint ())
Крис Смит,
@Smitty Это имеет смысл для случаев, когда SQL не может иначе определить отправную точку. Может быть, если форма удваивается над собой или другие странные обстоятельства?
Майкл - Где Клэй Ширки?
Да, в моих обстоятельствах форма дурацкая и перекрывает себя.
Крис Смит
0

В> = SQL Server 2012 метод ReorientObject () должен выполнить это. Для <SQL Server 2012 ниже приведен альтернативный метод.

Для существующей географии SQL @g, приведенный ниже код извлечет точки и заново создаст многоугольник с точками (вершинами) в обратном порядке:
(ПРИМЕЧАНИЕ 1: работает для простых многоугольников, а не для многоугольников или многоугольников с кольцами / центроидами)
(ПРИМЕЧАНИЕ 2: использование системы координат SRID 4326 (WGS 84))

--For existing geography @g
DECLARE @GeometryText varchar(max), @ReversedPolygon geography
DECLARE @GeometryType varchar(20) = 'POLYGON', @Count int
SET @Count = @g.STNumPoints()
WHILE @Count > 0
BEGIN
    SET @GeometryText = @GeometryText + CONVERT(varchar(30),CONVERT(decimal(12,8),@g.STPointN(@Count).Long)) + ' ' + CONVERT(varchar(30),CONVERT(decimal(12,8),@g.STPointN(@Count).Lat))
    SET @Count = @Count - 1
    IF @Count > 0 SET @GeometryText = @GeometryText + ','
END
SET @GeometryText = @GeometryType +'((' + @GeometryText + '))'
SET @ReversedPolygon = geography::STGeomFromText(@GeometryText, 4326); 
Baodad
источник
0

Похоже, я могу использовать какой-то нечестивый гибрид SQL и C # из SQL Server Spatial Tools , как предложено в Переполнении стека .

Примечание: на момент публикации этого ответа не было много информации. Пожалуйста, не пытайтесь использовать этот метод, если вам уже не нужны пространственные инструменты SQL Server для чего-то другого. Вместо этого попробуйте один из других ответов здесь или в Переполнение стека .

Майкл - Где Клэй Ширки
источник