Twitter Facebook RSS Feed

lunes, 21 de febrero de 2011 a las 10:39hs por Gustavo Cantero (The Wolf)

Quien haya desarrollado alguna aplicación web que contenga mapas utilizando la versión 2 de la API de Google Maps y haya querido migrar a la versión 3 (ya que es la versión oficial, funciona mucho mejor en dispositivos móviles y la anterior ya ha quedado oficialmente descartada), se habrá dado cuenta que no es tan sencillo como cambiar el JS a utilizar y listo, sino que cambiaron muchas cosas, por ejemplo, ahora las clases no comienzan con la letra G (como GMap) sino que utilizan el namespace google.maps (como google.maps.Map).

Este artículo tiene la idea de ser una guía básica para migrar de la versión 2 a la 3 de esta API, mostrando dónde cambiaron las cosas que comúnmente utilizamos. Para esto dividí el artículo en tareas donde muestro cómo hacerlas con ambas versiones para que sea más fácil de encontrar lo que estamos buscando.

Librería JS

Para comenzar tendremos que utilizar el JS de la nueva versión, por lo cual, donde antes apuntábamos a

http://maps.google.com/maps?file=api&v=2&key=API_KEY

ahora debemos apuntarlo a

http://maps.google.com/maps/api/js?sensor=false

Nótese que ahora no necesitamos utilizar el API_KEY, por lo tanto, ya no es necesario registrar la URL del sitio donde vamos a utilizar los mapas. También hay un nuevo parámetro llamado “sensor”, el cual establece si se debe obtener la ubicación de un usuario a través de un sensor. Para más información sobre este parámetro pueden consultar la Especificación del parámetro sensor.

Creación del mapa

Lo siguiente a modificar es la creación del mapa. Por ejemplo, en la versión 2 creábamos un mapa en el div “miMapa” de esta manera:

var mapa = new GMap2(document.getElementById('miMapa'));

ahora deberemos crearlo de esta manera:

var mapa = new google.maps.Map(document.getElementById('miMapa'));

Me gustaría comentar que en la nueva versión se puede establecer como segundo parámetro del constructor la mayoría de las opciones que veremos a continuación, permitiendo de esta manera crear el mapa de la manera que necesitamos de una vez. Para ver las distintas opciones disponibles consultar la Especificación del objeto MapOptions.

Ubicación (coordenadas) y zoom del mapa

Para centrar el mapa y hacerle zoom antes hacíamos esto:

var miPosicion = new GLatLng(latitud, longitud);
mapa.setCenter(miPosicion, nivelDeZoom);

Ahora debemos hacerlo de esta manera:

var miPosicion = new google.maps.LatLng(latitud, longitud);
mapa.setCenter(miPosicion);
mapa.setZoom(nivelDeZoom);

Si se prefiere, se pueden establecer cambiando las opciones del mapa, de esta manera:

var miPosicion = new google.maps.LatLng(latitud, longitud);
mapa.setOptions({
    center: miPosicion,
    zoom: nivelDeZoom
});

Tipo de mapa

Un punto a tener en cuenta con la nueva versión de la API es que antes, por defecto, nos mostraba el mapa del tipo “normal”, o sea, las calles sin imágenes satelitales, pero ahora si no le establecemos un tipo de mapa no nos muestra nada.
Entonces, antes para establecer el tipo de mapa (por ejemplo, satelital) hacíamos esto:

mapa.setMapType(G_SATELLITE_MAP);

Pero ahora es así:

mapa.setMapTypeId(google.maps.MapTypeId.SATELLITE);

Este valor también se puede establecer al momento de crear el mapa con la opción “mapTypeId”.
Para ver los distintos tipos de mapas posibles para la versión 3 pueden consultar la clase MapTypeId, y para los de la versión 2 pueden consultar la clase GMapType.

Controles de navegación

Antes para agregar un control de navegación, por ejemplo el control “chico”, debíamos hacer:

mapa.addControl(new GSmallMapControl());

Ahora, en cambio debemos hacerlo así:

mapa.setOptions({
    navigationControl: true,
    navigationControlOptions: { style: google.maps.NavigationControlStyle.SMALL}
});

Para ver que otros tipos de controles de navegación hay pueden consultar las constantes que hay en la clase NavigationControlStyle.

Agregar marcadores

Para crear marcadores con una imagen personalizada hasta ahora hacíamos:

var icono = new GIcon(G_DEFAULT_ICON);
icono.image = 'Images/MiImagen.png';
var marcador = new GMarker(new GLatLng(latitud, longitud), {
    icon: icono,
    title: 'Este es mi marcador'
});
mapa.addOverlay(marcador);

