Поделиться через


Polygon

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

Экземпляры Polygon

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

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

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

Примеры объектов Polygon типа geometry

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

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

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

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

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

Принятыми являются экземпляры Polygon, которые могут храниться в переменных geometry или geography без вызова исключения. В следующих примерах показаны принятые экземпляры Polygon для типа geometry.

  • Пустой экземпляр Polygon.

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

Чтобы быть допустимым, кольцо должно отвечать следующим требованиям.

  • Экземпляр LineString должен быть принятым.

  • Экземпляр LineString должен иметь как минимум четыре точки, включая не менее трех уникальных точек.

  • Начальная и конечная точки экземпляра LineString должны иметь те же значения X и Y.

    ПримечаниеПримечание

    Значения Z и M пропускаются.

Экземпляр Polygon типа geography принимается, только если экземпляр допустим. Дополнительные сведения см. в разделе Valid Geography Polygon Instances.

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

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

Экземпляр @g4 показывает, что принятый экземпляр Polygon может не быть допустимым экземпляром 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 зависит от его типа переменной.

Тип данных Geometry

Чтобы быть допустимым, экземпляр Polygon типа geometry должен отвечать следующим требованиям.

  1. Первое кольцо является внешним.

  2. Все внутренние кольца лежат в пределах внешнего кольца.

  3. Ни одно из внутренних колец не лежит в пределах другого внутреннего кольца.

  4. Ни одно кольцо не пересекает себя или другое кольцо.

  5. Два кольца не могут иметь общий край.

  6. Внутреннее пространство внутреннего кольца не может перекрывать внутреннее пространство другого внутреннего кольца.

  7. Все кольца могут соприкасаться сами с собой или с другими кольцами только в нуле или в бесконечном числе точек.

  8. Внутреннее пространство экземпляра Polygon подключено. Должен существовать как минимум один путь между любыми двумя внутренними точками экземпляра, целиком находящегося внутри экземпляра.

В следующих примерах показаны допустимые экземпляры 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) )';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid(), @g5.STIsValid();

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

Тип данных Geography

Чтобы быть допустимым, экземпляр Polygon типа geography должен отвечать следующим требованиям.

  1. Экземпляр должен отвечать всем правилам, использующимся для признания принятым экземпляра Polygon типа geometry.

  2. Внутреннее пространство экземпляра подключено с помощью правила левой руки.

  3. Экземпляр может уместиться в полушарии.

  4. Ни одно кольцо не пересекает само себя или другое кольцо.

  5. Все кольца могут соприкасаться сами с собой или с другими кольцами только в нуле или в бесконечном числе точек.

В следующем примере выдается исключение Microsoft.SqlServer.Types.GLArgumentException, поскольку экземпляр Polygon выходит за пределы полушария.

DECLARE @g geography = 'POLYGON((-122.358 47.653, 122.348 47.649, 122.348 47.658, 122.358 47.658, -122.358 47.653))';

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

DECLARE @g geography = 'POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))';

Примеры

В следующем примере создается простой экземпляр geometryPolygon с отверстием и значением 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);

Недопустимый экземпляр может быть введен и преобразован в допустимый экземпляр типа 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))');

В следующем примере недопустимый экземпляр преобразуется в допустимый с помощью метода 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)))