D. P. I. I.

LOCALIZACION DE COORDENADAS CON PYTHON Y GOOGLE (Python)

Fecha de publicación: 21/03/2018
Autor: Antonio Espín Herranz

700 visitas


En este artículo técnico vamos a utilizar Python y el servicio de localización de Google para geolocalizar coordenadas de ciudades. De Python necesitaremos acceso a una url, descargar el contenido y parsear el código JSON descargado. Vamos a utilizar los módulos urllib.request y json de Python. El formato de coordenadas que queremos mostrar es el siguiente:

python,json,geolocation,googlemaps,coordenadas,maps,urlopen,urllib,request codigo, articulos, tecnicos, programacion, informatica

Antes de entrar en los detalles de la conexión y el formato json que nos devuelve Google vamos a implementar un par de clases para la gestión de las coordenadas. Las coordenadas las queremos crear a partir de dos float porque Google nos devolverá las coordenadas en dos números float: latitud y longitud, cuando la primera es positiva, tendremos latitud norte y sur en caso contrario. En cuanto a la longitud: positiva será este y negativa oeste. Ambas coordenadas las separaremos en grados, minutos y segundos. De estas transformaciones se va a encargar la clase: posicion cuyo código se muestra a continuación:

class posicion(object):
	
	def __init__(self, grado, tipo):
		if tipo == 'Lat':
			self.__dir = 'N' if grado > 0.0 else 'S'
			
		if tipo == 'Long':
			self.__dir = 'E' if grado > 0.0 else 'W'
			
		self.__g = abs(int(grado))
		parteDecimal = abs(grado - int(grado))
		minutos = parteDecimal * 60.0
		self.__m = int(minutos)
		segundos = (minutos - self.__m) * 60.0
		self.__s = int(segundos)
		
	def toDouble(self):
		val = self.__g + self.__m / 60.0 + self.__s / 3600
		val = val * -1 if self.__dir == 'S' or self.__dir == 'W' else val
		return val

	def __str__(self):
		return str(self.__g) + "º " + str(self.__m) + "'" + str(self.__s) + "\" " + self.__dir

La siguiente clase dispondrá de dos atributos de la clase anterior para representar la latitud y la longitud. Los atributos se almacenarán en una tupla. El código de la clase: coordenadasGeo se muestra a continuación:

class coordenadaGeo(object):
	
	def __init__(self, lat, lon):
		self.__pos = (posicion(lat, 'Lat'), posicion(lon, 'Long'))
				
	def latitud(self):
		return self.__pos[0]
		
	def longitud(self):
		return self.__pos[1]
		
	def __str__(self):
		return str(self.__pos[0])+ "  " + str(self.__pos[1])

Añadimos un código principal para probar la clase:

if __name__ == '__main__':
	madrid = coordenadaGeo(40.4, -3.6875)
	print('Madrid', madrid)

Por último, nos queda la tercera clase GeoLocation que simplemente tendrá un método llamado: getCoordenadas() que recibirá la ciudad que queremos localizar y además hemos añadido otro parámetro boolean para imprimir o no una traza por consola. Para localizar una ciudad utilizaremos una URL que proporciona Google para tal efecto:
http://maps.googleapis.com/maps/api/geocode/json?address="+ciudad + "&sensor=false&language=es
En el parámetro address de la URL incrustamos la ciudad a localizar, añadimos el parámetro sensor=false y el lenguaje de respuesta: es, la petición nos devuelve el siguiente código en JSON:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Madrid",
               "short_name" : "Madrid",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Madrid",
               "short_name" : "M",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Comunidad de Madrid",
               "short_name" : "Comunidad de Madrid",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "España",
               "short_name" : "ES",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Madrid, España",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 40.5638447,
                  "lng" : -3.5249115
               },
               "southwest" : {
                  "lat" : 40.3120639,
                  "lng" : -3.8341618
               }
            },
            "location" : {
               "lat" : 40.4167754,
               "lng" : -3.7037902
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.5638447,
                  "lng" : -3.5249115
               },
               "southwest" : {
                  "lat" : 40.3120639,
                  "lng" : -3.8341618
               }
            }
         },
         "place_id" : "ChIJgTwKgJcpQg0RaSKMYcHeNsQ",
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

Leer el contenido de la URL en Python es muy sencillo. Con el método urlopen del módulo urllib.request abrimos el recurso y lo podemos leer con el método read(). Una vez leído el contenido, utilizaremos el método loads del módulo json que le pasamos una cadena en formato json y lo parsea a objetos python: diccionarios y listas. Es posible, que a la hora de localizar coordenadas en google nos salten excepciones del tipo se han superado el número de peticiones o si mandamos muchas seguidas también lo suelen controlar. Para que funcione mejor hemos añadido el módulo time para utilizar el método sleep que le mandamos 0.5 segundos, para que detenga la ejecución del script durante el tiempo (en segundos) indicado en sleep. De este comportamiento se encarga la clase GeoLocation que se muestra a continuación:

import coordenadas
import json
import time
from urllib.request import urlopen

class GeoLocation(object):
	
	def getCoordenadas(self, ciudad, traza=False):
		try:			
			f = urlopen("http://maps.googleapis.com/maps/api/geocode/json?address="+ciudad + "&sensor=false&language=es")	
			contenido = f.read().decode('utf-8')
			
			if traza: print(contenido)
			dic = json.loads(contenido)
			
			if dic == None:
				return False
			
			latitud = float(dic["results"][0]['geometry']['location']['lat'])
			longitud = float(dic["results"][0]['geometry']['location']['lng'])
			
			if traza:
				print("***********************************")
				print('latitud', latitud)
				print('longitud', longitud)
				print("***********************************")
			f.close()
			
			return coordenadas.coordenadaGeo(latitud, longitud)
			
			
		except Exception as e:
			#print("ERROR:", e)
			return False
				
	

Por último, añadimos un bloque de código principal para probar la clase.

if __name__ == '__main__':
	try:
		L = ['Teruel', 'barcelona', 'paris','brasilia','oslo','benasque']
		location = GeoLocation()
		for i in L:
			coor = location.getCoordenadas(i)
			print(i, coor)
			time.sleep(0.5)
			
		
	except Exception as e:
		print('Error modulo principal:', e)

El resultado de la ejecución se muestra a continuación:

python,json,geolocation,googlemaps,coordenadas,maps,urlopen,urllib,request codigo, articulos, tecnicos, programacion, informatica

A continuación enlaces a cursos de python y un enlace para descargar el código.


Cursos recomendados:
PY01 PY02 PY03

Descarga código