Polygon

Применимо к:SQL ServerБаза данных SQL AzureУправляемый экземпляр SQL AzureКонечная точка аналитики SQL в Microsoft FabricХранилище в Microsoft FabricБаза данных SQL в Microsoft Fabric

Polygon представляет собой двумерную поверхность, хранимую в виде последовательности точек, определяющих внешний контур и ноль или более внутренних колец.

Экземпляры многоугольников

Каждый экземпляр Polygon должен быть сформирован на основе кольца, содержащего не менее трех уникальных точек. Экземпляр Polygon может быть пустым.

Внешнее и любые внутренние кольца Polygon определяют его границу. Область внутри колец определяет внутреннюю область Polygon.

На следующем рисунке показаны примеры экземпляров Polygon .

Примеры экземпляров геометрического многоугольника.

На рисунке представлены:

  1. на рисунке 1 представлен экземпляр Polygon , граница которого определяется внешним кольцом;

  2. на рисунке 2 представлен экземпляр Polygon , граница которого определяется внешним и двумя внутренними кольцами. Область внутри внутренних колец является частью внешней области экземпляра Polygon.

  3. на рисунке 3 представлен допустимый экземпляр Polygon , поскольку внутренние кольца пересекаются в одной точке касания.

Принятые экземпляры

Допустимые экземпляры Polygon — это экземпляры, которые можно сохранить в переменной geometry или geography, не вызывая исключения. Допустимы следующие экземпляры Polygon:

  • Пустой экземпляр Polygon
  • Экземпляр Polygon с допустимым внешним кольцом (LineString) и с нулем или большим количеством допустимых внутренних колец (LineStrings).

Чтобы кольцо (LineString) считалось допустимым, необходимы следующие критерии.

  • Экземпляр LineString должен быть принят.
  • Экземпляр LineString должен иметь не менее четырех точек.
  • Начальная и конечная точки экземпляра LineString должны совпадать.

В следующем примере показаны допустимые экземпляры Polygon.

DECLARE @g1 geometry = 'POLYGON EMPTY';  
DECLARE @g2 geometry = 'POLYGON((1 1, 3 3, 3 1, 1 1))';  
DECLARE @g3 geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 3 3, 0 3, 0 0))';  
DECLARE @g4 geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(3 0, 6 0, 6 3, 3 3, 3 0))';  
DECLARE @g5 geometry = 'POLYGON((1 1, 1 1, 1 1, 1 1))';  

Как показывают @g4 и @g5, приемлемый экземпляр Polygon может не быть корректным экземпляром Polygon. @g5 также показывает, что экземпляру Polygon достаточно содержать только одно кольцо из любых четырёх точек, чтобы быть принятым.

В следующих примерах возникает исключение System.FormatException, так как экземпляры Polygon не принимаются.

DECLARE @g1 geometry = 'POLYGON((1 1, 3 3, 1 1))';  
DECLARE @g2 geometry = 'POLYGON((1 1, 3 3, 3 1, 1 5))';  

@g1 не принимается, так как экземпляр LineString для внешнего кольца не содержит достаточно точек. @g2 не принимается, так как начальная точка внешнего экземпляра LineString не совпадает с конечной точкой. В следующем примере имеется допустимое внешнее кольцо, но внутреннее кольцо неприемлемо. Это также вызовет System.FormatException.

DECLARE @g geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 0 0))';  

Допустимые экземпляры

Внутренние кольца многоугольника могут касаться как самих себя, так и друг друга в отдельных точках касания, но если внутренние кольца многоугольника пересекаются, объект недопустим.

В следующем примере показаны допустимые экземпляры Polygon .

DECLARE @g1 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20))';  
DECLARE @g2 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0))';  
DECLARE @g3 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 0 10, -5 -10, -10 0))';  
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid();  

@g3 является допустимым, так как два внутренних кольца соприкасаются в одной точке и не пересекаются. В следующем примере показаны недопустимые экземпляры Polygon.

DECLARE @g1 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (20 0, 0 10, 0 -20, 20 0))';  
DECLARE @g2 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (5 0, 1 5, 1 -5, 5 0))';  
DECLARE @g3 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 0 10, 0 -10, -10 0))';  
DECLARE @g4 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 1 5, 0 -10, -10 0))';  
DECLARE @g5 geometry = 'POLYGON((10 0, 0 10, 0 -10, 10 0), (-20 -20, -20 20, 20 20, 20 -20, -20 -20) )';  
DECLARE @g6 geometry = 'POLYGON((1 1, 1 1, 1 1, 1 1))';  
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid(), @g5.STIsValid(), @g6.STIsValid();  

