KML 2.1 Tutorial

This tutorial is designed to acquaint you with the exciting new features found in KML 2.1. If you're interested in a quick tour, start by clicking the links to view the samples in Google Earth. If you want more detail about the new KML elements, dive into the text and study the figures to understand how these features add flexibility and power to this new release of Google Earth. We're eager to see the innovative presentations and tours you create with these tools.

See the KML 2.1 Reference and KML 2.1 Schema for details on elements discussed here.

Highlights of KML 2.1

  • Regions - Regions provide culling and level-of-detail behavior that allow you to fine-tune how your data is presented in Google Earth. When used with NetworkLinks, Regions enable streaming of very large datasets, with "smart" loading of data at multiple levels of resolution (see the section on Super-Overlays). You can also simulate Google Earth's layers using Regions.
  • Textured 3D models - 3D objects can be modeled naturally in their own coordinate space and exported as COLLADA™ files, then imported into Google Earth and placed on the Earth's surface.
  • Incremental updates - Now you can incrementally update data loaded by NetworkLinks—changing, adding, and deleting KML data that was previously loaded into Google Earth.
  • Expiration date/time - You can specify a dateTime to refresh data so that the cache is flushed and data remains current.
  • Radio-button folders - To allow the user to select only one item in a folder at a time, use the new ListStyle element to specify a radioFolder.

Cool Samples

Check Out the Spec!

Here are some of the major new elements you'll be introduced to in KML 2.1:

Working with Regions

Regions are a powerful new KML feature that allows you to add very large datasets to Google Earth without sacrificing performance. Data is loaded and drawn only when it falls within the user's view and occupies a certain portion of the screen. Using Regions, you can supply separate levels of detail for the data, so that fine details are loaded only when the data fills a portion of the screen that is large enough for the details to be visible.

Note: In KML, some classes are derived from a "parent" class. The derived "child" classes inherit all of the elements of their parent class and add some specific elements of their own. (This is a common technique of object-oriented systems.) For convenience, this section refers to the parent class instead of listing all of the derived child classes. For example:

  • The term Feature refers to any KML element that is derived from Feature: Document, Folder, GroundOverlay, NetworkLink, Placemark, and ScreenOverlay.
  • Geometry refers to any geometric element in KML: Point, Polygon, LinearRing, LineString, Model, MultiGeometry.
  • Overlay refers to the elements derived from Overlay: GroundOverlay and Screen Overlay.

See the KML Reference for a diagram showing inheritance within KML elements.

Key Concepts

Any Feature can contain a Region. A Region affects visibility of a Placemark's geometry or an Overlay's image. Regions define both culling and level-of-detail behavior of the affected geometry or overlay. Regions are inherited through the KML hierarchy and affect the visibility of Features that are defined lower in the hierarchy.

This section describes the following key concepts that are necessary to understanding Regions:

Bounding Box

A Region has a <LatLonAltBox> that defines a bounding box for your data. A bounding box is a volume that encloses a set of objects or data points. Similar to the <LatLonBox> in a GroundOverlay, the <LatLonAltBox> in a Region has North, South, East, and West boundaries. If the data contained by the Region is 3D, or is 2D at altitude, then the Region's <LatLonAltBox> also needs to include a minimum altitude, <minAltitude>, and a maximum altitude, <maxAltitude>.

Objects associated with this bounding box are drawn when (1) the Region comes within view and (2) the projected onscreen size of the <LatLonAltBox> falls within the specified pixel range for that Region, as described in Level of Detail (LOD) . When both of these conditions are met, the Region is said to be "active."

Level of Detail (LOD)

The second important concept related to Regions is that of Level of Detail, or LOD for short. Since a computer screen has a limited amount of space, it's most efficient to set things up so that large amounts of data are loaded only when there are enough pixels to display the data adequately. When the Region is taking up a relatively small portion of the screen (perhaps because the user is viewing it from a great distance, or it is a flat area being viewed obliquely), the LOD mechanism allows you (the KML author) to specify a dataset with lower resolution to be substituted for the full-resolution data. This lower-resolution dataset loads faster, and since it occupies a small portion of the screen anyway, the user cannot possibly discern the difference.

In a Region, the <minLodPixels> and <maxLodPixels> elements allow you to specify an area of the screen (in square pixels). When your data is projected onto the screen, it must occupy an area of the screen that is greater than <minLodPixels> and less than <maxLodPixels> in order to be visible. Once the projected size of the Region goes outside of these limits, it is no longer visible, and the Region becomes inactive.

