Clustering: come gestire molti marker in Google Maps

Aggiornato il 13 Settembre 2013

Vuoi ricevere ogni settimana le ultime notizie dal mondo del Local SEO e della local Search, e per restare aggiornato sulle nostre ultime novità?

Iscriviti alla Newsletter

Non è raro ritrovarsi a gestire delle mappe di Google con più marker tramite le API. Avere tanti marker nelle mappe può rilevarsi un problema per l’enorme quantità di risorse che questi chiedono per essere caricati e mostrati nello schermo.

Per fortuna nella versione 3 delle API di Google Maps è possibile utilizzare il clustering (cioè quella tecnica che permette di raggrupapre elementi omogenei in un insieme di dati).

Questa tecnica ci può tornare utile in molte occasione, quando ad esempio vogliamo mostrare molti eventi in una mappa, oppure abbiamo molte strutture che vogliamo mostrare contemporaneamente.

Il risultato che otterremo è molto simile al seguente e per farlo ci bastano poche righe di codice.

mappa-demo

 

Proviamo a vedere un esempio che genera proprio l’immagine mostrata qui sopra:

<!DOCTYPE html>
<html>
<head>
<meta name=”viewport” content=”initial-scale=1.0, user-scalable=no”>
<meta charset=”utf-8″>
<title>Example</title>
<script type=”text/javascript” src=”http://maps.google.com/maps/api/js?sensor=false”></script>
<script type=”text/javascript” src=”http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js”></script>
</head>
<body>
<div id=”gmap” style=”width:400px;height:500px”></div>

<script>
var map_center = new google.maps.LatLng(0.1700235000, 20.7319823000);

var map = new google.maps.Map(document.getElementById(“gmap”), {
zoom:1,
center:map_center,
mapTypeId:google.maps.MapTypeId.HYBRID
});

var pos;
var marker;
var marker_list = [];
for (var i = 0; i < 100; i++) { //creiamo 100 marker in posizione casuale
pos = new google.maps.LatLng(Math.floor(Math.random() * 50), Math.floor(Math.random() * 100));
marker = new google.maps.Marker({
position:pos,
map:map,
title:’Title’
});
var storyClick = new Function(“event”, “alert(‘Click on marker ” + i + ” ‘);”);
google.maps.event.addListener(marker, ‘click’, storyClick);

    marker_list.push(marker);
}

var markerCluster = new MarkerClusterer(map, marker_list, {
gridSize:40,
minimumClusterSize: 4,
calculator: function(markers, numStyles) {
return {
text: markers.length,
index: numStyles
};
}
});
</script>

</body>
</html>

La parte che ci interessa di più e quella in grassetto.

In particolare in questo modo andiamo ad indicare che tutti i marker_list che abbiamo aggiunto in precedenza con .push devono essere mostrati con la tecnica del cluster, cioè raggruppati.

All’interno troviamo solo alcune opzioni, come il numero minimo di marker che dobbiamo mostrare raggruppati (4 in questo caso).

Documentazione ufficiale: https://developers.google.com/maps/articles/toomanymarkers
Annuncio: http://googlegeodevelopers.blogspot.it/2009/04/markerclusterer-solution-to-too-many.html
Demo meteo con i marker differenti in base allo zoom: https://code.google.com/archive/p/google-maps-utility-library-v3/

13 risposte

  1. Grazie del Tutorial, veramente interessante.

    Sto provando ad effettuare quanto da te indicato, ma stranamente non capisco perchè non ottengo quanto aspettato; cioè sembrerebbe quasi che prima vada ad effettuare il clustering, dopodichè a riempire l’array che contiene i marker, pertanto non riesce a gestire la funzionalità.

    Vi è qualche regola di scope o qualcosa del genere da tenere presente?

    1. Ad esempio io sto utilizzando anche la funzione geocoder.geocode; non è che per caso le due entrino in conflitto o sia necessario qualche altro accorgimento?

      1. Nessun conflitto, devi ricontrollare il tuo codice, probabilmente hai sbagliato.
        Comincia dall’esempio base e poi pian piano aggiungi le funzionalità, il debug è più difficile tutto insieme.

    2. Ciao, servirebbe il codice per sapere. In ogni caso puoi prendere l’esempio e caricare i dati nell’array in un altro modo. Solitamente è l’ordine delle operazioni che da problemi.
      Prova inoltre a fare meno zoom.

  2. Bingo!!
    Ho trovato il problema…

    In pratica lavorano in maniera asincrona… e quindi è necessario prima definire il Clusterer, e dopodichè una volta effettuato il geocoder, andare ad aggiungere i marcatori al clusterer di volta in volta…

    1. Salve, ho provato a copiare a incollare il codice sopra riportato e salvarlo in un file map.htm ma una volta aperto nel browser non si vede niente, pagina bianca… non ho modificato il codice, cosa non va? Devo fare qualche modifica? In che consiste quello che dice Giovanni “è necessario prima definire il Clusterer, e dopodichè una volta effettuato il geocoder, andare ad aggiungere i marcatori al clusterer di volta in volta…”? Puoi postare un esempio di codice funzionante? Grazie.

      1. Ciao, devi modificare gli apici, wordpress li trasforma in caratteri strani, sostituiscili tutti. Questo è solo un codice di esempio e serve per imparare, modificarlo non è così semplice.

    1. Ciao ele,

      non è molto difficile.
      Questa funzione
      for (var i = 0; i < 100; i++) { //creiamo 100 marker in posizione casuale pos = new google.maps.LatLng(Math.floor(Math.random() * 50), Math.floor(Math.random() * 100)); }
      Crea i marker a caso, salvandoli poi nell'array:
      marker_list.push(marker);
      basta semplicemente che var marker_list = []; contenga tutti i valori che vuoi separati come array, quindi sarà qualcosa del genere:
      var marker_list = [[42,15],[45,16]];

  3. scusate ma invece di far comparire l’alert al click sul marker vorrei far aprire la classica finestra con dei dati all’interno come dovrei fare?
    Ho provato a modificare questa riga

    var storyClick = new Function(“event”, “alert(‘Click on marker ” + i + ” ‘);”);
    google.maps.event.addListener(marker, ‘click’, storyClick);

    in quest’altra forma

    var boxText = “”+ scrividiv +””+ foto +”“+ nome +”“+ indirizzo +””+ citta +””+ regione +””;

    var storyClick = new Function(“event”, “ boxText”);
    google.maps.event.addListener(marker, ‘click’, storyClick);

    ma mi da errore in quanto le creano un problema

    avete suggerimenti !?

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *