Como obter cidade usando latitude e longitude

Existem ferramentas em python para consultar um shapefile e extrair as informações catalogadas da região à qual o ponto pertence. Também é possível usar outras ferramentas para usar uma API de um servidor de mapas e fazer a conversão de uma coordenada geográfica para uma cidade/estado. Veja uma opção de cada sistema e decida qual agrada mais.

Shapegeocode

Shapfile é o formato de arquivo que contém dados geoespaciais em forma de vetor. Ele consiste de três arquivos que trabalham conjuntamente: um principal (.shp), que traz o desenho do mapa propriamente, um índice (.shx), que é um indexador de informações para facilitar buscas, e um de banco de dados (.dbf), trazendo informações e atributos das unidades espaciais (população do município, renda per capita, etc). O que liga esses três arquivos é um ID, único para cada unidade espacial, geralmente chamado de Geocódigo.

Um shapefile com os municípios do Brasil pode ser baixado gratuitamente no site do IBGE (arquivo br_municipios.zip). O código de exemplo mais abaixo está também com o código comentado usando outro shapefile.

Os scripts python podem ser baixados do GitHub/pyshpgeocode https://github.com/gka/pyshpgeocode e instalados através do seguinte comando (para o Anaconda):

python setup.py install --prefix=~/anaconda2

O código a seguir lê um arquivo de colunas fixas separadas por espaços sem um cabeçalho. Também abre um arquivo de saída para gravar um cabeçalho e as linhas geradas. Dentro de um loop para todas as linhas do arquivo de entrada, são lidos os valores de latitude, longitude e as coordenadas temporais, que montarão uma string.

# -*- coding: utf-8 -*-
# Script to convert lat/lon into Cidade-UF

import pandas as pd
import shapegeocode
import json

# Load shapefile
#gc = shapegeocode.geocoder('municipios_br/municipios_br.shp')
gc = shapegeocode.geocoder('br_municipios/BRMUE250GC_SIR.shp')

names_cols = ['year','month','day','hour','minute','second','milisecond','latitude','longitude']
df = pd.read_csv('input.dat', delim_whitespace = True, names = names_cols)

# Erase output file and write header
with open('output.csv', 'wb') as f:
	#f.write('data,horario,latitude,longitude,codigo_ibge,municipio,estado\n')
	f.write('data,horario,latitude,longitude,codigo_ibge,municipio\n')

for index, row in df.iterrows(): 
	lat = row['latitude']
	lon = row['longitude']
	time = "%d-%02d-%02d,%02d:%02d:%02d.%d" %(row['year'],row['month'],row['day'],row['hour'],row['minute'],row['second'],row['milisecond'])
	g = gc.geocode(lat,lon)
	if g is not None:
		#print lat,lon,g['CODIGO_MUN'],g['NOME_1'],g['NOMEUF']
		print lat,lon,g['CD_GEOCMU'],g['NM_MUNICIP']
		with open('raios.csv', 'a') as f:
			#f.write("%s,%f,%f,%d,%s,%s\n" %(time,float(lat),float(lon),int(g['CODIGO_MUN']),g['NOME_1'],g['NOMEUF']))
			f.write("%s,%f,%f,%d,%s\n" %(time,float(lat),float(lon),int(g['CD_GEOCMU']),g['NM_MUNICIP']))
	else:
		print "nao achou cidade",lat,lon
	#exit("fim de teste")

Caso seja encontrada uma cidade para aquela coordenada, será impressa uma linha no arquivo de saída com as informações; caso contrário, imprime as coordenadas na tela dizendo que não encontrou.

Geocoder

O Geocoder é uma biblioteca de geocodificação simples e consistente, escrita em Python. Lida com vários provedores de geocodificação diferentes, como Google, Bing, OSM (Open Street Map) e outros. Ele pode ser instalado usando o Anaconda (vide post sobre python) ou usando o pip:

# pip install future # provavelmente será necessário
# pip install geocoder

O código a seguir lê um arquivo de colunas fixas separadas por espaços sem um cabeçalho. Também abre um arquivo de saída para gravar um cabeçalho e as linhas geradas. Dentro de um loop para todas as linhas do arquivo de entrada, são lidos os valores de latitude, longitude e as coordenadas temporais, que montarão uma string.

É usada a API do OSM para obter informações do ponto. Nesse caso, faz uma requisição online para um servidor de mapas remoto, mas também pode ser local se tiver instalado o servidor de mapas. Comentado, está uma chamada para a API do Google Maps.

# -*- coding: utf-8 -*-
# Script to convert lat/lon into Cidade-UF

import geocoder
import pandas as pd
import json

names_cols = ['year','month','day','hour','minute','second','milisecond','latitude','longitude']
df = pd.read_csv('input.dat', delim_whitespace = True, names = names_cols)

# Erase output file and write header
with open('output.csv', 'wb') as f:
	f.write('data,horario,latitude,longitude,codigo_ibge,municipio,estado\n')

for index, row in df.iterrows(): 
	lat = row['latitude']
	lon = row['longitude']
	time = "%d-%02d-%02d,%02d:%02d:%02d.%d" %(row['year'],row['month'],row['day'],row['hour'],row['minute'],row['second'],row['milisecond'])
	g = geocoder.osm([lat,lon], method='reverse')
	#g = geocoder.google([latitude,longitude], method='reverse')
	if g is not None:
		print g.city.encode('utf-8'),g.state.encode('utf-8')
	else:
		print "nao achou cidade",lat,lon
	#exit("fim de teste")

Caso seja encontrada uma cidade para aquela coordenada, será impresso na tela o nome da cidade e o estado; caso contrário, imprime as coordenadas e diz que não encontrou.

Outra forma de consultar uma API do OSM é através do seguinte link de exemplo:

http://nominatim.openstreetmap.org/reverse?format=json&lat=-23&lon=-57

Ela retorna os dados no formato JSON e são informadas a latitude e a longitude do ponto.

3 comments

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.