In the special case where you want the data to be active to infinite size, specify −1 (the default) for <maxLodPixels>.

Example 1: Region for a Ground Overlay

First, let's look at a simple example that constructs a Region for a 2D overlay at ground level. This example uses a ground overlay containing historic data showing a portion of Mountain View, California, in 1991. As the user zooms in on the area, the overlay becomes visible. Here is what the overlay looks like when it is first visible (the example file also includes a white LineString to make the overlay stand out better):

Screen shot showing black and white overlay coming into view

In this example, <minLodPixels> is 128, which means that the GroundOverlay comes into view when it occupies 128 square pixels on the screen. (The example uses the default value of -1 for <maxLodPixels>, which means that it will remain visible as the user zooms in at this angle.) The image used for this overlay is 256 square pixels square.

Here is what the image looks like as the user zooms in on it:

And here is what the tilted image looks like just before it becomes invisible because it consumes less screen space than the <minLodPixels> value:

The <LatLonAltBox> for this data does not need to include the <minAltitude> and <maxAltitude> elements because the data is flat and is at ground level. The bounding box for the data in the Region's <LatLonAltBox> is identical to the boundaries of the ground overlay's <LatLonBox>, as shown in the KML file below:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>Flat Region</name>
<Region>
<LatLonAltBox>
<north>37.430419921875</north>
<south>37.41943359375</south>
<east>-122.080078125</east>
<west>-122.091064453125</west>
</LatLonAltBox>
<Lod>
<minLodPixels>128</minLodPixels>
</Lod>
</Region>
<GroundOverlay>
<name>Mountain View DOQQ</name>
<Icon>
<href>files/image.JPEG</href>
</Icon>
<LatLonBox>
<north>37.430419921875</north>
<south>37.41943359375</south>
<east>-122.080078125</east>
<west>-122.091064453125</west>
</LatLonBox>
</GroundOverlay> <Document> </kml>

Also, within the KML file, notice that the Region is a sibling of the image (or geometry) whose visibility it affects.

Now that you've had time to examine the KML file, click the following link to load the overlay into Google Earth. Then experiment with different viewpoints and watch when the Region comes into view and out of view, depending on how much of the screen area it requires. Note that if you tilt the view far enough or if you zoom out quite a bit, the overlay disappears because it takes up too little screen space to meet the <minLodPixels> requirement.

View example in Google Earth (historicOverlay.kmz)

Altitude

Example 2: Region for a 3D Model

The following example shows how to construct a Region that contains 3D objects at ground level. The <LatLonAltBox> for this Region contains a <maxAltitude> of 300 meters since that is the height of the building. You'll probably recognize these buildings as the United Nations complex in New York City.

It's important to notice that the boundaries of the Region's <LatLonAltBox> do not necessarily match up exactly with the longitude and latitude boundaries of the Model. The coordinates for the Model are relative to its own local origin, which may be offset from the actual position of the Model on the Earth.

<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>3D Region on ground</name>
<Placemark>
<name>United Nations Headquarters</name>
<visibility>0</visibility>
<Region>
<Lod>
<minLodPixels>128</minLodPixels>
</Lod>
<LatLonAltBox>
<north>40.750683130314</north>
<south>40.748162385230</south>
<east>-73.966608428427</east>
<west>-73.969476624071</west>
<minAltitude>0</minAltitude>
<maxAltitude>300</maxAltitude>
<altitudeMode>absolute</altitudeMode>

</LatLonAltBox>
</Region>
<Model>
<altitudeMode>absolute</altitudeMode>
<Location>
<longitude>-73.967763927199</longitude>
<latitude>40.749458312255</latitude>
<altitude>0.406173708576</altitude>
</Location>
<Link>
<href>models/un.dae</href>
</Link>
</Model>
</Placemark>
</Document>
</kml>

Click the following link to load the file into Google Earth. Again, experiment with different viewpoints to see when the buildings become visible and when they are removed from the view.

View example in Google Earth (unitedNations.kmz)

Example 3: Region for a 2D Overlay at Altitude

This example shows how you would add a 2D overlay to display above the Earth's surface at a specified altitude. This technique is useful for data showing weather fronts and air traffic patterns. Here, the example shows a small cloud cover at an altitude of 100,000 meters above sea level.

The Region's <LatLonAltBox> specifies a value of 100,000 meters for both the <minAltitude> and <maxAltitude> elements. (The value is the same for both elements, since the Overlay is 2D and has no thickness.) The <altitudeMode> is absolute, which means that this value is relative to sea level.

