Geolocation API

Debido al maravilloso mundo de la movilidad, HTML 5 no pod铆a privarse de facilitar a los desarrolladores una API para poder geolocalizar a los usuarios de su aplicaci贸n web. Lo que realmente es de agradecer es la facilidad con la que podemos solicitar esta informaci贸n al usuario 馃榾
En este punto cabe remarcar que todas aquellas APIs que necesiten interactuar con cualquier tipo de hardware de nuestro dispositivo necesitar谩 previa autorizaci贸n con el objetivo de reforzar la seguridad y el derecho a la privacidad del individuo.

Recuperando la geolocalizaci贸n

Antes de obtener la informaci贸n es necesario saber que la misma puede ser proporcionada desde distintos mecanismos, lo que se conoce como location providers. Los proveedores m谩s comunes son el GPS y la IP. Los navegadores son los encargados de facilitar estos mecanismos de manera transparente para nosotros, teniendo uno de ellos por defecto. Por el momento no es posible elegir cu谩l de ellos utilizar en cada ocasi贸n y queda a manos de los desarrolladores de cada plataforma determinar cu谩l se usar谩. Normalmente en los dispositivos m贸viles el navegador tiene por defecto el uso del GPS y, para el resto, haremos uso de la direcci贸n IP para determinar esta localizaci贸n. El navegador llamar谩 al proveedor que le facilita la informaci贸n y la compartir谩 a trav茅s de la petici贸n del sitio web. Podemos comprobar el resultado a trav茅s de este sencillo ejemplo:

Al hacer clic sobre el bot贸n se solicitar谩 autorizaci贸n para recuperar la informaci贸n y acto seguido se nos mostrar谩n los valores. Algunos de ellos podr铆an no estar disponibles, dependiendo del navegador y dispositivo con el que hayamos ejecutado la prueba. En el caso de que la informaci贸n haya sido recogida a trav茅s del GPS obtendremos m谩s informaci贸n que por IP.

function log(msg) {

    var result = document.getElementById("result");
    result.innerHTML += "<li>" + msg + "</li>";
}

window.onload = function() {

    if (navigator.geolocation) {
        var btnPosition = document.getElementById("btnPosition");

        btnPosition.addEventListener("click", function() {

            navigator.geolocation.getCurrentPosition(function(data) {
                var coordinates = data.coords;

                console.log(coordinates);

                log("Accuracy: " + coordinates.accuracy);
                log("Altitude: " + coordinates.altitude);
                log("Altitude Accuracy: " + coordinates.altitudeAccuracy);
                log("Heading: " + coordinates.heading);
                log("Latitude: " + coordinates.latitude);
                log("Longitude: " + coordinates.longitude);
                log("Speed: " + coordinates.speed);

            }, function(error) {
                var code = error.code;

                switch(code){
                    case 0:
                        log("Error: Unknown error");
                        break;
                    case 1:
                        log("Error: Permission denied");
                        break;
                    case 2:
                        log("Error: Position unavailable");
                        break;
                    case 3:
                        log("Error: Time out!");
                }
            });
        });
    }
};鈥

La primera funci贸n que aperece en nuestro c贸digo solamente se utiliza para mostrar el resultado en un listado. Dentro del evento window.onload lo primero que debemos comprobar es si esta API est谩 disponible para nuestro navegador a trav茅s de navigator.geolocation. Una vez comprobado, podremos asignar al evento clic del bot贸n un manejador donde llamaremos a navigator.geolocation.getCurrentPosition, la cual recibe una funci贸n para recuperar la informaci贸n en el caso de 茅xito y una segunda (opcional) para poder controlar los posibles errores durante la petici贸n. Los valores que podemos obtener son siguientes:

  • Accuracy: Se trata del nivel de precisi贸n de la latitud y longitud. Se especifica en metros.
  • Altitude: Nos indica la altura de la posici贸n y s贸lo es proporcionada a trav茅s del GPS como mecanismo de geolocalizaci贸n
  • Altitude Accuracy: En este caso se nos proporciona la precisi贸n en metros de la altitud, en el caso de tener este valor.
  • Heading: En grados tambi茅n se nos proporciona la direcci贸n a la que apunta el dispositivo.
  • Latitude y Longitude: Se muestran en grados decimales.
  • Speed: Aunque parece incre铆ble tambi茅n se podr谩 conocer la velocidad. Deber谩 devolver los metros por segundo.

