Polígono
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.
Conforme mostrado na ilustração:
A Figura 1 é uma instância Polygon cujo limite está definido por um anel exterior.
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.
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. Estas instâncias Polygon são aceitas para o tipo geometry:
Uma instância Polygon vazia
Uma instância Polygon que tem um anel exterior aceitável e zero ou mais anéis interiores aceitáveis
Os critérios a seguir são necessários para um anel ser aceitável.
A instância LineString deve ser aceita.
A instância LineString deve ter pelo menos quatro pontos que incluam três pontos distintos.
Os pontos inicial e final da instância LineString devem ter os mesmos valores X e Y.
Observação Os valores Z e M são ignorados.
Uma instância Polygon de um tipo geography só será aceita se a instância for válida. Para obter mais informações sobre instâncias Polygon do tipo geography, consulte BkmkValidGeographyPolygons.
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))';
Conforme mostrado por @g4, uma instância Polygon aceita talvez não seja uma instância Polygon válida. Os exemplos a seguir geram 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 para o anel exterior não contém pontos suficientes. @g2 não é aceito porque o ponto inicial da instância LineString do anel exterior é diferente do ponto final. O exemplo a seguir tem um anel exterior aceitável, mas o anel interior não é aceitável. Isso também gera um 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 interiores de um Polygon podem tocar em si mesmos ou uns nos outros em pontos tangentes únicos, mas se os anéis interiores 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 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))';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid();
@g1 não é válido porque o anel interno toca o anel exterior em dois pontos. @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 tocam vários pontos consecutivos. @g4 não é válido porque os interiores dos dois anéis internos se sobrepõem.
tipo de dados Geometry
Para que uma instância Polygon de um tipo geometry seja válida, ela precisa atender aos seguintes critérios:
O primeiro anel é o anel exterior.
Todos os anéis interiores estão dentro do anel exterior.
Nenhum anel interior está dentro de outro anel interior.
Nenhum anel cruza ele mesmo ou outro anel.
Não há dois anéis compartilhando a mesma extremidade.
O interior de um anel interior não pode sobrepor o interior de outro anel interior.
Todos os anéis só podem tocar eles próprios ou outro anel em um ponto zero ou em um número limitado de pontos tangentes.
O interior da instância Polygon é conectado. Precisa haver pelo menos um caminho entre dois pontos interiores da instância que esteja totalmente 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á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 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) )';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid(), @g5.STIsValid();
@g1 não é válido porque o anel interno toca o anel exterior em dois pontos. @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 tocam vários pontos consecutivos. @g4 não é válido porque os interiores dos dois anéis internos se sobrepõem. @g5 não é válido porque o primeiro anel é um anel interior e o segundo anel é um anel exterior.
Tipo de dados geography
Para que uma instância Polygon de um tipo geography seja válida, ela precisa atender aos seguintes critérios:
A instância precisa atender a todas as regras necessárias para ser uma instância Polygon aceita do tipo geometry.
O interior da instância é conectado usando uma regra à esquerda.
A instância pode se ajustar em um hemisfério.
Nenhum anel cruza ele mesmo ou um outro anel.
Todos os anéis só podem tocar eles próprios ou qualquer outro anel em um ponto zero ou em um número limitado de pontos tangentes.
O exemplo a seguir gera um 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álida 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 geometryPolygon 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)))
Consulte também