jueves, 28 de abril de 2016

API Geolocation con HTML y JavaScript - 2 de 2



getCurrentPosition(ubicación, error, configuración)

El tercer atributo que podemos usar en el método getCurrentPosition() es un objeto conteniendo hasta tres posibles propiedades:

  • enableHighAccuracy Esta es una propiedad booleana para informar al sistema que requerimos de la información más exacta que nos pueda ofrecer. El navegador intentará obtener esta información a través de sistemas como GPS, por ejemplo, para retornar la ubicación exacta del dispositivo. Estos son sistemas que consumen muchos recursos, por lo que su uso debería estar limitado a circunstancias muy específicas. Para evitar consumos innecesarios, el valor por defecto de esta propiedad es false (falso).
  • timeout Esta propiedad indica el tiempo máximo de espera para que la operación finalice. Si la información de la ubicación no es obtenida antes del tiempo indicado, el error TIMEOUT es retornado. Su valor es en milisegundos. 
  • maximumAge Las ubicaciones encontradas previamente son almacenadas en un caché en el sistema. Si consideramos apropiado recurrir a la información grabada en lugar de intentar obtenerla desde el sistema (para evitar consumo de recursos o para una respuesta rápida), esta propiedad puede ser declarada con un tiempo límite específico. Si la última ubicación almacenada es más vieja que el valor de este atributo entonces una nueva ubicación es solicitada al sistema. Su valor es en milisegundos.

Código 9-4. Configuración del sistema

function iniciar(){
var boton=document.getElementById('obtener');
boton.addEventListener('click', obtener, false);
}
function obtener(){
var geoconfig={
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 60000
};
navigator.geolocation.getCurrentPosition(mostrar, errores,
geoconfig);
}
function mostrar(posicion){
var ubicacion=document.getElementById('ubicacion');
var datos='';
datos+='Latitud: '+posicion.coords.latitude+'<br>';
datos+='Longitud: '+posicion.coords.longitude+'<br>';
datos+='Exactitud: '+posicion.coords.accuracy+'mts.<br>';
ubicacion.innerHTML=datos;
}
function errores(error){
alert('Error: '+error.code+' '+error.message);
}
window.addEventListener('load', iniciar, false);

El código 9-4 intentará obtener la ubicación más exacta posible del dispositivo en no más de 10 segundos, pero solo si no hay una ubicación previa en el caché capturada menos de 60 segundos atrás (si existe una ubicación previa con menos de 60 segundos de antigüedad, éste será el objeto Position retornado).
El objeto conteniendo los valores de configuración fue creado primero y luego referenciado desde el método getCurrentPosition(). Nada cambió en el resto del código. La función mostrar() mostrará la información en la pantalla independientemente de su origen (si proviene del caché o es nueva).
Conceptos básicos: Javascript provee diferentes formas de construir un objeto. Por propósitos de claridad, elegimos crear el objeto primero, almacenarlo en la variable geoconfig y luego usar esta referencia en el método getCurrentPosition().
Sin embargo, podríamos haber insertado el objeto directamente en el método como un atributo. En aplicaciones pequeñas, objetos normalmente pueden ser evitados, pero no es el caso de códigos más complejos. Para aprender más sobre objetos y programación orientada a objetos en Javascript, visite nuestro sitio web y siga los enlaces correspondientes a este capítulo.

Con el último código, podemos apreciar el propósito real de la API Geolocation y cuál fue la intención de sus desarrolladores. Las funciones más efectivas y prácticas están orientadas hacia dispositivos móviles. El valor true (verdadero) para la propiedad enableHighAccuracy, por ejemplo, le solicitará al navegador usar sistemas como GPS para obtener la ubicación más exacta posible (un sistema casi exclusivo de dispositivos móviles), y los métodos watchPosition() y clearWatch(), que veremos a continuación, trabajan sobre ubicaciones actualizadas constantemente, algo solo posible, por supuesto, cuando el dispositivo que está accediendo la aplicación es móvil (y se está moviendo). Esto trae a la luz dos asuntos importantes. Primero, la mayoría de nuestros códigos tendrán que ser probados en un dispositivo móvil para saber exactamente cómo trabajan en una situación real. Y segundo, deberemos ser responsables con el uso de esta API. 
GPS y otros sistemas de localización consumen muchos recursos y en la mayoría de los casos pueden acabar pronto con la batería del dispositivo si no somos cautelosos. Con respecto al primer punto, disponemos de una alternativa. Simplemente visite el enlace dev.w3.org/geo/api/test-suite/ y lea acerca de cómo experimentar y probar Geolocation API. Con respecto al segundo punto, solo un consejo: configure la propiedad enableHighAccuracy como true solo cuando es estrictamente necesario, y no abuse de esta posibilidad.


