Visão geral de tipos de dados espaciais

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do Azure

Há dois tipos de dados espaciais. O tipo de dados geometry dá suporte a dados planares ou a dados euclidianos (planisfério). O tipo de dados geometry está de acordo com a Especificação de Recursos Simples do OGC (Open Geospatial Consortium) para o SQL versão 1.1.0 e está em conformidade com o SQL MM (padrão ISO). O SQL Server também é compatível com o tipo de dados de geografia, que armazena dados elipsoidais (redondos da Terra), como coordenadas de latitude e longitude de GPS.

Dica

O SQL Server Spatial Tools é uma coleção de ferramentas de código aberto patrocinada pela Microsoft para uso com os tipos espaciais no SQL Server. Esse projeto fornece um conjunto de funções reutilizáveis que podem ser usadas pelos aplicativos. Essas funções podem incluir rotinas de conversão de dados, novas transformações, agregações, etc. Consulte Microsoft/SQLServerSpatialTools no GitHub para obter mais detalhes.

Objetos de dados espaciais

Os tipos de dados geometry e geography dão suporte a 16 tipos de objetos de dados espaciais ou tipos de instâncias. No entanto, apenas 11 desses tipos de instâncias podem ser instanciados. É possível criar e trabalhar com essas instâncias (ou criar uma instância delas) em um banco de dados. Essas instâncias derivam determinadas propriedades de seus tipos de dados pai.

A figura a seguir mostra a hierarquia de geometry, na qual os tipos de dados geometry e geography são baseados. Os tipos a partir dos quais se podem criar instâncias de geometry e geography são indicados em azul.

geom_hierarchy

Há um tipo instanciável adicional para o tipo de dados de geografia: FullGlobe. Os tipos geometry e geography podem reconhecer uma instância específica, desde que ela seja bem formada, ainda que não esteja definida explicitamente. Por exemplo, se você definir uma instância de Point explicitamente usando o método STPointFromText(), geometry e geography a reconhecerão como uma instância de Point, desde que a entrada do método esteja bem formada. Se você definir a mesma instância usando o método STGeomFromText() , os tipos de dados geometry e geography reconhecem a instância como um Point.

Os subtipos dos tipos geometry e geography são divididos em tipos simples e de coleção. Alguns métodos como STNumCurves() só funcionam com tipos simples.

Os tipos simples são:

Os tipos de coleção são:

Diferenças entre os tipos de dados de geometria e geografia

Os dois tipos de dados espaciais geralmente se comportam de maneira semelhante. Há algumas diferenças importantes na forma como os dados são armazenados e manipulados.

Como bordas de conexão são definidas

Os dados definidos para os tipos LineString e Polygon são somente vértices. A borda de conexão entre dois vértices em um tipo geometry é uma linha reta. No entanto, a borda de conexão entre dois vértices em um tipo de geografia é um amplo arco elíptico curto entre os dois vértices. Uma grande elipse é a interseção do elipsoide com um plano por meio de seu centro. Um grande arco elíptico é um segmento de arco na grande elipse.

Como são definidos segmentos de arco circular

Os segmentos de arco circular para tipos geometry são definidos no plano de coordenadas cartesianas XY (são ignorados valores Z). Os segmentos de arco circular para tipos geography são definidos por segmentos de curva em uma esfera de referência. Qualquer paralelo na esfera de referência pode ser definido por dois arcos circulares complementares, onde os pontos para ambos os arcos têm um ângulo de latitude constante.

Medidas em tipos de dados espaciais

No sistema planar (de terra plana), as medidas de distâncias e de áreas são fornecidas na mesma unidade de medida das coordenadas. Usando o tipo de dados geometry, a distância entre (2, 2) e (5, 6) é de cinco unidades, independentemente das unidades usadas.

Em um sistema elipsoidal ou de terra redonda, as coordenadas são fornecidas em graus de latitude ou de longitude. No entanto, os comprimentos e áreas normalmente são medidos em metros e em metros quadrados, embora a medida possa depender do identificador de referência espacial da instância de geography. A unidade de medida mais comum para o tipo de dados geography é em metros.

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.

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.

No SQL Server, FullGlobe é um tipo especial de polígono que cobre o globo inteiro. Ele tem uma área, mas nenhuma borda ou vértices.

Anéis externos e internos no tipo de dados geography

A Especificação de Recursos Simples do OGC para SQL discute anéis externos e anéis internos, mas essa distinção faz pouco sentido para o tipo de dados de geografia do SQL Server. Qualquer anel de um polígono pode ser considerado o anel externo.

Para obter mais informações sobre as especificações do OGC, confira os seguintes documentos:

Segmentos de arco circular

Três tipos instanciáveis podem adotar segmentos de arco circular: CircularString, CompoundCurvee CurvePolygon. Um segmento de arco circular é definido por três pontos em um plano bidimensional e o terceiro ponto não pode ser igual ao primeiro. Alguns exemplos de segmentos de arco circular:

circular_arc_segments

Os dois primeiros exemplos mostram segmentos de arco circular típicos. Observe como cada um dos três pontos se situa no perímetro de um círculo.

Os outros dois exemplos mostram como um segmento de linha pode ser definido como um segmento de arco circular. Três pontos ainda são necessários para definir o segmento de arco circular, ao contrário de um segmento de linha normal, que pode ser definido por apenas dois pontos.