En cambio ahora debemos hacer:

var marcador = new google.maps.Marker({
    position: new google.maps.LatLng(latitud, longitud),
    map: mapa,
    icon: 'Images/MiImagen.png',
    title: 'Este es mi marcador'
});

Quitar marcadores

Para sacar un marcador, por ejemplo el creado en el paso anterior, en la versión 2 hacíamos:

mapa.removeOverlay(marcador);

En cambio en la versión 3 hacemos:

marcador.setMap(null);

Algo a tener en cuenta es que en la versión anterior para eliminar todo los marcadores (y demás objetos) del mapa podíamos utilizar la siguiente línea:

mapa.clearOverlays();

Pero en la versión 3 tenemos que guardar la referencia de cada marcador (por ejemplo, en un vector) para luego llamar al “setMap(null)” de cada uno.

Lanzar eventos de los marcadores

En la versión 2 de Google Maps, si queríamos lanzar el evento click de un marcador, podíamos hacer lo siguiente:

GEvent.trigger(marcador, 'click');

Esto ejecutaba las rutinas que estuvieran capturando el evento.
En la versión 3 de esta librería, para hacer lo mismo, podemos utilizar este código:

google.maps.event.trigger(marcador, 'click');

InfoWindow en un mapa

Para abrir una “viñeta” con información dentro de un mapa hacíamos:

var posicion = new GLatLng(latitud, longitud);
mapa.openInfoWindowHtml(posicion, 'Esta es mi viñeta');

En cambio ahora es:

var infoWin = new google.maps.InfoWindow({
  content: 'Esta es mi viñeta',
  position: google.maps.LatLng(latitud, longitud)
});

InfoWindow en un marcador

También podíamos abrir “viñetas” sobre un marcador de la siguiente manera:

marcador.openInfoWindowHtml('Esta es mi viñeta');

Pero ahora se hace de esta otra manera:

var infoWin = new google.maps.InfoWindow({
    content: 'Esta es mi viñeta'
});
infoWin.open(mapa, marcador);

Controles personalizados sobre el mapa

Hay veces que necesitamos crear nuestros propios controles y agregarlos sobre el mapa. Para esto la versión 2 de Google Maps nos permitía hacerlo creando una clase que debía heredar de GControl. Por ejemplo, para agregar un DIV llamado “miControl” en la esquina superior izquierda del mapa podíamos hacer esto:

function miControl() { }
miControl.prototype = new GControl();
miControl.prototype.initialize = function (map) {
    var div = document.getElementById('miControl');
    ctlMap.getContainer().appendChild(div);
    return div;
}
miControl.prototype.getDefaultPosition = function () {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(1, 1));
}

mapa.addControl(new miControl());

Pero ahora, con la versión 3 de la API, podemos hacerlo de una manera mucho más sencilla: simplemente agregando nuestro DIV a la pila de controles del mapa:

var div = document.getElementById('miControl');
mapa.controls[google.maps.ControlPosition.TOP_LEFT].push(div);

Ejemplo

Con estas pocas líneas voy a mostrar cómo hacer un mapa que se ubique en Bariloche mostrando el relieve de la región:

