Google Earth KML Tutorial

The Google Earth KML Document details everything you need to know to create and share information with the Google Earth client. If, however, you would like to jump right in and see some real examples of what you can do with KML, then this tutorial is for you.

All of the examples you will see here (and many more) are in the KML Tutorial file. Download that file to see what each of the following examples looks like in Google Earth.

Tip: If you want to see what the code looks like for any feature, you can simply click on the feature, right-click and select copy, and paste the content of the clipboard unto any text editor

Table of Contents:

1 Basic KML Documents

The simplest kind of KML documents are those that can be authored directly inside the client. That is, you don't need to edit or create any KML in a text editor. Placemarks, ground overlays, paths and polygons can all be authored directly in the Google Earth client.

1.1 Placemarks

Open the Google Earth Tutorial KML file and expand the Placemarks subfolder. There, you will see three different types of placemark: simple, floating, and tethered. The KML code for the tethered placemark looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Placemark>
  <description>Tethered to the ground by a customizable tail</description>
  <name>Tethethed placemark</name>
  <LookAt>
    <longitude>-122.0856375356631</longitude>
    <latitude>37.42240551227282</latitude>
    <range>305.8880792294568</range>
    <tilt>46.72425699662645</tilt>
    <heading>49.06133439171233</heading>
  </LookAt>
  <visibility>0</visibility>
  <Style>
    <IconStyle>
      <Icon>
        <href>root://icons/palette-3.png</href>
        <x>96</x>
        <y>160</y>
        <w>32</w>
        <h>32</h>
      </Icon>
    </IconStyle>
  </Style>
  <Point>
    <extrude>1</extrude>
    <altitudeMode>relativeToGround</altitudeMode>
    <coordinates>-122.0856204541786,37.42244015321688,50</coordinates>
  </Point>
</Placemark>
</kml>
The structure of this file breaks down as follows: (If you were wondering where the placemark is, it's right over Google's "Building 41," where we developed Google Earth!)

1.2 Descriptive HTML in Placemarks

The tutorial KML file has an example of almost everything you can do with your placemark text. Links can be made with standard <a href="http://...> tags, fonts can be sized, styled and colored, tables and text alignment are also possible. If you'd like to see the full list, copy and paste the "Descriptive Placemark" example into a text editor.

