Deutsch English
Internet, Programmierung Read this post in English

Google-Maps XHTML-konform einbinden

Ich bin ganz froh, diesen Post schreiben zu können, denn er erlaubt mir, beiläufig eine News einzustreuen, die eines eigenen Posts nicht unbedingt würdig gewesen wäre: Die letzten drei Tage habe ich damit verbracht, diese Seite XHTML-valide zu machen. Zuerst hatte ich mit der Transitional-Variante begonnen, weil sonst verschiedene Dinge, die ich gerne beibehalten wollte, nicht mehr so ohne weiteres funktioniert hätten. Aber dann traf es mich plötzlich wie der Blitz, und ich dachte: „Was zum Teufel tust du hier eigentlich?!“ – Und getreu meinem Motto „Ganz oder gar nicht“ machte ich mich daran, die Seite in XHTML Strict umzuschreiben. Wer sich vom Erfolg meiner Arbeit überzeugen möchte, kann gerne mal hier klicken. (Einzig die Besucherseite ist noch nicht angepaßt – da muß ich erst noch austüfteln, wie das geht.)

Ein großes Problem, dessen Lösung (einschließlich der vorangegangenen Suche nach selbiger[1] [2]) mich fast einen ganzen Tag gekostet hat, waren die Google Maps, die ich hier und da verwende. Google selbst bietet zum schnellen Einbau einer Karte in eine Homepage einen kurzen, einzeiligen Code an, welcher die Karte per IFrame in die Seite einbettet. Tja, dumm nur, daß IFrames in XHTML Strict nicht erlaubt sind. Auch meine Versuche, die URL der Karte aus dem Code zu nehmen und irgendwie als Objekt einzubinden, scheiterten kläglich. Also blieb mir nur noch eine Möglichkeit: die Google-Maps-API. Wie das geht, will ich im folgenden erläutern. Eines jedoch gleich vorweg: Es ist ein wenig umständlicher und erfordert ein kleines bißchen mehr Arbeit als nur mal eben einen Code-Schnipsel zu kopieren und irgendwo einzufügen.

Zuallererst benötigt man ein Google-Konto und einen Google-API-Key. Das kostet nichts, und man muß auch keine privaten Daten preisgeben. Lediglich die Domain, auf der der Key genutzt werden soll, muß angegeben werden. Dann kann es auch schon losgehen.

Schritt 1

Zuerst legt man da, wo die Karte erscheinen soll, ein <div> mit einer eindeutigen ID an:

<div id="map" style="width: 500px; height: 300px"></div>

Schritt 2

Nun muß man seinen API-Key wie folgt zwischen <head> und </head> einfügen:

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=DEIN_86_STELLIGER_API_KEY_HIER" 
type="text/javascript"></script>

Schritt 3

Gleich in Schritt 4 werden wir eine Javascript-Funktion schreiben, welche unsere Karte erstellt und in dem dafür vorgesehenen <div> anzeigt. Diese Funktion werden wir load() nennen. Damit sie dann beim Laden der Seite auch aufgerufen wird, muß man den <body>-Tag wie folgt erweitern:

<body onload="load()" onunload="GUnload()">

Die Funktion GUnload() gehört zur Google-API und dient der Verminderung von Speicherproblemen. Es ist daher empfehlenswert, sie an dieser Stelle ebenfalls einzubauen.

Schritt 4

Jetzt kommt das Herzstück des Codes, die load()-Funktion, die letztendlich unsere Karte erstellen wird. Man kann sie ebenfalls in den <head>-Bereich einbauen; das ist aber nicht zwingend erforderlich – man kann sie auch erst an späterer Stelle einfügen. Wenn man vorhat, eine sehr umfangreiche Karte mit vielen Ortsmarken zu erstellen, dann kann man das Script der Ordnung halber natürlich auch in eine eigene .js-Datei schreiben und diese dann so einbinden:

<script type="text/javascript" src="kartenscript.js"></script>

