Polígono

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure

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

Instâncias de polígono

Uma instância Polygon pode ser formada de um anel que tem, 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 geométricas Polygon

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 interna 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 interiores 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. As seguintes instâncias Polygon são aceitas:

  • Uma instância Polygon vazia
  • Uma instância Polygon que tem um anel exterior aceitável (LineString) e zero ou mais anéis interiores aceitáveis (LineStrings)

Os critérios a seguir são necessários para que um anel (LineString) seja aceitável.

  • A instância LineString deve ser aceita.
  • A instância LineString deve ter, pelo menos, quatro pontos.
  • Os pontos inicial e final da instância LineString devem ser iguais.

O exemplo a seguir mostra instâncias Polygon aceitas.

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

Conforme mostrado por @g4 e @g5 , uma instância Polygon aceita pode não ser uma instância Polygon válida. @g5 também mostra que uma instância do Polygon precisa conter apenas um anel com quatro pontos para ser aceita.

Os exemplos a seguir lançam um 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 é aceito porque a instância LineString do anel externo não contém pontos suficientes. @g2 não é aceito porque o ponto inicial da instância LineString do anel externo não é a mesmo que o ponto final. O exemplo a seguir tem um anel externo aceitável, mas o anel interno não é aceitável. Isso também lança 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

Os anéis internos de um Polygon podem tocar a si mesmos e uns aos outros em pontos tangentes únicos, mas se os anéis internos de um Polygon se cruzarem, a instância não será válida.

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álido porque os dois anéis interiores se tocam em um único ponto e não se cruzam. O exemplo a seguir mostra instâncias de Polygon que não são vá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) )';  
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 não é válido porque o anel interno toca o anel externo em dois lugares. @g2 não é válido porque o segundo anel interno está dentro do interior do primeiro anel interno. @g3 não é válido porque os dois anéis internos se tocam em vários pontos consecutivos. @g4 não é válido porque os interiores dos dois anéis internos estão sobrepostos. @g5 não é válido porque o anel externo não é o primeiro anel. @g6 não é válido porque o anel não tem pelo menos três pontos distintos.

Orientação de dados espaciais

A orientação de anel de um polígono não é um fator importante no sistema planar. A Especificação de Recursos Simples do OGC para SQL não dita uma ordenação de anel e o SQL Server não impõe a ordenação de anel.

Em um sistema elipsoidal, um polígono sem orientação não tem nenhum significado ou é ambíguo. Por exemplo, um anel ao redor do equador descreve o hemisfério norte ou o sul? Se usarmos o tipo de dados geography para armazenar a instância espacial, deveremos especificar a orientação do anel e descrever precisamente o local da instância.

O interior do polígono em um sistema elipsoidal é definido pela "regra à esquerda": se você imaginar que está caminhando ao longo do anel de um polígono de Geografia, seguindo os pontos na ordem em que são listados, a área à esquerda será tratada como o interior do polígono e a área à direita, como o exterior do polígono.

Sentido anti-horário

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

Visualização da orientação da 'regra da mão esquerda' no sentido anti-horário

Sentido horário

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

Visualização da orientação da 'regra da mão esquerda' no sentido horário

Quando o nível de compatibilidade é 100 ou inferior no SQL Server, o tipo de dados de geografia tem as seguintes restrições:

  • Cada instância de geography deve se ajustar dentro de um único hemisfério. Nenhum objeto espacial maior do que um hemisfério pode ser armazenado.

  • Qualquer instância de geography de uma representação WKT (Well-Known Text) ou WKB (Well-Known Binary) do Open Geospatial Consortium (OGC) que reproduza um objeto maior do que um hemisfério aciona uma ArgumentException.

  • Os métodos de tipo de dados geography que requerem a entrada de duas instâncias de geography , como STIntersection(), STUnion(), STDifference() e STSymDifference(), retornarão nulo se os resultados dos métodos não se ajustarem dentro de um único hemisfério. STBuffer() também retornará nulo se a saída ultrapassar um único hemisfério.

A orientação pode ser revertida com o uso do método estendido ReorientObject.

Exemplos

Exemplo A.

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

Exemplo B.

Uma instância que não seja válida pode ser inserida e convertida em uma instância válida de geometry. No exemplo a seguir de Polygon, os anéis interno e externo 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))'
    );  

Exemplo C.

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

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

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

Exemplo D.

Este é outro exemplo de conversão de uma instância inválida em uma instância de geometry válida. No exemplo a seguir, a instância Polygon foi criada usando três pontos que são exatamente iguais:

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

A instância de geometry retornada acima é um Point(1 3). Se o Polygon fornecido for POLYGON((1 3, 1 5, 1 3, 1 3)) , MakeValid() retornaria LINESTRING(1 3, 1 5).

Confira também

STArea (tipo de dados geometry)
STExteriorRing (tipo de dados geometry)
STNumInteriorRing (tipo de dados geometry)
STInteriorRingN (tipo de dados geometry)
STCentroid (tipo de dados geometry)
STPointOnSurface (tipo de dados geometry)
MultiPolygon
Dados espaciais (SQL Server)
STIsValid (tipo de dados geography)
STIsValid (tipo de dados geometry)