Varios marcadores en un mapa de Google Maps
- Informática

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({
...
Varios marcadores en un mapa de Google Maps
Fig. 1. Varios marcadores con sus respectivos infoWindows

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();
}

 

Sobre mí Rubén Alcaraz

Bibliotecario-documentalista e informático en continua iteración que habla de web y tecnología. There's no place like 127.0.0.1
Lee todas las entradas de Rubén Alcaraz

18 thoughts on “Introducción a Google Maps APIv3 (parte 5): múltiples marcadores con infoWindow

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

    1. Hola Delfina,

      Sin ver tu código es difícil saber que estas haciendo mal, pero quizá tenga que ver con no haber establecido un estilo para el id de tu mapa, en una CSS o en la misma cabecera del documento HTML:

      como se explica en http://www.rubenalcaraz.es/pinakes/informatica/introduccion-google-maps-api-v3/
      He revisado el código y a mí me funciona correctamente.

      Saludos y gracias por seguir el blog!

  2. Hola Rubén antes que nada muchas gracias por tus ejemplos que son de gran ayuda, te comento que yo estoy haciendo mi proyecto de tesis, lo que estoy haciendo es un rastreador en android, donde obtengo las coordenadas y el imei del dispositivo para distinguirlo de los demas, esta información la estoy guardando en una base de datos que se encuentra en el servidor, ahora lo que me falta hacer es mostrar esos dispositivos en una interfaz web, mi pregunta es como hacer para que ahora esas coordenas yo las pueda plasmar mediante un marker en la interfaz web? espero me puedas orientar y nuevamente muchas gracias por estos ejemplos.

    1. Hola David,
      Teniendo la latitud y longitud en dos campos de la base de datos, lo que tendrías que hacer es acceder a los valores almacenados y meterlos en un array o arraylist, recorrerlo con un bucle e ir utilizando esos valores en cada iteración para generar los marcadores. De una manera similar al ejemplo de esta entrada, pero en el lenguaje de programación que estes utilizando (imagino que Java).
      Saludos.

  3. Hola Rubén,
    he probado la inclusión de múltiples marcadores y funciona correctamente. És una buena solución para personalizar el contenido y los gráficos. El tutorial es excelente en todas sus partes y muy útil, por lo cual te estoy agradecido.
    Mi pregunta es como se podrían añadir nuevas capas al mapa (y poder activarlas o desactivarlas). Trabajo en la localización de agroturismos y quisiera incluir en una capa diferente las marcas de núcleos de población para luego poder hacer cálculos de distancia. Una vez hecho esto (si es que se puede) incluiría alguna capa más con información diferente.
    Te agradecería cualquier ayuda.
    Muchas gracias

  4. Hola Rubén
    Disculpa la molestia pero pero quiero saber si tienes la amabilidad de subir un demo de tu expolición por favor
    Muchas gracias

  5. Hola Rubén, en primer lugar quiero agradecerte por el aporte ya me ha servido mucho para adaptarlo a lo que estoy desarrollando, y quisiera también saber cómo hacer para refrescar los marcadores sin tener que recargar todo el mapa. Las ubicaciones yo las saco de una base de datos y cada una pertenece a una categoría por las que pueden ser filtradas, he probado que al seleccionar la categoría (de una lista despelgable) y darle click en el boton filtrar llame a setMarkers() pero no carga los marcadores, si llamo a initialize() si los carga pero también el mapa y quiero evitar eso. Te agradecería la ayuda. Muchas gracias.

  6. Hola, no encuentro información de como utilizar una variable que contiene una URL para mostrar una imagen en infowindow.setContent usando la API de Google Maps
    El codigo HTML que estoy insertando en la variable que pongo en infowindow.setContent es:

    var fachada = ”;

    la variable marcadores[i][10], contiene la URL (http://…….etc)
    infowindow.setContent(fachada);
    Lo que necesito al final es que cada marker en el mapa tenga su propia foto cuya URL viene de un archivo XML.
    Gracias

  7. hola que tal.

    trato de almacenar las coordenadas en una base de datos, después trato de mostrar mis coordenadas de la base de datos en un mapa donde solo sea vista sin que el mapa tenga algún evento.

    la verdad he buscado e intentado hacer eso y no encuentro un tutorial de como hacerlo.

    me imagino que dentro del ciclo for se manda a llamar la columna de mi tabla con php, para que despliege todas las coordenadas mostradas, pero no se donde debe ir el ciclo for. podrias ayudarme te lo agradeceria mucho.

  8. como haría si quiero colocar imagenes a cada marcador? (diferente imagen por cada uno) soy bastante novato en google map, podrías ayudarme?

    1. Hola José,
      Mete la ruta a las imágenes como nuevo valor en el array o vector y accede a ellos mediante el bucle, como se muestra en la entrada. Sólo tienes que añadir un valor más entre comillas. Por ejemplo
      [‘Barcelona’,41.385064,2.173404,’Barcelona’,’http://ejemplo.com/imagen.jpg’],
      Para acceder al valor usa:
      marcadores[i][4]
      Saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

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