Was nun die Karte betrifft, ist es, glaube ich, am einfachsten und verständlichsten, wenn ich ein fertiges Beispiel poste und erläutere:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script type="text/javascript">
/* <![CDATA[ */
	function load() {
		var map = new GMap2(document.getElementById("map"));
		map.setMapType(G_HYBRID_MAP);
 
		// Links oben Pfeile und "+" und "-" Tasten
		map.addControl(new GSmallMapControl());
 
		// Rechts oben Tasten "Karte", "Satellit", "Hybrid"
		map.addControl(new GMapTypeControl());
 
		// Mittelpunkt setzen
		var mittelpunkt = new GLatLng(51.08268706509852, 7.1428728103637695);
		map.setCenter(mittelpunkt, 15);
 
		// Ortsmarken setzen
		var ortsmarke1 = new GMarker(new GLatLng(51.08268706509852, 7.1489667892456055));
		GEvent.addListener(ortsmarke1, "click", function() {ortsmarke1.openInfoWindowHtml('<span style="color: black">Beschreibung der 1. Marke<span>')});
		map.addOverlay(ortsmarke1);
 
		var ortsmarke2 = new GMarker(new GLatLng(51.08188838771136, 7.1381038427352905));
		GEvent.addListener(ortsmarke2, "click", function() {ortsmarke2.openInfoWindowHtml('<span style="color: black">Beschreibung der 2. Marke<span>')});
		map.addOverlay(ortsmarke2);
	}
/* ]]> */
</script>
  • Zeilen 2 und 26:
    Das Script wird als CDATA-Block definiert. Das erlaubt es uns, innerhalb des Scripts Zeichen wie <, > usw. zu verwenden, ohne daß der Browser sie als HTML interpretiert und die Seite zerschießt.
  • Zeile 4:
    Die Karte wird erstellt und im Element mit der ID „map“ dargestellt. Und das ist ja unser eben erstelltes <div>, in das die Karte rein soll.
  • Zeile 5:
    Die Art der Darstellung wird gewählt. Hier gibt es drei Optionen:
    • G_NORMAL_MAP – normale vektorisierte Landkarte
    • G_SATELLITE_MAP – Satellitenfotos
    • G_HYBRID_MAP – eine Mischung aus den beiden vorangegangenen: Satellitenfotos, die von der Vektorkarte überlagert werden
  • Zeile 8:
    Die Knöpfe zum Zoomen und Navigieren auf der Karte werden erstellt. Auch hier gibt es wieder drei Optionen:
    • GSmallZoomControl() – nur zwei kleine Plus‑ und Minus-Buttons zum Zoomen
    • GSmallMapControl() – Plus‑ und Minus-Buttons sowie vier Richtungspfeile
    • GLargeMapControl() – vier Richtungspfeile und eine Zoom-Skala
  • Zeile 11:
    Die Buttons oben rechts, die dem User das Umschalten zwischen Vektor‑, Satelliten‑ und Hybridansicht erlauben, werden eingebaut.
  • Zeile 14:
    Der Mittelpunkt, also das Zentrum der Karte, wird definiert. Dazu macht man eine genaue Angabe in Breiten‑ und Längengraden. Wie man an diese Daten kommt, erkläre ich weiter unten noch.
  • Zeile 15:
    Die Karte wird nun auf den zuvor definierten Mittelpunkt zentriert. Außerdem wird hier der Zoomfaktor bestimmt: Je höher der Wert ist, desto weiter ist man von der Erde entfernt. Je kleiner der Faktor, desto näher und detaillierter ist die Ansicht.
  • Zeilen 18–20 sowie 22–24:
    Hier habe ich nun beispielhaft zwei Ortsmarken erstellt. Nach genau diesem Muster kann man so viele weitere Ortsmarken einfügen wie man will. In der ersten Zeile gibt man den gewünschten Ort wieder in Breiten‑ und Längengraden an, und in der zweiten Zeile kann man das Popup, das bei Klick auf die Marke erscheint, noch beliebig mit HTML gestalten. Bitte beim Copy & Paste nicht vergessen, daß die Bezeichner wie „ortsmarke1“, „ortsmarke2“ in jedem Abschnitt jeweils viermal vorkommen und dementsprechend angepaßt werden müssen.

