Mapas e dados georreferenciados no R – parte 1

Existem diversos softwares especializados para trabalhar com dados geográficos, que possuem funções das mais diversas, dedicadas desde desenhar e/ou corrigir polígonos, passando por gerenciamento de bancos dados até executar complexos modelos de estatística espacial. No entanto, pouco a pouco, a comunidade de usuários do R vem implementando pacotes, funções e interfaces para lidar com sistemas de informação geográficas (GIS). Talvez ainda hoje não possibilitam todos os usos que um software como o ArcGIS. Mas conhecendo um pouco da grande velocidade e gana com que se desenvolvem pacotes para o R, é bem provável daqui a pouco isso seja revertido (se é que é verdade!).

Neste post ilustro uma forma de lidar com dados georreferenciados (latitude/longitude) e plotar mapas. O pacote a ser usado é o ggmap, que possui uma função chamada geocode. Seu uso é bem simples: basta informar um endereço postal e recebemos de volta sua latitude e longitude. Detalhe: não pode haver acentos nas vogais, nem “ç”. Os caracteres aceitos são aqueles do teclado americano. :-/

Vamos obter a latitude e a longitude do MASP, Museu de Arte de São Paulo:

require(ggmap)
geocode("Av. Paulista, 1578 - Bela Vista, Sao Paulo, Brasil")

Information from URL : http://maps.googleapis.com/maps/api/geocode/json?address=Av.+Paulista,+1578+-+Bela+Vista,+Sao+Paulo,+Brasil&sensor=false
Google Maps API Terms of Service : http://developers.google.com/maps/terms
lon lat
1 -46.65726 -23.56049

A função geocode acessa o API do Google Maps e faz uma pesquisa pelo endereço informado. Obviamente, nem todos os endereços são unívocos. Qualquer um que já utilizou o Google Maps sabe que esse aplicativo retorna um rol de alternativas em caso de múltiplas possibilidades. O resultado acima é a alternativa mais provável (e, na realidade, é a correta). Mas se for o caso, é possível acessar, dentro do objeto que é resultado dessa pesquisa, as demais alternativas. É possível também procurar vários endereços de uma vez só. Basta que cada endereço esteja gravado dentro de um elemento de um vetor de caracteres (string ou character). O uso do API, no entanto, tem uma limitação: só é possível fazer 2500 consultas por dia. Limites são muito comuns em APIs de acesso gratuito. Há planos pagos que permitem elevar aquele número.

O que fazer com a latitude e a longitude? É possível plotá-las num mapa!

No exemplo abaixo, vou até o site da prefeitura de SP, baixo o código fonte da página que contém uma lista de endereços de 13 unidades do SESC na região metropolitana (existem mais unidades… mas para o exemplo, essas bastam).

# Baixando, na página da prefeitura de SP, os endereços dos SESCs
pag_pref = readLines("http://www9.prefeitura.sp.gov.br/secretarias/smpp/sites/saopaulomaisjovem/cultura/index.php?p=25")[71]

Reparem que já extraio diretamente a linha de número 71. É exatamente nela que estão todos os endereços. Então baixar o resto era desnecessário. Mas esse conteúdo não está formatado:

pag

É preciso fazer uma limpeza do código HTML e extrair apenas o conteúdo desejado:

# Separando as linhas e removendo conteúdos desnecessários
pag_pref = unlist(strsplit(pag_pref,"<br />|/ Tel"))
pag_pref =gsub("<strong>|</strong>","",pag_pref)

# Mantém apenas as linhas que contêm a expressão "Endereço"
pag_pref = pag_pref[grep("Endereço",pag_pref)]

# Remove a expressão "Endereço"
pag_pref = gsub("Endereço: ","",pag_pref)

# Retira todos os caracteres especiais
pag_pref = gsub("[[:punct:]]", ",", pag_pref)

# Remove conteúdo desnecessário da linha 1
pag_pref = gsub("esquina com a Rua 24 de Maio","Sao Paulo, SP",pag_pref)

# Adiciona a cidade à linha 8
pag_pref[8] = paste(pag_pref[8],", Sao Paulo, SP")

# Adiciona o país a todas as linhas
pag_pref = paste(pag_pref,", Brasil")

# Remove todos os acentos
pag_pref = iconv(pag_pref, to="ASCII//TRANSLIT")

Pronto, esse é o resultado, uma lista de endereços guardada num vetor de caracteres:

pag

Agora é só aplicar a função geocode para obter todas as latitudes e longitudes:

latlon = geocode(pag_pref)

Falta o mapa.

A função get_map do pacote ggmap acessa um repositório público de mapas, o stamen, copia a imagem (geocodificada) da região desejada e a retorna como um objeto do R. Há várias opções de formatação, cores etc. E há também outros repositórios de mapas (inclusive o próprio Google Maps).

# Baixa o mapa de SP (centrado na Sé - isto pode ser alterado)
sp.map =get_map(location="Sao Paulo", zoom = 11,
 source = "stamen", maptype = "toner", color = "color")

# Transforma o arquivo de mapa em um grafico (ggplot2)
sp.map.2012 <- ggmap(sp.map, base_layer =
 ggplot(aes(x = lon, y = lat), data = latlon), extent = "device")

#Plota o resultado (os pontos dos endereços)
sp.map.2012 + geom_point(size = I(4),colour="red", alpha = 2/3)

Pronto, o mapa final é esse aqui:

plot_zoom

Mas o assunto sobre dados georreferenciados e mapas está longe de ser esgotado aqui…

Anúncios