Notice that the <altitude> value of the GroundOverlay is also 100,000 (that is, it matches the altitude value of the Region's bounding box), and the <altitudeMode> of the GroundOverlay matches the value specified for the Region's <altitudeMode>.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>Flat Region at altitude</name>
<GroundOverlay>
<name>Cloud overlay</name>
<Region>
<LatLonAltBox>
<north>33.75</north>
<south>22.5</south>
<east>-45</east>
<west>-56.25</west>
<minAltitude>100000</minAltitude>
<maxAltitude>100000</maxAltitude>
<altitudeMode>absolute</altitudeMode>

</LatLonAltBox>
<Lod>
<minLodPixels>128</minLodPixels>
</Lod>
</Region>
<Icon>
<href>files/image.PNG</href>
</Icon>
<altitude>100000</altitude>
<altitudeMode>absolute</altitudeMode>

<LatLonBox>
<north>33.75</north>
<south>22.5</south>
<east>-45</east>
<west>-56.25</west>
</LatLonBox>
</GroundOverlay>
</Document>
</kml>

View example in Google Earth (cloudRegion.kmz)

Fade Extent

You can also specify a fade extent for a Region, which allows an object to transition gracefully from transparent to opaque, and back again. Google Earth uses the maxFadeExtent to determine the ramp from fully transparent to fully opaque when the Region is at its maximum visible size, and it uses minFadeExtent to determine the fade ramp when the Region is at its minimum visible size. Fade ranges are optional, but they prevent the "pop" effect between LineStrings or Polygons of different resolutions. Fading is very expensive in terms of performance and should not be used with imagery.

Note: The fade range applies to all objects except for placemark icons. These icons are drawn when the fade range is greater than 0.5.

 

The following example illustrates how the fade extent affects a LineString.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>Region in Placemark LineString</name>
<description>
The LineString corners mark the extent
of the Region LatLonAltBox.
The LineString minFadeExtent (at greatest range)
is 1/4 of the maxFadeExtent (at closest range)..
</description>
<Placemark>
<name>Region LineString</name>
<LineString>
<coordinates>
22,50,0
28,50,0
28,45,0
22,45,0
22,50,0
</coordinates>
</LineString>
<Region>
<LatLonAltBox>
<north>50</north>
<south>45</south>
<east>28</east>
<west>22</west>
</LatLonAltBox>
<Lod>
<minLodPixels>128</minLodPixels>
<maxLodPixels>1024</maxLodPixels>
<minFadeExtent>128</minFadeExtent>
<maxFadeExtent>512</maxFadeExtent>

</Lod>
</Region>
</Placemark>
</Document>
</kml>

View example in Google Earth (fadeLineString.kml)

Nesting Regions

A common use of Regions is to nest them, with the larger Regions associated with coarser resolution, and the smaller, inside Regions associated with increasingly finer levels of detail. In the following figure, each Region has a set of LOD limits that specify the projected screen size of the Region in pixels that is required for the associated Region to be active. As the user's viewpoint moves closer, Regions with finer level of detail (LOD) become active because the Region takes up more screen space. The Regions with finer LOD replace the previously loaded Regions with coarser LODs.

As successive nested Regions become active they can

  • Accumulate data associated with each Region (as in the Super-Overlay example described below)
  • Replace the data of the previously loaded Region with new data (as illustrated in the previous figure)

A <LatLonAltBox> in a child Region should be wholly contained within the <LatLonAltBox> of its parent Region. Regions are inherited through the Folder and NetworkLink hierarchy. Regions defined locally take precedence over Regions defined higher in the Folder hierarchy. The following example illustrates how the local scope of a Region overrides a Region defined higher in the hierarchy. In this example, the placemark "ukraineRegion" inherits the Region from its parent Document. The Folder "romaniaFolder" specifies its own Region, which is used by the Placemark "romaniaRegion." See the next section on "Smart" Loading of Region-Based Network Links for more examples of how to use Regions within NetworkLinks for maximum efficiency.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>Nested Regions</name> <Region> <LatLonAltBox> <north>56.25</north> <south>45</south> <east>33.75</east> <west>22.5</west> </LatLonAltBox> <Lod> <minLodPixels>128</minLodPixels> <maxLodPixels>1024</maxLodPixels> </Lod> </Region> <Placemark> <name>ukraineRegion</name> <LineString> <tessellate>1</tessellate> <coordinates> 22.5,45,0 33.75,45,0 33.75,56.25,0 22.5,56.25,0 22.5,45,0 </coordinates> </LineString> </Placemark> <Folder> <name>romaniaFolder</name> <Region> <LatLonAltBox> <north>50.625</north> <south>45</south> <east>28.125</east> <west>22.5</west> </LatLonAltBox> <Lod> <minLodPixels>128</minLodPixels> <maxLodPixels>1024</maxLodPixels> </Lod> </Region> <Placemark> <name>romaniaRegion</name> <LineString> <tessellate>1</tessellate> <coordinates> 22.5,45,0 28.125,45,0 28.125,50.625,0 22.5,50.625,0 22.5,45,0 </coordinates> </LineString> </Placemark> </Folder> </Document> </kml>

The Region-based NetworkLink shown in the preceding example is the most efficient way to publish a very large dataset in Google Earth. Using Regions in conjunction with NetworkLinks, you can create a hierarchy of pointers, each of which points to a specific sub-Region. The <viewRefreshMode>, as shown in the following KML file, has an onRegion option, which specifies to load the Region data only when the Region is active. If you provide nested Regions with multiple levels of detail, larger amounts of data are loaded only when the user's viewpoint triggers the next load. The following section on Super-Overlays provides a detailed example.

Part 1: Parent file

To run this example, save the first part as usual. Save the second part as romaniaRegion.kml so that the NetworkLink will be able to load the Region when it becomes active.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>Nested Regions</name> <Region> <LatLonAltBox> <north>56.25</north> <south>45</south> <east>33.75</east> <west>22.5</west> </LatLonAltBox> <Lod> <minLodPixels>128</minLodPixels> <maxLodPixels>1024</maxLodPixels> </Lod> </Region> <Placemark> <name>ukraineRegion</name> <LineString> <tessellate>1</tessellate> <coordinates> 22.5,45,0 33.75,45,0 33.75,56.25,0 22.5,56.25,0 22.5,45,0 </coordinates> </LineString> </Placemark> <NetworkLink> <name>romania NetworkLink</name> <Region> <LatLonAltBox> <north>50.625</north> <south>45</south> <east>28.125</east> <west>22.5</west> </LatLonAltBox> <Lod> <minLodPixels>128</minLodPixels> <maxLodPixels>1024</maxLodPixels> </Lod> </Region> <Link> <href>romaniaRegion.kml</href> <viewRefreshMode>onRegion</viewRefreshMode> </Link> </NetworkLink> </Document> </kml>
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>romania Document</name>
<Region>
<LatLonAltBox> <north>50.625</north> <south>45</south> <east>28.125</east> <west>22.5</west> </LatLonAltBox>
<Lod> <minLodPixels>128</minLodPixels> <maxLodPixels>1024</maxLodPixels> </Lod>
</Region> <Placemark> <name>romaniaRegion</name> <LineString> <tessellate>1</tessellate> <coordinates> 22.5,45,0
28.125,45,0 28.125,50.625,0 22.5,50.625,0 22.5,45,0 </coordinates> </LineString> </Placemark>
</Document>
</kml>

Super-Overlays

Q: How can I share a 47MB image with the world?
A: One piece at a time.

Q: What happens if everyone tries to do this?
A: If you use Region-based NetworkLinks and supply multiple levels of detail for your imagery as described in this tutorial—no problem!

This section describes how to create a "super-overlay"—a hierarchy of Regions and NetworkLinks that can be used to efficiently serve a large set of imagery. Tiles of appropriate resolution are loaded as portions of the imagery area come into view, with higher resolution tiles loaded as the viewpoint nears. It's a waste of effort to try to display a 7008-by-6720-pixel image on a 1024-by-768 screen. What's more, if the user is miles above the earth's surface, all that data might be crammed into a handful of pixels, and performance is dismal. Super-overlays, such as our sample showing a 1991 DOQQ of Mountain View, California, allow you to take advantage of NetworkLinks and their ability to determine (1) whether a given Region is within view and (2) whether its projected size is appropriate to the current viewpoint. If the Region is "active" (both conditions are met), the NetworkLink loads the data associated with the Region. If the Region is inactive, no data is loaded. If you subdivide the original image into a hierarchy of images with increasing levels of detail, Google Earth can load the imagery that best fits the current view.

To see how this image hierarchy is used, load this sample file into Google Earth and experiment by zooming in and out on the area of interest: Mountain View Historial DOQQ.

 

Example of using region-based network links to efficiently load a very large dataset. The original image is 7008 by 6720 pixels. The oblique view shown here loads only five small tiles to represent this image. (White linestrings have been added to highlight the tile boundaries.) This application shows presenting historical imagery for the city of Mountain View (a 1991 DOQQ).

Preparing Your Data for a Super-Overlay

In the sample super-overlay, the original Mountain View image is subdivided into hundreds of small GroundOverlays. These overlays, or tiles, are arranged in a five-level hierarchy. For purposes of example, the discussion here uses a simple three-level hierarchy and a set of 21 overlays, but the principles involved are the same. Note that this is just one approach to creating a hierarchy of region-based network links and that there are other ways to implement this mechanism.

To create a super-overlay, you need to

  1. Prepare the imagery by subdividing it into manageable chunks (256-by-256 pixels is recommended), and
  2. Create the KML files that set up the Regions, Links, Network Links, and, in this case, the files containing the GroundOverlays.

Prepare the imagery

Pick a standard size for your tiles, which are the subdivided images (of varying resolutions) that Google Earth will load as their associated Regions become active. For purposes of example, we'll use 256-by-256 pixels for our tiles, which is a small enough size to be manageable.

  1. Start with the original, full-resolution image. Subdivide it into n tiles, and then subdivide each of those tiles into n tiles.
    Continue subdividing until you have tiles of a given size (in our example, 256-by-256 pixels).

    Let's assume our original image is 1024-by-1024 pixels.
    The following hierarchy would result when we subdivide it.
  2.  

     

  3. Resample each tile in the hierarchy to the standard size you've chosen (for example, 256-by-256 pixels).
    These resampled tiles will have less detail, but will be associated with Regions that are active at more
    distant viewpoints, so the loss in detail will be imperceptible to the user.

 


The diagram below shows how the viewpoint and the definition of the nested Regions determine which tiles are actually loaded. Three levels of detail are provided for this sample large piece of imagery. When the user looks at the Region from the greatest distance, Google Earth displays the thumbnail view. This view is stretched over its entire LatLonAltBox (but since the projected size is small—256 square pixels—there is no actual loss of visual information). As the user zooms in on the scene, the Region is divided into four Regions. Each of these four "tiles" has the same size as the thumbnail image but provides more detailed imagery.

If the user continues to zoom in on the area, portions of the full resolution imagery come into view, depending on how close the user travels to them. Areas in the distance retain the less detailed imagery that was loaded first. In the Mountain View DOQQ example, enable "Boxes" and check out Placemarks A and B, which use LineStrings around the Regions and show multiple levels of the hierarchy at one time.

Notice that the sample uses the same values for minLodPixels and maxLodPixels for all Regions (at all levels of the hierarchy). It's the LatLonAltBox that determines which level of the hierarchy should be loaded, and which tile(s) within the Region.

Prepare the KML files

For each image, prepare a KML file that associates the ground overlay with a Region and a NetworkLink. Each KML file in this set has the following elements:

  • a Region (with LatLonAltBox, minLodPixels, and maxLodPixels so that Google Earth can determine whether the Region is active at any given time)
  • a set of NetworkLinks to the child files (the tiles in the next level of the hierarchy)
  • the ground overlay for this Region

This sample shows the top-level KML file for the Mountain View DOQQ example. For maxLodPixels, it specifies -1, which has the special meaning "active to infinite size." Without this specification, the entire hierarchy might never be triggered.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<NetworkLink>
<name>SuperOverlay: MV DOQQ</name>
<Region>
<LatLonAltBox>
<north>37.44140625</north>
<south>37.265625</south>
<east>-121.9921875</east>
<west>-122.16796875</west>
</LatLonAltBox>
<Lod>
<minLodPixels>128</minLodPixels>
<maxLodPixels>-1</maxLodPixels>
</Lod>
</Region>
<Link>
<href>http://mw1.google.com/mw-earth-vectordb/kml-samples/mv-070501/1.kml</href>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>
</NetworkLink>
</kml>

The following file shows a Region in the Mountain View DOQQ example (179.kml). This file contains five href tags: four refer to the four KML files in the next level of the image hierarchy, and one refers to the image file used for the GroundOverlay for this tile.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<Region>
<Lod>
<minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>
</Lod>
<LatLonAltBox>
<north>37.430419921875</north><south>37.41943359375</south>
<east>-122.091064453125</east><west>-122.10205078125</west>
</LatLonAltBox>
</Region>
<NetworkLink>
<name>001120</name>
<Region>
<Lod>
<minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>
</Lod>
<LatLonAltBox>
<north>37.430419921875</north><south>37.4249267578125</south>
<east>-122.0965576171875</east><west>-122.10205078125</west>
</LatLonAltBox>
</Region>
<Link>
<href>180.kml</href>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>

</NetworkLink>
<NetworkLink>
<name>001121</name>
<Region>
<Lod>
<minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>
</Lod>
<LatLonAltBox>
<north>37.430419921875</north><south>37.4249267578125</south>
<east>-122.091064453125</east><west>-122.0965576171875</west>
</LatLonAltBox>
</Region>
<Link>
<href>185.kml</href>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>

</NetworkLink>
<NetworkLink>
<name>001122</name>
<Region>
<Lod>
<minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>
</Lod>
<LatLonAltBox>
<north>37.4249267578125</north><south>37.41943359375</south>
<east>-122.0965576171875</east><west>-122.10205078125</west>
</LatLonAltBox>
</Region>
<Link>
<href>190.kml</href>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>

</NetworkLink>
<NetworkLink>
<name>001123</name>
<Region>
<Lod>
<minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>
</Lod>
<LatLonAltBox>
<north>37.4249267578125</north><south>37.41943359375</south>
<east>-122.091064453125</east><west>-122.0965576171875</west>
</LatLonAltBox>
</Region>
<Link>
<href>195.kml</href>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>

</NetworkLink>
<GroundOverlay>
<drawOrder>5</drawOrder>
<Icon>
<href>179.JPEG</href>
</Icon>

<LatLonBox>
<north>37.430419921875</north><south>37.41943359375</south>
<east>-122.091064453125</east><west>-122.10205078125</west>
</LatLonBox>
</GroundOverlay>
</Document>
</kml>

Displaying 3D Objects

In KML 2.1, you can import 3D models—such as buildings, bridges, monuments, and statues—in the COLLADA interchange file format. Models are defined independently of Google Earth in their own coordinate space, using applications such as SketchUp, 3D Studio Max, Softimage XSI, or Maya. When a 3D model is imported into Google Earth, it is translated, rotated, and scaled to fit into the Earth coordinate system. Models already loaded into Google Earth can be repositioned and resized using the <Update> element, another new feature in KML 2.1.

Sample Model

A model is used in Google Earth just as any other geometry object (point, linestring, or polygon). Here is a simple example of a KML file that imports a textured model.

The <Link> reference to the model can be an an absolute or relative file specification, or a URL.

To view this model, load the file MackyBldg.kmz, which is an archive that contains all the necessary texture and overlay files as well as this doc.kml file containing the Model:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Placemark>
<name>SketchUp Model of Macky Auditorium</name>
<description>University of Colorado, Boulder; model created by Noël Nemcik.</description> <LookAt>
<longitude>-105.2727379358738</longitude>
<latitude>40.01000594412381</latitude>
<altitude>0</altitude>
<range>127.2393107680517</range>
<tilt>65.74454495876547</tilt>
<heading>-27.70337734057933</heading> </LookAt> <Model id="model_4">
<altitudeMode>relativeToGround</altitudeMode>
<Location>
<longitude>-105.272774533734</longitude>
<latitude>40.009993372683</latitude>
<altitude>0</altitude>
</Location>
<Orientation>
<heading>0</heading>
<tilt>0</tilt>
<roll>0</roll>
</Orientation>
<Scale>
<x>1</x>
<y>1</y>
<z>1</z>
</Scale>
<Link>
<href>files/CU Macky.dae</href>
</Link>
</Model>
</Placemark>
</kml>

The model is positioned geographically with the Location element's latitude, longitude, and altitude specifications. This example uses default values for the Orientation and Scale elements, which are included here for completeness.

The Orientation element specifies rotations of the model around the x (tilt), y (roll) and z (heading) axes. The y axis points North and is parallel to longitude lines, and the x axis points East and is parallel to latitude lines. Rotations are specified in degrees, with positive rotations as shown in the following diagram.

Creating a .kmz Archive

A KMZ archive is collection of files used to create a single KML presentation. This archive includes all the local files that are referenced in the .kml file, such as images, textures, and models. A KMZ archive is a self-contained package that does not need to be hosted on a network server and can easily be e-mailed and stored as a single unit. Google Earth can read .kml and .kmz files directly.

The doc.kml file and the local files it references are compressed into an archive using the ZIP file format. Many applications can produce this format. WinZip on Windows systems, Stuffit on Macintosh systems, and zip on Linux or Macintosh systems are popular applications that can read and write the ZIP format. You can also work with zip archives using the Windows Explorer or Mac Finder directly.

After you have created the .zip file, change the file extension to .kmz.

The KMZ archive containing the complete textured model for the Macky Building includes these files:

  • doc.kml - the KML file shown above, which imports the COLLADA (.dae) model and places it in Google Earth. Place this file in the root directory of the KMZ (ZIP) file.
  • textures.txt - used to remap texture paths in the model file (here, CU Macky.dae) to paths inside the KMZ file. Place this file in the root directory of the KMZ (ZIP) file. Every texture referenced in CU Macky .dae has one line in textures.txt of the form:
<kmz_file_path> <COLLADA_file_path> [<KML_ID_of_model>]

<kmz_file_path> is the relative path within the KMZ archive to where the texture is located. This path is relative to CU Macky.dae, which is in the files/ directory in the KMZ archive. Since the textures are stored in the files/ directory, the <kmz_file_path> should begin with ../files/ .

<COLLADA_file_path> is the name of the texture file exactly as it appears in CU Macky .dae.

[KML_ID] is the KML ID of the model that uses this texture. Textures can be used by multiple models. This parameter is optional.

Here is an excerpt from the example's textures.txt file:

<../files/CU-Macky---Center-StairsnoCulling.jpg> <CU-Macky---Center-StairsnoCulling.jpg> <model_4>
<../files/CU-Macky-4sideturretnoCulling.jpg> <CU-Macky-4sideturretnoCulling.jpg> <model_4>
<../files/CU-Macky-Back-NorthnoCulling.jpg> <CU-Macky-Back-NorthnoCulling.jpg> <model_4>
  • files/ directory - contains the COLLADA files that define the geometry, textures, and material of the model. In the Macky Building example, this directory contains the COLLADA file (CU Macky.dae) as well as the numerous files containing the JPEG images used to texture the building (CU-Macky-BrickwallnoCulling.jpg, CU-Macky--Center-StairsnoCulling.jpg, CU_Macky-EastdetaildoornoCulling.jpg, and so on).

This example illustrates one way to structure the files in a KMZ archive. Actually, you can arrange the files in any structure that seems logical to you, just as you organize the files into folders or directories on your computer. For example, it might be useful to put all the images in an images/ directory. Relative references (such as the files referred to in the <href> element that is used in NetworkLink, Link, Overlay/Icon, and Model) are specified relative to the doc.kml file. If you include an Images directory, then the <href> specification for your images would be: images/myBrickTexture.jpg, images/myMountainOverlay.png, and so on).