Os métodos que operam em tipos de segmentos de arco circular usam segmentos de linha reta para aproximar o arco circular. O número de segmentos de linha usados para aproximar o arco dependerá do comprimento e da curvatura do arco. Valores de Z podem ser armazenados para cada tipo de segmento de arco circular, mas não serão usados nos cálculos.

Observação

Se forem fornecidos valores Z para segmentos de arco circular, eles deverão ser iguais para todos os pontos no segmento de arco circular para que o segmento seja aceito para entrada. Por exemplo, CIRCULARSTRING(0 0 1, 2 2 1, 4 0 1) é aceito, mas CIRCULARSTRING(0 0 1, 2 2 2, 4 0 1) não é.

Comparação de LineString e CircularString

Este exemplo mostra como armazenar triângulos isósceles idênticos que usam uma instância LineString e uma instância CircularString:

DECLARE @g1 geometry;
DECLARE @g2 geometry;
SET @g1 = geometry::STGeomFromText('LINESTRING(1 1, 5 1, 3 5, 1 1)', 0);
SET @g2 = geometry::STGeomFromText('CIRCULARSTRING(1 1, 3 1, 5 1, 4 3, 3 5, 2 3, 1 1)', 0);
IF @g1.STIsValid() = 1 AND @g2.STIsValid() = 1
  BEGIN
      SELECT @g1.ToString(), @g2.ToString()
      SELECT @g1.STLength() AS [LS Length], @g2.STLength() AS [CS Length]
  END

Observe que uma instância de CircularString requer sete pontos para definir o triângulo. A instância de LineString requer apenas quatro pontos para definir o triângulo. O motivo para isso é que uma instância CircularString armazena segmentos de arco circular e não segmentos de linha. Os lados do triângulo armazenados na instância de CircularString são ABC, CDE e EFA. Os lados do triângulo armazenados na instância de LineString são AC, CE e EA.

Considere o seguinte exemplo:

SET @g1 = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 4 0)', 0);
SET @g2 = geometry::STGeomFromText('CIRCULARSTRING(0 0, 2 2, 4 0)', 0);
SELECT @g1.STLength() AS [LS Length], @g2.STLength() AS [CS Length];

Este é o conjunto de resultados.

LS Length    CS Length
5.65685...   6.28318...

As instâncias CircularString usam menos pontos para armazenar limites de curva com maior precisão que as instâncias LineString. As instânciasCircularString são úteis para armazenar limites circulares como um raio de pesquisa de 20 milhas de um ponto específico. InstânciasLineString são boas para armazenar limites que são lineares como um quarteirão de cidade.

Comparação de LineString e CompoundCurve

Os exemplos de código seguintes mostram como armazenar a mesma figura usando instâncias LineString e CompoundCurve :

SET @g = geometry::Parse('LINESTRING(2 2, 4 2, 4 4, 2 4, 2 2)');
SET @g = geometry::Parse('COMPOUNDCURVE((2 2, 4 2), (4 2, 4 4), (4 4, 2 4), (2 4, 2 2))');
SET @g = geometry::Parse('COMPOUNDCURVE((2 2, 4 2, 4 4, 2 4, 2 2))');

Nos exemplos anteriores, uma instância LineString ou uma instância CompoundCurve poderiam armazenar a figura. Este próximo exemplo usa uma CompoundCurve para armazenar uma fatia de pizza:

SET @g = geometry::Parse('COMPOUNDCURVE(CIRCULARSTRING(2 2, 1 3, 0 2),(0 2, 1 0, 2 2))');  

Uma instância de CompoundCurve pode armazenar o segmento de arco circular (2 2, 1 3, 0 2) diretamente, mas uma instância de LineString teria que converter a curva em vários segmentos de linha menores.

Comparação de CircularString e CompoundCurve

O exemplo de código a seguir mostra como a fatia de pizza pode ser armazenada em uma instância CircularString :

DECLARE @g geometry;
SET @g = geometry::Parse('CIRCULARSTRING( 0 0, 1 2.1082, 3 6.3246, 0 7, -3 6.3246, -1 2.1082, 0 0)');
SELECT @g.ToString(), @g.STLength();

Para armazenar a fatia de pizza usando uma instância CircularString, é necessário que três pontos sejam usados para cada segmento de linha. Se um ponto intermediário não for conhecido, ele deverá ser calculado ou o ponto de extremidade do segmento de linha deverá ser dobrado como mostra o seguinte snippet:

SET @g = geometry::Parse('CIRCULARSTRING( 0 0, 3 6.3246, 3 6.3246, 0 7, -3 6.3246, 0 0, 0 0)');

As instânciasCompoundCurve permitem componentes LineString e CircularString , de forma que somente dois pontos para os segmentos de linha da fatia de pizza precisam ser conhecidos. Este exemplo de código mostra como usar uma CompoundCurve para armazenar a mesma figura:

DECLARE @g geometry;
SET @g = geometry::Parse('COMPOUNDCURVE(CIRCULARSTRING( 3 6.3246, 0 7, -3 6.3246), (-3 6.3246, 0 0, 3 6.3246))');
SELECT @g.ToString(), @g.STLength();

Comparação de Polygon e CurvePolygon

InstânciasCurvePolygon podem usar instâncias CircularString e CompoundCurve instances when defining their exterior e interior rings. Instâncias de Polygon não podem.

Confira também