Introducción a Google Maps APIv3 (parte 5): múltiples marcadores con infoWindow
Introducción
Como en el caso de la creación de un marcador simple, necesitamos utilizar el método «google.maps.events.addListener()» para ejecutar una función en el momento en que se active un evento (por defecto de clic) asociado a los marcadores. En este caso, no podemos utilizar el mismo código que cuando sólo teníamos un único marcador en el mapa. Si lo hiciéramos, al pulsar sobre cualquiera de los marcadores se abriría el «InfoWindow» del marcador creado en último lugar. Para solucionar este problema podemos utilizar dos alternativas: crear marcadores independientes o el uso de vectores.
Marcadores e infoWindows independientes
Esta primera opción consiste en definir una variable distinta para cada marcador y cada InfoWindow, que posteriormente se relacionarán mediante el método «open» desde cada uno de los «InfoWindow».
// marcador 1
var marker1 = new google.maps.Marker({
position: new google.maps.LatLng(41.385064, 2.173404),
map: map,
});
// InfoWindow para el marcador 1
var infowindow1 = new google.maps.InfoWindow({
content: 'Barcelona
<a href="http://es.wikipedia.org/wiki/Barcelona" target="_blank">Wikipedia</a>'
});
// Añadimos un evento de clic al marcador
google.maps.event.addListener(marker1, 'click', function() {
// Llamamos el método open del InfoWindow
infowindow1.open(map, marker1);
});
// final del marcador 1
// marcador 2
var marker2 = new google.maps.Marker({
...
Uso de vectores
La otra posibilidad es la utilización de vectores (en inglés arrays). Un vector es básicamente una secuencia de valores para una variable. También necesitaremos utilizar un bucle. Existen dos tipos de bucles en JavaScript. Los que se ejecutan un determinado número de veces, llamados bucles for, y los que se ejecutan mientras una determinada condición sea verdadera, o bucles while. En este caso utilizaremos un bucle for para ejecutar el mismo código varias veces pero con diferentes datos en cada iteración.
En primer lugar crearemos un vector que contendrá el título, las coordenadas y un texto que usaremos en los «infoWindow» de cada uno de los marcadores.
var marcadores = [
['Barcelona',41.385064,2.173404,'Barcelona'],
['Tarragona',41.119019,1.245212,'Tarragona'],
['Girona',41.9794,2.821426,'Girona'],
['Lleida',41.60034,0.609762,'Lleida'],
];
Una vez tenemos el vector con los datos que necesitamos para crear los marcadores, tenemos que extraer esos datos del vector con un bucle:
for (var i = 0; i < marcadores.length; i++) {
var myLatLng = new google.maps.LatLng(marcadores[i][1], marcadores[i][2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: marcadores[i][0],
});
El código anterior recorre el vector y crea un marcador en cada nueva iteración. El valor de i se inicializa con 0, en tanto que la condición se verifica como verdadera (i es menor que el número de «marcadores») se ejecuta el bloque del for:
- Obtenemos las coordenadas almacenadas para el primer marcador (var myLatLng = new google.maps.LatLng(marcadores[i][1], marcadores[i][2]);) que después pasaremos a «Position».
- Asociamos el marcador a nuestro mapa (map: map).
- Mostramos como «title» de nuestro marcador, el primer valor de cada elemento del vector. Para acceder al primer elemento escribiremos el nombre del vector (marcadores) y la posición en el índice del valor al que deseamos acceder. En este caso al ser el primer valor es la posición 0 (marcadores[i][0],).
- Después de ejecutarse el bloque del for, el bucle pasa a su tercer argumento. En este caso, el operador ++ incrementa en 1 el contenido de la variable i, y el bucle vuelve a empezar. El proceso acaba cuando i es superior a 4, momento en que la condición deja de ser verdadera.
Ahora necesitamos crear un «infoWindow» global con acceso al último de los valores del vector, que si recordamos era el texto que deseábamos que apareciera en el bocadillo.
google.maps.event.addListener(marker,'click',function() {
if (!infowindow) {
infowindow = new google.maps.InfoWindow();
}
infowindow.setContent(marcadores[i][3]);
infowindow.open(map, marker);
});
En el código anterior, creamos el «InfoWindow» y lo conectamos con su correspondiente marcador para que al pulsar sobre él, el bocadillo aparezca. Lo hacemos mediante el método «google.maps.events.addListener()».
google.maps.event.addListener(marker,'click',function() {
if (!infowindow) {
infowindow = new google.maps.InfoWindow();
}
A continuación, utilizamos el método «infowindow.setContent» para indicar cuál es el valor que debe mostrar. En este caso, el cuarto valor de cada vector (posición 3 en el índice)
infowindow.setContent(marcadores[i][3]);
Para acabar, llamamos el método «open» del objeto «InfoWindow».
infowindow.open(map, marker);
Para evitar que el último valor de i al finalizar el bucle sea el valor asignado a todos los marcadores por el event handler, debemos aislar la i de esta función, de la i del bucle, usando un closure. Así, pondremos el event listener dentro de una función anónima, pasándole las variables del bucle, de i, del marcador y de sus parámetros. Los cambios en la i del bucle no afectarán a los valores ya asignados a los infoWindows ya asignados dentro del event handler.
(function(i, marker) {
//código
})(i, marker);
Todo junto:
window.onload = function() {
function initialize() {
var latlng = new google.maps.LatLng(41.652393,1.691895);
var mapOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
}
var map = new google.maps.Map(document.getElementById('mapa'), mapOptions);
setMarkers(map, marcadores);
}
var marcadores = [
['Barcelona',41.385064,2.173404,'Barcelona'],
['Tarragona',41.119019,1.245212,'Tarragona'],
['Girona',41.9794,2.821426,'Girona'],
['Lleida',41.60034,0.609762,'Lleida'],
];
var infowindow;
function setMarkers(map, marcadores) {
for (var i = 0; i < marcadores.length; i++) {
var myLatLng = new google.maps.LatLng(marcadores[i][1], marcadores[i][2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: marcadores[i][0],
});
(function(i, marker) {
google.maps.event.addListener(marker,'click',function() {
if (!infowindow) {
infowindow = new google.maps.InfoWindow();
}
infowindow.setContent(marcadores[i][3]);
infowindow.open(map, marker);
});
})(i, marker);
}
};
initialize();
}
Hola, vengo siguiendo todos los posts paso a paso pero cuando quiero agregar los marcadores via el método de Marcadores e infoWindows independientes de esta página, cuando guardo los cambios del archivo js el mapa me desaparece de la página HTML. ¿Qué código me esta faltando?