To incrementally modify data loaded over a NetworkLink, use the Update element, which is a child of NetworkLinkControl. Update can contain any number of Change, Create, and Delete elements, which are processed in order.

The figure below illustrates the sequence of events.

  1. A NetworkLink loads the "original" KML file into Google Earth. An element that will later be updated needs to have an explicit id defined when it is first specified. The ids must be unique within a given file.
  2. Another NetworkLink loads a second KML file containing the updates (any combination of Change, Create, and Delete) to the KML object(s) that have already been loaded. The update file contains two references to identify the original KML data:
  3. To locate the objects within Google Earth, the Update element uses the targetHref element to identify the original file that defined the object(s) to be modified. To identify the object(s) to be modified or the container for new objects, the Change, Create, and Delete elements contain a targetId attribute that references the ids of those objects.

Change Example

The following example shows a set of sample NetworkLinks and KML data files. To run the sample:

  1. Load the Point-load.kml file into Google Earth. This file contains the NetworkLink that loads the original data file, which contains two points (Point.kml).
  2. Load the Update-load.kml file into Google Earth. This file contains the second NetworkLink, which loads the file containing the Update data (a new name for point123).

The first file contains the NetworkLink that loads the data file, which contains two points. The Placemarks that contain these points have ids assigned to them. The third file contains another NetworkLink, which adds the Update file. The Change element modifies the name of the Placemark for point123.

