Google Earth API

An Overview of Using KML in the Earth API

Roman Nurik, Google Geo APIs Team
January 2009

Contents

Objective

KML is a file format used to display geographic data in an Earth browser such as Google Earth, Google Maps, and Google Maps for Mobile. It was originally designed by Keyhole, Inc. (acquired by Google) and is currently maintained by the Open Geospatial Consortium, Inc. (OGC). You can find a significant amount of documentation for KML on Google Code and a large assortment of community-contributed KML datasets can be found in the Google Earth Gallery.

KML plays an important role in all of the Google Geo developer products, especially the Google Earth API. This article describes how to load and display KML files in the Google Earth Plug-in using fetchKml (or Network Links) as well as how to do the same with arbitrary KML strings using parseKml.

Prerequisites

This article assumes you are familiar with JavaScript and know the basics of the Earth API. Make sure you have read the Developer's Guide and have tried the Hello, Earth Demo before you continue.

Comparison of KML display methods

  KmlNetworkLink fetchKml parseKml
Coding difficulty Easy Medium Easy
Allows for manipulating KML before displaying it No Yes Yes
KML source URL pointing to a KML or KMZ file URL pointing to a KML or KMZ file KML String
Data return method N/A (no KML data is returned) Asynchronous (data returned via a callback function) Synchronous (data returned immediately)

In summary, if you need a quick and easy way of showing a hosted KML file and you do not need to do any intermediate processing, use the KmlNetworkLink approach. If you do need to do intermediate processing (for example, if you need to run through the features in the KML file and do something with them), use the fetchKml technique. Finally, if you have a string containing KML (as opposed to a URL), use the parseKml method.

Fetching, parsing and displaying a hosted KML file with fetchKml

Suppose that you want to do some intermediate processing before displaying a KML file in the Google Earth Plug-in. To do this, we will use fetchKml, which takes a URL string and returns an object derived from the KmlFeature class, representing the DOM hierarchy representing the contents of the URL.

Modify the addKmlFromUrl function as in the following example:

function addKmlFromUrl(kmlUrl) {
  google.earth.fetchKml(ge, kmlUrl, kmlFinishedLoading);
}

Then, write the code for the kmlFinishedLoading callback function, which adds kmlObject to the Google Earth Plug-in instance's own DOM hierarchy:

function kmlFinishedLoading(kmlObject) {
  if (kmlObject) {
    ge.getFeatures().appendChild(kmlObject);
  }
}

One of the key benefits to this method is that you can now traverse the loaded kmlObject and modify its DOM as needed before calling appendChild to show it to the end user. For example, if you want to remove the first child feature in the DOM tree, modify the kmlFinishedLoading function like so:

function kmlFinishedLoading(kmlObject) {
  if (kmlObject) {
    // check if the object is a KmlContainer (folder or document)
    if ('getFeatures' in kmlObject) {
      var firstChild = kmlObject.getFeatures().getFirstChild();
      if (firstChild !== null) {
        kmlObject.getFeatures().removeChild(firstChild);
      }
    }

    ge.getFeatures().appendChild(kmlObject);
  }
}

For more information on DOM traversal, see the API references for KmlContainer::getFeatures() and GESchemaObjectContainer.

A caveat with the fetchKml method is that the plugin view isn't automatically adjusted to zoom in on the KML file that was added. Currently, the best and most portable way of doing that is by supplying a document-level <LookAt> in your target KML file:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <LookAt>
      ...
    </LookAt>
    ...
  </Document>
</kml>

and then manually flying to that view like so:

function kmlFinishedLoading(kmlObject) {
  if (kmlObject) {
    ge.getFeatures().appendChild(kmlObject);

    if (kmlObject.getAbstractView() !== null)
      ge.getView().setAbstractView(kmlObject.getAbstractView());
  }
}

The target KML can have any type of Feature as the root element, be it <Document>, <Folder>, <Placemark>, etc. The kmlObject variable will be an instance of the corresponding Kml... class, such as KmlDocument, KmlFolder, KmlPlacemark, etc.

Behind the scenes

Under the hood, fetchKml and the Google Earth Plug-in do the following:

  1. First, fetchKml tells the Google Earth Plug-in to initiate an asynchronous HTTP GET request to the provided URL.

    Note: fetchKml returns immediately with no return value, since results are retrieved asynchronously.

  2. When a response is received, the plugin parses the response (be it in KML or KMZ format) into a KML DOM structure.
  3. fetchKml then calls the provided JavaScript callback function with a KmlFeature instance representing the DOM as the first argument.

If at any point there is an error (HTTP error or KML parsing error), fetchKml will call the callback function with a null first argument.

View fetchKml demo

Parsing and displaying a KML string with parseKml

Sometimes it is desirable to display an arbitrary KML string that isn't hosted publicly. For these cases, the Earth API exposes the parseKml method. The parseKml method of the GEPlugin class takes a KML string and returns a KmlFeature-derived object that represents it.

As per the comparison table above, parseKml differs from fetchKml in that the resulting object is returned immediately. Below is an example of an addKmlFromString method that will parse and display KML immediately after the plugin is loaded::

function addKmlFromString(kmlString) {
  var kmlObject = ge.parseKml(kmlString);

  ge.getFeatures().appendChild(kmlObject);
}

...

addKmlFromString(
  '<?xml version="1.0" encoding="UTF-8"?>' +
  '<kml xmlns="http://www.opengis.net/kml/2.2">' +
  '  <Placemark>' +
  '    <name>Test Placemark</name>' +
  '    <Point>' +
  '      <coordinates>' +
  '        -122,37' +
  '      </coordinates>' +
  '    </Point>' +
  '  </Placemark>' +
  '</kml>');

This method is often used as an alternative way to create Earth features, as opposed to using object creation functions such as createPlacemark. In some situations, it is faster and easier to call parseKml on a KML string built up using JavaScript string operations, than to make the equivalent Earth API calls. With parseKml, the bulk of the 'heavy lifting' work is done by the plugin, which runs on native, compiled code.

View parseKml demo

Next steps

This article showed some of the basic ways in which KML could be loaded in the Google Earth API. To learn more, visit the demo gallery or peruse the Earth API reference.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.