Monthly Archives: September 2009

Como crear un mapa con GoogleMaps version 2, en pasos simples

Introducción.

Utilizar el API de Google Maps para crear mapas interactivos con Javascript en nuestros sitios web es muy fácil de implementar.  Este servicio ofrece dos alternativas: los Mapplets que se ejecutan de manera asíncrona, directamente en el sitio de maps.google.com y los desarrolladores sólo debemos especificar y albergar un documento XML donde se encuentra la especificación y los datos del mapa.  Por el otro lado están los mapas implementados directamente con el API de manera síncrona, se incrustan en nuestras propias páginas web y su comportamiento se define a través del Javascript que implementemos.

En otras ocasiones me he referido a los Mapplets por esto la implementación de hoy la vamos a realizar utilizando el API síncrono.

Objetivo.

El objetivo del presente artículo es el de visitar a Cuba donde ubicaremos marcadores sobre 5 ciudades de este país y asociaremos globitos con mensajes personalizados que aparecerán cuando el usuario haga clic sobre las diferentes ciudades.

Resultado final

Resultado final

Procedimiento.

Condiciones inciales.

Para el desarrollo de esta mini aplicación vamos a utilizar PHP y vanilla Javascript, es decir, no nos apoyaremos en ningún framework de Javascript adicional a lo comúnmente soportado por los navegadores web actuales.

En mi caso, mi servidor web de destino será http://demo.jorgeivanmeza.com/.  Es muy importante determinar esto para la próxima etapa, la creación de la llave del API.

Creación de la llave del API.

Acceda al siguiente enlace y cree su propia llave para el API de Google.  Es necesario especificar el dominio bajo el cual se ejecutará la aplicación web.  En el caso de desarrollar la aplicación de manera local, puede obtener una llave para http://localhost/ y después la deberá modificar antes de desplegarla en el servidor de producción.  Si no especifica el dominio correcto, la aplicación no podrá generar el mapa.

http://code.google.com/apis/maps/signup.html

Es necesario contar con una cuenta de Google, así que de no contar con una es necesario abrirla antes de intentar crear una llave del API.

Creación de una estructura básica para la página web.

Cree el archivo simpleGoogleMaps.php (o como desee llamarlo) en una ubicación pública de su servidor web (bajo el DOCUMENT_ROOT).  Agregue siguiente contenido al archivo y guárdelo.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="Author" content="Jorge Iván Meza Martínez - http://jorgeivanmeza.com/ - jimezam@gmail.com" />
    <meta name="Description" content="Demostración Simple de Google Maps" />
    <title>Demostración Simple de Google Maps</title>
    <!-- Llave del API -->
    <!-- Estilos CSS -->
    <!-- Implementación Javascript -->
</head>
<body>
    <!-- Ubicación del mapa -->
</body>
</html>

Especificar la Llave del API.

En el contenido del archivo PHP actualice el siguiente código por la marca de Llave del API.

<script src='http://maps.google.com/maps?file=api&v=2&sensor=false&hl=es&key=XXXXX' type='text/javascript'></script>

Reemplace la cadena XXXXX por su Llave del API específica que obtuvo durante el paso anterior correspondiente.

Especificar la ubicación del mapa.

El mapa se generará en un div que determinemos dentro del body para tal fin, este puede estar integrado normalmente con el resto del diseño de la página.  En nuestro caso particular debido a su simplicidad, el contenido de la página será solamente dicho div.

Reemplace la etiqueta Ubicación del mapa con el siguiente código.

<div id='MiMapa'>Aqui viene el mapa!</div>

Es necesario identificar al div con un id único que utilizaremos posteriormente.

Actualizar el estilo del mapa.

El siguiente paso es el especificar un estilo para el div que contendrá al mapa.  Este estilo finalmente dependerá del diseño de la página.  Para este caso utilizamos CSS para definirle un alto y un ancho al mapa.

Reemplace la etiqueta Estilos CSS con el siguiente código.

<style content="text/css">
#MiMapa
{
    width: 640px;
    height: 480px;
}
</style>

Especificar la implementación Javascript.

El código faltante hace referencia a código Javascript que va a determinar el contenido y comportamiento del mapa.  Reemplace la etiqueta Implementación Javascript con el siguiente código base.

<script type='text/javascript'>
// El código de las siguiente secciones se incluye aquí ...
</script>

Preparar el mapa.

Para crear el mapa y establecer sus parámetros iniciales se realizan las siguientes acciones.

  1. Verificar que exista la compatibilidad adecuada con el navegador.
  2. Crear la instancia del mapa asociada al div especifico.
  3. Establecer la ubicación inicial del mapa.
  4. Establecer el tipo inicial del mapa.

