Google Maps für die Website
Webanwendungen mit Landkarten

DeveloperIT-ProjekteSoftware

In Version 2 bietet die Google-API viele neue Möglichkeiten für den Programmierer. Der Workshop zeigt, wie Sie Google Maps in Ihre Website einbinden und mit Ajax-Technik eigene Anwendungen darauf aufbauen.

Tipps & Tricks

Google Maps für die Website

Für ganz Deutschland und Europa liegen nunmehr hochauflösende Satellitenkarten und sämtliche Straßenkarten vor. Da die Maps auf Anhieb nicht unbedingt leicht zu handhaben sind, sollten Sie bereits mit Javascript vertraut sein, besonders dann, wenn Sie die Karten mit Markern, Polylines und Info-Fenstern ausstatten wollen.

Ort und Typ der anzuzeigenden Karten bestimmen Sie frei bei der Programmierung. Der Anwender hat die Möglichkeit, die Karte mit der Maus zu verschieben, hinein- und herauszuzoomen sowie Info-Material aufzurufen. Die Maps sind bislang werbefrei und lassen sich in private und gewerbliche Sites in beliebiger Anzahl und Größe einbinden. Bei über 50000 täglichen Zugriffen sollten Sie jedoch vorher bei Google anfragen. Die Karten basieren komplett auf Javascript.

Dieser Workshop zeigt Ihnen Tricks zum Einbinden von Google Maps in Ihre Website mit der neuen API-Version 2, die über die offizielle Dokumentation hinausgehen. Er stellt darüber hinaus eine umfangreiche Beispieldatei mit Kommentaren zur Verfügung. Weiter finden Sie auf der Heft-CD mehrere Skript-Bibliotheken, mit denen sich viele Features der API auf einfache Weise erweitern lassen.


Gewünschte Karte laden

Google Maps für die Website

Für die Ortsangaben der Karten und Marker sind zwei Koordinaten, genannt Latitude und Longitude, notwendig. Da Google keine Geokodierung anbietet, sind diese Werte leider nicht direkt abrufbar. In der beigefügten XML-Datei auf der Heft-CD finden Sie die Werte fast aller deutschen Großstädte und europäischen Hauptstädte. Andere benötigte Werte lassen sich leicht über externe Quellen beziehen.


var mapdiv = document.getElementById("map");
function buildMap() {
map = new GMap2(mapdiv);
map.setCenter(new GLatLng(parseFloat(markers[0].getAttribute("lat")), parseFloat(markers[0].getAttribute("lng"))), 5)
map.setMapType(G_SATELLITE_MAP);
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
}

Mit dem GMap2-Konstruktor erzeugen Sie ein Kartenobjekt, das sich innerhalb eines div-Elements befinden sollte. Damit legen Sie für die Karte eine beliebige Position und Größe fest. Natürlich können Sie auch mehrere Karten in eine Seite einbinden.
Achten Sie bitte darauf, dass die Variable map global ist. Erst dadurch können Sie im gesamten Skript auf sie zugreifen, um sie etwa mit Linien und Info-Fenstern zu versehen. Vermeiden Sie es in jedem Fall, das Wort long als Variable zu verwenden, weil es sich dabei um ein reserviertes Wort handelt.

Die Methode setCenter() lädt die Karte im angegebenen Ortspunkt und mit dem festgelegten Zoomfaktor 5. Die möglichen Werte für den Zoomfaktor reichen von 0 bis 17. Mit setMapType() lässt sich von Anfang an der gewünschte Kartentyp laden, etwa eine Satellitenkarte. Die verfügbaren Optionen heißen: G_NORMAL_MAP, G_SATELLITE_MAP und G_HYBRID_MAP. Am Ende werden Kontrollelemente hinzugefügt, die es dem Anwender erlauben, hinein- und herauszuzoomen oder auf einen anderen Kartentyp umzuschalten.


Ajax für die Abfrage

Google Maps für die Website

