Reconocimiento de la Geolocalización con Javascript en HTML 5 y Phonegap

Datos obtenidos por la geolocalización

Cuando se habla de HTML 5 de manera general, en realidad se habla de cambios y actualizaciones en los tres lenguajes que se usan para realizar un sitio web: html, css y javascript. En este caso, aunque nos referimos a una característica de HTML 5, en realidad todo tiene que ver exclusivamente con Javascript.

La geolocalización es la capacidad de los navegadores para reconocer su ubicación geográfica. Seguramente va a ser más útil cuando la estamos ocupando en un dispositivo móvil, pero también funciona en computadoras de escritorio y laptop. Sus usos son varios, como cuando entramos al sitio de nuestra cadena de cines favorita y nos muestra la información de las películas de las salas cercanas a nosotros. Se usa ampliamente en las aplicaciones deportivas como Runkeeper para trazar la ruta que corrimos, la maneja waze para indicar el camino, Uber para definir dónde se encuentra nuestro vehículo, etc.

Y aunque se puede acceder a la geolocalización desde diferentes tecnologías, en javascript es muy sencillo. O si estamos realizando una aplicación móvil con Phonegap, la API de geolocation utiliza el mismo código. Bueno, casi. Al final de este tutorial haremos los ajustes para crear nuestra aplicación con Adobe Phonegap Build. Pero la mayor parte del código se puede (y conviene) revisar primero en un navegador.




Solicitando la ubicación

En un nuevo documento de html, vamos a poner dentro de <body> una etiqueta donde vamos a atrapar la información. Por costumbre será un <div>, aunque puede ser de las glamorosas semánticas como <section> o <article>. Lo importante en este caso es el id, el cual será resultado.

<div id="resultado"></div>

Antes de que se escriba algo en esa etiqueta, es necesario solicitar la ubicación. Dentro de <head> ponemos el código de javascript. Registramos un listener para que tan pronto cargue la ventana, realice una función que llamaremos inicio().

<script>
window.addEventListener("load",inicio);
function inicio(){
}
</script>

Dentro de la función vamos a solicitar la posición actual. Javascript cuenta con una propiedad llamada geolocation, la cual está dentro del objeto navigator. A través de geolocation puedo solicitar la posición una sola vez o constantemente. Vamos a empezar con pedirla una sola vez, por lo que usaremos getCurrentPosition()

function inicio(){
 navigator.geolocation.getCurrentPosition(alExito, alError);
 }

El proceso de llamar los datos de geolocalización nos puede dar dos resultados: si la solicitud fue exitosa o si hubo un error. Estas dos funciones son los parámetros que lleva getCurrentPosition(). Aunque por el momento no vamos a indicar qué deben de realizar, es necesario declararlas, ya que de lo contrario habrá un error por no encontrarlas.

function alExito(){
}
function alError(){
}

Se recomienda revisar este código en Firefox o Safari, ya que Chrome maneja la geolocalización de manera diferente, que revisaremos más adelante. De todas formas, en los navegadores mencionados obtendremos una advertencia.

Advertencia de Firefox al solicitar la geolocalización del usuario

Siendo la ubicación del usuario una información sensible, todos los navegadores deben avisar cuando un sitio la está solicitando, para que uno decida si lo acepta o no. Si se comparte, todavía puede suceder que no haya conexión o algo más pase, con lo cual se dispara la segunda función, la del error.

Si hay un error

Dentro de los parentesis de alError() declaramos un parametro, que llamaremos error. Este cuenta con varias propiedades con las cuales se pueden detectar los errores. Dentro de la función, utilizando un bloque de switch definimos los mensajes que se lanzarán en una ventana de alerta.

function alError(error){
 switch(error.code) {
 case error.PERMISSION_DENIED:
 alert("El usuario no compartió la geolocalización");
 break;
 case error.POSITION_UNAVAILABLE:
 alert("No está disponible la información")
 break;
 case error.TIMEOUT:
 alert("Se agotó el tiempo de la petición");
 break;
 case error.UNKNOWN_ERROR:
 alert("Error desconocido");
 break;
 }
}

Vale la pena hacer prueba de estos casos. Por ejemplo, si negamos compartir la ubicación, debería de lanzar el primer mensaje.

Al recibir la información

La función de alExito() también recibe un parámetro, que es un objeto con la información. De ahí que la llamaremos info. Dentro de este objeto, hay unas propiedades que nos pueden ser útiles, como o timestamp, que es la fecha en que fue se tuvo la respuesta. También está coords, la cual a su vez cuenta con varias propiedades, como latitude, longitude, altitude. Estos valores los vamos a imprimir dentro del elemento <div>.

function alExito(info){
 resultado.innerHTML = "Latitud: " + info.coords.latitude + "<br/>Longitud: " + info.coords.longitude + "<br/>Altitud: " + info.coords.altitude + "<br/>Tiempo de la respuesta: " + info.timestamp;
 }

Al revisarlo en el navegador, debe de mostrar los datos

Datos obtenidos por la geolocalización

En el ejemplo que se está mostrando, la altitud regresa null. Esto se debe a que la petición fue por WIFI. Solamente cuando se pide por GPS es que esa propiedad obtiene valor.

Solicitando la información constantemente

Para hacer la solicitud una y otra vez, se debe realizar un sencillo cambio. Lo más elaborado es si queremos detener esa petición.

En lugar de poner getCurrentPosition(), vamos a sustituirla por watchPosition(). Este método se repite cada vez que el dispositivo cambia de posición. No está de más recordar que este acción debe probarse en un dispositivo con conexión GPS, ya que por WIFI estaría trayendo siempre la misma información.

navigator.geolocation.watchPosition(alExito, alError);