Para hacer esto creamos al objeto mapa1 y a la función prepararMapa con el siguiente código.

/*
 * Objeto que hace referencia al mapa desplegado.
 */
var mapa1 = null;
/*
 * Establece los parámetros iniciales del mapa instanciando
 * al objeto 'mapa'.
 *
 * @param String  - Nombre del DIV que albergará al mapa.
 * @param Double  - Latitud donde se centrará el mapa.
 * @param Double  - Longitud donde se centrará el mapa.
 * @param Integer - Altura donde se centrará el mapa.
 *
 * @return el mapa en éxito, null en fracaso.
 */
function prepararMapa(div, centerLat, centerLang, centerAlt)
{
    /* Verifica que el navegador sea compatible con
       Google Maps */
    if (GBrowserIsCompatible())   // [1]
    {
        /* Crea la instancia del objeto 'mapa' asociándole
           el div correspondiente */
        mapa = new GMap2(document.getElementById(div));    // [2]
        /* Centra el mapa en la ubicacion (latitud, longitud
           y altura) especificadas */
        mapa.setCenter(new GLatLng(centerLat, centerLang), centerAlt);     // [3]
        /* Establece el tipo de mapa.  Disponibles:
               - G_NORMAL_MAP
               - G_SATELLITE_MAP
               - G_HYBRID_MAP
           Enlace: http://code.google.com/apis/maps/documentation/controls.html */
        mapa.setMapType(G_HYBRID_MAP);      // [4]
        /* Establece el comportamiento por defecto de los
           elementos del UI del mapa.
           Enlace: http://code.google.com/apis/maps/documentation/reference.html#GMap2.setUIToDefault */
        mapa.setUIToDefault();
        /* Éxito */
        return mapa;
    }
    else     /* Fracaso */
        return null;
}

Agregar un marcador.

Posteriormente implementamos la función agregarMarcador que se ocupará de agregar un marcador creado con cierta información específica al mapa.  Su código es el siguiente.

/*
 * Agrega un marcado con la información especificada
 * al mapa.
 *
 * @param GMap2   - Referencia externa al mapa.
 * @param Double  - Latitud donde se centrará el mapa.
 * @param Double  - Longitud donde se centrará el mapa.
 * @param String  - Mensaje que tendrá la burbuja asociada.
 *
 * @return void.
 */
 function agregarMarcador(mapa, latitud, longitud, mensaje)
 {
    /* Crea el punto asociado a la longitud y latitud
       especificadas. */
    var punto = new GLatLng(latitud, longitud);
    /* Crea un marcador asociado a la ubicación anterior */
    var marcador = new GMarker(punto);
    /* Establece que en el evento 'onclick' del marcador
       muestre la burbuja con el mensaje especificado */
     GEvent.addListener(marcador, "click", function()
     {
         mapa.openInfoWindowHtml(punto, mensaje);
     });
     /* Agrega el marcador recién creado al mapa */
     mapa.addOverlay(marcador);
 }

Información de las ciudades de Cuba.

Los marcadores del mapa corresponderán como se dijo anteriormente, con cinco ciudades de Cuba que se predefinieron y de las cuales se conoce su ubicación: latitud y longitud.  Su información se almacena en el arreglo puntos en el cual cada una de sus celdas corresponde con una ciudad.

/* Información para los marcadores del mapa: Ciudades de
 * Cuba. */
 var puntos = new Array(
    {
        'nombre'  : 'La habana',
        'latitud' : 23.132,
        'longitud': -82.364
    },
    {
        'nombre'  : 'Santa Clara',
        'latitud' : 22.4,
        'longitud': -79.967
    },
    {
        'nombre'  : 'Bayamo',
        'latitud' : 20.379,
        'longitud': -76.643
    },
    {
        'nombre'  : 'Las Tunas',
        'latitud' : 20.962,
        'longitud': -76.951
    },
    {
        'nombre'  : 'Manzanillo',
        'latitud' : 20.343,
        'longitud': -77.117
    }
 );

Para automatizar el proceso de agregación de los marcadores basados en la información de los puntos creamos a la función agregarMarcadores cuya misión es la de invocar repetidas veces a la función agregarMarcador.  En ella se define además el contenido del globito de cada uno de las ciudades (mensaje).

