Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries. Thanks for all your past and future contributions.

HERE Maps API - Converting from JavaScript to KML

From Wiki
Jump to: navigation, search
Article Metadata
Code ExampleTested with
Devices(s): Internet Explorer, Google Chrome, Firefox, Opera
Platform(s): Web
Dependencies: HERE Maps 2.5.3 or higher
Keywords: HERE Maps, JavaScript, KML
Created: jasfox (05 Jan 2012)
Last edited: jasfox (20 Dec 2013)

Featured Article
15 Jan

KML has emerged as the de facto standard for online mapping data. This article explains how to convert an existing JavaScript-based Map into a KML-based solution and details the likely benefits to be gained by implementing such a solution


Introduction : What is KML

Keyhole Markup Language (KML) is an XML notation for geographic applications. It allows both two-dimensional maps and three-dimensional maps to display additional information overlaying the basic map. The current version of the HERE Maps API for JavaScript is KML compliant and is able to parse KML files. By separating the geographical application data (the model) from the method of rendering that data on the map (the view), the same KML data may be used be multiple applications. For example, most major search engines, such as Google, Bing and Ask are able to read KML files directly and return the map in their search results. Also since KML is a de facto standard, mapping libraries are optimised to use it, therefore converting from a Home-brew JavaScript solution to a KML solution should result in a faster rendering performance for basic map data.

What aspects of KML are relevant for two-dimensional maps?

KML was originally developed for three-dimensional Earth viewers, therefore only a subset of KML is strictly relevant to two-dimensional maps. Fortunately this also covers a high percentage of 2d-mapping use cases.

KML is able to:

  • Specify icons and labels to identify locations.
  • Specify additional information (e.g. address, phone number) to associate with a specific location.
  • Define other elements such as polygons and polylines and attach them to the map.
  • Define styles to specify feature appearance.
  • Write HTML descriptions of features, including hyperlinks and embedded images
  • Use folders for hierarchical grouping of features

Comparison between HERE Map elements and the KML syntax

Map Marker

A MapMarker is a KML <Placemark> with a <Point> geometry and an <IconStyle>

HERE Map KML Syntax
marker =  new
new nokia.maps.geo.Coordinate(52.5091331805643,-1.88484460115433), {
icon: "",
anchor: new nokia.maps.util.Point(16, 32)
<hotSpot x="16" y="32" xunits="pixels" yunits="pixels">

As can be seen, there is a one-to-one correspondence between the Marker attributes and the KML <Point> attributes. The coordinates of the marker are specified in the <coordinates> tag, although longitude and latitude are reversed, and altitude is added. Since altitude is irrelevant for a two-dimensional map, a placeholder of zero can be used. The icon of the marker is defined by the <href> tag. The anchor of the marker is specified in the <hotSpot> tag, with the Point offsets held in the x and y attributes. Note that <hotSpot> can be defined in three different ways, correspond directly,the xunit atttibute and the yunit attribute must be set to "pixels"

Map Standard Marker

A Map StandardMarker can be defined as KML <Placemark> with a <Point> geometry and a <styleUrl>

HERE Map KML Syntax
<script type="text/javascript"
var red = "#FF0000";
marker = new
new nokia.maps.geo.Coordinate(53.463043359365,-2.29132533073425),
{brush: {color: red}
<Style id='FF0000'>

KML does not have the concept of a StandardMarker. If a <Point> is defined without styling, it is up to the rendering library to decide what icon to use on the marker. Obviously if HERE Maps is used, the <Point> will default to the Nokia StandardMarker. Nokia's StandardMarker has a brush attribute which changes the color of the marker. This cannot be replicated directly in KML. However, it is possible to approximate this using a KML <Style>.

Firstly we need to create custom icons for the various default RGB colors:

Icon Color Style Id URL
000000.png Black 000000 [000000.png]
0000FF.png Blue 0000FF [0000FF.png]
FF0000.png Red FF0000 [FF0000.png]
FFFF00.png Yellow FFFF00 [FFFF00.png]
FFFFFF.png White 000000 [FFFFFF.png]

Thereafter, we can use the <styleURL> element of the <PlaceMark> to render the <Point> using the icon defined in the <Style> Marker.

Note.pngNote: The RGB value of the color is the same as the id of the <Style> containing the image of a marker with that color. This is how the <Style> and <styleUrl> can link together.


An Infobubble can be defined as KML <Placemark> with a <description> tag

HERE Map KML Syntax
function addInfoBubble(infoBubbles, marker, html) {
marker.html = html;
marker.addListener("click" , function(evt) {
}, false);
<script type="text/javascript"
marker = new
new nokia.maps.geo.Coordinate(53.4393381986981,-2.2211828827858));
addInfoBubble( infoBubbles, marker, "<div>HTML Description</div>");
<description><![CDATA[<div>HTML Description</div>]]></description>

The <description> tag is defined as being "User-supplied content that appears in the description balloon". As such it is analogous to the Nokia Map Infobubble. The usual way to create an InfoBubble is to associate additional data with the marker (in this case by adding an .html attribute) and then displaying the info bubble by adding an onclick event.

Note.pngNote: The naming of the additional data element is arbitrary, but frequently something like .html or .description will be used.

Many KML feeds make the assumption that the consumer of the KML file will render HTML, and therefore place HTML tags directly in the description - this could be avoided by using KML placeholders and creating a <BalloonStyle>, but this is beyond the scope of this article.


A Polyline can be defined as KML <Placemark> with a <LineString> geometry and a <LineStyle>

HERE Map KML Syntax
var roadCoords=[
new nokia.maps.geo.Coordinate(37.385433,-8.375983)
,new nokia.maps.geo.Coordinate(37.385577,-8.376008)
,new nokia.maps.geo.Coordinate(37.385674,-8.376025)
{pen: {
strokeColor: "#8dc72d",
lineWidth: 5

Again there is a one-to-one correspondence between the Polyline attributes and the KML <LineString> attributes. The coordinates of the route are specified in the <coordinates> tag, although longitude and latitude are reversed, and altitude is added - this can be left as a placeholder of zero if desired. The lineWidth of the route is defined by the <width> tag. Similarly the the strokeColor of the route corresponds to the <color> tag. There is however a difference in the encoding here, as HERE Maps uses RGB encoding, and the KML standard uses ABGR encoding, so the first two bytes define the opacity (which can be defaulted to FF) and the red and blue ordering is reversed.

The saveMapObjects function - a JavaScript library to convert the Map to KML

Nokia Map data is stored in map.objects - it is a relatively simple matter to traverse the markers and obtain the necessary data to create KML <Point>s. Note that since the additional data element for the pop-up description is arbitrary, the .html attribute in this example may need to be altered to cope with other maps.

var markerData = new Object();
markerData.latitude = map.objects.get(i).coordinate.latitude;
markerData.longitude = map.objects.get(i).coordinate.longitude;
markerData.description = map.objects.get(i).html;
markerData.href = map.objects.get(i).icon.src;
if ( markerData.href === undefined ){
markerData.color = map.objects.get(i).brush.color;

Similarly the data from a Polyline can be collected to hold the necessary information for a KML <LineString>

var lineData = new Object();
var path = map.objects.get(i).path.asArray();
var geocoords = new Array();
for (j=0; j< path.length; j = j + 3){
var geocoord = new Object();
geocoord.latitude = path[j];
geocoord.longitude = path[j+ 1];
lineData.coordinates = geocoords;
lineData.color = map.objects.get(i).pen.strokeColor;
lineData.width = map.objects.get(i).pen.lineWidth;

The collected data may then be written out as KML <Placemark>s using the method below:

var kmlOutput = "<?xml version='1.0' encoding='UTF-8'?><kml xmlns=''><Document>\n";
// Output all the routes
for (i=0; i< lines.length; i ++){
kmlOutput = kmlOutput + "<Placemark>\n";
kmlOutput = kmlOutput + "<LineString><coordinates>"
for (j=0; j< lines[i].coordinates.length; j++){
kmlOutput = kmlOutput + lines[i].coordinates[j].longitude + "," + lines[i].coordinates[j].latitude + ",0\n";
var RGBcolor = lines[i].color.replace("#", "");
kmlOutput = kmlOutput + "</coordinates></LineString>\n";
kmlOutput = kmlOutput + "<Style><LineStyle>";
kmlOutput = kmlOutput + "<width>" + lines[i].width + "</width>";
kmlOutput = kmlOutput + "<color>ff" + RGBcolor.substring(4,6)+ RGBcolor.substring(2,4)+ RGBcolor.substring(0,2)+ "</color>";
kmlOutput = kmlOutput + "</LineStyle></Style>\n";
kmlOutput = kmlOutput + "</Placemark>\n";
// Output all the markers
for (i=0; i< markers.length; i ++){
kmlOutput = kmlOutput + "<Placemark>\n";
if ( markers[i].description === undefined ){
kmlOutput = kmlOutput + "<description/>\n";
} else {
kmlOutput = kmlOutput + "<description><![CDATA[" + markers[i].description +"]]></description>\n";
kmlOutput = kmlOutput + "<Point><coordinates>" + markers[i].longitude + "," + markers[i].latitude + ",0</coordinates></Point>\n";
if ( markers[i].href === undefined ){
kmlOutput = kmlOutput + "<styleUrl>" + markers[i].color + "</styleUrl>\n";
} else {
kmlOutput = kmlOutput + "<Style><IconStyle><Icon>";
kmlOutput = kmlOutput + "<href>" + markers[i].href + "</href>";
kmlOutput = kmlOutput + " </Icon></IconStyle></Style>\n";
kmlOutput = kmlOutput + "</Placemark>\n";
// Add in coloured standard markers as Icon Styles
kmlOutput = kmlOutput + "<Style id='000000'>\n";
kmlOutput = kmlOutput + "<IconStyle><Icon><href></href></Icon></IconStyle>\n";
kmlOutput = kmlOutput + "</Style>\n";
kmlOutput = kmlOutput + "<Style id='0000FF'>\n";
kmlOutput = kmlOutput + "<IconStyle><Icon><href></href></Icon></IconStyle>\n";
kmlOutput = kmlOutput + "</Style>\n";
kmlOutput = kmlOutput + "<Style id='FF0000'>\n";
kmlOutput = kmlOutput + "<IconStyle><Icon><href></href></Icon></IconStyle>\n";
kmlOutput = kmlOutput + "</Style>\n";
kmlOutput = kmlOutput + "<Style id='FFFF00'>\n";
kmlOutput = kmlOutput + "<IconStyle><Icon><href></href></Icon></IconStyle>\n";
kmlOutput = kmlOutput + "</Style>\n";
kmlOutput = kmlOutput + "<Style id='FFFFFF'>\n";
kmlOutput = kmlOutput + "<IconStyle><Icon><href></href></Icon></IconStyle>\n";
kmlOutput = kmlOutput + "</Style>\n";
// Complete the document
kmlOutput = kmlOutput + "</Document></kml>";
// Output to screen
document.getElementById("kmloutput").value = kmlOutput;

Working Example : Premiership Teams

Warning.pngWarning: in order to load a KML file successfully, the KML file should be hosted on the same domain as the JavaScript or the results may be unpredictable. Some browsers will automatically prohibit cross-domain access.

For the working example the final line of the JavaScript will need to be altered to:

where is replaced with the domain name of the server where premiershipKML.html is hosted.

Tip.pngTip: The KML reader of the HERE Maps API for JavaScript will ignore elements it is unable to interpret. KML readers vary and are more or less forgiving in the strictness of interpreting the KML specifications. It is recommended that you validate your KML syntax yourself through an online validator such as:

<![CDATA[<div ><a href='' >Middlesbrough</a></div>
<div >Riverside Stadium<br>Capacity: 35,100</div>]]>

Tests have been run on three versions of the same map:

Adding in standard timing code, to display the length of time taken to load the map was generated. Obviously the rate at which map data is generated on screen will depend upon a variety of factors such as the performance of the browser and the load of the Internet at the time of test. For the attached coded example, the following metric was generated for three runs of the maps using the same browser. In all cases, the cache was not cleared for each run.


Initial Run Second Run Third Run
Nokia Map 0.551 s 0.97 s 0.584 s
Nokia Map KML 0.194 s 0.101 s 0.138 s
Google Map 1.087 s 0.894 s 0.74 s

The obvious conclusion to be drawn, is that using a KML file should increase the performance of the rendering of the map.

Additional Benefits

Since KML is a de facto standard, the same data file can be used by multiple applications. Most major search engines, such as Google, Bing and Ask are able to crawl KML files if the website contains an appropriate sitemap.xml file. For full details of the protocol, please read the definitions on:

Example Sitemap.xml File

<urlset xmlns=""

Additionally since KML is merely a subset of XML, Java ME mobile phone applications can read the same data using JSR-172. The screen shot below shows the same KML file embedded in a KML Reader running in the Java ME emulator:



Converting to KML format is relatively simple, and the process can be automated. The benefits of using KML format include faster rendering and the separation of mapping data from the code. Use of a standard format promotes cross-application use of the same data, and allows faster development of mapping applications across multiple platforms.

This page was last modified on 20 December 2013, at 15:31.
289 page views in the last 30 days.