Come gestire più marker in Google Maps

Giorgio Borelli

Gestire l'aggiunta di più segnaposto (marker) nella stessa Google Maps non è cosa difficile, le API V3 delle mappe di google mettono a disposizione una serie di oggetti veramente completi ed efficaci, per aggiungere pertanto più marker sulla mappa basterà sfruttare funzioni ed eventi delle API, mentre per la loro gestione, (ad es. cambio icona, titolo, posizione, etc. etc.), necessita di un piccolo workaround da parte nostra che prevede l'uso, ahimè!, di un array globale in Javascript contenitore dei nostri marker, la soluzione risulta comunque efficace, andiamo a scoprire come fare.

Supponiamo di avere n ristoranti, e per ognuno di esso desideriamo porre un segnaposto sulla nostra mappa indicante la sua posizione, quindi avremo un ciclo che scorre la lista o l'array dei ristoranti, ed all'interno di esso, creiamo un marker per ogni iterazione e lo assegniamo allo stesso tempo sia alla mappa che ad un array globale da noi creato (ci servirà dopo), vediamo il codice:

map = new google.maps.Map(document.getElementById("map"), mapOptions);
var markers = new array(); //array globale di markers
... 
for(i=0; i < restaurants.length; i++){
var marker = new google.maps.Marker({position: restaurants[i].latlng, map: map, icon: 'red.gif', flat: true});

markers[i] = marker; //aggiungo ogni nuovo marker all'array globale

google.maps.event.addListener(marker, 'mouseover', function () { changeIconOver(i);});
google.maps.event.addListener(marker, 'mouseout', function () { changeIconOut(i);});
} 

Come potete notare dal codice, definiamo un array "markers" a livello globale che conterra tutti i marker creati nel ciclo, per semplicità di codice ho supposto anche che l'array degli ipotetici ristoranti contengano i valori di latitudine e longitudine necessari per creare il marker, ovviamente potete adattare facilmente il codice alle vostre esigenze. Infine assegno alla mappa due eventi associati ai marker, uno per il mouseover ed uno per il mouseout. Al verificarsi di questi eventi (cioè quando il mouse passa o si sposta da sopra un marker sulla mappa) verranno invocate le funzioni ChangeIconOver e ChangeIconOut per cambiare ad es. l'icona del marker.