@g1 не является допустимым, так как внутреннее кольцо касается внешнего кольца в двух местах. @g2 недопустим, так как второе внутреннее кольцо находится внутри первого внутреннего кольца. @g3 некорректен, так как два внутренних кольца соприкасаются в нескольких последовательных точках. @g4 недопустим, так как внутренние области двух внутренних колец перекрываются. @g5 не является допустимым, так как внешнее кольцо не является первым кольцом. @g6 недействителен, так как кольцо не имеет по крайней мере трех разных точек.

Ориентация пространственных данных

Ориентация кольца многоугольника не является важным фактором в планарной системе. Спецификация OGC Simple Features for SQL не задаёт порядок колец, и SQL Server не требует соблюдения порядка колец.

В эллиптической модели без указания ориентации многоугольник не определен или является неоднозначным. Например, описывает ли кольцо вокруг экватора северное или южное полушарие? При использовании типа данных geography для хранения пространственного экземпляра необходимо указать ориентацию кольца и точно описать расположение экземпляра.

Внутренняя область многоугольника в эллипсоидальной системе определяется по «правилу левой руки»: если представить, что вы идёте вдоль контура географического многоугольника, следуя по точкам в том порядке, в котором они перечислены, то область слева считается внутренней областью многоугольника, а область справа — внешней областью многоугольника.

Counter-clockwise

DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 0 0, 20 0, 20 20, 0 20))', 4326);
SELECT @square;

Визуализация ориентации против часовой стрелки по правилу левой руки.

Clockwise

DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 20 20, 20 0, 0 0, 0 20))', 4326);
SELECT @square;

Визуализация ориентации по часовой стрелке по правилу левой руки.

Если уровень совместимости равен 100 или ниже в SQL Server, географический тип данных имеет следующие ограничения:

  • Любой экземпляр geography должен лежать в пределах одного полушария. Не допускается сохранение пространственных объектов больше размера полушария.

  • Любой экземпляр geography, заданный в виде Open Geospatial Consortium (OGC) Well-Known Text (WKT) или Well-Known Binary (WKB), который приводит к созданию объекта размером больше полушария, вызывает исключение ArgumentException.

  • Методы типа данных geography, требующие наличия двух экземпляров geography (например, STIntersection(), STUnion(), STDifference() и STSymDifference()), возвращают значение NULL, если результаты работы этих методов не помещаются в пределах одного полушария. STBuffer() также возвращает значение NULL, если выходные данные превышают одно полушарие.

Ориентация может быть изменена с помощью расширенного метода ReorientObject (geography Data Type).

Examples

Пример A.

В следующем примере создаётся простой экземпляр geometry Polygon с зазором и SRID 10.

DECLARE @g geometry;  
SET @g = geometry::STPolyFromText(
    'POLYGON((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1))',
    10);

Пример B.

Недопустимый экземпляр можно ввести и преобразовать в допустимый geometry экземпляр. В следующем примере Polygon внутреннее и внешнее кольца перекрываются, и объект некорректен.

DECLARE @g geometry;  
SET @g = geometry::Parse(
    'POLYGON((1 0, 0 1, 1 2, 2 1, 1 0), (2 0, 1 1, 2 2, 3 1, 2 0))'
    );  

Пример C.

В следующем примере недопустимый экземпляр преобразуется в допустимый с помощью метода MakeValid().

SET @g = @g.MakeValid();  
SELECT @g.ToString();  

Экземпляр geometry, возвращённый в предыдущем примере, является объектом типа MultiPolygon.

MULTIPOLYGON (((2 0, 3 1, 2 2, 1.5 1.5, 2 1, 1.5 0.5, 2 0)),
              ((1 0, 1.5 0.5, 1 1, 1.5 1.5, 1 2, 0 1, 1 0)))

Пример D.

Это еще один пример преобразования некорректного объекта в корректный геометрический объект. В следующем примере экземпляр Polygon был создан с использованием трёх точек, которые полностью совпадают:

DECLARE @g geometry  
SET @g = geometry::Parse('POLYGON((1 3, 1 3, 1 3, 1 3))');  
SET @g = @g.MakeValid();  
SELECT @g.ToString()  

Экземпляр геометрии, возвращённый ранее, представляет собой Point(1 3). Если Polygon равно POLYGON((1 3, 1 5, 1 3, 1 3)), то MakeValid() вернет LINESTRING(1 3, 1 5).