/*
 * Automatiza el agregar los marcadores basados en la
 * información del arreglo de puntos.
 *
 * @param GMap2   - Referencia externa al mapa.
 * @param Array   - Información de los marcadores a agregar.
 *
 * @return void.
 */
 function agregarMarcadores(mapa, informacion)
 {
    for(var i=0; i<informacion.length; i++)
    {
        var nombre   = puntos[i]['nombre'];
        var latitud  = puntos[i]['latitud'];
        var longitud = puntos[i]['longitud'];
        var mensaje  = "Este es <b>" + nombre + "</b>,<br /> su latitud es <b>" +
                       latitud + "</b><br /> y su longitud es <b>" + longitud + "</b>.";
        agregarMarcador(mapa, latitud, longitud, mensaje);
    }
 }

Finalmente, el programa principal.

En este fragmento del código definimos la ejecución del programa principal del mapa.  Se ejecuta tan pronto como la página se encuentra cargada (onLoad) y desarrolla las siguiente actividades.

  1. Prepara el mapa.
  2. Verifica que el mapa haya sido creado exitosamente.
  3. Agrega los marcadores sobre las ciudades especificadas.

Su código es el siguiente.

/* Inicio del programa Javascript (setup) */
window.onload = function()
{
    /* Solicita la creación del mapa especificando el DIV
       que lo albergará y la ubicación (latitud, longitud,
       altura). */
    mapa1 = prepararMapa('MiMapa', 21.4, -79.8, 7);
    if(mapa1 == null)
    {
        alert("Su navegador no incluye soporte para Google Maps!");
        return false;
    }
    /* Solicita la agregación de los marcadores de ejemplo
       especificando la referencia al mapa y el arreglo con
       la información de los puntos */
    agregarMarcadores(mapa1, puntos);
    return true;
}

Listo!

Probar la página web utilizando un navegador como Firefox.

Enlaces.

Algunas funciones del manejo de variables en PHP que acostumbro olvidar

Conversiones de tipos de datos.

  • doubleval($mixed) o floatval($mixed): convierte el valor de $mixed a su representación de punto flotante.
  • intval($mixed[, $base=10]): convierte el valor de $mixed a su representación entera en la $base especificada.
  • strval($mixed): convierte el valor de $mixed a su representación en cadena.
  • settype($mixed, $type): convierte el valor de $mixed a su correspondiente representación según el $type seleccionado.  Los $type válidos son: boolean (bool), integer (int), float, string, array, object y null.

Verificación de tipos de datos.

  • is_array($mixed): verifica si $mixed es un arreglo.
  • is_binary($mixed): verifica si $mixed es una cadena binaria nativa.
  • is_bool($mixed): verifica si $mixed es un valor booleano.
  • is_buffer($mixed): verifica si $mixed es un valor de cadena nativa binaria o Unicode.
  • is_callable($mixed): verifica si el contenido de $mixed puede invocarse como una función.
  • is_double($mixed), is_float($mixed) o is_real($mixed): verifica si $mixed es un valor real.
  • is_int($mixed), is_integer($mixed) o is_long($mixed): verifica si el contenido de $mixed es un valor entero.
  • is_null($mixed): verifica si el contenido de la variable $mixed es null.
  • is_numeric($mixed): verifica si el contenido de la variable $mixed es un número, independiente de si la variables es numérica o su representación en cadena.
  • is_object($mixed): verifica si $mixed es una instancia de una clase.
  • is_resource($mixed): verifica si $mixed es una referencia a un recurso PHP.
  • is_scalar($mixed): verifica si $mixed es un valor escalar, es decir, un entero, real, cadena o booleano.
  • is_string($mixed): verifica si $mixed es una cadena.
  • is_unicode($mixed): verifica si $mixed es una cadena Unicode.
  • gettype($mixed): obtiene el nombre del tipo de datos que representa $mixed.  Los posibles tipos de datos obtenidos son: boolean, integer, double, string, array, object, resource, NULL y unknown type.
  • get_resource_type($handle): obtiene el nombre del tipo de recurso referenciado por $handle.

Serialización de información.

  • serialize($mixed): retorna la representación serializada de $mixed.
  • unserialize($str): retorna la representación original de la variable serializada con $str.

Existencia de las variables.

  • isset($variable): verifica si la $variable ha sido definida en el contexto.
  • unset($variable): destruye la definición de la $variable en el contexto.
  • get_defined_vars(): retorna un arreglo asociativo con las variables definidas en el contexto.
  • import_request_variables($types[, $prefix]): importa las variables contenidas en GET, POST o COOKIE en el contexto actual y con el $prefix si se especificó.  Los posibles $types por ende son una cadena con las combinaciones de las letras G, P y C.