Il problema rispetto all'articolo precedente: Cambiare l'icona di un marker in Google Maps è che qui abbiamo un numero indefinito di marcatori (segnaposto), come facciamo a capire quale di questi passare come parametro, ci viene così in aiuto l'array globale che contiene tutti i marker, e del quale teniamo l'indice tramite il contatore "i" (volendo i marker si potevano assegnare anche in modo associativo all'array), il codice delle due funzioni risulta pertanto:

function changeIconOver(index) {
    if (markers[index] != null) {
        markers[index].setIcon("/g/green.gif"); }
}
 
function changeIconOut(index) {
    if (markers[index] != null) {
        markers[index].setIcon("/g/red.gif"); }
}

le due funzioni ricevono entrambe l'indice come parametro, e facciamo riferimento al marker corretto accedendo all'elemento presente all'indice "index" dell'array markers, come sempre viene fatto un controllo per verificare se sia nullo o meno, dopodichè tramite la proprietà setIcon assegniamo le nuove icone green.png e red.png rispettivamente per il onmouseover e onmouseout, ma avremmo potuto effettuare qualsiasi altra operazione o definire funzioni per altri eventi. Una volta creato l'array globale ed assegnati gli elementi marker possiamo fare ciò che vogliamo poichè abbiamo un controllo completo su tutti i segnaposto creati sulla mappa.

Unica pecca di questa tecnica, è che stiamo usando un array Javascript globale, che non è proprio il massimo dal punto di vista di eleganza e pulizia del codice, chiunque voglia suggerire una soluzione diversa o più brillante di questa sarà il benvenuto. Per chi invece volesse approfondire l'uso delle classi di Google Maps il link ufficiale delle API alla versione 3 è:

Google Maps Javascript API V3 Reference

Chiunque voglia aggiungere qualcosa, chiedere chiarimenti, su "come aggiungere e gestire più marker su una google maps" può farlo tramite i commenti, ogni contributo alla discussione sarà ben accetto.

Categorie: Google | Javascript

Tags: , ,

Commenti (10) -

Marco Attanasio
Marco Attanasio says:

Ma come posso fare invece se voglio mettere più Marker con l'indirizzo, utilizzando la geocoder.

Nel mio caso specifico, io sono riuscito a trovare il primo indirizzo e posizionarlo tramite geocode.

Poi successivamente, recupero da un db mysql altri indirizzi delle sedi e vorrei farle vedere, ma non ci sto riuscendo.

Rispondi

quando prelevi i dati dal db, con un linguaggio lato server, che suppongo sia PHP, cicla sui dati e crea tanti marker quanti sono i dati ritornati con l'istruzione spiegata nell'articolo:
var marker = new google.maps.Marker({...
che poi andrai ad aggiungere all'array dei marker.
Queste istuzioni di codice javascript puoi scriverle in PHP come stringa assegnandola ad una variabile che fornirai in uscita (con un echo suppongo) alla pagina restituita al client; la stringa così generata non sarà altro che il tuo codice Javascript per la gestione dei markers di google maps.

Ovviamente, il mio è solo un input, un suggerimento, devi adattarlo al codice della tua pagina ed alle tue esigenze.

Se hai bisogno, posta pure nuovamente, ciao.

Rispondi

Ciao.
Sto provando a fare un array su una mappa creata seguendo questa guida di Google (developers.google.com/maps/articles/phpsqlajax_v3).

I markers sono collegati al file xml generato dall'elenco dei markers presenti nel database.
Non riesco però ad integrare gli array javascript per poter tramite link selezionare determinati marker.
Potete aiutarmi?

Rispondi

Ciao a te Luca,
potresti spiegarti meglio e darmi più informazioni quando dici:
Non riesco però ad integrare gli array javascript per poter tramite link selezionare determinati marker.

Non dare per scontato che sappia cosa tu stia facendo, ho una vaga idea ma non riesco a seguirti bene, prova a spiegarmi meglio e se sarò in grado sarò felice di aiutarti.

Rispondi

Ciao Giorgio.
Cerco di spiegarti nel metodo più semplice possibile.
Ho realizzato una mappa come indicato dalla guida di Google. Il risultato è una mappa con due tipi di marker, bar e ristoranti, con due icone diverse.
I markers sono determinati dal file xml con tag <bar> e tag <ristoranti> in base alla tipologia.
Questa è la mappa.
Io vorrei tramite una spunta o un link disattivare e visualizzare sulla mappa solo i marker con tag bar.
Per poter far questo mi è stato suggerito di creare degli array in javascript ma non riesco a capire come realizzarli nella mia mappa già creata.
Spero che sono riuscito a farti capire il problema e che tu possa darmi un aiutino.
Se c'è qualcos'altro scrivi e ti rispondo.

Grazie
Luca

Rispondi

Non puoi creare gli array quando la mappa è già creata, devi crearli e popolarli prima, quando crei la mappa (lato server per capirci), in quel momento stai creando i vari markers (per bar e ristoranti) ed oltre a far questo puoi definirti due array javascript globali distinti, uno per il bar ed uno per i ristoranti e popolarli via via con i markers a seconda del tag.
Una volta che hai i due array globali (in questo momento la pagina è stata scaricata ed hai la mappa completa con entrambi i tipi markers), puoi mettere due link (o radiobutton) del tipo: visualizza solo bar, visualizza solo ristoranti. All'evento onclick su questi link associa una funzione javascript che ricrea la mappa caricando un solo array a seconda del link cliccato; la mappa puoi innestarla direttamente via javascript prelevandoti l'id con getElementById della mappa.


Questa è una prima soluzione, oppure se sei pratico di AJAX, puoi realizzarne una seconda ancora più pulita, sempre all'onclick su uno dei due link invoca via javascript un chiamata AJAX che ti ritorni solo i marker bar o ristorante e ricrei a volo la mappa, così eviti di usare gli array globali.

Immagino che quanto detto a primo impatto, forse, possa sembrarti complicato, ma non lo è, segui questo mio suggerimento e procedi per passi e vedrai che riuscirai ad implementare detto script.

Se hai ancora bisogno, io sono sempre qui, saluti Giorgio.

Rispondi

Si. A primo impatto sembra difficilissimo però ti ringrazio della risposta.

Il metodo che mi indichi tramite javascript prevede il reload della mappa? perchè questo può risultare fastidioso all'utente che si ritrova, cliccando sul radiobutton, nella posizione originale.

A parte questo, io ho la funzione load dove definisco la mappa, scarico il file php dove ci sono i markers.. ti inserisco parte del codice per farti capire meglio:

------------------------------------------------------------
    function load() {
    
      var map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(47.6145, -122.3418),
        zoom: 13,
        mapTypeId: 'terrain'
      });
    
    

  
      downloadUrl("phpsqlajax_genxml-bar.php", function (data) {      
        var xml = data.responseXML;  
    var markers = xml.documentElement.getElementsByTagName('allmarkers');
    
    
        for (var i = 0; i < markers.length; i++) {
      var name = markers[i].getAttribute("name");
          var address = markers[i].getAttribute("address");
          var type = markers[i].getAttribute("type");
          var point = new google.maps.LatLng(
              parseFloat(markers[i].getAttribute("lat")),
              parseFloat(markers[i].getAttribute("lng")));
          var html = "<b>" + name + "</b> <br/>" + address;
        
     var icon = markers[i].getAttribute("img") || {};
          var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon,
      type: 'bar',
          });
      
      
        bindInfoWindow(marker, map, infoWindow, html);
        }
      });

    
      // Change this depending on the name of your PHP file


  } // fine funzione load