watchPosition(ubicación, error, configuración)

Similar a getCurrentPosition(), el método watchPosition() recibe tres atributos y realiza la misma tarea: obtener la ubicación del dispositivo que está accediendo a la aplicación. La única diferencia es que el primero realiza una única operación, mientras que watchPosition() ofrece nuevos datos cada vez que la ubicación cambia. Este método vigilará todo el tiempo la ubicación y enviará información a la función correspondiente cuando se detecte una nueva ubicación, a menos que cancelemos el proceso con el método clearWatch().
Este es un ejemplo de cómo implementar el método watchPosition() basado en códigos previos:

Código 9-5. Probando el método watchPosition().

function iniciar(){
var boton=document.getElementById('obtener');
boton.addEventListener('click', obtener, false);
}
function obtener(){
var geoconfig={
enableHighAccuracy: true,
maximumAge: 60000
};
control=navigator.geolocation.watchPosition(mostrar, errores,
geoconfig);
}
function mostrar(posicion){
var ubicacion=document.getElementById('ubicacion');
var datos='';
datos+='Latitud: '+posicion.coords.latitude+'<br>';
datos+='Longitud: '+posicion.coords.longitude+'<br>';
datos+='Exactitud: '+posicion.coords.accuracy+'mts.<br>';
ubicacion.innerHTML=datos;
}
function errores(error){
alert('Error: '+error.code+' '+error.message);
}
window.addEventListener('load', iniciar, false);

No notará ningún cambio en un ordenador de escritorio usando este código, pero en un dispositivo móvil nueva información será mostrada cada vez que haya una modificación en la ubicación del dispositivo. El atributo maximumAge determina qué tan seguido la información será enviada a la función mostrar(). Si la nueva ubicación es obtenida 60 segundos (60000 milisegundos) luego de la anterior, entonces será mostrada, en caso contrario la función mostrar() no será llamada.
Note que el valor retornado por el método watchPosition() fue almacenado en la variable control. Esta variable es como un identificador de la operación. Si más adelante queremos cancelar el proceso de vigilancia, solo debemos ejecutar la línea clearWatch(control) y watchPosition() dejará de actualizar la información. 
Si ejecuta este código en un ordenador de escritorio, el método watchPosition() funcionará como el anterior estudiado getCurrentPosition(); la información no será actualizada. La función mostrar() es solo llamada cuando la ubicación cambia. 


Usos prácticos con Google Maps

Hasta el momento hemos mostrado la información sobre la ubicación exactamente como la recibimos. Sin embargo, estos valores normalmente no significan nada para la gente común. La mayoría de nosotros no podemos inmediatamente decir cuál es nuestra actual ubicación en valores de latitud y longitud, y mucho menos identificar a partir de estos valores una ubicación en el mundo. Disponemos de dos alternativas: usar esta información internamente para calcular posiciones, distancias y otros valores que nos permitirán ofrecer resultados específicos a nuestros usuarios (como productos o servicios en el área), o podemos ofrecer la información obtenida por medio de la API Geolocation en un medio mucho más comprensible. ¿Y qué más comprensible que un mapa para representar una ubicación geográfica?
Más atrás en esta serie de publicaciones hablamos acerca de la API Google Maps. Esta es una API Javascript externa, provista por Google, que nada tiene que ver con HTML5 pero es incluida extraoficialmente dentro de la especificación y es ampliamente utilizada en sitios webs modernos estos días. Ofrece una variedad de alternativas para trabajar con mapas interactivos e incluso vistas reales de lugares muy específicos a través de la tecnología StreetView.
Vamos a mostrar un ejemplo simple de utilización aprovechando una parte de la API llamada Static Maps API. Con esta API específica, solo necesitamos construir una URL con la información de la ubicación para obtener en respuesta la imagen de un mapa con el área seleccionada.

Código 9-6. Representando la ubicación en un mapa.

function iniciar(){
var boton=document.getElementById('obtener');
boton.addEventListener('click', obtener, false);
}
function obtener(){
navigator.geolocation.getCurrentPosition(mostrar, errores);
}
function mostrar(posicion){
var ubicacion=document.getElementById('ubicacion');
var mapurl='http://maps.google.com/maps/api/staticmap?center='+
posicion.coords.latitude+','+posicion.coords.longitude+'&zoom=
12&size=400x400&sensor=false&markers='+posicion.coords.latitude+
','+posicion.coords.longitude;
ubicacion.innerHTML='<img src="'+mapurl+'">';
}
function errores(error){
alert('Error: '+error.code+' '+error.message);
}
window.addEventListener('load', iniciar, false);

