Hat man sehr viele Marker auf einer Google Maps Karte, kann es sehr schnell sehr unübersichtlich werden. Oft überlagern sich die Marker Icons und man erkennt nichts mehr. Ihr kennt das auch?
Heute zeigen wir euch, wie ihr Google Maps Marker serverseitig durch eine Cluster-Funktion schickt, damit eure Karten immer schön übersichtlich bleiben. Ein Cluster bildet in unserem Fall einen Punkt, der die in seiner Umgebung befindlichen Marker zusammenfasst und deren Anzahl darstellt.
Fangen wir an:
Wir beginnen mit einer einfachen MySQL Datenbank Abfrage zum Auslesen aller unserer Google Map Marker in einem PHP Array.Hinweis: Diese Abfrage dient lediglich als simples Beispiel und sollte so nicht Live genutzt werden.
// Neues Marker Array definieren $alleMarker = array(); $sql = "SELECT * FROM mapping_marker"; $qry = mysql_query($sql); while($res = mysql_fetch_array($qry)) { $alleMarker[] = $res; }
Würden wir nun dieses Marker Array ausgeben, fänden wir – je nach Menge und Distanz der Marker – möglicherweise rechts stehendes Bild vor.
Dieses Bild zeigt das Mapping Tool der Außenwerbefirma Ströer mit einigen, jedoch noch wenigen Markern (auf der Ströer Karte werden nur maximal 250 Marker angezeigt).
Die Marker liegen einfach übereinander, damit kann – zumindest ich persönlich – nicht viel anfangen.
Versuchen wir es nun besser zu machen…
Dazu benötigen wir eine Cluster Funktion, die ich nach langem suchen bei Mika Tuupola gefunden habe euch nun hier – in leicht modifizierter Variante – vorstellen möchte.
<?php define('OFFSET', 268435456); define('RADIUS', 85445659.4471); function lonToX($lon) { return round(OFFSET + RADIUS * $lon * pi() / 180); } function latToY($lat) { return round(OFFSET - RADIUS * log((1 + sin($lat * pi() / 180)) / (1 - sin($lat * pi() / 180))) / 2); } function pixelDistance($lat1, $lon1, $lat2, $lon2, $zoom) { $x1 = lonToX($lon1); $y1 = latToY($lat1); $x2 = lonToX($lon2); $y2 = latToY($lat2); return sqrt(pow(($x1-$x2),2) + pow(($y1-$y2),2)) >> (21 - $zoom); } function clusterMarker($markers, $distance, $zoom) { $clustered = array(); while (count($markers)) { $marker = array_pop($markers); $cluster = array(); $countClusterSets = 1; foreach ($markers as $key => $target) { $pixels = pixelDistance($marker['y'], $marker['x'], $target['y'], $target['x'], $zoom); if ($distance > $pixels) { $countClusterSets++; unset($markers[$key]); $cluster[] = $target; } } if (count($cluster) > 0) { $marker['clustered'] = '1'; $marker['clusterCount'] = $countClusterSets; $clustered[] = $marker; } else { $marker['clustered'] = '0'; $marker['clusterCount'] = '1'; $clustered[] = $marker; } } return $clustered; } ?>
Rufen wir nun die Hauptfunktion beispielsweise wie folgt auf:
// clusterMarker(MarkerArray, DistanzZumClustern, ZoomWertDerGoogleMap); $clusteredMarkers = clusterMarker($alleMarker, 40, 10);
Erhalten wir ein Array, welches entweder den ursprünglichen Marker beinhaltet (nicht geclustert) oder einen geclusterten Marker mit dem entsprechenden Variablen Wert $clusteredMarkers[…][‚clustered‘] = ‚1‘ und der Anzahl der Marker im Cluster mit $clusteredMarkers[…][‚clusterCount‘].
Geben wir dieses Array der geclusterten Marker nun in einer foreach-Schleife aus und füllen damit unsere Google Map, kann das ungefähr wie rechts stehend (von unserem Kunden AWK-Sales / Degesta) aussehen.
Wie ihr die Ausgabe vornehmt und vor allem wie das Ganze optisch aussieht, ist natürlich euch überlassen.
Die Werte für Distanz beim Funktionsaufruf der Cluster Funktion dürft ihr natürlich nach belieben anpassen.
Viel Erfolg beim umsetzen!