Impresión de las variables.

  • print_r($mixed[, $return]): imprime recursivamente el contenido de $mixed.  Si $return es true el resultado de la función no se imprime sino que se retorna.
  • var_dump($mixed1[, $mixed2, $mixed3, ...]): imprime recursivamente el contenido de $mixed(s) junto con su respectivo tipo de datos.
  • var_export($mixed[, $return]): imprime recursivamente la representación de la variable $mixed.  Si $return es true el resultado de la función no se imprime sino que se retorna.

Enlaces.

Probando Firebug Lite 1.2

Introducción.

Firebug es una de los mejores acompañantes del desarrollador web que conozco actualmente, tiene muchas funciones que facilitan enormemente el desarrollo y la depuración de las aplicaciones web.  En mi caso me facilita la revisión de problemas en cuanto a los CSS y la estructura del árbol DOM de la página se refiere, especialmente cuando se está manipulando dinámicamente con Javascript y AJAX.

Entre sus principales características se cuentan las siguientes.

  • Integración con Firefox.
  • Inspección y edición del árbol DOM y el HTML.
  • Edición en línea del CSS.
  • Visualización de las métricas del CSS.
  • Monitoreo de la actividad durante la carga de las páginas.
  • Depuración y perfil de los códigos Javascript.
  • Evaluación dinámica de código Javascript.
  • Mensajes de depuración.
  • Integración con múltiples complementos que aumentan su funcionalidad.

Esta herramienta, como se podría inferir de su nombre, ha sido desarrollada como un complemento de Firefox, lo cual acostumbra a no ser un problema ya que FF es el navegador preferido por muchos usuarios, especialmente desarrolladores y por mi.  El problema surge cuando debo iniciar Windows para probar los sitios con el -muy- problemático Internet Explorer que es ya conocido por su poco apego a las normas y estándares establecidos.  Repetir la frase "funciona perfecto con FF pero terrible con IE" es mucho mas común que la casi nunca mencionada versión inversa.

En algunas ocasiones he probado algunos complementos para IE que prometen funciones similares sin embargo he tenido poco éxito con ellas.  Hace poco leí que Microsoft estaba preparando un complemento propietario para su navegador y que permitiría realizar estas maravillas y hasta mas.

Mientras aparece una mejor opción descubrí que es posible utilizar una versión Lite (reducida) de Firebug incluye parte de las funcionalidades de la versión completa.  En mi opinión personal, incluye las tres características básicas que mas necesito y que me hacen terrible falta cuando utilizo el IE: Mejor visualización de errores (consola), Inspección de los objetos del DOM y la revisión de sus estilos CSS.

Formas de uso.

El método rápido.

Utilizando este método no es necesario modificar el código fuente de la página, este se actualiza de manera dinámica.  Es muy útil para utilizar el complemento sobre sitios que no estan dentro de nuestro control, sin embargo no permite iniciarlo desde la carga de la página por lo cual no alcanza a captar los mensajes y errores que esta genere antes de activarlo.

Para utilizar este método es necesario crear un favorito en la barra de Internet Explorer (o del navegador que se esté utilizando).

Favorito FirebugLite en IE8

Favorito FirebugLite en IE8

La dirección web de este favorito deberá estar apuntando a la siguiente invocación de Javascript.

javascript:var%20firebug=document.createElement('script');firebug.setAttribute('src','http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js');document.body.appendChild(firebug);(function(){if(window.firebug.version){firebug.init();}else{setTimeout(arguments.callee);}})();void(firebug);

Para utilizar el complemento simplemente será necesario presionar el botón del favorito (Firebug Lite) cuando se desee activarlo.

Método invasivo.

Para utilizar este método es necesario modificar el contenido de las páginas web, es decir, útil para depurar las páginas que uno mismo está desarrollando.  Para utilizarlo es necesario agregar la siguiente inclusión de código Javascript en la sección HEAD de la página.

<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>

De manera opcional es posible modificar el alto del panel de Firebug mediante la inclusión de la siguiente instrucción.

<script type="text/javascript">
firebug.env.height = 200;  // pixels
</script>

A partir del momento de la carga se cuenta con el acceso a la consola de Firebug Lite para esa página.

Ejemplo de Firebug Lite en una página web

Ejemplo de Firebug Lite en una página web

Inclusive es posible generar mensajes de depuración a la consola con instrucciones como la siguiente.

console.log("hola");

Conclusiones.

Firebug Lite es efectivamente una versión reducida de Firebug cuya principal ventaja es la de poder utilizarse con diferentes navegadores distintos a Firefox.

