En entradas anteriores vimos como obtener las coordenadas GPS donde se tomó una fotografía por medio de la interpretación de los datos EXIF.

Sin embargo, las coordenadas 37.3861888 -5.9925535 a la mayoría de nosotros nos dicen poco. Necesitamos convertirlo a algo más familiar para saber a que lugar nos referimos, una calle, una ciudad y un país, o un monumento conocido. Algo que «traduzca» 37.3861888 -5.9925535 a «la Giralda de Sevilla«.

Siguiendo con el ejemplo, si a partir de una foto obtengo las coordenadas 37.87943195 -4.77986509433761, ¿cómo se a que lugar corresponden?

Nominatim – OpenStreetMap

Nominatim es un servicio de OpenStreetMap, por supuesto gratuito, que proporciona información a partir de coordenadas GPS o una dirección.

Nominatim tiene una cómoda e intuitiva interfaz web y como veremos a continuación, una API accesible desde Python con la que podemos integrarlo en nuestros proyectos.

En el caso de Monumentos únicamente es necesario escribir su nombre, por ejemplo, la Mezquita de Córdoba:

O la Giralda de Sevilla:

Pulsando «details» obtendremos información más detallada:

Todo esto sin duda es muy util, ahora, veamos como utilizarlo en nuestro código.

Nominatim en Python – CoordsGPS a direcciones

Instalar Geopy

Instalamos geopy, cliente Python para los servicios de geocodificación más utilizados, entre ellos OpenStreetMap:

pip3 install geopy

Codigo fuente

Incluimos la referencias a las librerias:

from geopy.geocoders import Nominatim
from geopy.exc import GeopyError

Y dos funciones:

  • get_coords(saddress) – para obtener coordenadas a partir de dirección o nombre de monumento.
  • get_address(lan, lon) – para obtener dirección a partir de coordenadas.
def get_coords(saddress):
	try:
		geolocator = Nominatim(user_agent="altaruru_testgeopy")
		location = geolocator.geocode(saddress)
		print("C# %s %s  ---> %s" % (location.latitude, location.longitude, location.address))
		#print(location.raw)
		return location.latitude, location.longitude
	except:		
		debug.print_exception()
		return None	

def get_address(lan, lon):
	try:
		geolocator = Nominatim(user_agent="altaruru_testgeopy")
		scoord = ("%s %s" % (lan, lon))
		location = geolocator.reverse(scoord)
		print("A# %s %s  ---> %s" % (location.latitude, location.longitude, location.address))
		#print(location.raw)
		return location.address
	except:		
		debug.print_exception()
		return None	

Para el control de excepciones utilizo debug.print_exception(), si te interesa mira esta entrada: control de excepciones python

Ejemplo 1

print("###")
get_address("37.3937585","-5.9976877")
get_coords("Calle Betis 18, Sevilla, Andalucía, España")
get_coords("Mezquita, Córdoba, Andalucía, España")
print("###")

Genera la salida por Terminal:

###
A# 37.3937585 -5.9976877  ---> Catedral, Calle Virgen de los Buenos Libros, San Vicente, Casco Antiguo, Sevilla, Andalucía, 41001, España
C# 37.3057938 -4.6711331  ---> Calle Betis, Barriada  Olof Palme, Badolatosa, Sevilla, Andalucía, España
C# 37.87943195 -4.77986509433761  ---> Mezquita, El Salvador y La Compañía, Santiago, Distrito Centro, Córdoba, Andalucía, España
###

Ejemplo 2

Algunos ejemplos de llamadas

get_coords("Parque de Maria Luisa, Sevilla, Andalucía, España")
get_coords("Parque de los Príncipes, Sevilla, Andalucía, España")
get_coords("Catedral, Sevilla, Andalucía, España")
get_coords("Calle Triana, Tomares, Sevilla, Andalucía, España")
get_coords("Calle Betis 54, Sevilla, Andalucía, España")
get_coords("Calle Real, San Fernando, Cadiz, Andalucía, España")
get_coords("Mezquita, Córdoba, Andalucía, España")

Y la salida:

C# 37.374771 -5.98879429509356  ---> Parque de María Luisa, El Prado-Parque de María Luisa, Distrito Sur, Sevilla, Andalucía, España
C# 37.3739359 -6.0062220330977  ---> Parque de los Príncipes, Los Remedios, Sevilla, Andalucía, España
C# 37.3937585 -5.9976877  ---> Catedral, Calle Virgen de los Buenos Libros, San Vicente, Casco Antiguo, Sevilla, Andalucía, 41001, España
C# 37.3772046 -6.0364732  ---> Calle Triana, Sport Aljarafe, Tomares, Sevilla, Andalucía, 41910, España
C# 37.3821089 -5.9988061  ---> 54, Calle Betis, Nucleo Residencial Manuel Arellano, Triana, Sevilla, Andalucía, 41010, España
C# 36.4565316 -6.2079251  ---> Calle Real, San Fernando, Cádiz, Andalucía, 11100, España
C# 37.87943195 -4.77986509433761  ---> Mezquita, El Salvador y La Compañía, Santiago, Distrito Centro, Córdoba, Andalucía, España

Ejemplo 3 – Dirección de una fotografía

Por último, veamos como recuperar el lugar donde fue tomada una fotografía.

Para ello combinamos la función get_address() de esta entrada, con la recuperación de coordenadas desde EXIF:

sfilepath="/media/lubuntu/4A5B-42E5/cmrep/201606/20160621201251_efbbd74f15d4d1b8f3ca081f8af7b7f4.jpg"
exif=get_exif(sfilepath)
datetimeimg = exif["DateTimeOriginal"]
lat,lon=get_decimal_coordinates(exif['GPSInfo'])
saddress=get_address(lat, lon)
print("#######")
print("La fotografía %s fue tomada en %s el %s" % (sfilepath, saddress, datetimeimg))
print("#######")

Salida por Terminal:

#######
La fotografía /media/lubuntu/4A5B-42E5/cmrep/201606/20160621201251_efbbd74f15d4d1b8f3ca081f8af7b7f4.jpg fue tomada en Calle Triana, Sport Aljarafe, Tomares, Sevilla, Andalucía, 41910, España el 2016:06:21 20:12:51
#######

Conclusiones

Con apenas unas lineas y gracias a las comunidades que hacen posible proyectos como OpenStreetMaps, Nominatim o Geopy es posible construir soluciones fácilmente, desde aquí mi agradecimiento y reconocimiento a su labor.

Si alguien tiene dudas, como siempre en comentarios 😉

Saludos y feliz código!