Visão geral de tipos de dados espaciais

Há dois tipos de dados espaciais. O tipo de dados geometry oferece suporte a dados planares ou a dados euclidianos (planisfério). O tipo de dados geometry (planar) está de acordo com os Recursos Simples do Open Geospatial Consortium (OGC) para o SQL Specification versão 1.1.0 e compatível com o SQL MM (padrão ISO).

Além disso, o SQL Server oferece suporte ao tipo de dados geography que armazena dados elipsoidais (globo), como coordenadas de latitude e longitude de GPS.

Observação importanteImportante

Para obter uma descrição detalhada e exemplos dos novos recursos espaciais nesta versão, incluindo melhorias aos tipos de dados espaciais, baixe o white paper sobre novos recursos espaciais no SQL Server Code-Named "Denali".

Neste tópico

  • Objetos de dados espaciais

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

  • Segmentos de arco circular

Objetos de dados espaciais

Os tipos de dados geometry e geography oferecem suporte a dezesseis objetos de dados espaciais, ou tipos de instâncias. No entanto, apenas onze 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 que as distingue como Points, LineStrings, CircularStrings, CompoundCurves, Polygons, CurvePolygons ou como instâncias geometry ou geography múltiplas em uma GeometryCollection. O tipo Geography tem um tipo de instância adicional, FullGlobe.

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

Hierarquia do tipo de geometria

Como a figura indica, os dez tipos dos quais se pode criar uma instância dos tipos de dados geometry e geography são Point, MultiPoint, LineString, CircularString, MultiLineString, CompoundCurve, Polygon, CurvePolygon, MultiPolygon e GeometryCollection. Há um tipo adicional do qual se pode criar uma instância para o tipo de dados de geography: FullGlobe. Os tipos geometry e geography podem reconhecer uma instância específica desde que ela esteja 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 a reconhecerão como uma instância de 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 incluem:

Os tipos de coleção incluem:

[INÍCIO]

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

Os dois tipos de dados espaciais sempre se comportam de maneira muito semelhante, mas há algumas diferenças importantes na maneira como eles 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 no centro, e um amplo 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 ou 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 de geometry, a distância entre (2, 2) e (5, 6) é de 5 unidades, independentemente das unidades usadas.

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

Orientação de dados espaciais

No sistema de planar, a orientação de anel de um polígono não é um fator importante. Por exemplo, um polígono descrito por ((0, 0), (10, 0), (0, 20), (0, 0)) é o mesmo que um polígono descrito por ((0, 0), (0, 20), (10, 0), (0, 0)). Os Recursos Simples do OGC para SQL Specification não ditam uma ordenação de anel e o SQL Server não impõe ordenação de anel.

Em um sistema elipsoidal, um polígono não tem nenhum significado ou é ambíguo, sem uma orientação. 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.

Quando o nível de compatibilidade é 100 ou abaixo no SQL Server 2012, 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 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 2012, FullGlobe é um tipo especial de Polígono que abrange o globo inteiro. FullGlobe tem uma área, mas nenhuma borda ou vértices.

Anéis externos e internos não são importantes no tipo de dados geography

Os Recursos Simples do OGC para SQL Specification discutem anéis externos e internos, mas essa distinção faz pouco sentido para o tipo de dados geography do SQL Server: qualquer anel de um polígono pode ser usado como anel externo.

Para obter mais informações sobre especificações do OGC, consulte o seguinte:

[INÍCIO]

Segmentos de arco circular

Três tipos instanciáveis podem adotar segmentos de arco circular: CircularString, CompoundCurve e 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.

As figuras A e B mostram segmentos de arco circular típicos. Observe como cada um dos três pontos se situa no perímetro de um círculo.

As figuras C e D mostram como um segmento de linha pode ser definido como um segmento de arco circular. Observe que 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 segmento de arco circular usam segmentos de linha reta para aproximar o arco circular. O número de segmentos de linha usado para aproximar o arco dependerá do comprimento e da curvatura do arco. Podem ser armazenados valores Z para cada um dos tipos de segmento de arco circular; porém, os métodos não usarão os valores Z em seus cálculos.

ObservaçãoObservaçã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

O diagrama a seguir mostra triângulos isósceles idênticos (o triângulo A usa segmentos de linha para definir o triângulo, e o triângulo B usa segmentos de arco circular para definir o triângulo):

7e382f76-59da-4b62-80dc-caf93e637c14

Este exemplo mostra como armazenar os triângulos isósceles anteriores que usam uma instância LineString e uma 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

Note que uma instância CircularString requer sete pontos para definir o triângulo, mas uma instância LineString requer somente 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. Portanto, os lados do triângulo armazenados na instância CircularString são ABC, CDE e EFA, ao passo que os lados do triângulo armazenados na instância LineString são AC, CE e EA.

Considere o seguinte trecho de código:

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];

Esse trecho produzirá os seguintes resultados:

LS LengthCS Length
5.65685…6.28318…

A ilustração a seguir mostra como cada tipo é armazenado (a linha vermelha mostra LineString@g1 e a linha azul mostra CircularString@g2):

e52157b5-5160-4a4b-8560-50cdcf905b76

Como a ilustração acima mostra, as instâncias CircularString usam menos pontos para armazenar limites de curva com maior precisão que instâncias LineString. As instâncias CircularString são úteis para armazenar limites circulares como um raio de pesquisa de vinte milhas de um ponto específico. Instâncias LineString 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))');

ou

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 CompoundCurve pode armazenar o segmento de arco circular (2 2, 1 3, 0 2) diretamente, ao passo que uma instância 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 trecho de código:

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

As instâncias CompoundCurve 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âncias CurvePolygon podem usar instâncias CircularString e CompoundCurve ao definir os seus anéis exteriores e interiores. Instâncias Polygon não podem usar os tipos de segmento de arco circular: CircularString e CompoundCurve.

[INÍCIO]

Consulte também

Referência

STNumCurves (tipo de dados geometry)

STNumCurves (tipo de dados geography)

STGeomFromText (tipo de dados geometry)

STGeomFromText (tipo de dados geography)

Conceitos

Dados espaciais (SQL Server)

Referência de método de tipo de dados geometry

Outros recursos

Referência de método de tipo de dados geography