Der Vorteil von Ajax besteht darin, dass wesentliche Inhalte der Seite auf externen Daten beruhen. Werden diese Daten stets aktuell gehalten, dann verfügt der Anwender immer über die neuesten Informationen. Auf diese Weise lassen sich etwa auf einer Karte nur jene Parkhäuser anzeigen, in denen noch Plätze frei sind. Der Aufwand dafür ist relativ gering, weil außerhalb der Datenbank keine Änderungen vorzunehmen sind.

Da die dokumentierte Methode GDownloadUrl() mit dem IE nicht in allen Fällen klappt, verwenden Sie für die Ajax-Abfrage am besten die klassische Methode:


function readData() {
var request = GXmlHttp.create();
request.open("GET", "db.xml", true);
request.onreadystatechange = function() {
if( request.readyState == 4 ) {
var xml = request.responseXML;
markers = xml.documentElement.getElementsByTagName("ger");
buildMap();
}
}; request.send(null);
}

Der Code zeigt Ihnen, wie Sie über die API eine XML-Datei, hier db.xml, mittels Ajax laden und auslesen. Auf die Unterschiede in der Implementierung des XML-HTTP-Objekts in den verschiedenen Browsern brauchen Sie hierbei nicht zu achten. Denn das wird alles von der API erledigt.

Im Wesentlichen wird nach Verbindungsaufbau über den Event-Listener onreadystatechange abgefragt, ob die readyState-Variable den Wert 4 aufweist. In diesem Fall besteht eine vollständige Verbindung, und die gewünschten Elemente werden in der Variablen markers gespeichert. Wenn es sich hierbei um eine globale Variable handelt, steht sie im gesamten Skript zur Verfügung, und Sie brauchen die Daten kein weiteres Mal vom Server anfordern.

Die zu Grunde liegende XML-Datei sieht folgendermaßen aus:






...

Weil in den Namens-Attributen auch Umlaute vorkommen können, sollte die Angabe des Zeichensatzes ISO-8859-1 keinesfalls fehlen. Kontrollieren Sie bitte auch, dass die Datei keine sonstigen Fehler oder unnötige Leerstellen enthält.


Kontrollelemente

Google Maps für die Website

In der neuen API wurde zu den bereits bestehenden Kontrollelementen ein neues hinzugefügt: das Element GOverviewMapControl. Hierbei handelt es sich um eine verkleinerte Karte, die die Umgebung der Hauptkarte anzeigt. Es ist auch deshalb recht beliebt, weil die Bewegungen auf beiden Karten immer simultan verlaufen, wodurch man größere Entfernungen schnell überbrücken kann.

Um dieses Kontrollelement an der von Ihnen gewünschten Stelle zu positionieren, müssen Sie auf nicht dokumentierte Weise vorgehen:


overview = new GOverviewMapControl(new GSize(165,165));
map.addControl(overview);
setOverviewPos();

Zunächst speichern Sie das neu erzeugte Element in einer globalen Variablen. Mit dem Konstruktor GSize() erzeugen Sie ein Rechteck in der angegebenen Breite und Höhe in Pixel. Damit legen Sie die Größe des Kontrollelements fest.

Als Container für dieses Element wird von der API ein div-Bereich mit der ID map_overview angelegt. Sie dürfen diesen div-Bereich also nicht selbst zur Verfügung stellen, weil er sonst doppelt vorhanden wäre. Mit dem nun bekannten Wissen ist es aber nicht mehr schwierig, das Element exakt zu positionieren.

Sie brauchen lediglich die style-Eigenschaften left und top des div-Bereichs in einer eigenen Funktion zu definieren. Und in setOverviewPos() setzen Sie einen Timeout auf diese Funktion, so dass sie mit einer gewissen Verzögerung ausgeführt wird. Der Timeout ist deshalb notwendig, damit das vom Google-Server geladene Element beim Funktionsaufruf auch vorhanden ist. Da Sie ansonsten eine Fehlermeldung erhalten, müssen Sie nur darauf achten, den Timeout auch für langsamere Verbindungen hoch genug anzusetzen.


