Wir haben schon ein paar Mapping-Projekte realisiert. Zeit, einen Blick unter die Haube zu werfen.
Anforderungen:
Alle Geschäftsstellen einer Bank sollen wahlweise mit oder ohne Bankomaten auf einer Karte dargestellt werden.
Wenn man auf einen Marker klickt, öffnet sich eine Sprechblase mit Infos wie Öffnungszeiten, Adresse etc.
Das Ganze soll in eine Lotus Notes Anwendung eingewoben werden, und somit steht auch fest, wo die Koordinaten gespeichert werden: In der dokumentorientierten Datenbank von Notes.
Am Anfang war der Marker
Google stellt eine Mapping-API zur Verfügung, um Karten in die eigene Homepage einzubinden und mit allerhand tollen Sachen auszuschmücken.
Was wir brauchen, sind Marker.


Viele Marker. Die Bank besitzt fast 1500 Geschäftsstellen mit über 5500 Bankomaten - die wollen alle dargestellt werden!
Spätestens bei 200 Markern ist im IE 6 dann aber Feierabend - jeder Marker ist ein DOM-Element mit einem Event drauf. Und viele Events = langsam.
Wir müssen die Anzahl der gleichzeitig dargestellten Marker einschränken.
Aber wie? Local.ch stellt tausende Marker gleichzeitig dar, und jeder einzelne von denen ist klickbar!

Magie? Nicht ganz, sondern ein schlauer Trick. Später dazu mehr.
Nur Marker aus der Umgebung
Wir entscheiden uns, Marker auf der niedrigen Zoomstufe zu einem Gruppenmarker zusammenzufassen.
Sobald man näher heranzoomt, werden alle Marker aus der Umgebung geladen und dargestellt.
Marker aus der Umgebung laden - bei einer SQL Datenbank mit „SELECT WHERE distance < mittelpunkt" (vereinfacht gesagt) nicht so aufwändig.
Aber wie sieht's aus bei einer dokumentorientierten Datenbank wie Lotus Notes, wo man solche Abfragen nicht machen kann?
Alex hat ein ausgeklügeltes Backend gebaut. Wir unterteilen die ganze Schweiz in Kacheln und speichern alle Marker, die sich in einer Kachel befinden. Die Kacheln sind eine vorberechnete Notes-View, indiziert mit Start- und Endkoordinaten. Anhand der übergebenen Koordinaten findet Notes heraus, welche Kachel(n) es laden muss und liefert die dazugehörigen Marker zurück.
JSON ist toll
Wir haben eine JSON-Datenstruktur definiert, wie das Backend die Marker zurückliefern soll.
Es gibt „locations" mit „bancomats", welche je eine Positionsangabe haben und im Attribut „data" mit beliebigen Zusatzinformationen angereichert werden können.
Das schöne daran ist: Ich kann diese Datenstruktur holen und in Javascript gleich so verwenden - und zwar für die Generierung der Marker auf der Karte, wie auch für die Darstellung des Menüs links. Beide greifen auf die gleichen Daten zurück, und somit kennen sich die Titel und die Marker.
Ganz zu schweigen vom Fakt, dass JSON ein kompaktes Klartextformat ist, und ich alle tollen Features nutzen kann, die mir Klartext bietet: Ich kann es komprimieren, zwischenspeichern, maschinell verarbeiten und auf anderen Systemen weiterverwenden. #wooha
Mir gefällts.
Magie auf mehreren Ebenen
Zurück zur magischen Karte bei Local.ch.
Viele Marker. Richtig viele. Und es läuft difig, selbst im IE6. Wie machen die das?
Ich weiss wie! :-)
Es werden transparente Bilder mit den Markern (in Echtzeit?) berechnet und auf die gesamte Karte als Layer drübergelegt.

Man kann so praktisch unbegrenzt viele Marker in vielen Layern darstellen. Und mit Javascript kann man mit nur einem Event, der auf der Karte lauscht, herausfinden, wo der Benutzer auf der Karte geklickt hat und so tun, als hätte er auf einen Marker geklickt.
Und ich find's enorm praktisch, dass die Erde eine Scheibe ist, denn so muss man nicht ständig Koordinaten mit komplizierten Formeln auf Pixel umrechnen.
Cool, danke Claude! ;-)
Im IE6 ist die Performance auch darum so langsam, weil es Zeit kostet, DOM-Elemente in einem Loop per JavaScript einzufügen. Besser ist es, zunächst alle Elemente als Objekte zu generieren, in einem Parent-Objekt abzulegen und nur dieses eine Element in den DOM-Baum einzufügen. Dazu ist insertBefore() schneller als appendChild(). Und anstelle von tausenden von Event-Listenern verwendet man natürlich nur einen einzigen auf dem Parent mit Event-Delegation. ;-)
Schöne Einführung inkl. dem "Local-Trick" (search.ch resp. Urban Müller wählte einen Ansatz, welcher POIs "verteilt" wegliess, so dass man den Eindruck vermittelt bekommt alle zu sehen)
Hi Claude
Sehr interessante Lösung! Für den Locationfinder mussten wir für die vielen Marker ebenfalls eine Lösung finden. Für das Clustering haben wir das Marker Clusterer Plugin verwendet. Die Marker werden abhängig von Zoom Level und Menge zusammengefasst.
Unter http://code.google.com/p/gmaps-utility-library-dev/ findet man weitere nützliche Google Map Helper.