Vigilar la posici贸n del usuario

Otra alternativa a getCurrentPosition es la posibilidad de vigilar la posici贸n del usuario. Para ello esta API nos facilita adem谩s otra funci贸n llamada watchPosition, la cual tiene como par谩metros los mismos que getCurrentPosition pero la diferencia est谩 en que esta funci贸n llamar谩 a sus callbacks repetidas veces permitiendo de este modo actualizar la informaci贸n si el usuario se ha movido o si la precisi贸n de los datos ha variado. La forma de invocarla es exactamente igual:

function log(msg) {

    var result = document.getElementById("result");
    result.innerHTML += "<li>" + msg + "</li>";
}

window.onload = function() {

    if (navigator.geolocation) {
        var btnWatchPosition = document.getElementById("btnWatchPosition"),
            btnStop = document.getElementById("btnStop"),
            watchID;

        btnWatchPosition.addEventListener("click", function() {

            watchID = navigator.geolocation.watchPosition(function(data) {
                var coordinates = data.coords;

                log("Watching your position");

                log("Accuracy: " + coordinates.accuracy);
                log("Altitude: " + coordinates.altitude);
                log("Altitude Accuracy: " + coordinates.altitudeAccuracy);
                log("Heading: " + coordinates.heading);
                log("Latitude: " + coordinates.latitude);
                log("Longitude: " + coordinates.longitude);
                log("Speed: " + coordinates.speed);

            }, function(error) {
                var code = error.code;

                switch (code) {
                case 0:
                    log("Error: Unknown error");
                    break;
                case 1:
                    log("Error: Permission denied");
                    break;
                case 2:
                    log("Error: Position unavailable");
                    break;
                case 3:
                    log("Error: Time out!");
                }
            });
        });

        btnStop.addEventListener("click", function() {
            log("Stop watching you");
            navigator.geolocation.clearWatch(watchID);
        });
    }
};鈥

En este caso debemos tener en cuenta un detalle adicional: Es posible que en alg煤n momento necesitemos parar esa petici贸n y es por ello que navigator.geolocation.watchPosition nos devuelve un ID con el que podremos parar la detecci贸n autom谩tica a trav茅s de navigator.geolocation.clearWatch(nuestroID).

Si bien hasta este punto tenemos bastante informaci贸n, es importante conocer un tercer par谩metro opcional, disponible para las dos funciones anteriores, con el que podremos afinar m谩s nuestra petici贸n. El mismo recibe un objeto donde podremos incluir los siguientes valores:

  • enableHighAccuracy: Se trata de un boolean donde podemos habilitar una precisi贸n m谩s alta. Por motivos obvios en algunas ocasiones no tendr谩 efecto alguno pero si que es importante saber que puede perjudicar al estado de la bater铆a del dispositivo. El valor por defecto es false.
  • maximumAge: Podemos establecer el tiempo de expiraci贸n de una localizaci贸n dada por el navegador en milisegundos. El navegador podr铆a cachear la informaci贸n para mejorar el rendimiento pero es posible controlarlo a trav茅s de esta propiedad. Su valor por defecto es cero, con lo que nunca se cachear谩 la informaci贸n.
  • timeout: Cuando lanzamos la petici贸n el tiempo de espera deber铆a de ser controlado. A trav茅s de esta propiedad podemos establecerlo en milisegundos. Por defecto es infinito.

Desde mi punto de vista personal, si bien es cierto que esta API puede mejorar la experiencia del usuario en nuestro sitio, deber铆amos tener una alternativa en el caso de que la posici贸n no est茅 disponible por diversos motivos: El usuario est谩 buscando informaci贸n de otra zona, no permite la geolocalizaci贸n, han ocurrido varios timeouts, etc茅tera.

Espero que sea de utilidad 馃榾

隆Saludos!