Here are the four files used in this example. First, this is the Point-load.kml file, which contains the NetworkLink that loads the original data file (Point.kml).

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<NetworkLink>
<name>Loads Point.kml</name>
<Link>
<href>http://developers.google.com/kml/documentation/Point.kml</href>
</Link>
</NetworkLink>
</kml>

Here is the Point.kml file, which contains the original data (two points). The point with the id "point123" is the point we will be modifying.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<Placemark id="pm123">
<name>point123</name>
<Point> <coordinates>-95.44,40.42,0</coordinates> </Point>
</Placemark> <Placemark id="pm456"> <name>point456</name>
<Point> <coordinates>-95.43,40.42,0</coordinates>
</Point>
</Placemark>
</Document>
</kml>

Next is the second NetworkLink file (Update-load.kml). This file loads the file that contains the Update information.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<NetworkLink>
<name>Update</name>
<Link>
<href>http://developers.google.com/kml/documentation/NetworkLinkControl-Update.kml</href></Link> </NetworkLink>
</kml>

And finally, here is the KML file (NetworkLinkControl-Update.kml) that contains the Update information:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<NetworkLinkControl>
<Update>
<targetHref>http://developers.google.com/kml/documentation/Point.kml</targetHref>
<Change>
<Placemark targetId="pm123"> <name>Name changed by Update Change</name>
<!-- coordinates remain the same -->
</Placemark>
</Change> </Update>
</NetworkLinkControl>
</kml>