El código es simple. Usamos el método getCurrentPosition() y enviamos la información a la función mostrar() como siempre, pero ahora en esta función los valores del objeto Position son agregados a una URL de Google y luego la dirección obtenida es insertada como la fuente de un elemento <img> para mostrar el mapa en pantalla. 
Hágalo usted mismo: Pruebe el código 9-6 en su navegador usando la plantilla del Código 9-1. Cambie los valores de los atributos zoom y size en la URL para modificar el mapa retornado por la API. Visite la página de Google Maps API para estudiar las diferentes alternativas provistas por esta API: code.google.com/apis/maps/.


Referencia rápida

Determinar la ubicación física del usuario se ha vuelto crítico en aplicaciones web modernas. El reciente éxito de los dispositivos móviles ofrece nuevas posibilidades para crear aplicaciones que aprovechan esta información.

Métodos

La API Geolocation provee tres métodos para obtener la ubicación de un dispositivo: 

  • getCurrentPosition(ubicación, error, configuración) Este método retorna información sobre la ubicación del dispositivo que está accediendo a la aplicación. El primer atributo es una función destinada a procesar la información, el segundo atributo es otra función para procesamiento de errores, y el tercer atributo es un objeto con valores de configuración (vea Objeto Configuración debajo).
  • watchPosition(ubicación, error, configuración) Este método retorna información sobre la ubicación del dispositivo que está accediendo a la aplicación cada vez que la ubicación cambia. El primer atributo es una función destinada a procesar la información, el segundo atributo es otra función para procesamiento de errores, y el tercer atributo es un objeto con valores de configuración (vea Objeto Configuración debajo).
  • clearWatch(id) Este método cancela el proceso que ha sido empezado por el método watchPosition(). El atributo id es el valor de identificación retornado por el método watchPosition() cuando es llamado.

Objetos

Los métodos getCurrentPosition() y watchPosition() generan dos objetos para comunicar la información retornada por el sistema de ubicación y el estado de la operación. 


  • Objeto Position Este objeto es generado para contener la información acerca de la ubicación detectada. Tiene dos atributos: coords y timestamp. 
    • coords Este es un atributo del objeto Position. Tiene siete atributos internos para retornar la información de la ubicación: latitude (latitud), longitude (longitud), altitude (altitud en metros), accuracy (exactitud en metros), altitudeAccuracy (exactitud de la altitud en metros), heading (dirección en grados) y speed (velocidad en metros por segundo).
    • timestamp Este es un atributo del objeto Position. Retorna el momento en el que la ubicación fue detectada.
  • Objeto PositionError Este objeto es generado cuando un error ocurre. Ofrece dos atributos generales con el valor y el mensaje del error, y tres valores específicos para identificación de errores individuales (listados debajo).
    • message Este es un atributo del objeto PositionError. Retorna un mensaje describiendo el error detectado.
    • error Este es un atributo del objeto PositionError. Contiene el valor del error detectado. Los posibles valores son listados debajo:
      • PERMISSION_DENIED (permiso denegado) - valor 1 en el atributo error. Esta constante es true (verdadero) cuando el usuario no permite a la aplicación acceder a la información sobre su ubicación.
      • POSITION_UNAVAILABLE (ubicación no disponible) - valor 2 en el atributo error. Esta constante es true (verdadero) cuando la ubicación del dispositivo no puede ser determinada.
      • TIMEOUT (tiempo excedido) - valor 3 en el atributo error. Esta constante es true (verdadero) cuando la ubicación no puede ser determinada antes del periodo de tiempo declarado en la configuración.
El siguiente objeto es requerido por los métodos getCurrentPosition() y watchPosition() para propósitos de configuración.

  • Objeto Configuración Este objeto provee valores de configuración correspondientes para los métodos getCurrentPosition() y watchPosition().
    • enableHighAccuracy Esta es una de las posibles propiedades del Objeto Configuración. Si es declarada como true (verdadero), le solicitará al navegador obtener la ubicación más precisa posible.
    • timeout Esta es una de las propiedades del Objeto Configuración. Indica el máximo tiempo disponible que tiene la operación para realizarse.
    • maximumAge Esta es una de las propiedades del Objeto Configuración. Indica por cuánto tiempo la última ubicación detectada será válida.


Espero haber ayudado en algo. Hasta la próxima oportunidad!











  

No hay comentarios:

Publicar un comentario en la entrada