Wo bekomme ich die Breiten‑ und Längengrade her?

Was die Koordinaten angeht, gibt es Anbieter, die sich genau darauf spezialisiert haben, z. B. itouchmap.com. Dort kann man eine Adresse eingeben oder auch einfach den Marker auf der Karte an die gewünschte Position schieben und dann sofort Latitude (Breite) und Longitude (Länge) ablesen.

Das Ergebnis all dieser Mühen kann dann beispielsweise so aussehen:

Update (12. Oktober 2009)

Auch wenn es jetzt schon ein Weilchen her ist: Ich habe immer wieder mal über die Diskussion mit Kommentator „Peter“ nachgedacht und denke, daß ich noch einmal genauer darauf eingehen sollte:
Wenn es einem lediglich darum geht, dem Kunden ein „This document was successfully checked as XHTML 1.0 Strict!“ präsentieren zu können, man sich aber in Wirklichkeit gar nicht dafür interessiert, welchen Code der Browser am Ende tatsächlich darstellen muß, dann kann man natürlich den Trick anwenden, die invaliden Abschnitte einfach in ein Javascript zu packen. So werden sie zwar vom Validator überlesen, der Browser wird aber später trotzdem gezwungen, sie per document.write() einzubetten und darzustellen. Man sollte sich nur überlegen, ob das dann wirklich der Sinn der Sache war.

Das endgültige HTML, das der Browser bei meiner Methode am Ende darstellen muß, besteht fast ausschließlich aus Containern und Bildern und ist somit so gut wie valide. Man kann ihn sich hier anschauen. (Einzig die alt-Attribute bei den Bildern fehlen – daran hat man bei Google leider nicht gedacht.)
Baut man jedoch den direkt von Google gelieferten, „schlechten“ Code mittels Javascript ein, muß der Browser anschließend das hier darstellen. Also doch wieder einen I-Frame. Und die entsprechen nun mal einfach nicht der XHTML-Spezifikation.

Es ist also natürlich ein Leichtes, schlechten/falschen/invaliden Code vor dem tollen W3C-Validator zu verstecken, aber das war ja hier nicht mein Anliegen. Mir ging es darum, eine Google-Map so einzubauen, daß das, was am Ende beim Browser ankommt, auch tatsächlich valider Code ist und nicht invalider, der nur geschickt reingeschmuggelt wurde.

Links:
  1. Google Maps über API einbinden  – webmasterpro.de
  2. Google Maps API benutzen  – drweb.de


