GEOG 585
Open Web Mapping

Working with vector KML


KML (Keyhole Markup Language) is a popular format for vector GIS features due to its association with Google Earth and Google Maps. KML is just XML formatted according to an open specification, previously maintained by Google, but now enshrined in an OGC standard. Although KML can define the placement of raster layers, we will focus on vector KML in this lesson.

The key XML tag behind KML is the placemark. This defines a geographic feature, a symbol, and extra information that can appear in a popup. You can see some placemarks if you save the example KML file and open it in a text editor. This isn't the cleanest file, but it will do for the purposes of seeing a placemark:

	   <name>Sundial, Plymouth, Devon, UK</name>
               <description><![CDATA[The gnonom is 27 feet high, the pool has 21 feet diameter.  It was designed by architect Carole Vincent from Boscastle in Cornwall and was unveiled by Her Majesty the Queen on Friday, July 22nd, 1988 at a cost of cost £70,000. The sundial runs one hour and seventeen minutes behind local clocks.
	<img src="">
	Image source:<a href="</a>]]>

This particular placemark has a single coordinate, contained in the Point tag. For polylines and polygons, the LineString and Polygon tags are used, respectively, although these do not appear in the above example.

Notice that the Description tag can contain HTML, which gives you more control over formatting popups. The full KML file is much longer than the snippet above, as it contains many points and descriptions.

Leaflet doesn't offer a way to read KML directly. This is an area where OpenLayers holds an advantage. However, Mapbox has produced a free Leaflet plugin called Omnivore that makes it fairly simple to read in vector file types, including KML. First, you need to put a reference to Omnivore in a script tag at the top of your page. You could reference it from a CDN like this:

<script src=""></script>

Then you can reference the KML in a layer, like this:

var runLayer = omnivore.kml('sundials.kml')
  .on('ready', function() {
    runLayer.eachLayer(function(layer) {            

One thing to be aware of is that Omnivore converts the KML to the GeoJSON format before displaying it; (see the next section of the lesson for more info on GeoJSON). Thus, your map may not be able to show all the styling that was originally defined in the KML. If your KML contains some kind of custom picture symbol for the points, you'll need to write Leaflet code to apply that picture to the markers. Notice, however, that the above code does bring in the KML description and applies that text in a popup. This is accomplished using the bindPopup method on the layer.

Again, don't worry about memorizing all the syntax. In most scenarios, you should just be able to tweak the above example to connect to your own KML.