O tipo de dados Geografia do SQL Server é diferente de outros tipos simplesmente porque você não o usa com frequência. Não é como varchar , int , flutuar , ou DataHora presente em todas as tabelas, pelo menos em um tipo.
Precisamos do tipo de dados Geografia do SQL Server? Para dar sentido a algo novo, precisamos responder a três perguntas fundamentais:
• Quais problemas ele resolve ? A resposta está nos casos de uso.
• Quais são as coisas envolvidas em estudá-lo? Você aprenderá algumas definições básicas e siglas. Eu coletei apenas as coisas importantes, então não vai te aborrecer.
• Existem exemplos para explicar melhor como funciona e é fácil de implementar? Nosso tipo vive com código. Nós comemos e dormimos com ele. Então, vamos ter códigos de amostra neste post.
Não é um post para enchê-lo com jargão técnico e sintaxe como está. Você está pronto para ir depois de ter decifrado o básico do tipo de dados de geografia do SQL Server. Soa bem?
Vamos mergulhar.
Casos de uso de dados espaciais
Vamos começar com o mais óbvio e o mais importante – o termo geral “dados espaciais”.
Dados espaciais ou geoespaciais são os dados sobre objetos, eventos ou fenômenos localizados na superfície da Terra. Em outras palavras, é informação recheada em um mapa. Pense no Google Maps ou Waze, por exemplo.
Mas tem mais:
- Localize um caminhão de entrega da empresa por meio de um site ou aplicativo para dispositivos móveis.
- Encontre pontos de interesse, como restaurantes, bancos ou hospitais próximos.
- Analise dados sobre terremotos, disseminação da COVID-19, inundações ou tráfego rodoviário – análise geoespacial.
E assim por diante.
Várias plataformas de banco de dados estão lidando com dados espaciais, mas vamos nos concentrar em apenas uma.
O que é o tipo de dados geográficos do SQL Server?
A Microsoft adicionou tipos de dados de geografia e geometria no SQL Server 2008. Geografia representa dados em um sistema de coordenadas de terra redonda. Ele também é implementado como um tipo de dados .Net CLR, que possui propriedades como latitude ou longitude.
Este post se concentra no tipo de dados de geografia e suas aplicações, particularmente em:
- Pontos de interesse, como localização de restaurantes próximos e um exemplo de consulta.
- Análise geoespacial.
Como este é um tipo de dados, criamos uma tabela. Em seguida, definimos uma coluna ou colunas como geografia. E, finalmente, fazemos um índice espacial nessas colunas.
Quando você consulta uma tabela com uma coluna de geografia, a saída será em binário.
Vamos tentar executar um exemplo elementar abaixo:
SELECT
[CityID]
,[CityName]
,[GeoLocation]
FROM [Cities]
A Figura 1 abaixo mostra o conjunto de resultados:
Quando um conjunto de resultados inclui dados espaciais, um Resultados Espaciais guia também aparecerá. A Figura 2 ilustra os resultados espaciais da consulta acima:
Agora, o que acabou de acontecer?
Parece que visualizar o conjunto de resultados está longe de ser fácil e útil, muito menos os pontos ao longo das linhas de grade. Mostrei o que esperar no primeiro SELECT declaração sobre tipos de dados geográficos. A próxima seção irá revelar uma perspectiva muito melhor.
Criando instâncias geográficas do SQL Server
Você precisa de uma instância para operar em dados com o tipo de dados de geografia do SQL Server. Há quatro maneiras de criar uma instância de geografia:
- de outra instância geográfica
- usando um texto conhecido (WKT)
- usando um binário conhecido (WKB)
- de uma entrada de texto Geography Markup Language (GML)
Vamos nos concentrar em usar um texto bem conhecido.
Usando texto conhecido (WKT)
Esta representação baseia-se no Open Geospatial Consortium (OGC). Ele permite a troca de dados geográficos em forma textual.
Veja nosso exemplo anterior, mas em vez de uma saída binária, vamos convertê-la em uma string:
SELECT
[CityID]
,[CityName]
,[GeoLocation].ToString() AS GeoLocationString
FROM [Cities]
Observe o ToString () método. Ele converterá a saída para o valor da string. Você pode ver a saída na Figura 3 abaixo:
Melhorar? Bem, ainda são apenas números. Mas e se eu te disser que esses números são latitude e longitude dessas cidades? Faz mais sentido, certo?
É um texto bem conhecido (WKT) e é essencial quando você coloca os dados na coluna. Mais sobre isso mais tarde. Agora, precisamos de mais uma coisa para examinar.
Identificador de Referência Espacial (SRID)
Além de um texto conhecido, cada instância de geografia tem um Identificador de Referência Espacial (SRID). É necessário para medir instâncias geográficas (lugares ou pontos) em um mapeamento de terra redonda.
A unidade de medida mais difundida é em metros ou metros quadrados, indicada pelo SRID 4326. Todos os outros SRIDs podem ser encontrados em sys.spatial_reference_systems .
Suas colunas de geografia podem ter SRIDs diferentes. Observe que quando você executa operações em duas instâncias geográficas, como medir suas distâncias. Ambas as instâncias devem ter o mesmo SRID ou retornará NULL .
STGeomFromText
Depois de aprender sobre WKT e SRID, a criação de uma instância de geografia requer um método chamado STGeomFromText . Tem a seguinte sintaxe:
geografia::STGeomFromText(
Exemplo:
INSERT INTO Cities
(CityName, GeoLocation)
VALUES
('CITY OF MANILA',geography::STGeomFromText('POINT(14.6077 120.98202)', 4326))
Vamos verificar os valores dos parâmetros:
'PONTO(14,6077 120,98202)' – um texto bem conhecido de um ponto no mapa com a latitude de 14,6077 e a longitude de 120,98202. Isso corresponde a Manila, a capital das Filipinas.
4326 – o identificador de referência espacial
Vamos pular direto para os exemplos e usar essa nova joia que encontramos.
Exemplos práticos de tipos de dados de geografia do SQL Server
Teremos dois aplicativos comuns para colocar você em funcionamento com dados geográficos.
Cálculo de distâncias (vizinho mais próximo)
Uma aplicação comum em dados espaciais geográficos é chamada de consulta do vizinho mais próximo. Nesta consulta, você deseja saber a que distância ou perto algo está de outro objeto ou lugar.
No meu post sobre o gráfico SQL, descrevi como um cliente pode encontrar os restaurantes próximos a partir do local atual. Vamos nos referir a esse exemplo novamente:
-- Query the location of the customer
DECLARE @deliveryLocation GEOGRAPHY
SELECT @deliveryLocation = Locations.GeoLocation
FROM Customers, willReceiveIn, Locations
WHERE MATCH(Customers-(willReceiveIn)->Locations)
AND Customers.CustomerID = 3
-- Query the restaurants within 1000 meters from the location of the customer
SELECT
Restaurants.Name
,Restaurants.Description
,Restaurants.Opening
,Restaurants.Closing
,Locations.Description
,ROUND(Locations.GeoLocation.STDistance(@deliveryLocation),2) AS Distance
FROM Restaurants, isLocated, Locations
WHERE MATCH(Restaurants-(isLocated)->Locations)
AND locations.GeoLocation.STDistance(@deliveryLocation) <= 1000
ORDER BY Distance
O segredo para esta consulta do vizinho mais próximo é STDistance (). Precisa de duas localizações geográficas:uma para o cliente e outra para os restaurantes a menos de 1000 metros da localização do cliente.
O legal é que o mesmo conceito se aplica a outras ideias envolvendo dois ou mais locais.
Análise geoespacial usando o Power BI
Outra aplicação de dados espaciais é usá-los para análise geoespacial. Nesta seção, temos um exemplo usando casos COVID-19 por local e apresentando-o usando o Power BI.
(Em uma nota lateral, aqui estão mais informações sobre o que é o Power BI e como instalá-lo)
A instalação do Power BI Desktop é gratuita. Uma das visualizações padrão é a visualização de Mapa usando o Bing Maps. Não precisamos de coordenadas para locais conhecidos, como países e estados dos EUA. Veja isso no exemplo abaixo:
Observe a caixa vermelha na Figura 4. Latitude e longitude são deixadas em branco, mas as bolhas são plotadas no mapa perfeitamente.
No entanto, no próximo exemplo, usaremos regiões e cidades nas Filipinas. As coordenadas são essenciais para traçar as bolhas corretamente.
O QUE VOCÊ PRECISA
Antes de entrarmos na parte importante do relatório, aqui estão as coisas básicas que precisamos:
- Power BI Desktop
- Visualização do mapa
- Tabelas e consultas
- Dados de amostra
PREPARANDO OS DADOS
Preparando as Tabelas e Visualizações
No início, precisamos configurar os contêineres para nossos dados. Assim, precisamos das seguintes tabelas:
- Cidades – uma lista de cidades nas Filipinas categorizadas por região.
- Regiões – uma lista de áreas nas Filipinas
- CityCases – uma lista contendo o número de casos para cada cidade.
Segue abaixo a estrutura da tabela:
CREATE TABLE [dbo].[Cities](
[CityID] [int] IDENTITY(1,1) NOT NULL,
[CityName] [varchar](50) NOT NULL,
[RegionID] [int] NOT NULL,
[GeoLocation] [geography] NULL,
CONSTRAINT [PK_Cities] PRIMARY KEY CLUSTERED
(
[CityID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[Regions](
[RegionID] [int] IDENTITY(1,1) NOT NULL,
[Region] [varchar](50) NOT NULL,
[GeoLocation] [geography] NULL,
CONSTRAINT [PK_Regions] PRIMARY KEY CLUSTERED
(
[RegionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[CityCases](
[CityCaseID] [int] IDENTITY(1,1) NOT NULL,
[CityID] [int] NOT NULL,
[DateReported] [date] NOT NULL,
[TotalCases] [int] NOT NULL,
[TotalDeaths] [int] NOT NULL,
CONSTRAINT [PK_CityCases] PRIMARY KEY CLUSTERED
(
[CityCaseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[CityCases] WITH CHECK ADD CONSTRAINT [FK_CityCases_Cities] FOREIGN KEY([CityID])
REFERENCES [dbo].[Cities] ([CityID])
GO
ALTER TABLE [dbo].[CityCases] CHECK CONSTRAINT [FK_CityCases_Cities]
GO
Como o tipo de dados de geografia é desconhecido para a visualização do Mapa do Power BI, você precisa criar exibições. O objetivo é expor a latitude e longitude dessas colunas. Fazemos isso para as cidades e regiões – veja abaixo:
CREATE VIEW vwCityCoordinates
AS
SELECT
CityID
,CityName
,GeoLocation.Lat AS Latitude
,Geolocation.Long AS Longitude
,RegionID
FROM Cities
CREATE VIEW vwRegionCoordinates
AS
SELECT
RegionID
,Region
,GeoLocation.Lat AS Latitude
,GeoLocation.Long AS Longitude
FROM Regions
É isso. Lat e Longo são propriedades para latitude e longitude. Agora é possível usá-los em nosso relatório do Power BI.
Construindo os dados
A seguir, você precisa construir os dados para nossas três tabelas.
Muito obrigado ao Departamento de Saúde das Filipinas por disponibilizar o conjunto de dados ao público. O arquivo está no formato CSV. A convenção de nomenclatura do arquivo é DOH COVID Data Drop_ yyyymmdd – 04 Case Information.CSV.
Veja como obter o arquivo para obter uma melhor experiência prática com nosso exemplo:
- Clique no link para o conjunto de dados.
- Selecione uma pasta de mês. Agosto de 2020 está em DOH COVID Data (08).
- Selecione uma data. 12 de agosto de 2020, por exemplo, está em DOH COVID Data Drop_20200812.
- Baixar DOH COVID Data Drop_ 20200812 – 04 Case Information.CSV. Repita as etapas 2 a 4 para obter o relatório dos outros dias.
Além disso, você precisa importar esses dados para o SQL Server. Veja como fazer:
- Abra o arquivo CSV no Excel.
- Adicione uma coluna DateReported e preencha todos os registros com a data correspondente. Neste caso, 10/08/2020.
- Salve-o como um arquivo Excel (.xlsx).
- Exporte o arquivo do Excel para o SQL Server para uma tabela chamada covid_ph .
Agora que os dados estão prontos no SQL Server, a próxima tarefa é executar o seguinte no editor de consultas do SSMS:
INSERT INTO CityCases
(CityID, DateReported, TotalCases, TotalDeaths)
SELECT DISTINCT
c.CityID
,cp.DateReported
,(SELECT COUNT(*) FROM covid_ph cp1 WHERE cp1.CityMunRes = cp.CityMunRes AND
cp1.DateReported = cp.DateReported) AS TotalCases
,(SELECT COUNT(*) FROM covid_ph cp1 WHERE cp1.CityMunRes = cp.CityMunRes AND
cp1.DateReported = cp.DateReported AND
cp1.RemovalType='DIED') AS TotalDeaths
FROM covid_ph cp
INNER JOIN Cities c ON cp.CityMunRes = c.CityName
ORDER BY cp.DateReported
Enquanto isso, não há coordenadas no conjunto de dados que usamos. Então, adicionei manualmente a latitude e longitude de regiões e cidades de latlongdata.com.
Aqui estão os dados para Regiões :
INSERT INTO Regions
(Region, GeoLocation)
VALUES
('BARMM',geography::STGeomFromText('POINT(121.987 6.42964)', 4326)),
('CAR',geography::STGeomFromText('POINT(121.466 17.4737)', 4326)),
('CARAGA',geography::STGeomFromText('POINT(125.492 9.78604)', 4326)),
('NCR',geography::STGeomFromText('POINT(120.984 14.5995)', 4326)),
('Region I: Ilocos Region',geography::STGeomFromText('POINT(120.381 17.5553)', 4326)),
('Region II: Cagayan Valley',geography::STGeomFromText('POINT(121.811 16.9754)', 4326)),
('Region III: Central Luzon',geography::STGeomFromText('POINT(120.712 15.4828)', 4326)),
('Region IV-A: CALABARZON',geography::STGeomFromText('POINT(121.079 14.1008)', 4326)),
('Region IV-B: MIMAROPA',geography::STGeomFromText('POINT(118.736 9.84321)', 4326)),
('Region IX: Zamboanga Peninsula',geography::STGeomFromText('POINT(123.259 8.15408)', 4326)),
('Region V: Bicol Region',geography::STGeomFromText('POINT(123.414 13.421)', 4326)),
('Region VI: Western Visayas',geography::STGeomFromText('POINT(122.537 11.005)', 4326)),
('Region VII: Central Visayas',geography::STGeomFromText('POINT(124.064 9.81687)', 4326)),
('Region VIII: Eastern Visayas',geography::STGeomFromText('POINT(125.039 12.2446)', 4326)),
('Region X: Northern Mindanao',geography::STGeomFromText('POINT(124.686 8.02016)', 4326)),
('Region XI: Davao Region',geography::STGeomFromText('POINT(126.089 7.30416)', 4326)),
('Region XII: SOCCSKSARGEN',geography::STGeomFromText('POINT(124.686 6.27069)', 4326))
Aqui estão os dados de uma lista parcial de cidades para Cidades tabela:
INSERT INTO Cities
(CityName, RegionID, GeoLocation)
VALUES
('CALOOCAN CITY',4,geography::STGeomFromText('POINT(120.967 14.6488)', 4326)),
('CITY OF LAS PIÑAS',4,geography::STGeomFromText('POINT(120.999 14.4325)', 4326)),
('CITY OF MAKATI',4,geography::STGeomFromText('POINT(121.033 14.5502)', 4326)),
('CITY OF MALABON',4,geography::STGeomFromText('POINT(120.957 14.6633)', 4326)),
('CITY OF MANDALUYONG',4,geography::STGeomFromText('POINT(121.039 14.5771)', 4326)),
('CITY OF MANILA',4,geography::STGeomFromText('POINT(120.982 14.6077)', 4326)),
('CITY OF MARIKINA',4,geography::STGeomFromText('POINT(121.097 14.6409)', 4326)),
('CITY OF MUNTINLUPA',4,geography::STGeomFromText('POINT(121.05 14.4209)', 4326)),
('CITY OF NAVOTAS',4,geography::STGeomFromText('POINT(120.933 14.6775)', 4326)),
('CITY OF PARAÑAQUE',4,geography::STGeomFromText('POINT(121.017 14.4664)', 4326)),
('CITY OF PASIG',4,geography::STGeomFromText('POINT(121.061 14.5876)', 4326)),
('CITY OF SAN JUAN',4,geography::STGeomFromText('POINT(121.037 14.6001)', 4326)),
('CITY OF VALENZUELA',4,geography::STGeomFromText('POINT(120.967 14.6823)', 4326)),
('PASAY CITY',4,geography::STGeomFromText('POINT(121 14.5505)', 4326)),
('PATEROS',4,geography::STGeomFromText('POINT(121.071 14.5487)', 4326)),
('QUEZON CITY',4,geography::STGeomFromText('POINT(121.033 14.633)', 4326)),
('TAGUIG CITY',4,geography::STGeomFromText('POINT(121.062 14.5216)', 4326)),
('ALFONSO',8,geography::STGeomFromText('POINT(120.861 14.1214)', 4326)),
('AMADEO',8,geography::STGeomFromText('POINT(120.922 14.1693)', 4326)),
('BACOOR CITY',8,geography::STGeomFromText('POINT(120.974 14.413)', 4326)),
('CARMONA',8,geography::STGeomFromText('POINT(121.041 14.3108)', 4326)),
('CAVITE CITY',8,geography::STGeomFromText('POINT(120.897 14.4791)', 4326)),
('CITY OF DASMARIÑAS',8,geography::STGeomFromText('POINT(120.959 14.299)', 4326)),
('CITY OF GENERAL TRIAS',8,geography::STGeomFromText('POINT(120.907 14.3214)', 4326)),
('GEN. MARIANO ALVAREZ',8,geography::STGeomFromText('POINT(121.013 14.3051)', 4326)),
('GENERAL EMILIO AGUINALDO',8,geography::STGeomFromText('POINT(120.792 14.1931)', 4326)),
('IMUS CITY',8,geography::STGeomFromText('POINT(120.941 14.4064)', 4326)),
('INDANG',8,geography::STGeomFromText('POINT(120.873 14.192)', 4326)),
('KAWIT',8,geography::STGeomFromText('POINT(120.904 14.441)', 4326)),
('MAGALLANES',8,geography::STGeomFromText('POINT(120.746 14.1583)', 4326)),
('MARAGONDON',8,geography::STGeomFromText('POINT(120.735 14.253)', 4326)),
('MENDEZ (MENDEZ-NUÑEZ)',8,geography::STGeomFromText('POINT(120.902 14.1312)', 4326)),
('NAIC',8,geography::STGeomFromText('POINT(120.792 14.2965)', 4326)),
('NOVELETA',8,geography::STGeomFromText('POINT(120.88 14.4279)', 4326)),
('ROSARIO',8,geography::STGeomFromText('POINT(120.857 14.414)', 4326)),
('SILANG',8,geography::STGeomFromText('POINT(120.969 14.2142)', 4326)),
('TAGAYTAY CITY',8,geography::STGeomFromText('POINT(120.962 14.1153)', 4326)),
('TANZA',8,geography::STGeomFromText('POINT(120.85 14.3429)', 4326)),
('TERNATE',8,geography::STGeomFromText('POINT(120.678 14.2714)', 4326)),
('TRECE MARTIRES CITY (CAPITAL)',8,geography::STGeomFromText('POINT(120.868 14.2822)', 4326))
Agora que os dados estão todos definidos, estamos prontos para preparar o relatório.
PREPARANDO O RELATÓRIO
Antes de começarmos, precisamos de duas páginas de relatórios. Uma página é para os dados por região e a outra página é por cidade.
Relatório COVID-19 por região
Aqui estão as etapas simples para criar o relatório por região:
- Conecte-se ao SQL Server do Power BI. Indique o servidor e o banco de dados.
- Escolha as tabelas e visualizações necessárias para o relatório.
3. Defina os relacionamentos – veja a Figura 6 abaixo. Para obter mais detalhes sobre como definir relacionamentos no Power BI, visite esta página.
4. Clique na visualização do Mapa e preencha as propriedades. Vincule as propriedades de latitude e longitude de vwRegionCoordinates . Em seguida, a dica de ferramenta de vwRegionCoordinates Região coluna. E, finalmente, o tamanho de CityCases ‘ TotalCases coluna. Veja a Figura 7 abaixo:
- Adicione um Slicer e vincule-o a DateReported de CityCases tabela.
- Insira um cartão e vincule-o a TotalCases de CityCases tabela
- Adicione um gráfico de barras agrupado. Vincule a propriedade Axis a Region coluna de vwRegionCoordinates . Em seguida, vincule os valores a TotalCases coluna de CityCases . Veja a Figura 8 abaixo:
Após as etapas acima, você verá a aparência final. Deve ser semelhante à Figura 9 abaixo:
Relatório COVID-19 por cidade
A primeira página está pronta. Adicionar a próxima página do relatório por cidade não deve ser difícil.
Aqui estão os passos:
- Adicione uma nova página clicando no + na parte inferior da janela e renomeie-a por cidade (Filipinas).
- Inclua uma segmentação de dados e vincule-a à região de vwRegionCoordinates .
- Insira outro slicer e vincule-o a DateReported de CityCases .
- Adicione um cartão e vincule-o a TotalCases de CityCases .
- Insira uma visualização de mapa. Você define as propriedades de latitude e longitude de vwCityCoordinates . A dica de ferramenta é de vwCityCoordinates Cidade coluna e o tamanho é de CityCases ‘ TotalCases coluna.
- Adicione um gráfico de barras agrupado e vincule o eixo a CityName coluna de vwCityCoordinates e valores para TotalCases de CityCases .
A aparência final do relatório por cidade deve ser semelhante à Figura 10 abaixo:
Agora, qual é o grande problema em usar mapas para análise em comparação com gráficos de barras ou linhas?
Em primeiro lugar, não se trata apenas de estética e impressionar seu público com relatórios atraentes. Mais importante, dá-lhes uma compreensão mais clara dos dados relativos a um local.
Em nosso exemplo, você pode ver onde o problema da pandemia é mais difundido com base no tamanho das bolhas. Além disso, podemos ver e comparar de relance o número de casos de lugares diferentes em relação uns aos outros. Isso também ajudará os funcionários do governo a tomar melhores decisões.
Nosso exemplo de relatório é muito simples, mas demonstra como os tipos de dados geográficos do SQL Server podem ajudá-lo na análise geoespacial.
Conclusão
Você entendeu o que há para você ao usar o tipo de dados espaciais de geografia?
- Dados espaciais ou geoespaciais representam os dados em pontos localizados na superfície da Terra.
- Pode ser usado para a consulta "vizinho mais próximo" procurando cinemas, restaurantes, clubes, etc.
- Também é útil para análise de dados geoespaciais, como o relatório que criamos no Power BI.
- Os elementos fundamentais na criação de uma instância de geografia são coisas como texto conhecido (WKT), identificador de referência espacial (SRID) e o método STGeomFromText .
Neste post, abordamos apenas uma parte do que os dados espaciais no SQL Server podem fazer por você. Você pode não usá-los todos de uma vez, mas os casos de uso mais comuns estão aqui para você começar. Por que não explorar mais as referências da Microsoft abaixo?
- Visão geral dos dados espaciais
- Tipos de dados espaciais
- Indexação de dados espaciais
Se você gostou deste post, compartilhe-o em suas redes sociais favoritas.