Marker und Info-Fenster

Google Maps für die Website

Marker repräsentieren einen Punkt auf der Karte, der jeweils mit den beiden bekannten Werten festgelegt wird. Soll beim Anklicken der Marker ein Info-Fenster geöffnet werden, definieren Sie dies gleich beim Erstellen der Marker. Dafür verwenden Sie am besten die folgende Hilfsfunktion. Damit es zu keinen Überschneidungen mit anderen Variablennamen kommt, notieren Sie hier nur lokale Variablen. Die genaue Berücksichtigung des Geltungsbereichs der Variablen zählt mit zum Wichtigsten bei der Map-Programmierung.


function createMarker(point, icon, name) {
var info_html = "

";
info_html += name + "<\/div>";
var marker = new GMarker(point, icon);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(info_html);
});
return marker;
}

Über das name-Argument der Funktion lässt sich der Inhalt des Info-Fensters ändern. Indem Sie dem Fenster einen Klassennamen zuweisen, können Sie die Anzeige sogar mit CSS formatieren.

Um einen Marker zu erstellen, gibt es den Konstruktor GMarker(). Als erstes Argument wird ihm der Punkt, an dem er sich befinden soll, übergeben. Wenn Sie dem Konstruktor kein zweites Argument für das zu verwendende Icon mitgeben, wird er mit dem Standard-Icon dargestellt. Die mit der obigen Funktion erstellten Marker sind natürlich alle anklickbar. Sie können aber auch Marker erstellen, die man nicht anklicken kann. Dazu brauchen Sie dem Marker-Konstruktor als drittes Argument nur true übergeben.

Um auf Mausereignisse zu reagieren, benötigt der Marker einen Event-Listener. Der Code zeigt Ihnen, wie dabei vorzugehen ist. Natürlich können Sie einem Objekt auch mehrere unterschiedliche Listener zuweisen und diese sogar untereinander verschachteln.

Die API stellt Ihnen nunmehr auch Info-Fenster mit Tabs zur Verfügung. Diese sind zwar etwas schwieriger zu handhaben, dafür jedoch gut dokumentiert.


Icons und Polylines

Google Maps für die Website

Neben den Standard-Icons stehen kleinere Icons in vielen Farben zur Verfügung. Sie können die Icons, die Sie verwenden wollen, natürlich auch selbst anfertigen. Aus Kompatibilitätsgründen mit verschiedenen Browsern verfügen die Icons über eine ganze Reihe von Eigenschaften.

Um die jeweiligen Marker-Icons mit den erforderlichen Eigenschaften auszustatten, definieren Sie eine weitere Hilfsfunktion. Dies hat den Vorteil, dass der Code nur einmal vorkommt und nicht für jedes Icon separat notiert werden muss:


function addIcon(icon) {
icon.shadow = icon_url + "mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);
}

Dies sind Größenangaben zur punktgenauen Verankerung der Icons und Info-Fenster. Hinzu kommt eine eigene Grafik zur Darstellung des Marker-Schattens. Für die Erstellung eines Markers mit dem Icon Ihrer Wahl genügen nun drei Code-Zeilen:


var icon = new GIcon();
icon.image = icon_url +"mm_20_red.png";
addIcon(icon);

Nach Aufruf des icon-Konstruktors brauchen Sie als image-Eigenschaft nur die Adresse des gewünschten Icons zu notieren. Die übrigen Eigenschaften werden von der Hilfsfunktion hinzugefügt.

Linien zwischen beliebigen Punkten auf der Karte heißen Polylines. Mit ihnen können Sie etwa Entfernungen zwischen Punkten sichtbar machen. Sie lassen sich aber auch zur Umgrenzung bestimmter Gebiete nutzen:


var poly = new GPolyline([point1, point2], "#ffa500", 2, 1);
map.addOverlay(poly);

