Cómo saber la ubicación de un usuario

Más de alguna vez nos hemos topado con la situación en la que necesitamos saber desde que parte del mundo nos está visitando un usuario, y en base a eso mostrar o no cierto contenido. Acá veremos que opciones hay para determinar la ubicación de un visitante.

La forma tradicional: según la dirección IP

De hecho, hasta hace un tiempo esta era la única forma de saber la procedencia de un visitante: tomar la dirección IP (pública) desde la cual recibimos la petición y compararla con una base de datos de IPs con sus posibles localizaciones. Para determinar la IP desde la cual nos visita el usuario, desde de php sería:

$ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) 
    ? $_SERVER['HTTP_X_FORWARDED_FOR'] 
    : $_SERVER['REMOTE_ADDR'];

Esta ip no representa el nodo real desde el cual nos visitan, pero usualmente es una buena aproximación del origen del usuario.

Existen varias bases de datos dedicadas a recopilar este tipo de información, quizás la más popular sea la versión gratuita de IPligence (mientras no se use para fines comerciales y se les dé el crédito). Esta versión incluye 150,000 referencias por país, Microsiervos hizo un experimento en el que determinaron que es 95% exacta.

Hay que tener en cuenta que IPligence te da su base de datos en formato CSV y con las IP’s convertidas a número enteros, pero ellos explican como hacer la conversión de IPs y como cargar estos datos hacia un gestor de base de datos.

Otra opción son los datos de Hostip, un proyecto abierto que con ayuda de la comunidad y algunos ISPs ha ido recolectando sus datos. Puedes descargar la base de datos de IP’s, o usar su API incluso.

Deja que el mismo usuario te diga con HTML5

Una de las nuevas funcionalidades de HTML5, es la posibilidad de saber la ubicación del usuario (una vez este lo autorice). Obviamente los navegadores aún tienen que implementar la especificación de Geolocalización del W3C, que hasta el momento Firefox 3.5, el iPhone OS, Android y Google Chrome, entre otros, ya ofrecen esta opción.

Si nos basamos en la especificación del W3C, para detectar la ubicación del usuario es bastante sencillo:

if (typeof navigator.geolocation == 'object'){
    navigator.geolocation.getCurrentPosition(mostrar_ubicacion);
}

function mostrar_ubicacion(p)
{
    alert('posición: '+p.coords.latitude+','+p.coords.longitude );
}

La exactitud dependerá del agente con el cual se intente detectar la ubicación, los móviles que cuentan con GPS obviamente serán mucho más exactos que si se usan las redes WIFI cercanas para adivinar la ubicación.

Tal vez convenga usar geo-location-javascript, un framework que agrupa varias propuestas de Geolocalización (aparte de la del W3C) en un solo lugar. Usarlo es igual de sencillo:

if(geo_position_js.init()){
   geo_position_js.getCurrentPosition(success_callback,error_callback);
}
else{
   alert("Functionality not available");
}

function success_callback() {...}
function error_callback() {...}

Hice un pequeño ejemplo usando este framework para que lo prueben en su navegador. Para ver como funciona, solo vean el código fuente o bien pueden bajarlo desde github ;)

Base de datos de IP’s vs HTML5

Usar una base de datos de IP’s tiene la ventaja que todo funciona detrás, el usuario no debe autorizar el compartir su ubicación ni debe usar un navegador moderno; lo malo que estos datos son precisos solo a nivel de país y si el hardware del usuario ya cuenta con un GPS no lo estamos aprovechando. Dependiendo de lo que queramos hacer, probablemente el mejor enfoque sea usar una base de datos de IP’s sencilla y a la vez preguntarle al usuario que nos comparta su ubicación.

Javier Aroche
Coordinador tecnológico de Maestros del Web. Desarrollador Web y de Software, promotor del movimiento Open Source.
Eigiem
5/02/2010

Un artículo muy interesante :)

El problema X-Forwarded-For es que no es un estandar y que el IP enviado a través de la cabezera, que no siempre se envía, puede ser falsificada por el cliente HTTP. Se puede ver más info aquí http://microuri.com/vo

Creo que sí es una opción pagar por uno de esos servicios pagos, pero ahora se me ocurre una opción que puede funcionar.

Hay servicios en internet que le pasas el IP y te devuelven la latitud y longitud (si no los hay, creo que no es dificil hacerlo), luego usando el api de google u otro servicio, con la longitud y la latitud se podria obtener la localidad… Realmente no sé si sería posible, pero es lo que se me ocurre, luego investigaré.

Buen artículo.

    @David, si lo del Reverse Geocoding con Google Maps funciona bien a nivel de ciudad; para más exactitud dependería del país pues al menos para Guatemala, los nombres son incorrectos.

    Lo malo que también estarías haciendo dos consultas externas, no deberías hacerlas para todas las páginas generadas.

    Hola Javier y David. A mi gusto lo mejor es usar un servicio como el que menciona David, que en teoría se mantiene actualizado. Asi lo uso yo.. en http://climaYa.com

    Con el caso de Google Reverse geocoding creo que a lo mas que te puede servir en todos los casos es a nivel pais / ciudad.. en GT así funciona. Aca otra vez dependemos que los ISP locales reporten bien sus ip’s / ciudades.

    En mi caso yo lo he usado y el mismo ISP me da 2 diferentes ciudades por ratos.. Creo que para que podamos llegar a geolocalizar all 100% deberá de ser por medio de un GPS y BD confiables, espero que pronto Google incorpore todo lo que se esta generando en MApMAker.

    saludos

este articulo me parece muy bueno , quiero aplicarlo y comprobar

Gildus
8/02/2010

Excelente uso del API del Google, gracias Javier, si es exacto o casi exacto, esto lo podriamos usar para capturar solo las coordenadas como para armar un registro de logs, accesos, y todo eso.

Excelente aporte.

Saludos
Gildus

[...] viernes! qué tal si comes algo nuevo”(La más reciente entrada de Stephanie Falla) hasta “Cómo saber la ubicación de un usuario” (por Javier [...]

7140