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.

Introducción al AJAX con Mootools 1.2.1

Introducción.

De vuelta a Mootools, fue el primero de los frameworks de Javascript que utilicé hace un poco mas de un año.  Después he experimentado un poco mas con Prototype/Scriptaculous y ahora estoy empezando a leer un poco acerca de jQuery.  Sin embargo siempre me ha gustado Mootools y es hora de documentar, tal y como se hizo con Prototype, como se realizan los llamados asíncronos (AJAX) con él.

En este artículo voy a describir las cuatro maneras como es posible realizar llamados con AJAX utilizando MooTools.

  1. El método load de los elementos.
  2. El método Request.HTML.
  3. El objeto Request directamente.
  4. El método Request.JSON.

1. El método load de los elementos.

Este método lo tienen los elementos (componentes) de Mootools.  Es muy útil porque permite actualizar rápidamente cualquier elemento con el contenido HTML retornado por un llamado asíncrono.  A pesar de ser muy fácil de utilizar, carece de las opciones y la flexibilidad de los métodos siguientes, por ejemplo, del paso de parámetros.

Para hacer uso de este método se utiliza la siguiente instrucción.

$('componente').load(urlRemota);

Donde componente es el elemento que se desea actualizar (un div por ejemplo) y urlRemota es el URL que se invoca de manera asíncrona para obtener el código HTML con el que se reemplazará el contenido del elemento.

Para más información acerca de este método consultar la documentación de Request.HTML.

2. El método Request.HTML.

Este método es una facilidad implementada sobre el método analizado a continuación.  Permite obtener el mismo objetivo del método anterior con una mayor flexibilidad.

    var myHTMLRequest = new Request
        .HTML({
            url:       urlRemota,
            update:    'componente',
            method:    'post',
            data:      $('formulario'),

            onRequest: function()
            {
                // Al iniciar la solicitud.
            },

            onComplete: function(html)
            {
                // Al completarse la solicitud.
            },

            onSuccess: function(responseTree, responseElements, responseHTML, responseJavaScript)
            {
                // Si la solicitud se completó exitosamente.

                /*
                   responseTree - (element) The node list of the remote response.
                   responseElements - (array) An array containing all elements of the remote response.
                   responseHTML - (string) The content of the remote response.
                   responseJavaScript - (string) The portion of JavaScript from the remote response.
                */
            },

            onFailure: function(elemento)
            {
                // Si la solicitud se completó con problemas.
            }
        })
        .send();

De manera similar al método anterior, el atributo url define el URL que se invocará para obtener de manera asíncrona el código HTML para actualizar el elemento referenciado por el atributo update.  El atributo method define si se utilizará POST o GET para la invocación del llamado.

El resto de atributos son opcionales.   El atributo data permite especificar variables que van a ser incluídas con el requerimiento.  Pueden especificarse como un query string de la forma “var1=valor1&var2=valor2”, como un hash de la forma {“var1”: “valor1”, “var2”: “valor2”} o enviando un formulario por completo de la forma $(‘id_formulario’).

Los atributos onXXX son manejadores de eventos a manera de callbacks y son ejecutados según lo que acontezca durante la solicitud del llamado asíncrono.

  • onRequest: ha sido iniciado el proceso de la solicitud.
  • onComplete: la solicitud ha terminado.
  • onSuccess: la solicitud ya ha terminado y terminó exitosamente.
  • onFailure: la solicitud ya ha terminado y terminó de manera fallida.

Para más información acerca de este método consultar la documentación de Request.HTML.

3. El objeto Request directamente.

Esta es la forma mas flexible de utilizar AJAX con MooTools ya que permite realizar la solicitud y manipular que se desea hacer con el resultado obtenido, ya no necesariamente actualizar un elemento.

    var myRequest = new Request({
        url:    urlRemota,
        method: 'post',
        data:   $('formulario'),

        onRequest: function()
        {
            // Al iniciar la solicitud.
        },

        onComplete: function(html)
        {
            // Al completarse la solicitud.
        },

        onSuccess: function(responseText, responseXML)
        {
            // Si la solicitud se terminó exitosamente.

            /*
                responseText - (string) The returned text from the request.
                responseXML - (mixed) The response XML from the request.
            */

            // Aquí se implementa que hacer con la respuesta del llamado asíncrono
            // cuando el procedimiento fue exitoso.

            /*
                Actualizando manualmente el componente,
                reproduce la funcionalidad de Request.HTML:

                $('componente').set('html', responseText);
            */
        },

        onFailure: function(xhr)
        {
            // Si la solicitud se completó con problemas.

            /*
                xhr - (XMLHttpRequest) The transport instance.
            */

            // Aquí se implementa que hacer con la respuesta del llamado asíncrono
            // cuando el procedimiento fue fallido.
        },

        onCancel: function()
        {
            // La solicitud fue cancelada.
        },

        onException: function(headerName, value)
        {
            // La transmisión de la cabecerá falló.

            /*
                headerName - (string) The name of the failing header.
                value - (string) The value of the failing header.
            */
        }
    }).send();

Se incluyen dos manejadores de eventos adicionales.

  • onCancel: la solicitud ha sido cancelada.
  • onException: la transmisión de la cabecera (header) provocó una excepción.

Se incluyen además, entre otras cosas, la propiedad running que permite verificar si el objeto myRequest se encuentra o no actualmente procesando una solicitud y al método cancel() que permite cancelar la solicitud activa, generando consecuentemente un evento de cancelación (ver onCancel).

Para más información acerca de este método consultar la documentación de Request.

4. El método Request.JSON.

Es una facilidad construída sobre el objeto Request que permite manipular respuestas de llamadas asíncronas en formato JSON (Javascript Object Notation).

    var jsonRequest = new Request.JSON({
        url:    urlRemota,
        method: 'post',
        data:   $('formulario'),

        onRequest: function()
        {
            // Al iniciar la solicitud.
        },

        onComplete: function(responseJSON)
        {
            // Al completarse la solicitud.
        },

        onSuccess: function(responseJSON, responseText)
        {
            // Si la solicitud se terminó exitosamente.

            /*
                responseJSON - (object) The JSON response object from the remote request.
                responseText - (string) The JSON response as string.
            */

            /*
                La información recibida del llamado asíncrono se puede obtener como atributos
                del objeto responseJSON, por ejemplo acceder a responseJSON.nombres
            */
        },

        onFailure: function(xhr)
        {
            // Si la solicitud se completó con problemas.

            /*
                xhr - (XMLHttpRequest) The transport instance.
            */
        }
    }).send();

Para más información acerca de este método consultar la documentación de Request.JSON.

Ejemplo funcional.

La aplicación de ejemplo obtiene información dinámica del servidor de manera asíncrona, para actualizar los campos DIV de la página utilizando cada una de las cuatro técnicas descritas en este artículo.

Para la generación de la información dinámica del lado del servidor se utilizaron dos scripts muy simples desarrollado en PHP, uno de ellos genera una cadena constante junto con la fecha actual y el otro prepara la respuesta JSON a partir de la información recibida.  Además muestra la información recibida a través del POST.  El script ContenidoRemoto.php es utilizado para los métodos 1, 2 y 3 mientras que el script Contenido RemotoJson.php es utilizado para el método 4.

Para consultar el ejemplo funcionando en el servidor de demostración se debe seguir este enlace.

Para consultar el código fuente de cada uno de los archivos que componen el ejemplo se deben seguir los enlaces dispuestos a continuación: index.php, ContenidoRemoto.php y ContenidoRemotoJson.php.

Enlaces.