Podría ser que en algún momento ya no deseemos pedir los datos. Hasta este momento no hay forma de indicar que deje de hacerlo. La forma para detenerlo sería usando el método, clearWatch(), el cual lleva como parámetro un identificador del watcher. De la forma en que hemos escrito el código, no hay forma de reconocer la operación. Se debe vincular a una variable. Como se va a utilizar en varias funciones, vamos a declararla de manera global.

var observador;

Y le asignamos valor con la función que tenemos en inicio().

observador = navigator.geolocation.watchPosition(alExito, alError);

Ahora, con un botón en el documento, lo vamos a detener. Dentro de <body> ponemos la etiqueta <button> con el llamado a una función que se dispare al click y que la bautizaremos detener().

 <button onClick="detener()">Detener Watcher</button>

Dentro del scrip, declaramos a esta función para que realice el método clearWatch() de geolocation.

function detener(){
 navigator.geolocation.clearWatch(observador); 
}

Revisando esto desde un dispositivo, deben mostrarse los cambios en la posición. Y al apretar el botón, debe detener la petición. El documento debe estar en un servidor. Si no cuentas con uno, puedes revisar el archivo final en esta dirección.




El código final es:

<!doctype html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Geolocalizaci&oacute;n</title>
<script>
var observador;
window.addEventListener("load",inicio);
function inicio(){
 //Llamar los datos una sola vez
 //navigator.geolocation.getCurrentPosition(alExito, alError);
 //Llamar los datos una vez
 observador = navigator.geolocation.watchPosition(alExito, alError); 
}
function alExito(info){
 resultado.innerHTML = "Latitud: " + info.coords.latitude + "<br/>Longitud: " + info.coords.longitude + "<br/>Altitud: " + info.coords.altitude + "<br/>Tiempo de la respuesta: " + info.timestamp;
}
function alError(error){
 switch(error.code) {
 case error.PERMISSION_DENIED:
 alert("El usuario no compartió la geolocalización");
 break;
 case error.POSITION_UNAVAILABLE:
 alert("No está disponible la información")
 break;
 case error.TIMEOUT:
 alert("Se agotó el tiempo de la petición");
 break;
 case error.UNKNOWN_ERROR:
 alert("Error desconocido");
 break;
 }
}
function detener(){
 navigator.geolocation.clearWatch(observador); 
}
</script>
</head>
<body>
<button onClick="detener()">Detener Watcher</button>
<div id="resultado"></div>
</body>
</html>

También puedes descargar el ejercicio final.

Cambios para publicarlo en Phonegap Build

Como mencionaba, para que esta aplicación ocupe la API de Phonegap y podamos hacer nuestra aplicación móvil, es muy sencillo. Solamente se deben realizar cuatro cambios.

a) Cambiar el nombre del documento a index.html, si es que este va a ser nuestro único documento de html en la aplicación.

b) Añadir la indicación de que se va a usar la biblioteca de phonegap.js. Arriba de la etiqueta <script> que ya tenemos, añadimos otra.

<script src="phonegap.js"></script>

Vale la pena recordar que el archivo phonegap.js no existe dentro de nuestro documento, ya que se añade en la nube al compilar desde http://build.phonegap.com

c) Conviene cambiar el listener de carga de la ventana, por el de deviceready del documento.

document.addEventListener("deviceready",inicio);
//window.addEventListener("load",inicio);

d) Dentro del archivo config.xml, se debe añadir el plugin de geolocation.

<plugin name="cordova-plugin-geolocation" source="pgb" />

Los archivos finales para phonegap quedaron de la siguiente manera.

index.html

<!doctype html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Geolocalizaci&oacute;n</title>
<script src="phonegap.js"></script>
<script>
var observador;
document.addEventListener("deviceready",inicio);
//window.addEventListener("load",inicio);
function inicio(){
 //Llamar los datos una sola vez
 //navigator.geolocation.getCurrentPosition(alExito, alError);
 //Llamar los datos una vez
 observador = navigator.geolocation.watchPosition(alExito, alError); 
}
function alExito(info){
 resultado.innerHTML = "Latitud: " + info.coords.latitude + "<br/>Longitud: " + info.coords.longitude + "<br/>Altitud: " + info.coords.altitude + "<br/>Tiempo de la respuesta: " + info.timestamp;
}
function alError(error){
 switch(error.code) {
 case error.PERMISSION_DENIED:
 alert("El usuario no compartió la geolocalización");
 break;
 case error.POSITION_UNAVAILABLE:
 alert("No está disponible la información")
 break;
 case error.TIMEOUT:
 alert("Se agotó el tiempo de la petición");
 break;
 case error.UNKNOWN_ERROR:
 alert("Error desconocido");
 break;
 }
 }
 function detener(){
 navigator.geolocation.clearWatch(observador);
 }
 </script>
 </head>
<body>
 <button onClick="detener()">Detener Watcher</button>
 <div id="resultado"></div>
 </body>
 </html>

config.xml

<?xml version="1.0" encoding="UTF-8" ?>
 <widget xmlns = "http://www.w3.org/ns/widgets"
 xmlns:gap = "http://phonegap.com/ns/1.0"
 id = "mx.machschool.alexmena.cursophonegap"
 versionCode = "10" 
 version = "1.0.0" >
<!-- versionCode is optional and Android only -->
<name>Ejemplo de geolocation</name>
<description>
 Curso de Argot Training 
 </description>
<author href="https://www.argottraining.com" email="alexmenar@gmail.com">
 Alex Mena 
 </author>
<plugin name="cordova-plugin-geolocation" source="pgb" />
</widget>

Estos dos documentos son los únicos que hacen falta para crear el archivo .zip para subir al build de phonegap. O si prefieres, puedes descargarlo desde este link.

Be the first to comment

Leave a Reply

Your email address will not be published.


*