new google.maps.Map(document.getElementById('miMapa'), {
    center: new google.maps.LatLng(-41.156686, -71.302299),
    zoom: 10,
    mapTypeId: google.maps.MapTypeId.TERRAIN
};

Conclusión

La nueva versión de la API de Google Maps cambia muchas cosas y migrar los scripts de una versión a otra lleva tiempo, pero la nueva versión trae muchas mejoras y una vez migrado notaremos que la sintaxis es más cómoda en la nueva versión.
La referencia de la versión 2 de la API la pueden encontrar aquí y la de la versión 3 aquí. Cabe mencionar que la propia versión 3 está en continua evolución y ya va, a la fecha, por la versión 3.4. Para ver el historial de los cambios lo pueden hacer desde esta dirección: Javascript Maps API v3 Changelog.

Espero que esta nota les sea de utilidad y los invito a dejar sus comentarios.

¡Suerte!


26 comentarios »

  1. Javier Garcia dice:

    Gracias por la ayuda que he recibido con su manera sencilla y organizada para explicar los cambios para migrar de la version 2 a la 3.
    Saludos desde Toronto, Canada

  2. Javier Garcia dice:

    Nota: esto no es un comentario.
    Solamente sirve para corregir la direccion de e-mail
    del comentario anterior.

    Gracias

  3. Marcos dice:

    Gracias muy bien explicado, horas googleando y de lo mejor que encontre saludos!

  4. Cristian dice:

    Muchas gracias por el tutorial
    Muy claro, practico y fácil de seguir

    Saludos.

  5. hanibal dice:

    Bien chavon me quitaste un par de horas de googlear ,bravo !

  6. Veronica dice:

    Ola tu script me ayudo mucho , pero hay cosas que aun no lo entiendo de esto como el cambio de GEvent.addListener v2 al v3 ajajajajajaj pero aun asi muchissimas gracias por el contenido!!!

  7. Hola, primero felicitarte por la simplesa del blog abordando un tema algo complejo de manera simple. Me comunico contigo poruqe estoy diseñando un sistema el cual necesita cargar marcadores sacados de un BD dependiendo de un combobox, para el cual uso Ajax y todo bien, recoge la informacion la incluyo en el script, pero no la toma, solo trabaja la que en la primera oportunidad fur cargada. Pensaba en eliminar lo marcadores y luego cargar los nuevos, pero no lo hace y justo en tu blog aparece una pequeña reseña de como hacerlo, pero ahi esoy entrampado, no se como hacer que funcione siendo que la informacion que me llega devuelta esta correcta, si me pudiera ayudar te lo agradeceria. Gracias.

  8. Ingrid dice:

    Que tal super interesante el tutorial….mas bien justo cuando intento poner los marcadores de google maps en mi aplicacion, no me esta reconociendo mi imagen local, saben porque puede ser eso?

    var iconoMarca = new google.maps.MarkerImage(‘../../images/int.png’, new google.maps.Size(17, 17), new google.maps.Point(0,0),new google.maps.Point(11, 16));
    var imageBounds = new google.maps.LatLngBounds(new google.maps.LatLng(parseFloat(x.firstChild.data), parseFloat(y.firstChild.data)), new google.maps.LatLng(parseFloat(x.firstChild.data) + parseFloat(1000), parseFloat(y.firstChild.data) + parseFloat(1000) ));
    var oldmap = new google.maps.GroundOverlay(«../../images/int.png», imageBounds);

    oldmap.setMap(map);

  9. SENDEROPRESS dice:

    No me queda mas que felicitarte por tu trabajo, estoy peleando para poner una marca en el mapa y cuando la pongo, el bendito mapa no sale. De todos modos, seguire con tus instrucciones. Un cordial saludo

  10. Cristian dice:

    Buena hermano me ayudaste de verdad, gracias

  11. alejandro dice:

    por mas que estuve buscando y contigo lo encontre logre poner mi icono personalizado ahora solo me falta como poner varios iconos en un mismo mapa son para sucursales de una empresa

    • Alejandro: para que cada «marker» tenga un ícono distinto, simplemente usá una imagen distinta en cada uno.
      Por ejemplo:

      var marcador1 = new google.maps.Marker({
          position: new google.maps.LatLng(latitud1, longitud1),
          map: mapa,
          icon: 'Images/Sucursal1.png',
          title: 'Este es el marker de la sucursal 1'
      });
      
      var marcador2 = new google.maps.Marker({
          position: new google.maps.LatLng(latitud2, longitud2),
          map: mapa,
          icon: 'Images/Sucursal2.png',
          title: 'Este es el marker de la sucursal 2'
      });

      Suerte!

  12. camilo dice:

    je, perdonen mi ignorancia, pero es que yo no se nada de migrar ni siquiera se como hacer lo del Java Script xd yo solo queria usar el simulador de barcos «Ships» pero me pide una clave diferente por lo que quise hacer eso de migrar pero no entiendo NADA!…si alguien me diera una breve explicacion de donde es que se cambia se lo agradeceria 🙂

  13. Martín dice:

    Hola
    Estoy tratando de pasar mis mapas a la nueva versión v.3 pues he recibido un correo de google diciendo que en Mayo se cierra la anterior.
    ¿Como puedo añadir una caja de busqueda en la parte inferior izquierda del mapa.
    Antes la tenía en el mapa y ahora no se como se hace con la nueva versión.

    Si es posible, el código entero pues no se nada de programación.
    Gracias

  14. Juan David Vélez V. dice:

    Hola Gustavo.

    Muy interesante el tema.

    Necesito, si puedes, tu email para una consulta interna.

    Gracias,

    Juan David Vélez V.
    All DigitAll

  15. Victor dice:

    Buenisima Explicación, Gracias por tomarte el tiempo de realizar esta explicación.

  16. Atardecer dice:

    hola quisiera saber si hay un costo o licencia para migrar de una version a otra, o es totalmente gratuita, o que es lo que necesito

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.