jueves, 29 de abril de 2010

Actualizando Google Maps API de la v2 a la v3

Me ha tocado actualizar unos mapas que estaban utilizando la versión 2 de la API de Google Maps a la versión 3.

Algunas de las novedades de la versión 3 son el soporte a iPhone y Android, mejora de la velocidad de carga, ya no es necesaria una clave de acceso y siguiendo la línea del resto de aplicaciones de Google ya no soporta IE6.

La idea de este post es hacer una guía rápida de migración, con el código de la v2 y el equivalente de la v3, no he utilizado ninguna nueva funcionalidad.

Suponiendo que tenemos definidas las variables longitude, latitude, zoom_level, image_path, html_content y div_element (autoexplicativas todas)

Primero de todo incluimos el JS de google, que ha pasado de

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


a

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


Donde sensor indica si la aplicación utiliza un sensor para localizar al usuario.

La creación de un mapa en la v2 era

var myLatlng = new GLatLng(latitude, longitude)
map = new GMap2(div_element);
map.setCenter(myLatlng, zoom_level);



Y en la nueva versión

var myLatlng = new google.maps.LatLng(latitude,longitude);
var myOptions = {
  zoom: zoom_level,
  center: myLatlng,
}
map = new google.maps.Map(div_element, myOptions);



Por una parte se ha sustituido la 'G' del nombre de los objetos por el namespace 'google.maps.' y por otra parte, las propiedades se asignan a través de un objeto (myOptions en este caso) en lugar de utilizando métodos.

Una vez creado el mapa, se le pueden cambiar / asignar nuevas propiedades con el método setOptions, p.e. los controles del mapa, que en la versión 2 se asignaban con

map.addControl(new GSmallMapControl());

Ahora se asignan


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

         
No es exactamente el mismo control, pero todavía no están implementados todos en la nueva versión.

A la hora de crear un marcador con imagen personalizada pasamos de

var icon = new GIcon(G_DEFAULT_ICON);
icon.image = image_path;
marker = new GMarker(new GLatLng(latitude, longitude), icon);
map.addOverlay(marker);


a

marker = new google.maps.Marker({
  position: point,
  map: map,
  icon: image_path
});


Igual que en la creación del mapa, por medio de un objeto pasamos todas las propiedades al marker.


Al borrar elementos de pantalla la cosa se complica. En la versión anterior simplemente llamando a map.clearOverlays() limpiabamos el mapa. En la nueva versión hay que guardar la referencia a los objetos para borrarlos manualmente aplicando el método setMap(null). En la documentación hay un ejemplo bastante completo

Por último tambien ha cambiado tambien la creación de mensajes (bubbles), antes era:


var myLatlng = new GLatLng(latitude, longitude)
map.openInfoWindowHtml(myLatlng, html_content)


Y ahora

var myLatlng = new google.maps.LatLng(latitude,longitude);
var infowindow = new google.maps.InfoWindow({
  content: html_content,
  position: myLatlng
});


Disclaimer: No he pretendido hacer una guía exhaustiva de migración, simplemente explicar los cambios que me aplicado migrando un mapa ya existente. Es posible que tanto la implementación anterior como la nueva no fueran de la forma más óptima o canónica, ya que como en la mayoría de las cosas, no soy experto en el tema....