No
artigo anterior falamos da importância dos dados espaciais em
nossas aplicações, porque e quando devemos utilizar, o que é o
plano geométrico e suas dimensões, qual diferença dos tipos de
dados geometry
e geography
os quais são novos tipos de dados que estão presente no SQL Server
2008 e por último vimos quais são os tipos
específicos para cada tipo de dados existente.
Ao
termos conhecido as diferenças dentre os tipos de dados geometry e
geography o que nos resta neste momento é conhecermos quais são os
diferentes formatos que podem ser utilizados para representar os
dados espaciais, existe exatamente três:
-
1.
The
Well-Known-Binary (WKB) format -
2.
The
Well-Known-Text (WKT) format -
3.
The
Geography Markup Language (GML) data format.
Todos
os formatos mostrado acima foram publicados pela Open Geospatial
Consortium (OGC), o qual é lider dos padrões geoespaciais e serviços
baseados em localizações.
-
1.
The
Well-Known-Binary (WKB) format
: Este é o formato binário pelo qual representa a instância do
tipo de dados geography, é um dos formatos preferidos serializados
das aplicações que necessitam armazenar informações geoespacial
em compactação. -
2.
The
Well-Known-Text (WKT) format:
Este formato é compacto, ou melhor nos garante uma leitura fácil,
isto porque é um formato amigável e o mais comum para se usar em
consultas geoespaciais. -
3.
The
Geography Markup Language (GML) data format:
Este formato representa o padrão (XML), o qual é a melhor
alternativa para incluir informações geoespaciais em documentos
XML. Este formato é útil em aplicações onde é necessário
alterar informações geoespaciais por meios de XML Web Service.
Os
padrões, conforme foi ilustrado acima, nos oferecem vastas vantagens, o
que precisa ser analisado é: qual deles se comportaria de melhor
forma em nossas aplicações. Os dados espaciais também suportam
algumas funções, atualmente existem mais de 60 nos tipo de dados
geometry
e geography.
STDifference
Retorna uma nova instância
consistindo em pontos da instância base em que não contém pontos
da instância parâmetro
-- Results: POLYGON ((10 10, 40 10, 40 26.666666666666668, 20 20, 26.666666666666668 40, 10 40, 10 10))
DECLARE @g geometry
='POLYGON((10 10, 40 10, 40 40, 10 40, 10 10))'
DECLARE @h geometry
='POLYGON((20 20, 50 30, 50 50, 30 50, 20 20))'
SELECT @G.STDifference(@H).ToString();
Figura
1 – Function – STDifference
STIntersects
Retorna
verdadeiro se todos os valores geometric
possuírem mais de uma intersecção, por outro lado este método irá
retorna NULL
se todos SRID
da instância não possuírem o valor adequado ao SRID da outra
instância ou melhor. Este método tem por objetivo conter apenas os
pontos comuns entre a instância base e a instância parâmetro.
-- Results: POLYGON ((30 30, 40 30, 40 40, 30 40, 30 30))
DECLARE @g geometry
='POLYGON((10 10, 40 10, 40 40, 10 40, 10 10))'
DECLARE @h geometry
='POLYGON((30 30, 50 30, 50 50, 30 50, 30 30))'
SELECT @g.STIntersection(@h).ToString();
Figura 2 – Function – STIntersects
STSymDifference
Retorna
uma nova instância contendo apenas os pontos únicos da instância
base e parâmetro ( i.e., excluindo os pontos que retornam
STIntersection() ).
-- Results: MULTIPOLYGON (((50 30, 50 50, 30 50, 40 40, 50 30)),
((10 10, 40 10, 40 40, 10 40, 10 10)))
DECLARE @g geometry
='POLYGON((10 10, 40 10, 40 40, 10 40, 10 10))'
DECLARE @h geometry
='POLYGON((40 40, 50 30, 50 50, 30 50, 40 40))'
SELECT @g.STSymDifference(@h).ToString();
Figura 1.2 (Function - STSysmDifference)
Figura 3 – Fucntion – STSysmDifference
STUnion
Retorna
uma nova instância contendo todo os pontos aninhados da instância
base e parâmetro.
-- Results: MULTIPOLYGON (((50 30, 50 50, 30 50, 40 40, 50 30)),
((40 10, 40 40, 10 40, 20 20, 40 10)))
DECLARE @g geometry
='POLYGON((20 20, 40 10, 40 40, 10 40, 20 20))'
DECLARE @h geometry
='POLYGON((40 40, 50 30, 50 50, 30 50, 40 40))'
SELECT @g.STUnion(@h).ToString();
Figura 4 – Function – STUnion
Blended
Types
Este método descreve não
justamente os polígonos, no entanto é possível usar diferentes
tipos específicos em cada coleção ou em cada tipo de definido.
-- Results: MULTILINESTRING ((40 40, 30 30), (25 25, 8 8))
DECLARE @g geometry='LINESTRING(8 8, 40 40)'
DECLARE @h geometry='POLYGON((25 25, 15 30, 30 30, 30 15, 25 25))'
SELECT @g.STDifference(@h).ToString();
Figura 4 – Function Blended Types
STArea,
STLength
Retorna a soma de todas
as áreas calculadas na superfície definida pelo usuário do tipo
geometric.
- STArea()
retorna o tipo float indicando a área quadrangular da instância - STLength()
retorna o tipo float indicando o tamanho de unidade da instância (0
ou se a instância é um ponto ou se não possui tamanho)
-- Results: 400 | 121.28990204492
DECLARE @g GEOMETRY='POLYGON((10 10, 30 50, 50 50, 10 10))'
SELECT @g.STArea(), @g.STLength()
Figura 5 – Function STArea, STLength
STCentroid
Este
é um dos métodos padrões OGC que retorna ‘Point’
indicando o centro da forma quandrangular, se a instância adotada
não for Polygon ou MultiPolygon o valor NULL será retornado.
-- Results: POINT (20 30)
DECLARE @g GEOMETRY='POLYGON((10 10, 10 40, 40 40, 10 10))'
SELECT @g.STCentroid().ToString()
Figura 6 – Function – STCentroid
STWithin,
STContains
Dois métodos que
seguem também o padrão OGC retornando 1 ou 0 e indica se todos
‘Points’
da instância existe totalmente ao lado de outra
instância.
- STContains()
testa se o parâmetro instância
está do lado da instância base - STWithin()
testa se a instância base está do
lado da instância parâmetro, retorna verdadeiro se dado o valor
geometric
estiver juntamente á outro, de outra forma, retorna falso. Este
método irá retorna NULL
se todos SRID da instância não possuir o valor adequado ao SRID da
outra instância.
-- Results: 1 0
-- 0 1
DECLARE @g geometry='POLYGON ((10 10, 13 30, 30 30, 30 15,10 10))'
DECLARE @h geometry='LINESTRING (16 16, 16 24, 25 18)'
SELECT @g.STContains(@h), @g.STWithin(@h)
SELECT @h.STContains(@g), @h.STWithin(@g)
Figura 7 – Function – STContains
STPointOnSurface
Este
método irá retornar de certa forma um ponto aleatório que nos
garante a localização dentro da instância base.
-- Results: POINT (23 25)
DECLARE @g geometry='POLYGON((10 10, 14 15, 50 12, 45 30,10 30, 10 10))'
SELECT @g.STPointOnSurface().ToString()
Figura 8 – Function – STPointOnSurface
STGeometryType
Retorna o tipo Open Geospatial Consortium (OGC) o qual representa
a instância geometry.
-- Results: Polygon
DECLARE @g geometry;
SET @g =geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', 0);
SELECT @g.STGeometryType();
STGeomFromText
Retorna
uma instância geometry
da representação Open Geospatial Consortium (OGC) Well-Known
Text(WKT) representando assim o argumento de elevações (Z) e
medidas (M).
-- Results: LINESTRING (100 100, 20 180, 180 180)
DECLARE @g geometry;
SET @g =geometry::ST
GeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0);
SELECT @g.ToString();
STTouches
Retorna verdadeiro se dado o valor geometric
faz parte de outro; de outra forma, retorna falso. Este método
retorna null se todos SRID (Spatial
Reference Identifier) da instância
não possuírem o valor adequado SRID da outra instância.
STDistance
Retorna
a distância entre os valores do tipo específico Point
geometric.
Este método irá retorna null se SRID (Spatial
Reference Identifier) da instância
não possuir o valor adequado ao SRID da outra instância.
Figura
1.9 – Geography Methods
Aos
analisarmos algumas funções e formatos existentes nos dados
espaciais, o que nos resta agora é apenas aplicá-los. Os tipos
específicos podem ser usados em definições de tabela e tipos
variáveis. Dependendo de sua manipulação dos dados espaciais, sendo
plano ou elíptico, pode-se usar os dois tipo de dados, geometry e
geography.
Exemplo
prático:
USEmaster
GO
IFEXISTS(SELECT Name FROMsys.databasesWHERE name =N'SpatialDatabase')
DROPDATABASE SpatialDatabase
CREATEDATABASE SpatialDatabase
ONPRIMARY
(NAME = SpatialDatabase_data,
FILENAME='C:\DatabaseSpatial\SpatialDatabase.mdf'),
FILEGROUP SpatialGroup1
(NAME = SpatialGroup2,
FILENAME='C:\DatabaseSpatial\SpatialDatabase.ndf')
LOGON
(NAME = Spatial_log,
FILENAME='C:\DatabaseSpatial\SpatialDatabase.ldf')
GO
USE SpatialDatabase;
CREATETABLE #GeometrySpatial
(
LocationID INTPRIMARYKEYCLUSTEREDNOTNULL,
LocationName NVARCHAR(30),
Position GEOGRAPHY
);
INSERTINTO #GeometrySpatial(LocationID,LocationName,Position)
VALUES (1,'Nova York',geography::Parse('POLYGON((
-75.17031 39.95601, -75.16786 39.95778, -75.17921 39.96874,
-75.18441 39.96512, -75.17031 39.95601 ))'))
INSERTINTO #GeometrySpatial(LocationID,LocationName,Position)
VALUES (2,'Chicago',geography::Parse('POLYGON((
-75.17031 39.95601, -75.16786 39.95778, -75.18870 39.97789, -75.18521 39.99237,
-75.18603 40.00677, -75.19922 40.01136, -75.21746 40.03142, -75.22534 40.02586,
-75.21052 40.01430, -75.19192 40.00634, -75.19248 39.99570, -75.20526 39.98374,
-75.19437 39.97704, -75.19087 39.96920, -75.17031 39.95601))'))
INSERTINTO #GeometrySpatial(LocationID,LocationName,Position)
VALUES (3,'Miami',geography::Parse('POLYGON((
-75.22280 40.02387, -75.21442 40.02810, -75.21746 40.03142,
-75.22534 40.02586, -75.22280 40.02387))'))
-- Trazendo os valores de forma compreensivel.
SELECT
LocationID,LocationName,Position.ToString()as WKT,
Position.STLength()as longitude
FROM #GeometrySpatial
Figura 10 – Results measures and longitude
-- Visualizando o Spatial Results
SELECT * FROM #GeometrySpatial
Figura 11 – Spatial Results – Map
OBS:
Se por acaso quisermos obter a lista de todos SRIDs suportados pelo
SQL Server, podemos executar a instrução:
SELECT
* FROM
sys.spatial_reference_systems
Para mais informações relacionado aos SRIDs, visite:
http://msdn.microsoft.com/en-us/library/bb964707.aspx
Figura
12 – Results – SRIDs
Conclusão
Ótimo,
agora que conhecemos o que são os dados espacias, quando devemos
utilizar, quais são as diferença dentre os tipos de dados geometry
e geography, quais são os formatos e tipos existentes suportados
pelo SQL Server e o exemplo prático, o que resta neste momento é
apenas implementá-los em nossa aplicação e, assim, termos a
convicção de que possuímos uma aplicação que tem ótimas
vantagens quando o assunto se relata em buscas (mundialmente).