Deutsch English
Internet, Programming Diesen Artikel auf Deutsch lesen

Embedding Google Maps XHTML conform

I’m quite glad I can write this post, for it allows me to parenthetically intersperse the news that I did not deem worthy of an own post: I have spent the last three days making this site XHTML valid. First I had started with the Transitional version, because otherwise several things which I wanted to keep wouldn’t have worked anymore. But then suddenly, I was struck by thunder and thought: “What the hell are you doing?!” – And true to my motto “Completely or not at all”, I began rewriting this site to XHTML Strict. If anybody wants to convince himself of the success of my work, you are welcome to click here. (Only the visitors page has not been adapted yet – I still have to figure out how this can be done.)

A great problem that took me almost a whole day to solve (including search for solutions[1] [2]) were the Google Maps I use here and there. Google itself offers a short, single-line code for quick integration of maps on a website, which embeds the map into the page by means of an IFrame. Well, what a pity that IFrames aren’t allowed in XHTML Strict. My attempts to take the map URL from the code and somehow embed it as an object failed miserably as well. So there was only one way left: the Google Maps API. In the following, I will try to explain how that works. But one thing beforehand: It is a little more laborious and requires a bit more work than just copying a code snippet and inserting it somewhere.

First of all, you will need a Google account and a Google API key. That doesn’t cost anything, and you don’t have to reveal private data either. You only have to specify the domain on which the key shall be used. Then we’re ready to go.

Step 1

First you need to create a <div> with a unique ID in the place where the map should appear:

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

Step 2

Now you have to insert your API key between <head> and </head> as follows:

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

Step 3

In step 4, we will write a javascript function which creates our map and displays it inside of our <div>. We shall call that function load(). In order to activate it when loading the page, you have to extend the <body> tag as follows:

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

The function GUnload() belongs to the Google API and is useful to minimize memory problems. It is therefore advisable to implement it here.

Step 4

Now for the heart of our code, the load() function, which will finally create our map. You can put it in the <head> section as well; that’s not necessarily needed though – you can also insert it at a later point. If you plan to create a very extensive map with many location markers, you can of course write the script into an own .js file for order’s sake, and then integrate it like this:

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

Now, as for the map, I think it’s easiest and most comprehensible if I post a complete example and then explain it:

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>
  • Lines 2 and 26:
    The script is defined as a CDATA section. That allows us to use characters like <, > etc. inside of the script without the browser interpreting them as HTML and destroying the layout.
  • Line 4:
    The map is being created and displayed inside the element with the ID “map”. And that is our <div> which we created earlier and which shall contain the map.
  • Line 5:
    The display type is chosen. There are three options:
    • G_NORMAL_MAP – ordinary vectorized map
    • G_SATELLITE_MAP – satellite photos
    • G_HYBRID_MAP – a mixture of the former two: satellite photos which are overlaid with the vector map
  • Line 8:
    The buttons for zooming and navigation on the map are created. Again, there are three options:
    • GSmallZoomControl() – only two small plus and minus buttons for zooming
    • GSmallMapControl() – plus and minus buttons as well as four arrows
    • GLargeMapControl() – four arrows and a zoom scale
  • Line 11:
    The buttons in the upper right, which allow the user to switch between vector, satellite and hybrid view, are being implemented.
  • Line 14:
    The center point, i. e. the centering of the map, is defined. For this purpose, you need to specify an exact location in degrees of longitude and latitude. I will explain below how to obtain these data.
  • Line 15:
    The map is now centered to the previously defined point. Also, the zoom factor is specified here: The higher the value, the further away you are from earth. The smaller the factor, the closer and more detailed is the view.
  • Lines 18–20 and 22–24:
    Here I have created two exemplary location markers. Based on this pattern, you can insert as many additional markers as you like. In the first line, you specify the desired location in degrees of latitude and longitude again, and in the second line you can design the popup, which appears after a click on the marker, with HTML as you wish. When copy & pasting, please don’t forget that the identifiers like “location1”, “location2” etc. always appear four times in every section and must be adapted accordingly.

Where do I get the latitudes and longitudes?

As for the coordinates, there are providers who have specialized in this very subject, e. g itouchmap.com. There you can enter an address or just move the marker to the desired position on the map and then immediately read off latitude and longitude.

The result of all these efforts can for example look like this:

Update (12. October 2009)

Although it’s been quite a while now: I remembered the discussion with commentator “Peter” every now and then and think that I should elaborate on that again in a more detailed manner:
If you only want to present the customer a “This document was successfully checked as XHTML 1.0 Strict!”, but actually don’t really care what code the browser has to display in the end, you can of course use the trick and just put the invalid parts inside a Javascript. This way they will be ignored by the validator, the browser, however, will later be forced to embed and display them via document.write() anyway. You should just ask yourself if that really was the point of it.

The final HTML that the browser has to display using my method consists almost exclusively of containers and images and is thereby as good as valid. You can have a look at it here. (Only the alt attributes of the images are missing – unfortunately, Google didn’t think of that.)
If, however, you insert the “bad” code delivered by Google itself with the help of Javascript, the browser has to display this afterwards. So, it’s an I-Frame again after all. And those simply don’t meet the XHTML specifications.

So, it is of course easy to hide bad/wrong/invalid code from the W3C validator, but that was not my concern here. I wanted to show how to implement a Google Map in a way so that the code that finally arrives at the browser is indeed valid code and not an invalid one that has just been cleverly smuggled in.

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


Comments

  1. 18th December 2010
    5:29 pm

    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. 18th December 2010
    4:35 pm

    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. 22nd May 2009
    4:38 pm

    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. 22nd May 2009
    2:39 pm

    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. 22nd May 2009
    2:35 pm

    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. 22nd May 2009
    1:26 pm

    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. 19th May 2009
    12:00 pm

    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. 3rd May 2009
    1:24 am

    Ginchen flag

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

  9. 3rd May 2009
    1:09 am

    Andre flag

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

Write comment

Allowed 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=""> | Code snippets can be posted in `backticks`. Example: `<?php echo "Hi!"; ?>`