Comme nous l'avons vu dans le billet précédent sur le gestionnaire de marqueurs, l'API Google Maps ne gère pas automatiquement le remplacement d'un groupe de marqueurs proches par un marqueur unique à faible facteur de zoom. Heureusement, Jef Poskanzer a écrit une librairie implémentant cette fonctionnalité : Clusterer.

Partons de l'exemple 9 qui est identique à l'exemple 4 d'un précédent billet auquel j'ai ajouter une concentration importante de marqueurs à l'est de Paris. Déclarons la librairie dans l'en-tête HTML :

<script src="http://www.acme.com/javascript/Clusterer2.jsm" type="text/javascript"></script>
La gestion automatique se fait en déclarant une variable clusterer, instanciée dans la fonction load :
var clusterer; function load() { if (GBrowserIsCompatible()) { map = new GMap2(document.getElementById("map")); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); map.setCenter(new GLatLng(46.85, 1.75), 6); clusterer = new Clusterer(map); clusterer.SetMaxVisibleMarkers(10); clusterer.SetMinMarkersPerCluster(5); GDownloadUrl("exemple10.json", setup_json); } else { alert("Desole, l'API Google Maps n'est pas compatible avec votre navigateur."); } }

Un objet Clusterer possède 4 méthodes :

  • SetMaxVisibleMarkers(n) : définie le nombre de marqueurs au delà duquel le clustering est mis en place (150 par défaut).
  • SetMinMarkersPerCluster(n) : définie le nombre minimum de marqueurs constituant un cluster (5 par défaut).
  • SetMaxLinesPerInfoBox(n) : définie le nombre de ligne s'affichant dans la fenêtre d'information du marqueur correspondant au cluster (10 par défaut).
  • SetIcon(icon) : définie l'icône du marqueur correspondant au cluster si celui par défaut ne convient pas.

Il suffit ensuite de remplacer chaque appel à map.addOverlay(marker) par un appel à clusterer.AddMarker(marker, title) (où title est la ligne du marqueur réel qui s'affichera dans la fenêtre d'information du marqueur correspondant au cluster) et chaque appel à map.removeOverlay(marker) par un appel à clusterer.RemoveMarker(marker). Exemple dans la fonction setup_json :

setup_json = function(json, status) { var data = eval('(' + json + ')'); for (var i=0; i<data.markers.length; i++) { var point = new GLatLng(data.markers[i].lat, data.markers[i].lng); var marker = createMarker(point, data.markers[i].html); clusterer.AddMarker(marker, data.markers[i].html); } }

Le résultat est visible sur l'exemple 10.

Cette solution permet de rendre de bons services, mais n'est toute fois pas idéale. En effet, le clustering est lié au nombre de marqueurs plutôt qu'à leur densité. Ainsi, deux marqueurs supperposés ne seront vus que comme un seul marqueur à fort grossissement (en l'absence de clustering). D'autre part, l'algorithme n'est pas très précis : sur l'exemple 10, le marqueur placé sur Le Havre a été intégré au cluster bien qu'il en soit assez éloigné !

Les autres billets de cette série sur l'API Google Maps :