Compartilhar via


Polígono

Um Polygon é uma superfície bidimensional armazenada como uma seqüência de pontos que define um anel delimitador exterior e zero ou mais anéis internos.

Instâncias de polígonos

Uma instância Polygon pode ser formada de um anel com pelo menos três pontos distintos. Uma instância Polygon também pode estar vazia.

Os anéis exteriores e todos os anéis interiores de um Polygon definem seu limite. O espaço dentro dos anéis define o interior do Polygon.

A ilustração a seguir mostra exemplos de instâncias Polygon.

Exemplos das instâncias Polygon de geometria

Conforme mostrado na ilustração:

  1. A Figura 1 é uma instância Polygon cujo limite está definido por um anel exterior.

  2. A Figura 2 é uma instância Polygon cujo limite está definido por um anel exterior e dois anéis interiores. A área dentro dos anéis interiores faz parte do exterior da instância Polygon.

  3. A Figura 3 é uma instância Polygon válida porque seus anéis internos cruzam em um único ponto tangente.

Instâncias aceitas

Instâncias Polygon aceitas são instâncias que podem ser armazenadas em uma variável geometry ou geography sem gerar uma exceção. A seguir estão as instâncias Polygon aceitas para o tipo geometry:

  • Uma instância Polygon vazia

  • Uma instância Polygon que possui um anel externo aceitável e zero ou mais anéis internos aceitáveis

Os critérios a seguir são necessários para que um anel seja aceito.

  • A instância LineString deve ser aceita.

  • A instância LineString deve possuir pelo menos quatro pontos que incluam três pontos distintos.

  • Os pontos inicial e final da instância LineString devem possuir os mesmos valores X e Y.

    ObservaçãoObservação

    Os valores Z e M são ignorados.

Uma instância de polígono de um tipo geography será aceita somente se a instância for válida. Para obter mais informações, consulte Valid Geography Polygon Instances.

O exemplo a seguir mostra instâncias Polygon aceitas de tipos 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))';

Como @g4 mostra que uma instância Polygon aceita pode não ser uma instância Polygon válida. O exemplo a seguir gera uma System.FormatException porque as instâncias Polygon não são aceitas.

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

@g1 não é aceita porque a instância LineString para o anel externo não contém pontos suficientes. @g2 não é aceita porque o ponto inicial da instância do anel externo LineString não é igual ao ponto final. O exemplo a seguir possui um anel externo aceito, mas o anel interno não é aceito. Isso também gera uma System.FormatException.

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

Instâncias válidas

A validade de uma instância de polígono depende do seu tipo de variável.

Tipo de dados de geometria

Para que uma instância Polygon de um tipo geometry seja válida, ela deverá atender ao seguinte critério:

  1. O primeiro anel é o anel externo.

  2. Todos os anéis internos no anel externo.

  3. Nenhum anel interno reside em outro anel interno.

  4. Nenhum anel cruza si mesmo ou outro anel.

  5. Dois anéis não podem compartilhar a mesma borda.

  6. O interior de um anel interno não pode sobrepor o interior de outro anel interno.

  7. Todos os anéis somente podem tocar a si mesmos ou outro anel em zero ou um número finito de pontos tangentes.

  8. O interior da instância Polygon está conectado. Deve haver pelo menos um caminho entre quaisquer dois pontos internos da instância que esteja completamente dentro da instância.

O exemplo a seguir mostra instâncias Polygon válidas.

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 é válida porque dois anéis internos tocam em um único ponto e não se cruzam. O exemplo a seguir mostra instâncias Polygon inválidas.

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 não é válida porque o anel interno toca o anel externo em dois lugares. @g2 não é válida porque o segundo anel interno está no interior do primeiro anel interno. @g3 não é válida porque dois anéis internos tocam em vários pontos consecutivos. @g4 não é válida porque os interiores dos dois anéis internos se sobrepõe. @g5 não é válida porque o primeiro anel é um anel interno e o segundo anel é um anel externo.

Tipo de dados de geografia

Para que uma instância Polygon de um tipo geography seja válida, ela deverá atender aos seguintes critérios:

  1. A instância deve atender a todas as regras necessárias para que uma instância Polygon do tipo geometry seja aceita.

  2. O interior da instância está conectado usando a regra do lado esquerdo.

  3. A instância pode se ajustar dentro de um hemisfério.

  4. Nenhum anel cruza si mesmo ou qualquer outro anel.

  5. Todos os anéis somente podem tocar a si mesmos ou qualquer outro anel em zero ou um número finito de pontos tangentes.

O exemplo a seguir gera uma Microsoft.SqlServer.Types.GLArgumentException porque a instância Polygon excede um hemisfério.

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

O exemplo a seguir mostra uma instância Polygon válidas para o tipo 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))';

Exemplos

O exemplo a seguir cria uma instância Polygon de geometry simples com um buraco e 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);

Uma instância que não é válida pode ser inserida e convertida em uma instância geometry válida. No exemplo seguinte de um Polygon, os anéis interiores e exteriores se sobrepõem e a instância não é válida.

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

No exemplo a seguir, a instância inválida é tornada válida com MakeValid().

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

A instância geometry retornada do exemplo anterior é um 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)))