×
Namespaces

Variants
Actions
(Difference between revisions)

HERE Maps API - How to create a KML data file

From Nokia Developer Wiki
Jump to: navigation, search
jasfox (Talk | contribs)
m (Jasfox - links)
jasfox (Talk | contribs)
m (Jasfox - Update links)
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Category:Nokia Maps]][[Category:Code Examples]][[Category:JavaScript]]
+
[[Category:HERE Maps]][[Category:Code Examples]][[Category:JavaScript]]
 
{{Abstract|This article explains how to create and edit a sample '''KML''' file using an online editor }}  
 
{{Abstract|This article explains how to create and edit a sample '''KML''' file using an online editor }}  
 
{{Note| in order to load a KML file successfully, the generated 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.
 
{{Note| in order to load a KML file successfully, the generated 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.
Line 8: Line 8:
 
and both the KML loading HTML and the  generated_kml_data_file.kml should be placed on  {{Icode|http://example.com/}}
 
and both the KML loading HTML and the  generated_kml_data_file.kml should be placed on  {{Icode|http://example.com/}}
 
}}
 
}}
{{SeeAlso|<br />
+
{{Tip| The KML reader of the [http://developer.here.net/javascript_api 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 [http://www.opengeospatial.org/standards/kml KML specifications]. It is recommended that you validate your KML syntax yourself through an online validator such as: http://feedvalidator.org
* [http://developer.here.net/javascript_api Nokia Maps API]
+
* [[Nokia Maps API - Converting any data file to KML]]
+
* [[Nokia Maps API - How to display KML file data on the map]]
+
* [http://developer.here.net/apiexplorer/examples/api-for-js/data-visualization/map-with-interactive-kml-objects.html Loading a KML file example]
+
* [http://developer.here.net/apiexplorer/examples/api-for-js/places-search/search-by-address.html Search example]
+
* [http://developer.here.net/apiexplorer/examples/api-for-js/places-search/reverse-geocode.html Reverse Geocode example]
+
 
}}
 
}}
 
{{ArticleMetaData
 
{{ArticleMetaData
|sourcecode= [[Media:KMLGeneratorExample.zip|KMLGeneratorExample.zip]]
+
|sourcecode= [https://github.com/heremaps/examples/blob/master/maps_api_for_javascript/demos/generate-kml/generate-kml-file-from-map.html-file-from-map.htmll]
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|devices= Firefox, Internet Explorer, Google Chrome, Opera
 
|devices= Firefox, Internet Explorer, Google Chrome, Opera
Line 23: Line 17:
 
|platform= Web Browser
 
|platform= Web Browser
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
|dependencies= Nokia Maps API 2.2.3
+
|dependencies= HERE Maps API 2.5.3
 
|signing=<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 
|signing=<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
|keywords= Nokia Maps, JavaScript, KML
+
|keywords= HERE Maps, JavaScript, KML
 
|id= <!-- Article Id (Knowledge base articles only) -->
 
|id= <!-- Article Id (Knowledge base articles only) -->
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
Line 38: Line 32:
 
|creationdate=20120110
 
|creationdate=20120110
 
|author=[[User:jasfox]]
 
|author=[[User:jasfox]]
 +
}}
 +
{{SeeAlso|<br />
 +
* [http://developer.here.net/javascript_api HERE Maps API]
 +
* [[HERE Maps API - Converting any data file to KML]]
 +
* [[HERE Maps API - How to display KML file data on the map]]
 +
* [http://developer.here.net/apiexplorer/examples/api-for-js/data-visualization/map-with-interactive-kml-objects.html Loading a KML file example]
 +
* [http://developer.here.net/apiexplorer/examples/api-for-js/places-search/search-by-address.html Search example]
 +
* [http://developer.here.net/apiexplorer/examples/api-for-js/places-search/reverse-geocode.html Reverse Geocode example]
 +
* [http://www.opengeospatial.org/standards/kml KML specifications]
 
}}
 
}}
  
Line 54: Line 57:
 
== WSYIWIG Editor ==
 
== WSYIWIG Editor ==
  
=== Initialisation ===
 
After the usual Map set up, we need to get a reference to each of the text boxes on the right of the screen. This is done by using {{Icode|document.getElementById()}}
 
<code javascript>
 
var lat = document.getElementById("lat");
 
var lng = document.getElementById("lng");
 
var waypoints = document.getElementById("waypoints");
 
 
var title = document.getElementById("title");
 
var name = document.getElementById("name");
 
var description = document.getElementById("description");
 
var address = document.getElementById("address");
 
var icon = document.getElementById("icon");
 
var styleURL = document.getElementById("styleURL");
 
var lineStyleURL = document.getElementById('lineStyleURL');
 
</code>
 
  
  
 
=== Adding Markers ===
 
=== Adding Markers ===
Markers can be added by pressing and holding down the mouse , this is the {{Icode|longpress}} event. An event handler has been added to the map to cope with this. The associated values such as {{Icode|&lt;description&gt;}} and {{Icode|&lt;name&gt;}} come directly from the text boxes defined above.
+
Markers can be added by pressing and holding down the mouse , this is the {{Icode|longpress}} event. An event handler has been added to the map to cope with this. The associated values such as {{Icode|&lt;description&gt;}} and {{Icode|&lt;name&gt;}} come directly from the text boxes associated with the HTML.
 
<code javascript>
 
<code javascript>
eventExEl.addListener("longpress", function(evt) {
+
function addClickListener(map){
var markerData = new Object();
+
map.addListener("longpress", function (evt){
        markerData.coords = map.pixelToGeo(evt.targetX , evt.targetY);
+
var data = getMarkerData();
        markerData.title = map.objects.getLength() + 1;
+
data.coords = map.pixelToGeo(evt.targetX , evt.targetY);
        markerData.description = description.value;
+
currentMarker = addMarker(data);
        markerData.name = name.value;
+
        markerData.address = address.value;
+
        if (icon.value != ""){
+
            markerData.icon = icon.value;
+
        } else {
+
            markerData.styleURL = styleURL.value;
+
        }
+
        addMarker(markerData);
+
       
+
}, false);
+
  
 +
// If a description has been added, display the info bubble.
 +
if (data.description != ""){
 +
infoBubbles.addBubble(data.description, currentMarker.coords );
 +
}
 +
});
 +
}
 
</code>
 
</code>
 +
 +
<code javascript>
 +
function getMarkerData(){
 +
var markerData = {
 +
title : $('#title').val(),
 +
description : $('#description').val(),
 +
name : $('#name').val(),
 +
address: $('#address').val()
 +
};
 +
if ($('#icon').val() != ""){
 +
markerData.icon = $('#icon').val();
 +
} else {
 +
markerData.styleURL = $('#styleURL').val();
 +
}
 +
return markerData;
 +
}
 +
</code>
 +
 
An alternative method of adding a marker is by adding an address. This uses the standard geoCoding service, and picks the first address found on the list. If your address is in the "wrong" format, just try making the address more general for now e.g.try the city only.
 
An alternative method of adding a marker is by adding an address. This uses the standard geoCoding service, and picks the first address found on the list. If your address is in the "wrong" format, just try making the address more general for now e.g.try the city only.
 
The handler for geo-coding retrieves most of its information from the text boxes on the right hand side of the screen, but the address comes from the callback function.
 
The handler for geo-coding retrieves most of its information from the text boxes on the right hand side of the screen, but the address comes from the callback function.
Line 101: Line 103:
 
</code>
 
</code>
 
<code javascript>
 
<code javascript>
   var onSearchComplete = function (data, requestStatus) {
+
   function onSearchComplete (data, requestStatus) {
        // If the search  has finished we can process the results
+
// If the search  has finished we can process the results
          if (requestStatus == "OK") {
+
if (requestStatus == "OK") {
var markerData = new Object();
+
var markerData = getMarkerData()
markerData.coords = data.location.position;
+
markerData.address = data.location.address.text;
markerData.title = map.objects.getLength() + 1;
+
markerData.coords = data.location.position;
markerData.description = description.value;
+
// Ensure the address edit box contains the latest address contents.
markerData.name = name.value;
+
$("#address").val(data.location.address.text);
+
currentMarker = addMarker(markerData);
var address =  data.location.address;
+
map.setCenter(data.location.position);
+
 
markerData.address = "";
+
} else if (requestStatus == "ERROR") {
markerData.address = markerData.address  + address.houseNumber + "\n";
+
alert("The search request failed.");
markerData.address =  markerData.address + address.street + "\n";
+
}
markerData.address =  markerData.address + address.district + "\n";
+
}
markerData.address =  markerData.address + address.city  + "\n";
+
markerData.address =  markerData.address + address.postalCode  + "\n";
+
markerData.address = markerData.address + address.country;
+
+
addMarker(markerData);
+
map.setCenter(data.location.position);
+
+
} else if (requestStatus == "ERROR") {
+
alert("The search request failed.");
+
}
+
  };
+
 
</code>
 
</code>
 
The {{Icode|addMarkers()}} method actually adds the marker, which itself contains a copy of its own {{Icode|&lt;description&gt;}}, {{Icode|&lt;address&gt;}}, {{Icode|&lt;name&gt;}} & etc.  The marker has two events:
 
The {{Icode|addMarkers()}} method actually adds the marker, which itself contains a copy of its own {{Icode|&lt;description&gt;}}, {{Icode|&lt;address&gt;}}, {{Icode|&lt;name&gt;}} & etc.  The marker has two events:
Line 134: Line 125:
 
<code javascript>
 
<code javascript>
 
function addMarker(markerData) {
 
function addMarker(markerData) {
var marker;
+
var marker;
 +
 
 +
if (markerData.title === undefined){
 +
markerData.title = "";
 +
}
 +
 
 +
// Either an a Standard Marker or an icon, both are left
 +
// Draggable, so the location can be corrected.
 +
if (markerData.icon === undefined){
 
marker = new nokia.maps.map.StandardMarker(markerData.coords, {
 
marker = new nokia.maps.map.StandardMarker(markerData.coords, {
 
text:  markerData.title, //small title
 
text:  markerData.title, //small title
 
draggable: true,  //the marker is marked  to be draggable
 
draggable: true,  //the marker is marked  to be draggable
 
$data: markerData
 
$data: markerData
 
 
});
 
});
+
} else {
marker.addListener("click" ,  function(evt) {
+
marker =  new nokia.maps.map.Marker(markerData.coords, {
    title.value = evt.target.text;
+
icon: markerData.icon,
    description.value = evt.target.$data.description;
+
anchor: new nokia.maps.util.Point(16, 32),
    address.value = evt.target.$data.address;
+
draggable: true,  //the marker is marked  to be draggable
            name.value = evt.target.$data.name;
+
$data: markerData
            styleURL.value = evt.target.$data.styleURL;
+
});
    lat.innerHTML = evt.target.coordinate.latitude;
+
}
    lng.innerHTML = evt.target.coordinate.longitude;
+
+
    if ( evt.target.$data.description != ""){
+
        infoBubbles.addBubble(evt.target.$data.description, evt.target.coordinate);
+
            } else {
+
              infoBubbles.removeBubble();
+
            }
+
 
+
          currentMarker = evt.target;
+
}, false);
+
+
marker.addListener("drag" ,  function(evt) { infoBubbles.removeBubble();}, false);
+
map.objects.add(marker);
+
}
+
  
 +
// When the marker is clicked, the edit boxes must be refreshed.
 +
marker.addListener("click" ,  function(evt) {
 +
currentMarker = evt.target;
 +
setMarkerData(currentMarker);
 +
});
 +
 +
// If a marker is dragged, we need to close the infobox.
 +
marker.addListener("drag" ,  function(evt) {
 +
removeBubble();
 +
currentMarker = evt.target;
 +
});
 +
 +
map.objects.add(marker);
 +
return marker;
 +
 +
}
 
</code>
 
</code>
  
 
=== Editing Marker Data ===
 
=== Editing Marker Data ===
 
The {{Icode|editMarker()}} method, removes the {{Icode|currentMarker}} and adds another one with the current data from the text fields.
 
The {{Icode|editMarker()}} method, removes the {{Icode|currentMarker}} and adds another one with the current data from the text fields.
<code>
+
<code javascript>
function editMarker() {
+
function editMarker(addWaypoint) {
      map.objects.remove(currentMarker);
+
// deletes the current marker
      infoBubbles.removeBubble();
+
map.objects.remove(currentMarker);
      var markerData = new Object();
+
removeBubble();
markerData.coords = currentMarker.coordinate;
+
if (addWaypoint == true){
        markerData.title = title.value;
+
currentWaypoints.push( currentMarker.coordinate);
                markerData.description = description.value;
+
$('#waypoints').text(JSON.stringify(currentWaypoints));
                markerData.name = name.value;
+
} else {
                markerData.address = address.value;
+
var data = getMarkerData();
addMarker(markerData);
+
data.coords = currentMarker.coordinate;
 +
currentMarker = addMarker(data);
 +
// If a description has been added, display the info bubble.
 
if ( description.value != ""){
 
if ( description.value != ""){
  infoBubbles.addBubble(markerData.description, markerData.coords );
+
infoBubbles.addBubble(data.description, data.coords );
 +
}
 
}
 
}
 +
 
}
 
}
 
</code>
 
</code>
Line 199: Line 203:
 
</code>
 
</code>
 
<code javascript>
 
<code javascript>
function createLineFromWaypoints() {
+
function createLineFromWaypoints(waypoints) {
 
var lineData = new Object();
 
var lineData = new Object();
 
lineData.lineNo = map.objects.getLength() + 1;
 
lineData.lineNo = map.objects.getLength() + 1;
        lineData.waypoints = currentWaypoints ;
+
lineData.waypoints = waypoints ;
        if( lineStyleURL.value != ""){
+
if( lineStyleURL.value != ""){
            lineData.styleURL =  lineStyleURL.value;
+
lineData.styleURL =  lineStyleURL.value;
        }  
+
}
map.objects.add(new nokia.maps.map.Polyline(
+
addLine(lineData);
lineData.waypoints,
+
 
{   
+
// Clear the current waypoint list and the info <span>
    color: "#22CA" ,
+
currentWaypoints = new Array();
    width: 5,
+
$('#waypoints').text("");
    $data: lineData
+
}
+
));
+
currentWaypoints = new Array();
+
waypoints.innerHTML = "";
+
 
}
 
}
 
</code>
 
</code>
  
 
== KML Generator ==
 
== KML Generator ==
The {{Icode|saveMapObjects()}} method has been taken from the [[Nokia_Maps_:_Converting_from_JavaScript_to_KML| converting from JavaScript to KML]] article. All the map Objects currently on screen are iterated through and added as '''KML''' equivalents. In order to discourage the use of inline styles, a {{Icode|&lt;styleURL&gt;}} element has been added. This should refer to a  {{Icode|&lt;Style&gt;}} somewhere else in the document, but obviously the {{Icode|&lt;Style&gt;}} has not been created, and must be added manually. An example of how to add a {{Icode|&lt;styleURL&gt;}}  and an associated {{Icode|&lt;Style&gt;}} is shown below:  
+
The {{Icode|kmlGenerator.generateKML();}} method has been taken from the [[HERE_Maps_:_Converting_from_JavaScript_to_KML| converting from JavaScript to KML]] article. All the map Objects currently on screen are iterated through and added as '''KML''' equivalents. In order to discourage the use of inline styles, a {{Icode|&lt;styleURL&gt;}} element has been added. This should refer to a  {{Icode|&lt;Style&gt;}} somewhere else in the document, but obviously the {{Icode|&lt;Style&gt;}} has not been created, and must be added manually. An example of how to add a {{Icode|&lt;styleURL&gt;}}  and an associated {{Icode|&lt;Style&gt;}} is shown below:  
  
 
<code xml>
 
<code xml>
Line 258: Line 257:
  
 
== Summary ==
 
== Summary ==
It should be easy to create a simple '''KML''' file using the technique described above. Editing can be done either directly on the source '''KML''' or by moving elements around on the map. The generated file is valid '''KML''', and can  be displayed using the standard technique described in the [[Nokia_Maps_API_-_How_to_display_KML_file_data_on_the_map|How to display KML file data on the map]]. The generated '''KML''' could also be added to an existing file (provided that  the header and {{Icode|&lt;Document&gt;}} lines are not included.
+
It should be easy to create a simple '''KML''' file using the technique described above. Editing can be done either directly on the source '''KML''' or by moving elements around on the map. The generated file is valid '''KML''', and can  be displayed using the standard technique described in the [[HERE_Maps_API_-_How_to_display_KML_file_data_on_the_map|How to display KML file data on the map]]. The generated '''KML''' could also be added to an existing file (provided that  the header and {{Icode|&lt;Document&gt;}} lines are not included.
 +
 
 +
A full working example can be found at:
 +
 
 +
http://rawgithub.com/heremaps/examples/master/maps_api_for_javascript/demos/generate-kml/generate-kml-file-from-map.html

Latest revision as of 13:30, 28 November 2013

This article explains how to create and edit a sample KML file using an online editor

Note.pngNote: in order to load a KML file successfully, the generated 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 example, if you are hosting at example.com, the final line of the JavaScript to load the KML will need to be:

kml.parseKML("http://example.com/" + "generated_kml_data_file.kml")
and both the KML loading HTML and the generated_kml_data_file.kml should be placed on http://example.com/

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: http://feedvalidator.org

Article Metadata
Code Example
Source file: [1]
Tested with
Devices(s): Firefox, Internet Explorer, Google Chrome, Opera
Compatibility
Platform(s): Web Browser
Dependencies: HERE Maps API 2.5.3
Article
Keywords: HERE Maps, JavaScript, KML
Created: jasfox (10 Jan 2012)
Last edited: jasfox (28 Nov 2013)


Contents

[edit] Introduction

Keyhole Markup Language (KML) is an XML notation for geographic applications. The advantages of using KML are numerous, and have been listed in a previous article. The learning curve for KML is quite steep, requires a thorough understanding of both XML and mapping technologies, and since the reference documentation is written for 3d rather than 2d maps, much of it is irrelevant for simple mapping cases. All this means that some web developers are put off using KML, which is a pity, since KML is a standard data format, and the use of KML would result in the faster porting of a mapping applications to other platforms.

In order to remedy this, it would be useful to have a WYSIWYG point and click KML generator, where a map could be edited on screen, and the resultant KML file generated. The coded example below, attempts to fill this gap as shown.

KMLGenerator.png

[edit] WSYIWIG Editor

[edit] Adding Markers

Markers can be added by pressing and holding down the mouse , this is the longpress event. An event handler has been added to the map to cope with this. The associated values such as <description> and <name> come directly from the text boxes associated with the HTML.

function addClickListener(map){
map.addListener("longpress", function (evt){
var data = getMarkerData();
data.coords = map.pixelToGeo(evt.targetX , evt.targetY);
currentMarker = addMarker(data);
 
// If a description has been added, display the info bubble.
if (data.description != ""){
infoBubbles.addBubble(data.description, currentMarker.coords );
}
});
}
function getMarkerData(){
var markerData = {
title : $('#title').val(),
description : $('#description').val(),
name : $('#name').val(),
address: $('#address').val()
};
if ($('#icon').val() != ""){
markerData.icon = $('#icon').val();
} else {
markerData.styleURL = $('#styleURL').val();
}
return markerData;
}

An alternative method of adding a marker is by adding an address. This uses the standard geoCoding service, and picks the first address found on the list. If your address is in the "wrong" format, just try making the address more general for now e.g.try the city only. The handler for geo-coding retrieves most of its information from the text boxes on the right hand side of the screen, but the address comes from the callback function.

var searchManager = nokia.places.search.manager;
searchManager.geoCode({
searchTerm : address.value,
onComplete: onSearchComplete});
  function onSearchComplete (data, requestStatus) {
// If the search has finished we can process the results
if (requestStatus == "OK") {
var markerData = getMarkerData()
markerData.address = data.location.address.text;
markerData.coords = data.location.position;
// Ensure the address edit box contains the latest address contents.
$("#address").val(data.location.address.text);
currentMarker = addMarker(markerData);
map.setCenter(data.location.position);
 
} else if (requestStatus == "ERROR") {
alert("The search request failed.");
}
}

The addMarkers() method actually adds the marker, which itself contains a copy of its own <description>, <address>, <name> & etc. The marker has two events:

  • a click event to display the data in text boxes for editing. This will also display an infobubble if the <description> field is set. A reference is kept on the currentMarker i.e. the last one selected.
  • a drag event to remove the infobubble if a marker is repositioned. All markers are defined as draggable so the user can reposition them as necessary.
function addMarker(markerData) {
var marker;
 
if (markerData.title === undefined){
markerData.title = "";
}
 
// Either an a Standard Marker or an icon, both are left
// Draggable, so the location can be corrected.
if (markerData.icon === undefined){
marker = new nokia.maps.map.StandardMarker(markerData.coords, {
text: markerData.title, //small title
draggable: true, //the marker is marked to be draggable
$data: markerData
});
} else {
marker = new nokia.maps.map.Marker(markerData.coords, {
icon: markerData.icon,
anchor: new nokia.maps.util.Point(16, 32),
draggable: true, //the marker is marked to be draggable
$data: markerData
});
}
 
// When the marker is clicked, the edit boxes must be refreshed.
marker.addListener("click" , function(evt) {
currentMarker = evt.target;
setMarkerData(currentMarker);
});
 
// If a marker is dragged, we need to close the infobox.
marker.addListener("drag" , function(evt) {
removeBubble();
currentMarker = evt.target;
});
 
map.objects.add(marker);
return marker;
 
}

[edit] Editing Marker Data

The editMarker() method, removes the currentMarker and adds another one with the current data from the text fields.

function editMarker(addWaypoint) {
// deletes the current marker
map.objects.remove(currentMarker);
removeBubble();
if (addWaypoint == true){
currentWaypoints.push( currentMarker.coordinate);
$('#waypoints').text(JSON.stringify(currentWaypoints));
} else {
var data = getMarkerData();
data.coords = currentMarker.coordinate;
currentMarker = addMarker(data);
// If a description has been added, display the info bubble.
if ( description.value != ""){
infoBubbles.addBubble(data.description, data.coords );
}
}
 
}

[edit] Adding Polylines

It is impossible to create Polylines without first having some defined waypoints. The waypoints are merely geo.Coordinates, so a button has been added to take the coordinates of the currentMarker and add them to an array. The marker is then removed to "tidy up" the display. When the create line from Waypoints button is pressed, the Polyline is created.

Warning.pngWarning: There is currently no method to delete waypoints or Polylines, this must be done by editing the KML directly.

var currentWaypoints = new Array();
map.objects.remove(currentMarker);
currentWaypoints.push( currentMarker.coordinate);
function createLineFromWaypoints(waypoints) {
var lineData = new Object();
lineData.lineNo = map.objects.getLength() + 1;
lineData.waypoints = waypoints ;
if( lineStyleURL.value != ""){
lineData.styleURL = lineStyleURL.value;
}
addLine(lineData);
 
// Clear the current waypoint list and the info <span>
currentWaypoints = new Array();
$('#waypoints').text("");
}

[edit] KML Generator

The kmlGenerator.generateKML(); method has been taken from the converting from JavaScript to KML article. All the map Objects currently on screen are iterated through and added as KML equivalents. In order to discourage the use of inline styles, a <styleURL> element has been added. This should refer to a <Style> somewhere else in the document, but obviously the <Style> has not been created, and must be added manually. An example of how to add a <styleURL> and an associated <Style> is shown below:

<Style id='smallIcon'>
<IconStyle>
<Icon>
<href>http:www.example.com/Icon-Small.png</href>
</Icon>
</IconStyle>
</Style>
<Placemark>
<Point><coordinates>-0.12759880162775517,51.50320703163743,0</coordinates></Point>
<styleUrl>#smallIcon</styleUrl>
</Placemark>

Since KML is just a form of XML, the generated file can be read using jQuery and applying the technique found in the Create map markers from XML data, the KML is in a known format, it is merely an exercise to extract the name from the <name> element, the address from the <address> element and so on. Two problems do need to be solved however. Firstly the geocoordinates are held as comma separated text, rather than individual <longitude> and <latittude> elements and secondly the description in the <description> element can contain formatted HTML and is held in a CDATA section. The first problem is dealt with by splitting the text using the search() function:

var lng = coord.substring( 0 , coord.search(","));
coord = coord.substring(coord.search(",")+ 1);
var lat = coord.substring( 0 , coord.search(","));
markerData.coords = new nokia.maps.geo.Coordinate(parseFloat(lat), parseFloat(lng));

The CDATA section is dealt with by stripping out the marker characters, and safely encoding the HTML data within it. The HTML is re-inflated using the escape() function when it is read.

while ( kml.search ("<!\\[CDATA\\[")  > - 1){
var from = kml.search ("<!\\[CDATA\\[");
var to= kml.search ("\\]\\]>");
kml = kml.substring(0, from) + escape(kml.substring(from + 9, to)) + kml.substring(to+ 3);
}
markerData.description =  unescape($(this).find('description').text());

[edit] Summary

It should be easy to create a simple KML file using the technique described above. Editing can be done either directly on the source KML or by moving elements around on the map. The generated file is valid KML, and can be displayed using the standard technique described in the How to display KML file data on the map. The generated KML could also be added to an existing file (provided that the header and <Document> lines are not included.

A full working example can be found at:

http://rawgithub.com/heremaps/examples/master/maps_api_for_javascript/demos/generate-kml/generate-kml-file-from-map.html

This page was last modified on 28 November 2013, at 13:30.
150 page views in the last 30 days.
×