Expiration

By default, data is loaded only once by Links into Google Earth. To prevent KML data from becoming stale, you can specify a refreshMode of onExpire for any data loaded by an <href> element (in a Link or Icon element). By default, HTTP expiration headers specify the expiration time. You can also now specify an expires time in a KML NetworkLinkControl. The time is expressed as an XML dateTime (see XML Schema Part 2: Datatypes Second Edition). If both HTTP headers and KML expiration times are specified, the KML expiration time takes precedence.

Example 1: Expiration using HTTP server expiration time

This example is for illustration only. It shows a GroundOverlay with an Icon that sets a refreshMode of onExpire. Since no KML expiration time is set, this example uses the HTTP server expiration time.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>refreshMode onExpire</name>
<Snippet maxLines="10">
Image automatically reloads according to http
server expiration.

</Snippet>
<GroundOverlay>
<Icon>
<href>http://www.someserver.com/image.jpeg</href>
<refreshMode>onExpire</refreshMode>

</Icon>
<LatLonBox>
<!-- from edit session in earth -->
<!-- The roof of a building in the Presidio -->
<north>37.80385180177469</north>
<east>-122.4558710620651</east>
<south>37.80337403503347</south>
<west>-122.4564295653771</west>
</LatLonBox>
</GroundOverlay>
</Document>
</kml>