The most important thing you need to know about authoring your own HTML in placemarks is the use of the <![CDATA["]]> tag. If you want to write standard HTML inside a <description> tag, you really should put it inside a CDATA element. If you don't, the angle brackets will need to be written as entity references to prevent the Google Earth from parsing the HTML incorrectly. (This is a standard feature of XML applications and not unique to Google Earth.)

Consider the difference between HTML markup with CDATA tags:

<description>
    <![CDATA[
    <h1>CDATA Tags are important!</h1>
    <p><font color="red">Text is <i>more readable</i> and <b>easier to write</b> when you can avoid using entity references.</font></p>
    ]]>
</description>

And some without:

<description>
	&lt;h1&gt;CDATA Tags are important!&lt;/h1&gt;
	&lt;p&gt;&lt;font color="red"&gt;Text is &lt;i&gt;more readable&lt;/i&gt; and &lt;b&gt;easier to write&lt;/b&gt; when you can avoid using entity references.&lt;/font&gt;&lt;/p&gt;
</description>

Please note that GIF images are not supported in <img src=""> tags at the moment. This will be fixed for the next release.

 

1.3 Ground Overlays

KML for the various features shares a lot of common features. If you look at the source code for the example ground overlay in the tutorial file (which shows the eruption of Mt Etna in 2001), this is how it will appear:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<GroundOverlay>
  <description>Overlay shows Mount Etna erupting on July 13th, 2001.</description>
  <name>Large-scale overlay on terrain</name>
  <LookAt>
    <longitude>15.02468937557116</longitude>
    <latitude>37.67395167941667</latitude>
    <range>30350.36838438907</range>
    <tilt>58.31228652890705</tilt>
    <heading>-16.5581842842829</heading>
  </LookAt>
  <visibility>0</visibility>
  <Icon>
    <href>http://bbs.keyhole.com/ubb/z0302a1700/etna.jpg</href>
  </Icon>
  <LatLonBox id="khLatLonBox751">
    <north>37.91904192681665</north>
    <south>37.46543388598137</south>
    <east>15.35832653742206</east>
    <west>14.60128369746704</west>
    <rotation>0</rotation>
  </LatLonBox>
</GroundOverlay>
</kml>

You can see how it shares the XML header and KML namespace declaration (all KML files have these two lines at the top), and how it has similar <LookAt> and <visibility> tags.

The positioning of a ground overlay is controlled by the <LatLonBox> tag. Bounding values are given for the north and south latitudes, and east and west longitudes. In addition, rotation values are given for images whose y-axis doesn't coincide with grid north.

1.4 Paths

Many different types of paths can be created by and for Google Earth, and it is easy to be very creative with your data. Take a look at the "Absolute Extruded" example in the Paths folder and you can see how the shape has been generated by the following code:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Placemark>
  <description>Transparent green wall with yellow outlines</description>
  <name>Absolute Extruded</name>
  <LookAt>
    <longitude>-112.2643334742529</longitude>
    <latitude>36.08563154742419</latitude>
    <range>4451.842204068102</range>
    <tilt>44.61038665812578</tilt>
    <heading>-125.7518698668815</heading>
  </LookAt>
  <visibility>1</visibility>
  <open>0</open>
  <Style>
    <LineStyle>
      <color>ff00ffff</color>
    </LineStyle>
    <PolyStyle>
      <color>7f00ff00</color>
    </PolyStyle>
  </Style>
  <LineString>
    <extrude>1</extrude>
    <tessellate>1</tessellate>
    <altitudeMode>absolute</altitudeMode>
    <coordinates>
        -112.2550785337791,36.07954952145647,2357
        -112.2549277039738,36.08117083492122,2357
        -112.2552505069063,36.08260761307279,2357
        -112.2564540158376,36.08395660588506,2357
        -112.2580238976449,36.08511401044813,2357
        -112.2595218489022,36.08584355239394,2357
        -112.2608216347552,36.08612634548589,2357
        -112.262073428656,36.08626019085147,2357
        -112.2633204928495,36.08621519860091,2357
        -112.2644963846444,36.08627897945274,2357
        -112.2656969554589,36.08649599090644,2357
    </coordinates>
  </LineString>
</Placemark>
</kml>

Notice how it is really just one line drawn at altitude above the ground. The tessellate tag breaks the line up into smaller chunks, and the extrude tag extends the line down to the ground.

1.5 Polygons

Polygons are one of Google Earth's most powerful features. The tutorial folder contains a few examples to get you started.

Take a look at the Pentagon polygon in that folder. The shape is generated by the following code:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Placemark>
  <name>The Pentagon</name>
  <LookAt>
    <longitude>-77.05580139178142</longitude>
    <latitude>38.870832443487</latitude>
    <range>742.0552506670548</range>
    <tilt>48.09646074797388</tilt>
    <heading>59.88865561738225</heading>
  </LookAt>
  <Polygon>
    <extrude>1</extrude>
    <altitudeMode>relativeToGround</altitudeMode>
    <outerBoundaryIs>
      <LinearRing>
        <coordinates>
            -77.05788457660967,38.87253259892824,100 
            -77.05465973756702,38.87291016281703,100 
            -77.05315536854791,38.87053267794386,100 
            -77.05552622493516,38.868757801256,100 
            -77.05844056290393,38.86996206506943,100 
            -77.05788457660967,38.87253259892824,100
        </coordinates>
      </LinearRing>
    </outerBoundaryIs>
    <innerBoundaryIs>
      <LinearRing>
        <coordinates>
            -77.05668055019126,38.87154239798456,100 
            -77.05542625960818,38.87167890344077,100 
            -77.05485125901024,38.87076535397792,100 
            -77.05577677433152,38.87008686581446,100 
            -77.05691162017543,38.87054446963351,100 
            -77.05668055019126,38.87154239798456,100
        </coordinates>
      </LinearRing>
    </innerBoundaryIs>
  </Polygon>
</Placemark>
</kml>

It should be clear how the shape is generated by drawing simple inner and outer shells and extruding them down to the ground.

2 Advanced KML Documents

As powerful as the Google Earth client is for generating almost all of the features you will want to use, there are still more it can understand. These features, however, must be authored by you in a text editor.

2.1 Custom Styles

Once you have created features within the client and examined the code Google Earth generates, you will notice how styles are in important part of how your data is displayed. Power users will want to learn how to define their own styles.

The "Simple Icon Rollover" in the Styles and Markup folder shows you how to create a roll-over effect with KML.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
  <description>Place your mouse over the icon to see it display the new icon</description>
  <name>Simple Icon Rollover</name>
  <visibility>0</visibility>
  <Style id="normalPlacemark">
    <IconStyle>
      <Icon>
        <href>http://bbs.keyhole.com/ubb/z0302a1700/keyhole_icon.jpg</href>
      </Icon>
    </IconStyle>
  </Style>
  <Style id="highlightPlacemark">
    <IconStyle>
      <Icon>
        <href>http://bbs.keyhole.com/ubb/z0302a1700/google_icon.jpg</href>
      </Icon>
    </IconStyle>
  </Style>
  <StyleMap id="exampleStyleMap">
    <Pair>
      <key>normal</key>
      <styleUrl>#normalPlacemark</styleUrl>
    </Pair>
    <Pair>
      <key>highlight</key>
      <styleUrl>#highlightPlacemark</styleUrl>
    </Pair>
  </StyleMap>
  <Placemark>
    <name>Example Placemark</name>
    <visibility>0</visibility>
    <styleUrl>#exampleStyleMap</styleUrl>
    <Point>
      <coordinates>-122.0856545755255,37.42243077405461,0</coordinates>
    </Point>
  </Placemark>
</Document>
</kml>

Two separate styles are defined which are then mapped to a key pair. When the user places their mouse over the icon, it switches from "normal" to "highlight."

2.2 Screen Overlays

Screen overlays cannot be authored directly within the Google Earth client, and are thus more difficult to create than ground overlays. A comprehensive collection of samples is included in the Screen Overlays folder in the tutorial KML.

Let's take just one of these as an example. Open the "Absolute Positioning: Top left" file and you will see a screen overlay at the top left of the view window. This was created with the following KML code:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<ScreenOverlay>
  <name>Absolute Positioning: Top left</name>
  <Icon>
   <href>http://bbs.keyhole.com/ubb/z0302a1700/top_left.jpg</href>
  </Icon>
  <overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
  <screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
  <size x="0" y="0" xunits="fraction" yunits="fraction"/>
</ScreenOverlay>
</kml>

Positioning is controlled by mapping a point in the image specified by <overlayXY> to a point on the screen specified by <screenXY>. In this case, the top-left corner of the image (0,1) has been made coincident with the same point on the screen.

Check the other examples in the folder to see how it is possible to obtain other fixed positions, and to create images that size dynamically with screen size. (Note that xunits and yunits can also be specified as "pixels" for precision control.)

2.3 Network Links

So far, all of our examples have required that the KML be delivered to the Google Earth client from the local machine. Network links give you the power to serve content from a remote location. Network Links are commonly used to distribute data to large numbers of users. In this way, if the data needs to be amended, it has to be changed only at the source location, and all users receive the updated data automatically.

3 CGI Scripting for KML

A more powerful use of the network link is its use as a medium for the delivery of dynamic data. With some knowledge of a scripting language such as PHP, Python, or Perl, it's easy to deliver highly customized KML to each network link.

Two things are necessary for delivering KML through a network CGI:

When a call is made from the client to the server, the server must return a response code of HTTP 200 and set the response's content type to text/plain or application/keyhole

The response must be valid KML. For complex applications, it is imperative that the error-handling is perfect.

Tip: A simple way to handle errors is to parse the server's error as the text for a folder name. For example, you could have the server return <Folder><name>database inaccessible</name></Folder> as a string. This is more informative (and more user-friendly) than letting the connection drop.

The following examples will use PHP, but they are equally valid in any other scripting language.

3.1 Generating a Random Placemark

<?php
$lat_int = rand(-90, 90);
$lat_dec = rand(0, 1000000000);
$lon_int = rand(-180, 180);
$lon_dec = rand(0, 1000000000);
$lat = $lat_int.'.'.$lat_dec;
$lon = $lon_int.'.'.$lon_dec;
$response = '<Placemark>';
$response .= '<description>Generates a random placemark on each call to the server</description>';
$response .= '<name>Random KML server</name>';
$response .= '<visibility>1</visibility>';
$response .= '<Point>';
$response .= "<coordinates>$lon,$lat,0</coordinates>";
$response .= '</Point>';
$response .= '</Placemark>';
echo $response;
?>

This code generates random numbers for the integer and decimal components of the placemark and concatenates them into $lat and $lon. The KML code is then written to the $response variable, and echoed to the network link upon completion. You can activate the "Random Placemark" network link in your tutorial KML file to see this in action. To generate a new placemark, right-click on the link and select refresh. (To fly to the placemark, expand the network link and double-click on the placemark.)

4 View-Based Refresh Queries

A standard network link is a uni-directional link: data flows only from the server to the client. The view-based refresh enables bi-directional communication. When the view-based refresh is active, the client returns the view coordinates to the server at a specified time. This may be every N seconds, minutes or hours, or once a certain amount of time has elapsed since the view stopped moving.

The coordinates are returned to the server by means of an HTTP GET that appends the coordinates as follows:

GET /path/to/sever/script/query.php?BBOX=[longitude_west, latitude_south, longitude_east, latitude_north] HTTP/1.1

Which might look as follows if the request was made while the user was looking down on San Francisco:

GET /path/to/server/script/query.php?BBOX=-122.497790,37.730385,-122.380087,37.812331 HTTP/1.1

This feature can be used for some very creative applications, but to get you started, a simple example is presented below.

4.1 Tracking a Point Directly Under Your View

The following server-side PHP code will parse the client's return message and respond with a placemark at the center of the screen that has the current time in the name field. (To see it in action, open the Network Links folder in your tutorial KML and switch on the "View Centrered Placemark" link.)

<?php
// get the time
$timesnap = date("H:i:s");

// split the client's BBOX return by commas and spaces to obtain an array of coordinates
$coords = preg_split('/,|\s/', $BOX);

// for clarity, place each coordinate into a clearly marked bottom_left or top_right variable
$bl_lon = $coords[0];
$bl_lat = $coords[1];
$tr_lon = $coords[2];
$tr_lat = $coords[3];

// calculate the approx center of the view -- note that this is innaccurate if the user is not looking straight down
$userlon = (($coords[2] - $coords[0])/2) + $coords[0];
$userlat = (($coords[3] - $coords[1])/2) + $coords[1];

$response = '<?xml version="1.0" encoding="UTF-8"?>';
$response .= '<kml xmlns="http://earth.google.com/kml/2.0">';
$response .= '<Placemark>';
$response .= '<name>'.$timesnap.'</name>';
$response .= '<Point>';
$response .= "<coordinates>$userlon,$userlat,0</coordinates>";
$response .= '</Point>';
$response .= '</Placemark>';
$response .= '</kml>';
echo $response;
?>

The principle illustrated in the above code can be used for some very complex applications. For example, if you have a database of geographic information, you can extract the coordinates of the viewer, make a call to the database for the data specific to the view, and return it to the client as KML.

5 KML Server requirements

When responding to a request from the Google Earth client, a KML server must follow a certain set of rules so that the client can correctly interpret responses.

  • Upon success, the server must return a response code of HTTP 200 and set the response's content-type to a suitable MIME type.
  • Google Earth reads KML and KMZ files, and the MIME types for these are:
  • The body of the response must contain valid KML data, including the xml declaration header (<?xml version="1.0" encoding="UTF-8"?>). If the server returns invalid KML, the Network Link will stop deactivate and output an error message.
  •