Las no muy extensas pruebas que he realizado hasta ahora me han mostrado algunas de sus limitaciones y diferencias con respecto a la versión completa, como por ejemplo cuando se inspecciona (Inspect) un objeto DOM a pesar de que si se actualizó la selección de la etiqueta en el árbol HTML, las propiedades que se estaban mostrando no se actualizaron hasta que hice clic sobre la el nodo HTML del componente.

En conclusión, la versión Lite no es tan completa ni poderosa como la versión completa por obvias razones, su forma de implementación, sin embargo es un gran alivio para quienes de vez en cuando tenemos que intentar depurar problemas en navegadores como IE que a juzgar por la precisión de sus mensajes, parece no ser amigo de los desarrolladores.

De momento el complemento Lite va en su versión 1.2 mientras que el complemento completo va en la 1.4.  Hay que estar pendientes de nuevas actualizaciones y mejoras.

Enlaces.

Controlar presentaciones con el wiimote en Windows utilizando GlovePIE

Introducción.

De manera análoga a como hace un tiempo expliqué como manipular las presentaciones de OpenOffice Impress con el wiimote desde Linux utilizando CWiid, ahora el turno es hacerlo desde Windows, en este caso la prueba la realicé utilizando Windows 7 RC1 y su funcionamiento puede ser igualmente personalizado según los requerimientos de la presentación y por ende es totalmente compatible con Microsoft PowerPoint.

Hay varias formas de implementar este tipo de solución con el wiimote para este artículo preferí la mas "universal", es decir, una en la que se utilizara el software mas difundido posible.

Al igual que con la versión de Linux lo que se busca es emular la presión de teclas específicas según el botón del control presionado.  Para este artículo se utiliza entonces GlovePie que es una herramienta muy útil que nos permite implementar lo que requerimos e incluso más aún al incluír un lenguaje elaborado para la preparación de scripts.

Implementación.

1. Descargue GlovePie de la siguiente ubicación.

http://carl.kenner.googlepages.com/glovepie_download

Para este caso se utilizó la versión 0.29.

2. Descomprima el archivo descargado y ubíquelo en su ruta destino.

3. Con un editor de texto (Bloc de notas) edite el siguiente contenido según sus necesidades.  Verifique que el archivo guardado tenga efectivamente la extensión .PIE y no la .txt que agrega automáticamente el editor de texto.  De ser así, corrija este problema antes de continuar.

PageDown = Wiimote.A
PageUp = Wiimote.B

up = Wiimote.Up
down = Wiimote.Down
left = Wiimote.Left
right = Wiimote.Right

Key.NumpadMinus = Wiimote.Minus
Key.NumpadPlus = Wiimote.Plus
Key.Home = wiimote.Home
Key.f5 = wiimote.One
Key.Esc = wiimote.Two

4. Grábelo con un nombre conocido, por ejemplo: Presentaciones.PIE y ubíquelo en una carpeta de su preferencia, que puede ser la misma <ruta>\GlovePIEXXX\WiimoteScripts.

5. Emparente su wiimote con el sistema operativo.  Para hacer esto haga click sobre el ícono de Bluetooth en su barra de tareas y elija la opción Agregar un nuevo dispositivo (Add a device).

6. Presione simultáneamente los botones 1 y 2 del wiimote para ponerlo en modo de descubrimiento.

7. En el computador seleccione el wiimote tan pronto como sea reconocido: Nintendo RVL-CNT-01.

8. Seleccione la opción de realizar el emparentamiento sin utilizar contraseña alguna (Pair without using a code).

9. Inicie GlovePIE: <ruta>\GlovePIEXXX\GlovePie.exe.

10. En GlovePIE seleccione el menú File > Open y elija el script recién creado.

11. Para verificar el script (opcional) seleccione el menú Run! > Check for errors.

12. Para ejecutar el script seleccione el menú Run! > Run!.

13. Abra una presentación y utilice el wiimote para manipularla.

Uso.

El script propuesto puede ser totalmente manipulado para ajustarse a los gustos y necesidades de la presentación, sin embargo esta es la funcionalidad básica que yo busco para realizar mis presentaciones.

  • Teclas del cursor: mover la diapositiva / opciones del menú.
  • Botón A: siguiente slide.
  • Botón B: slide anterior.
  • Botones + y -: aumentar y disminuír el acercamiento (no aplica para modo presentación -F5).
  • Botón home: ir al primer slide.
  • Botón 1: entrar en modo presentación.
  • Botón 2: salir del modo presentación / cancelar.

Enlaces.