Partilhar via


Polígono

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure Ponto de extremidade de análise de SQL no Microsoft Fabric Warehouse no Microsoft Fabric Banco de dados SQL no Microsoft Fabric

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 de Polygon .

Exemplos de instâncias de geometry 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))';  

As @g4 e @g5 show uma instância de Polygon aceita pode não ser uma instância de 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 geography 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 exigem a entrada de duas instâncias geography (como STIntersection(), STUnion(), STDifference(), e STSymDifference()), retornarão null se os resultados dos métodos não couberem em um único hemisfério. STBuffer() também retornará null se a saída exceder um único hemisfério.

A orientação pode ser revertida aproveitando o método estendido ReorientObject (geography Data Type).

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 é válida pode ser inserida e convertida em uma instância válida 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 geometry instância 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)))

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 geometria retornada anteriormente é 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).