Kommentare

  1. 18. Dezember 2010
    17:29 Uhr

    Ginchen flag

    Jor – das war damals eigentlich nur ein „Unfall“. Hatte da beim Erstellen meines neuen Themes noch den alten Wert drin gehabt. Dennoch ändert das ja nix an dem hier vorgestellten Code, darum hatte ich diesen „Einwand“ damals nicht ganz verstanden. ;)

  2. 18. Dezember 2010
    16:35 Uhr

    abcman flag

    So lange die Seite nicht als application/xhtml+xml ausgeliefert wird, ist sie nicht zu 100 % XHTML und kein Browser profitiert davon da immer noch der langsame HTML-Parser verwendet werden muss!

  3. 22. Mai 2009
    16:38 Uhr

    Peter flag

    “ … leider geht aber Dein Link schon wieder nicht… “

    Deshalb hab‘ ich ihn auch gleich ein zweites mal geposted, der geht hoffentlich. ;-)

    Den ersten Eintrag darfst Du also getrost wieder löschen falls er zu arg stört!

    Und der „Quell der Weisheit“ ist geschenkt, denn der Titel gebührt wohl eher Google…:-)

  4. 22. Mai 2009
    14:39 Uhr

    Ginchen flag

    Naja, das Maskieren mache ich ja nur, damit ich unkompliziert HTML-Tags im Javascript notieren kann und nicht, um dort nicht-valides HTML notieren zu können. ;) Was der Browser in meinem Beispiel am Ende mittels Javascript erzeugt, ist reines, valides HTML in Form von etlichen Containern und Bildern. Bei Deiner Methode dagegen erzeugt er einen (nicht validen) I-Frame.

    Dennoch bist Du ein wahrer Quell der Weisheit – auf die Idee mit PHP kam ich irgendwie auch noch nicht. ;)
    … leider geht aber Dein Link schon wieder nicht… :D

  5. 22. Mai 2009
    14:35 Uhr

    Peter flag

    Naja,

    mit dem div-Container für das Ajax hast du vielleicht recht, der ist in der Tat XHTML-konform (wie alle Container).

    Aber Javascript ist es per se eigentlich nicht!
    Du maskierst ja auch das Javascript mit dem CDATA vor dem Validator – oder nicht? Da macht es qualitativ kaum einen Unterschied auch noch einen iframe zu maskieren…

    Cool wird es erst, wenn Du Googlemaps via php einbindest – nämlich ganz ohne Javascript.

    Dann ist es immer schön valide und es ist (großes Plus!) zudem auch völlig gleich ob jemand Javascript clientseitig abgestellt hat.

    Wie das geht?

    Schau hier!

  6. 22. Mai 2009
    13:26 Uhr

    Ginchen flag

    Deine Google-API Sache ist ja auch nur deswegen valide weil sie auf Javascript basiert!

    Hmm, das ist irgendwie nicht ganz richtig. Da ist doch nur ein div, in das per Script verschiedene Bilder reingeladen werden. Kein iframe oder sowas, der nur durch Javascript vor dem Validator „getarnt“ wird.
    Also, wenn man es auf echtes XHTML anlegt, würde ich bei meiner Methode bleiben, während bei Deiner der Browser am Ende ja doch wieder gezwungen wird, nicht-validen Code darzustellen.

    Trotzdem finde ich Deine Variante super, wenn man nicht ganz so ein Korinthenkacker ist wie ich! ;)
    Ich füge das später mal noch in den Post ein.

    P.S.: Das mit den Sonderzeichen in Kommentaren muß ich echt mal ändern… :D

  7. 19. Mai 2009
    12:00 Uhr

    Peter flag

    Ach Ginchen!
    Du bist mir vielleicht ein Bienchen!
    Ist nicht bös‘ gemeint… ;-)

    Probier‘ mal folgendes (XHTML 1.0 strict valides) script :

    <script type="text/javascript">
    /* <![CDATA[ */
    
    document.write('<iframe width="425" height="350" frameborder="0" scrolling="no"
    marginheight="0" marginwidth="0" src="http://maps.google.de/maps?f=q&source=s_q&hl=de&
    geocode=&q=Pariser+Platz+1,+10117+Berlin&sll=52.52301,13.381948&
    sspn=0.035929,0.077248&ie=UTF8&z=14&iwloc=A&ll=52.522854,13.381948&output=embed">
    </iframe><br /><small><a href="http://maps.google.de/maps?f=q&source=embed&hl=de&
    geocode=&q=Pariser+Platz+1,+10117+Berlin&sll=52.52301,13.381948&sspn=0.035929,0.077248&
    ie=UTF8&z=14&iwloc=A&ll=52.522854,13.381948" style="color:#0000FF;text-align:left">
    Größere Kartenansicht</a></small>');
    
    /* ]]> */
    </script>

    dann funzt es XHTML 1.0 Strict valide, weil scriptbasierte funktion…

    Deine Google-API Sache ist ja auch nur deswegen valide weil sie auf Javascript basiert!

    Viel Spass!

  8. 3. Mai 2009
    1:24 Uhr

    Ginchen flag

    Okay, I am now. But I don’t see what that has to do with my Google Map code!?

  9. 3. Mai 2009
    1:09 Uhr

    Andre flag

    you are not serving your page with Content-Type: application/xhtml+xml

Kommentieren

Erlaubtes HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <p> <pre lang="" line="" escaped=""> <q cite=""> <strike> <strong> <img src="" alt="" class="" width="" height=""> | Codeschnipsel können in `backticks` gepostet werden. Beispiel: `<?php echo "Hi!"; ?>`