Damit konstruieren Sie eine Linie zwischen dem angegebenen Array zweier Punkte. Dahinter legen Sie Farbe, Breite und Transparenz der Linie fest, wobei die letzten beiden Argumente optional sind.

Für die Farbe müssen Sie die üblichen Hex-Werte angeben, Farbnamen werden nicht erkannt. Die Angabe der Breite erfolgt in Pixel, und für die Transparenz ist ein Wert zwischen 0 und 1 erlaubt. Anschließend wird die Linie auf die Karte gezeichnet.


Externe Bibliotheken nutzen

Google Maps für die Website

Mit API-Erweiterungen ersparen Sie es sich, einige nützliche Effekte selbst zu programmieren. Mit ihrer Hilfe können Sie etwa Marker mit transparenten Tooltipps ausstatten oder eigene Texte und Grafiken über die Karte legen.

Alle Erweiterungen werden mit einem eigenen Skript-Tag unmittelbar hinter der Referenz auf die Javascript-API eingebunden:




Der Parameter v=2 vor dem Key-Code verweist auf Version 2 der API. Damit wird automatisch die jeweils aktuelle Version geladen. Um Browser-Probleme zu vermeiden, können Sie auch eine spezielle Unterversion verwenden, indem Sie beispielsweise v=2.48 notieren.

Um die Features der Erweiterung zu nutzen, stehen Ihnen entweder eigene Konstruktoren zur Verfügung, oder die vorhandenen Konstruktoren werden schlichtweg durch neue ersetzt. So verwenden Sie zum Beispiel für die Erstellung eines Markers mit Tooltipp statt GMarker() einfach den Konstruktor GxMarker(). Die API-Erweiterungen auf der Heft-CD befinden sich bereits alle auf dem Stand der Version 2.


Maßnahmen für Internet Explorer

Google Maps für die Website

Auch wenn die API-Dokumentation IE 5.5 als kompatiblen Browser auflistet, sind die Maps in der Tat erst mit IE 6 kompatibel. Auch mit der Beta-Version von IE 7 gibt es bislang Darstellungsprobleme. Um die User auf eventuell inkompatible Browser hinzuweisen, können Sie die von der API zur Verfügung gestellte Methode GBrowserIsCompatible() einsetzen.

Soll die Karte im IE 6 einwandfrei funktionieren, sind einige spezielle Angaben notwendig. Da der Internet Explorer Polylines mittels VML zeichnet, werden zwei Angaben benötigt. Die erste unmittelbar nach dem Dokumententyp:



Die zweite innerhalb des Stylesheets:

v\:* { behavior:url(#default#VML); }

Wenn möglich, sollte der Funktionsaufruf zum Laden der Karte immer über den Event-Handler onload im Body-Tag erfolgen. Dieser sorgt dafür, dass die Funktion erst abgearbeitet wird, nachdem die übrige Seite vollständig geladen ist. Achten Sie bitte auch darauf, dass sich kein Skript innerhalb einer Tabelle oder in einem -Element befindet.

Weil der Internet Explorer die Marker-Icons nicht im Cache zwischenspeichert, sondern einzeln nachlädt, dauert es ziemlich lange, bis eine größere Anzahl von Markern geladen wird. Abhilfe schafft in diesem Fall ein Trick, mit dem Sie die Icons vorladen, indem Sie im Body eine entsprechende Referenz notieren:



Dasselbe sollte natürlich auch mit dem Schatten der Marker geschehen. Versuchen Sie möglichst, die maximale Anzahl der Marker auf etwa 200 zu beschränken, weil sonst die Ladezeit drastisch ansteigt und der Speicherbedarf des Browsers einfach zu groß wird. Des Weiteren sollten Sie nicht vergessen, die Funktion GUnload() mit dem Event-Handler onunload aufzurufen. Der Browser gibt dadurch bei weitem mehr Speicher wieder frei, wenn die Map-Datei geschlossen wird.


Alle Dateien und Listings zum Workshop finden Sie auf der Heft-CD und unter listings.internet-pro.de.