Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 8

KML in Google Maps and Earth

Written by Ian Elliot   


Tuesday, 06 May 2014

Article Index

KML in Google Maps and Earth

Maps and the MAP API


Page 1 of 2
KML is the way to code geographic data so that it can be displayed on a map. In this article we look
at how KML works, how to use it in both Google Maps and Google Earth, and how to work with it in
code.
 
In Getting started with Google Maps we looked at how to add a map into a web page using Google
Maps and nothing but Javascript and a few bits of HTML that mostly didn't do anything other than
set up the page. In the rest of this article it is assumed that you know how to set up a web page that
creates a Google Maps or a Google Earth object that a script can work with -  see Getting started
with Google Earth.
You can create almost any mapping facility you like using nothing but code but Google Maps and
Google Earth support another way of doing the same job - KML or Keyhole Markup language.
In case you are wondering why its "Keyhole" rather than "Mapping" or some other more relevant
word the simple reason is that its in homage to the pioneering KH or Keyhole reconnaissance
satellites.
The basic idea is that KML is a dialect of XML used to describe locations or more generally the
sorts of things you might want to add to a map display. Its a sort of HTML for places and geographic
locations. You can use it to arrange data in a format that applications such as Google Maps and
Earth can understand and use to create graphical displays as the correct location on a map.
For example, in the previous article we discovered how to place default marker in Google Maps at a
given location using Javascript:
marker1 = new google.maps.Marker({
  position:new google.maps.LatLng(55, -1.5),
  map: map
});

The same thing can be achieved using KML and it works in both Maps and Earth:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
 <Placemark>
   <Point>
    <coordinates>
     -1.5,55
    </coordinates>
  </Point>
 </Placemark>
</kml>

You should be able to understand the way that the KML file is organised. If you don't follow any of it
then read the tutorial on XML. 
However the principles are fairly obvious. The file always starts with the first two lines which identify
the file as a dialect of XML and using the Google extensions to KML. After these two lines there are
a list of nested tags.
Each tag like <Placemark> has a closing tag like </Placemark> and other tag pairs are placed
between them to refine the definition. A <Placemark> is a basic location on a map and you can use
lots of other tags within it to specify the location and how it is displayed. In this case we simply use
the <Point> tag to give longitude and latitude within a pair of <coordinates> tags.

A common example
There are lots of tags that defined lots of different things and the art of using KML is simply
discovering what tags do what and then making use of them.
Obviously there are lots and lots of KML features that we could cover in this article but it make more
sense to focus on the most commonly used techniques.
The most common is to use a custom icon for the Placemark so lets see how this is done and add
some additional tags:
<?xml version="1.0" encoding="UTF-8"?>
 <kml xmlns="http://earth.google.com/kml/2.2">
  <Document>
   <name>My Markers</name>
   <Placemark>
    <name>My Marker</name>
    <description>
     My Marker description
    </description>
    <Style>
     <IconStyle>
      <Icon>
      <href>
        http://www.i-programmer.info/
                                maps/IP.png
      </href>
     </Icon>
    </IconStyle>
   </Style>
   <Point>
    <coordinates>-1.5,55</coordinates>
   </Point>
  </Placemark>  
 </Document>
</kml>

 
If you examine the example you should be able to work out what everything is doing. 
The <Document> tag can be used to group multiple items together - that is you can place multiple
Placemark items in the single KML file. In this case it isn't necessary because there is only a single
Placemark.
The first <Name> tag assigns a name to the entire document, the second names the Placemark.
The only complicated section is the <Style> tag which is used to group everything that relates to the
way that the Placemark displays. In this case the only modification to the default style is to supply a
custom icon.
The <IconStyle> tag is the section that contains tags that set the icon's style but in this case the
only thing we want to change is the icon itself and this is done by specifying a URL where the file is
stored. You can use local files in this case and you can also zip the graphic into the XMZ file and it
will be correctly extracted and loaded.
If you have a kml file saved and hosted by a web server then you can display it on Google Maps.
To do this you have to is go to Google Maps
https://www.google.com/maps
Click the "gear wheel" icon at the bottom right and select My Places.
Finally copy and paste the URL of the KML file into the search box. 
If you want to try the demo listed above the file is available at
http://www.i-programmer.info/maps/demo2.kml
along with graphics file and when loaded into a map it displays as below:
 

 
 
Our next problem is how exactly to display a KML file and make best use of our efforts.

