Saturday, 26 January 2008

Playing with KML

The Idea

When I came back from holidays, I thought about creating a map of the journey in a way that I could share with friends. So I decided to try to do that using KML, the description language used by Google Earth. Google has tutorials and reference documentation about KML that got me started. In practice, what I wanted to do was very simple: lines showing the route and location pins showing the places I had visited on the way.

Document Structure

KML is a fairly straightforward XML dialect and the basic structure is very simple:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
  <Document>
    Content goes here
  </Document>
</kml>

Route

For the route, I wanted lines that would roughly follow the route I had taken. To do this in KML is simple: add a Placemark tag containing a LineString tag that itself contains the coordinates of the different points on the line. So a simple straight line from London to Hamburg looks something like this:

<Placemark>
  <name>Outward flight</name>
  <LineString>
    <altitudeMode>clampToGround</altitudeMode>
    <coordinates> -0.1261270000000025,51.50896699999998
    9.994621999999991,53.55686600000001
    </coordinates>
  </LineString>
</Placemark>

The name tag is not essential but this is what will show in the side bar in Google Earth so it's better to have one. The clampToGround value in the altitudeMode tag tells Google Earth that each point on the line is on the ground so you don't have to specify the altitude in the coordinates. In the coordinates tag is a space separated list of coordinates. In this case, each point is specified by a longitude and a latitude separated by a comma, the altitude being implied. Longitude is specified with positive values East of the Greenwich meridian and negative values West of it. Latitude is specified with positive values North of the equator and negative values South of it.

That's good but another thing I wanted to do was specify different colours for the different types of transport I used during my holidays. KML has the ability to define styles that you can then apply to Placemark tags. This is done by adding a number of Style tags at the beginning of the document. You then have to specify the style using a styleUrl tag. Applying this to the simple line above, we get:

<Style id="planeJourney">
  <LineStyle>
    <color>ff00ff00</color>
    <width>4</width>
  </LineStyle>
</Style>


<Placemark>
  <name>Outward flight</name>
  <styleUrl>#planeJourney</styleUrl>
  <LineString>
    <altitudeMode>clampToGround</altitudeMode>
    <coordinates> -0.1261270000000025,51.50896699999998
    9.994621999999991,53.55686600000001
    </coordinates>
  </LineString>
</Placemark>

Note that the value for the color tag in the LineStyle is the concatenation of 4 hexadecimal bytes. The first byte is the Alpha value, that is how opaque is the colour, in our case the value ff specifies it is completely opaque. The next three bytes represent the Red, Green and Blue values, in our case a simple green.

Places

For places, I wanted a simple marker that showed more information when you clicked on it. This is also very simple in KML: a Placemark tag containing a name, a description and a Point tags. The name needs to be a simple string but the description can contain a full blown HTML snippet inside a CDATA node so you can include images, links and all sorts of things. Note that the box that will pop up when you select the place mark is quite small so don't overdo it. Here is an example for London:

<Placemark>
  <name>London</name>
  <description><![CDATA[<p><img src="some URL" /></p>
<p><a href="some URL">More photos...</a></p>]]></description>
  <Point>
    <coordinates>-0.1261270000000025,51.50896699999998,0</coordinates>
  </Point>
</Placemark>

Note that the coordinates here include the altitude as well as the longitude and latitude. You could also apply a style to the location place marks, in the same way as was done for the lines.

KML or KMZ

Once you've created your file, you need to save it with a .kml extension. You can then open it in Google Earth. When you're happy with it, you can also zip it and rename it with a .kmz extension: Google Earth will be able to load it as easily but the file will be smaller. Both files can also be used with Google Maps and can be shared online. So here is my complete holiday map built with KML.

Tips and Tricks

Getting the exact coordinates of a particular place can be cumbersome. To make it easy, just find the place in Google Earth, create a temporary place mark if there is none you can use, copy it with the Edit > Copy > Copy menu option and paste it in your text editor: you'll get the KML that defines the placemark, with exact coordinates.

The clampToGround option in the altitudeMode tag specifies that the points you define in the coordinates are at ground level. The line between two points will be straight, irrespective of what lays between said points. So if you have a mountain range in between, you will see your line disappear through the mountains. To correct this, you should insert intermediary points where the highest points are located. This is why on my map the flight between Izmir and Paris has intermediary points so that the line can go past the Alps without being broken.

If you want to do more complex stuff, be careful that Google Maps only supports a subset of KML. Of course, the whole shebang is supported by Google Earth.

Conclusion

KML is a nice and simple XML dialect to describe geographical data and share it online. It certainly beats writing postcards to show your friends and family where you've been and it doesn't get lost in the post.

No comments: