SQL Выберите допустимые геометрии без использования MakeValid - PullRequest
0 голосов
/ 29 июня 2018

У меня есть большая таблица данных со значениями SQLGeometry. Многие строки содержат «не правильно сформированные» геометрии в соответствии с OGC ( Geometry.STIsValid () ). Это приводит к тому, что многие мои геометрии выдают ошибку, когда я проверяю Geometry.STGeometryType () .

Когда я использовал этот SQL-запрос, я ошибочно предполагал, что он пропустит неправильные геометрии:

SELECT [Geometry] FROM Features 
  WHERE [Geometry] IS NOT NULL
    AND [Geometry].STIsValid() = 1
    AND [Geometry].STGeometryType() = 'Point'

Функция STGeometryType() выдает эту ошибку:

Ошибка .NET Framework произошла во время выполнения пользовательской подпрограммы или совокупной «геометрии»: System.ArgumentException: 24144: эту операцию невозможно выполнить, поскольку экземпляр недопустим. Используйте MakeValid для преобразования экземпляра в допустимый экземпляр. Обратите внимание, что MakeValid может вызвать незначительное смещение точек экземпляра геометрии. System.ArgumentException: в Microsoft.SqlServer.Types.SqlGeometry.ThrowIfInvalid () в Microsoft.SqlServer.Types.SqlGeometry.STGeometryType ()

Я получаю ту же ошибку, используя подзапрос:

SELECT G.* FROM (
  SELECT [Geometry] FROM Features 
    WHERE [Geometry] IS NOT NULL
     AND [Geometry].STIsValid() = 1
) AS G
   WHERE G.[Geometry].STGeometryType() = 'Point'

Использование функции Geometry.MakeValid () не является работоспособным решением, у меня не может быть SQL Server, который произвольно меняет мои геометрии, но мне нужно иметь возможность сказать, какого они типа для вида, подобного этому. :

CREATE VIEW vw_Points
AS
  SELECT [Geometry] FROM vwValidFeatures 
    WHERE [Geometry].STGeometryType() = 'Point'

У кого-нибудь есть лучшее решение или обходной путь для этого?

Лучшее решение, которое я могу найти, - это выбрать все геометрии STAsText () и затем проанализировать строку, потому что STAsText() не выдает никаких ошибок, если она недопустима.

1 Ответ

0 голосов
/ 29 июня 2018

Это лучшее решение, которое я смог найти сам:

CREATE VIEW [vwValidGeometries]
AS
  SELECT A.* FROM (
    SELECT 
        Id,
        CASE [Geometry].STIsValid() 
           WHEN 1 THEN [Geometry] 
           ELSE NULL 
        END AS 'Geo'
    FROM Features
  )
    WHERE Geo IS NOT NULL

Тогда:

SELECT * FROM vwValidGeometries WHERE Geo.STGeometryType() = 'Point'

Это настолько изолирует функцию STIsValid(), что она не затрагивается никакими функциями, которые выдают ошибку, если геометрия неверна.

Я нашел этот ответ на MSDN .

...