Maps or Earth?
There are a number of different ways of displaying a KML file and they are each worth knowing
about. You can display the file using either Maps or Earth. Each has some advantages and
disadvantages so you do need to know how to work with both.
Google Maps doesn't need a developer key to use and it doesn't need the user to download a
browser plugin or desktop application. It is also more suitable for use on mobiles.
However Google Maps has one disadvantage that is important to know about and understand the
implications of. Using Google Maps you can only load a KML file that is accessible via a public URL.
You also cannot get access to the objects created by the KML file via script. What this means is that
you can create and use a KML file that is located on a server and you can even manipulate the file
server side but you can't load or manipulate a KML file on the client side.
Google Earth on the other hand has facilities to load KML file from a URL or from a local file and
you can work with the object created by the KML file. That is you can do both server and client side
manipulation of KML.
KML in Google Maps
Google Maps can only load a KML file from a publicly accessible URL. There are also a number of
ways of doing this via the Google Maps web site and within your own code.
From within Google Maps you can either use a URL that corresponds to the location of the KML file
you have created or you can upload a local file and Google will host it for you internally. To do this
you need to have a Google account.
The simplest way of getting KML onto a map is if it is hosted by a web server as explained earlier.
For example the demo file constructed earlier is available from the URL
http://www.i-programmer.info/maps/demo1.kml
If you type, or copy and paste this into the search box on Google Maps you will be taken to view the
default pushpin marker.
 

 
You can also save your KML to MyMaps and reload it when ever you need to - provided the file is
still at the same URL. If you hover over the marker that the KML has added to the map one of the
options that appears is Save to map.
 
 
If you select this option you can give the map a name and save it to My Maps for redisplay - select
My Maps and your named map from the list.
You also need to know that Google Maps caches the KML file and so any changes you make to it
aren't necessarily visible when you refresh the page.
If you do have a Google account you can upload a local KML file and have Google host it for you.
Unfortunately at the time of writing you can't import a KML file to the latest Map Engine - you have
to use the Classic Map. 
To do this first log in to your account on the Google Maps page or into any Google application. Next
display a Google Map in your browser and click on Places form the "gear wheel" icon and then click
on the  "Or create with classic My Maps" link under the big red button marked "CREATE MAP".
To import your KML file select the import link  next to the Done button and specify the location of the
file either a local file or a URL.  
Give the map a title and description if you want to and select either Public or Unlisted for a private
map.
The maximum file size supported is 10MB. Notice that this facility works by uploading and hosting
your KML file on Google's own server so it isn't really directly accessing a local file.
If the KML file is big then you can significantly reduce its size by zipping it. All you have to do is Zip
the file and rename it to have a .KMZ extension. A KMZ file can be used just like a KML file and the
application using it will automatically unzip the file after downloading it.

Page 2 of 2

Sharing Maps
If you want to share your KML files then uploading them to Google Maps is an easy solution -.
simply set them to Public. You can even set up a collaborative project.
You can also get Google to take notice of your KML/KMZ files that you host and offer them to a
wider public audience in response to searches.
To do this you have to

1. Create your KML/KMZ file


2. Make sure it contains attribution tags that contain information such as author, name, url to your
website etc.
3. Post the KML/KMZ to a publicly accessible webserver
4. Create a Geo site map - that is an XML format file that describes where on the webserver there
are KML/KMZ files that you would like Google to index.
5. Submit the Sitemap to Google search in the usual way.

KML via the Map API