Example 2: Example using KML expiration time

The following example delivers a Placemark at randomly selected coordinates. This example includes a Link with a refreshMode of onExpire. In this case, the expiration date/time is specified (in a Python script) using the new KML <expires> element. This KML expiration time takes precedence over any time that may have been specified in the HTTP headers.

Here is the KML NetworkLink containing the Link with the <href> and <refreshMode> elements:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<NetworkLink>
<Link>
<href>http://dev.someserver.com/cgi-bin/expires.py</href>
<refreshMode>onExpire</refreshMode>
</Link>
</NetworkLink>
</Document>
</kml>

This is the Python script that sets an expires time of [now + 11 seconds] and refreshes the Placemark's coordinates:

#!/usr/bin/python

import random
import time
lat = random.random() * 180. - 90.
lon = random.random() * 360. - 180.
now = time.time()
future = time.gmtime(now + 11)
y = future[0]
mo = future[1]
d = future[2]
h = future[3]
mi = future[4]
s = future[5]
iso8601 = '%04d-%02d-%02dT%02d:%02d:%02dZ' % (y,mo,d,h,mi,s)
print 'Content-type: application/vnd.google-earth.kml+xml'
print
print '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'
print '<kml xmlns=\"http://earth.google.com/kml/2.1\">'
# must be child of <kml>
print '<NetworkLinkControl>'
print '<expires>%s</expires>' % iso8601
print '</NetworkLinkControl>'
print '<Placemark>'
print '<name>placemark expires %s</name>' % iso8601
print '<Point>'
print '<coordinates>%f,%f,0</coordinates>' % (lon,lat)
print '</Point>'
print '</Placemark>'
print '</kml>'

Folders with Radio-Style Items

You can now create folders with radio-style items using the ListStyle element and specifying a listItemType of radioFolder. The following example illustrates this use of the new list style element.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<name>ListStyle radiofolder</name>
<Folder>
<name>radioFolder Folder</name>
<Style>
<ListStyle>
<listItemType>radioFolder</listItemType>
</ListStyle>

</Style>
<Placemark>
<name>north</name>
<Point>
<coordinates>-114,41.79,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>south</name>
<Point>
<coordinates>-114,41.78,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>

Here is how the Places panel displays this Folder and its Placemark children: