Geocodificação reversa em R

Gratuito sem o Google ou a API do Bing

Aisha Sikder Blocked Unblock Seguir Seguindo 6 de janeiro Foto do Lonely Planet no Unsplash

Enquanto continuo a trabalhar na minha dissertação, eu me deparei com algumas falhas na execução do que deve ser scripts fáceis de vários pacotes em R e Python. Neste fim de semana, eu me dei a tarefa de reverter geocódigo de ~ 1 milhão de coordenadas de latitude e longitude. Eu encontrei um ótimo pacote em R chamado revgeo e pensei que seria bem fácil de implementar. Eu teria apenas que especificar o provedor e a chave da API. Google e Bing limitam o número de consultas gratuitas por dia, por isso não era uma opção viável, mas o Photon não! A única ressalva é que locais detalhados, como nomes de endereços, nem sempre estão disponíveis. Abaixo está uma amostra de como utilizar o pacote revgeo:

 biblioteca (revgeo) 
 revgeo (longitude = -77.0229529, latitude = 38.89283435, provedor = 'fóton', saída = 'frame') 

Então onde está o problema? Bem, como afirmado na página da Web Photons:

Você pode usar a API para o seu projeto, mas por favor, seja justo – o uso extensivo será limitado. Nós não garantimos a disponibilidade e o uso podem estar sujeitos a alterações no futuro.

Não tenho certeza de quantas consultas são necessárias antes que a API de Photon diminua, mas é importante estar atento a quantas solicitações enviamos ao servidor. Decidi começar com 500.000 coordenadas para reverter o geocodito, mas isso não funcionou bem. Eu corri o código e fui embora por algum tempo e quando voltei vi o afogamento tinha começado, então eu precisava ajustar o código. Além disso, R estava jogando um erro cannot allocate vector of size xx Gb , o que significa que minha memória RAM disponível foi esgotada.

Neste momento eu tive dois problemas: 1) Throttling e 2) Memory Allocation. Para o problema 1, eu precisava incorporar os tempos de inatividade no código e trabalhar com subconjuntos menores do meu dataframe já subconjunto. Para o problema 2, encontrei um thread no stackoverflow que tinha conselhos úteis:

Alocação de memória "Erro: não é possível alocar vetor de tamanho 75,1 Mb"
No decorrer da vetorização de algum código de simulação, encontrei um problema de memória. Estou usando o 32 bit R versão 2.15.0 (via… stackoverflow.com

Uma solução que me ajudou foi executar memory.limit(size = _ _ _ _ _ _) . Além disso, usei o comando rm() para remover qualquer quadro de dados que não fosse mais necessário em meu código e o comando gc() para coleta de lixo. Mostrado abaixo, eu carreguei o dataframe com ~ 1 milhão de coordenadas chamado main . Eu subdividi os dados para apenas 100.000 linhas. Como você verá mais adiante, eu subdividirei os dados ainda mais em um loop while para evitar problemas de alocação de memória.

 biblioteca (revgeo) 
 # o dataframe chamado 'main' é onde os 1 milhão de pontos de coordenadas residem. 
 main <- readRDS ("main.rds")) 
 main_sub <- main [0: 100000,] # Trabalhando com um subconjunto inicial menor 
 rm (principal) 
gc ()

Abaixo está o código completo. O script incorpora outras ações não relacionadas a esse assunto de postagens, mas eu gostaria de publicá-lo aqui para que você possa ver toda a imagem e, esperamos, tirar algumas dicas úteis em geocodificação reversa.

 # Etapa 1: crie um dataframe em branco para armazenar os resultados. 
data_all = data.frame ()
 start <- Sys.time () 
 # Etapa 2: crie um loop while para que a função seja executada até que o # dataframe com 100.000 linhas esteja vazio. 
while (nrow (main_sub)> 0) {
 Etapa 3: Subconjunto os dados ainda mais para que você esteja enviando apenas uma pequena porção de solicitações para o servidor Photon. 
 main_sub_t <- main_sub [1: 200,] 
 Etapa 4: Extrair os lat / longs dos dados subconjuntos de 
# o passo anterior (Passo 3).
 latlong <- main_sub_t%>% 
selecione (latitude, longitude)%>%
unique ()%>%
mutate (index = row_number ())


Etapa 5: Incorporar o pacote revgeo aqui. Eu deixei_jeitar o
# output com o dataframe de latlong da etapa anterior para adicionar
# as informações de latitude / longitude com os dados geocodificados reversos.
 cidades <- revgeo (latlong $ longitude, latlong $ latitude, provider = 'fóton', saída = 'frame'))%>% 
mutate (index = row_number (), country = as.character (country))%>%
filter (country == 'Estados Unidos da América')%>%
mutate (location = paste (cidade, estado, sep = ","))%>%
selecione (índice, localização)%>%
left_join (latlong, by = "index")%>%
select (-index)

# Removendo o dataframe de latlong porque não preciso mais dele. este
# ajuda a reduzir a memória no meu ambiente global.
rm (latlong)


# Etapa 6: Adicionando as informações do dataframe da cidade para
# main_sub_t dataframe (da etapa 3).

data_new <- main_sub_t%>%
left_join (cidades, por = c ("latitude", "longitude"))%>%
selecione (X, texto, localização, latitude, longitude)

# Etapa 7: Adicionando data_new ao dataframe data_all vazio
# todos os dados geocodificados reversos com subconjunto serão combinados.

data_all <- rbind (data_all, data_new)%>%
na.omit ()

Etapa 8: Remova as linhas que foram usadas no primeiro loop do quadro # main_sub para que as próximas 200 linhas possam ser lidas no laço # while.

main_sub <- anti_join (main_sub, main_sub_t, por = c ("X"))
print (nrow (main_sub))

# Remova os quadros de dados que não são necessários antes que o loop while feche # para liberar espaço.
rm (data_sub_t)
rm (data_new)
rm (latlong_1)
rm (cidades)

print ('Dormir por 10 segundos')
Sys.sleep (10)

}
end <- Sys.time ()

Depois de implementar esse código, demorou cerca de 4 horas para reverter geocódigo 100.000 coordenadas. Na minha opinião, essa não é uma opção viável se eu tiver 1 milhão de coordenadas para converter. Talvez eu tenha que encontrar outro método para atingir meu objetivo, mas imaginei que isso seria útil para alguns de vocês que têm conjuntos de dados menores.

Obrigado pela leitura e feliz codificação!