Of course if you are hosting Google Maps in your own web page, as described in Getting started
with Google Maps then the obvious thing to do is to find our how to display KML within a hosted
map. This turns out to be very easy.
First let's tackle the case where the KML file is available via a publicly accessible URL. In this case
all we have to do is create a KmlLayer object using the URL in the constructor. This downloads and
interprets the KML file and when you add the KmlLayer to the map the graphics it specifies appear.
The technique works with KMZ files as well.
For example, assuming that we already have the code to create a map object then the demo1.KML
file can be loaded using:
var kml=new google.maps.KmlLayer(
      "http://www.i-programmer.info/
                       maps/demo1.kml");
kml.setMap(map);

Notice that there is no way of loading KML generated by Javascript say directly into a map. In
Google maps all KML has to be hosted at a public URL.
There are obvious ways round this but they are too difficult to go into here and will be covered in a
future project. 

KML in Google Earth


Google Earth is better at supporting KML than Maps - it has more facilities and more extensions.
There are many ways to load KML into Google Earth but it is also worth knowing that if you select
any displayed graphic on a Google Earth display, right click and select copy then a KML
representation of the object is loaded to the clipboard. If you paste the KML into a text editor you
can view it and modify it for use in your own code. This is a good way to learn about KML and to get
KML that you can use as a starting point for your own custom objects.
The easiest way to display a KML file is to simply load the KML file into Google Earth. If you have
Earth installed on your machine than simply double clicking on the KML file will open it in Google
Earth and display the contents of the file. You can also use the File,Open command and navigate to
the KML file. KML files, once loaded can be saved as part of MyPlaces.
If you want to load the KML file using the API then there are three basic ways of doing the job. The
first is very similar to the Google Maps API way. You first have to ensure that the KML file is publicly
accessible via a URL. If this is the case you can create a NetworkLink object and load it into the
Google Earth object for display.
Assuming that the Google Earth object is loaded and initialised then you can display the demo1.kml
file given at the start of the article as follows.
First create the link object:
var link = ge.createLink('');
link.setHref(
       "http://www.i-programmer.info/
                          maps/demo1.kml");

Next create the NetworkLink object and initialise it to the URL using the Link object:
var networkLink = ge.createNetworkLink(''); networkLink.set(link, true, true);

The set method is used to initialise the link and to make it visible and make the map "fly" to the
location.
Finally add the NetworkLink object to the map:
ge.getFeatures().
             appendChild(networkLink);

If you run this short code segment then you will see the map pan to the new location and you will
see a default marker.
So far we haven't done anything we couldn't have achieved using Google Maps - the KML file is
loaded from a URL and you can't modify it. If you use either the fetchKML method then you can do
the same job but now you can manipulate the resulting KML objects.
The fetchKml method accepts three parameters - the Google Earth object, the url as a string and a
call back function that accepts the resulting kmlObject as its first parameter.
For example to load the demo1.kml file you would use something like:
google.earth.fetchKml(ge,
           "http://www.i-programmer.info/
           maps/demo1.kml",
           getKML);

Where getKML is a function that is called when the KML has been loaded into the kmlObject.
For example to load the kmlObject into the map you would use:
function getKML(kmlObject){
 if (kmlObject) {
   ge.getFeatures().appendChild(kmlObject);
 }
}
 
Notice that this doesn't zoom and pan the map to the new location but if you use  the mouse to
move to the location you will see the default marker in place. Also notice that if the URL is incorrect
or if there is any problem with the KML file the kmlObject is null.
The final KML load method, parseKML, is perhaps the most versatile as it can parse KML presented
to it as a string. This means you can obtain the KML from any source you care to problem - a local
file say, a URL or generated using code.
For example, if we store the text of the previous KML example in a variable:
var KML = '<?xml version="1.0" 
                   encoding="UTF-8"?>' +
 '<kml xmlns="http://earth.google.com/
                            kml/2.2">' +
 ' <Placemark>' +
 '  <Point>' +
 '   <coordinates>' +
 '     -1.5,55  ' +
 '   </coordinates>' +
 '  </Point>' +
 ' </Placemark>' +
 '</kml>';

The strange way of entering the string literal is used to preserve some of the formatting within the
program - line breaks and spaces are mostly ignored in KML.
To create the kmlObject from the string we use:
var kmlObject = ge.parseKml(KML);

As long as everything worked and kmlObject isn't null we can display it on the map in the usual
way:
ge.getFeatures().appendChild(kmlObject);

Once again the map doesn't automatically pan to the new location but if you do the job manually
you will see the marker.

Working with the KML DOM


The main reason for wanting to load the KML into a kmlObject is to manipulate it before displaying
it.
The kmlObject can be thought of as a sort of map equivalent of the DOM - Document Object Model.
Indeed the same idea applies to the map object itself.
What happens is that as the KML is parsed objects are created with the same structure as the
nested tags. Each tag gives rise to an object in the DOM and they are nested within each other in
the same way that the tags are.  That is if <tag2> is nested within <tag1> e.g.
<tag1>
  <tag2>
  </tag2>
</tag1>

the object that represents tag2 is a child of the object that represents tag1.
Sometimes tags at the lowest level of the hierarchy are converted into properties of the object that
corresponds to the tag that contains them - see the example below.
The biggest problem you have in any given situation is working out what object in the Google Earth
API correspond to which tags. You also have to realise that the structure of a KML file can be far
more complicated than the one we have been using so far - in particular there can be multiple
features like placemarkers and you have to write code which navigates its way through the DOM
tree to find what you are looking at.
A simple example will help get you started. In the case of the sample file demo1.kml that was
loaded into the kmlObject variable there is only only feature i.e. the single placemarker. Thus the
kmlObject isn't a collection of features it is a an instance of the KmlPlacemark object.  The
KmlPlacemark object has getGeometry and setGeometry methods that can be use to manipulate its
child objects - which correspond to the tags nested within it.
In this case the only child object is a kmlPoint object which was created to correspond to the point
tag. This has get and set Latitude and Longitude methods and we don't need to dig any deeper
because the co-ordinate tags have been converted into properties of the kmlPoint object.
So putting all this together. To set the latitude and longitude of the placemark to 0,0 we would use:
kmlObject.getGeometry().setLatitude(0);
kmlObject.getGeometry().setLongitude(0);

and to discover the current values we would use:

alert(kmlObject.getGeometry().
          getLatitude ());
alert(kmlObject.getGeometry().
          getLongitude());

Notice that the connection between the kmlObject and the map is live in the sense that if you
change the details of the object after it has been added to the map then the display is updated.
In a more complicated case the kmlObject may contain lots of placemark objects and other objects
and you would have to navigate the DOM to find the placemark you needed to modify or add to.

You might also like