------------------------------------------------------------

Dove devo inserire il codice per creare l'array?
Scusami ma sono proprio imbranato..

Rispondi

Scusa Luca ma già hai l'array con tutti i markers, questa riga di codice secondo te che cos'è:
var markers = xml.documentElement.getElementsByTagName('allmarkers');

quella var markers è il tuo array, infatti poi cicla con un for e preleva le altre informazioni con l'indice "i", del tipo:
var address = markers[i].getAttribute("address");

Penso che il più è fatto, devi solo "modificare" lo script php che ti restituisce i markers, al click su uno dei link di cui parlavamo, puoi invocare ad esempio due funzioni diverse o diversificarle tramite parametro per avere i soli bar o i soli ristoranti, del tipo:

downloadUrlBar("phpsqlajax_genxml-bar.php ...
e
downloadUrlRistoranti("phpsqlajax_genxml-ristoranti.php ...

devi uscire queste funzioni fuori dall'onload ed attivarle all'onclik dei link (o radiobutton).

Secondo me non è difficile da implementare, ovviamente devi mettere mano dentro il file php e ricavarti i soli marker con type bar o ristorante a seconda quelli che ti servono; poi sarà la bindInfoWindow che trovi in fondo al codice a visualizzare i marker, per non fare il reload della pagina però devi ricreare (all'onclick) per prima cosa di nuovo la mappa con:
  var map = new google.maps.Map(document.getElementById("map"),

Penso che questo basti, ciao Giorgio.

Rispondi

Grazie mille Giorgio.
La selezione l'ho fatta ma la mappa si rigenera.
Vedo come posso risolvere.
Grazie ancora
Luca

Rispondi

Che significa si "rigenera"?
Cmq credo che tu abbia "carpito" il meccanismo e con qualche prova e test riuscirai ad ottenere il comportamento desiderato.

Felice di esserti stato d'aiuto e grazie a te per essere intervenuto, alla prossima, saluti Giorgio.

Rispondi

Pingbacks and trackbacks (1)+

Aggiungi Commento

biuquote
Loading