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....

5 comentarios:

  1. hola. Por casualidad,¿¿ sabes como se aumenta y disminuye el zoom con un control personalizado???
    Antes se hacia con map.zoomOut(); Ahora en la version 3 ni idea. Gracias

    ResponderEliminar
  2. Saludos. Necesito un programador que sepa trabajar sobre Google Map Pro. Puede ser usted o tioene el telefono de alguin. mi correo su-asesor@live.com.mx

    ResponderEliminar
  3. hola que tal mira tengo una v2 y quiero subirlo peorcreo q ando mal en la tranformacion de vercion a la 3 por q desaparece el mapa no se si me puedas ayudar mira este es mi codigo
    function initialize() {
    if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map_canvas"));
    gdir = new GDirections(map, document.getElementById("directions"));
    GEvent.addListener(gdir, "error", handleErrors);
    GEvent.addListener(gdir, "addoverlay", onGDirectionsAddOverlay); // Triggers marker swap, Esa
    map.setCenter(new GLatLng(0, 0), 0); // inital setCenter() added by Esa.

    setDirections("23.362429", "-103.849363",9);


    document.getElementById("api-v").innerHTML = '2.' + G_API_VERSION;
    }
    }

    ResponderEliminar
  4. Hola Verónica.

    Si pegas tambien el nuevo código que has hecho para v3, miro a ver si veo algún error, aunque hace ya bastante tiempo que no trabajo con mapas (desde que escribí esta entrada en el blog, hace 2 años....)

    ResponderEliminar
  5. Bueno, tras mucho buscar creo que ha llegado el momento de lanzarme, no encuentro otra vía ya que mis conocimientos de programación son muy escasos. Cómo no, he de actualizar maps v2 a v3, y lo que no consigo es almacenar las coordenadas del mapa...introduzco este código, pero desconozco el método para recoger las coordenadas en tablas mysql, creo que es a través de un echo<...pero estoy vendido con php :S....os copio con explicaciones, a ver si he metido la gamba:


    var map;

    //PINTAMOS MAPA

    window.onload = function initialize() {
    var myOptions = {
    center: new google.maps.LatLng(40.417221, -3.703104),
    zoom: 16,
    streetViewControl: false,
    mapTypeId: google.maps.MapTypeId.HYBRID
    };

    //APUNTAMOS A LA ETIQUETA DIV "map-canvas"

    map = new google.maps.Map(document.getElementById('map-canvas'),
    myOptions);

    // Try HTML5 geolocation - NOS UBICAMOS

    if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {

    var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

    var infowindow = new google.maps.InfoWindow({
    map: map,
    position: pos,
    content: 'Mi ubicaci&oacuten'
    });
    map.setCenter(pos);
    }, function() {
    handleNoGeolocation(true);
    });
    } else {
    // Browser doesn't support Geolocation
    handleNoGeolocation(false);
    }

    //AÑADIDO PARA OBTENER UBICACIÓN

    var point = new google.maps.LatLng(
    parseFloat(markers[i].getAttribute("lat")),
    parseFloat(markers[i].getAttribute("lng")));


    }


    function handleNoGeolocation(errorFlag) {
    if (errorFlag) {
    var content = 'Error: El servicio de geolocalización ha fallado.';
    } else {
    var content = 'Error: Tu navegador no soporta que lo geolocalicen.';
    }

    var options = {
    map: map,
    position: new google.maps.LatLng(60, 105),
    content: content
    };

    var infowindow = new google.maps.InfoWindow(options);
    map.setCenter(options.position);
    }

    google.maps.event.addDomListener(window, 'load', initialize);


    //////////////////////////////////////////////////////////////////////
    creo que estoy haciendo varias cosas mal, pero mi único propósito es obtener las coordenadas y guardarlas con la variable $geoloc_x y $geoloc_y en la tabla del usuario.

    Muchas gracias de antemano :D


    ResponderEliminar