3

I have a leaflet map and a kml file. I load the kml file using the plugin: leaflet-omnivore. Now I want to access the <folder> <name>(which is "RegionName"). I need it because I want to link the kml with an other json file which also has RegionName as a properties.name. But when output the loaded kml file via console.log(myKML) I can only access the <name> below <placemark>

The code I load the kml with:

var myKML = omnivore.kml('KML/Testdaten_KML.kml', null, L.mapbox.featureLayer());

The kml file is structured like:

<Folder>
  <name>RegionName</name>
  <Placemark>
    <name>Form 1</name>
    <Polygon>
      <outerBoundaryIs>
        <LinearRing>
          <tessellate>1</tessellate>
          <coordinates>
            11.82,52.60
            11.86,52.58
            11.90,52.61
            11.87,52.62
            11.82,52.60
          </coordinates>
        </LinearRing>
      </outerBoundaryIs>
    </Polygon>
  </Placemark>
</Folder>

2 Answers 2

1
+50

So this is one possible solution, it is a bit long but straightforward!

Step 1: Create a global variable ("kmlJSON") and load your KML via a JQUERY AJAX call (or vanilla JS, as you prefer):

var kmlJSON;
var url = 'KML/Testdaten_KML.kml'

$.ajax({
    url: url,
    data: {},
    success: function(data){
        kmlJSON=xmlToJson(data);
    },
    dataType: 'xml',
    error: function (request,status,error) {
        console.log(request.responseText);
    }
});

Step 2: Enter this function ('xmlToJson') as is, taken from here:

function xmlToJson(xml) {

    // Create the return object
    var obj = {};

    if (xml.nodeType == 1) { // element
        // do attributes
        if (xml.attributes.length > 0) {
        obj["@attributes"] = {};
            for (var j = 0; j < xml.attributes.length; j++) {
                var attribute = xml.attributes.item(j);
                obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
            }
        }
    } else if (xml.nodeType == 3) { // text
        obj = xml.nodeValue;
    }

    // do children
    if (xml.hasChildNodes()) {
        for(var i = 0; i < xml.childNodes.length; i++) {
            var item = xml.childNodes.item(i);
            var nodeName = item.nodeName;
            if (typeof(obj[nodeName]) == "undefined") {
                obj[nodeName] = xmlToJson(item);
            } else {
                if (typeof(obj[nodeName].push) == "undefined") {
                    var old = obj[nodeName];
                    obj[nodeName] = [];
                    obj[nodeName].push(old);
                }
                obj[nodeName].push(xmlToJson(item));
            }
        }
    }
    return obj;
};

Step 3: You can then access the KML as a JSON. Normally, it should be:

kmlJSON.kml.Document.Folder.name

but assuming the KML snippet you attached is the whole KML then it should just be:

kmlJSON.Folder.name
3
  • hm, my var kmlJSON ends up beind "undefined"
    – obrob
    Feb 13, 2018 at 17:02
  • That most likely means the ajax call didn't succeed, is the relative path (var url) to your data ('KML\Testdaten_KML.kml) correct? Try an absolute path, see here: w3schools.com/html/html_filepaths.asp
    – 15Step
    Feb 13, 2018 at 18:03
  • yes, I was trying to access the var kmlJSON before the ajax call succeeded. Fixed it now and worked
    – obrob
    Feb 15, 2018 at 8:08
1

Interesting question!

My line of reasoning:

  1. omnivore.kml does two things

    • loads the kml file over http
    • parses the kml file and generates geoJSON
  2. omnivore does not extract the tag you want

  3. Therefore, what I would do is: 3.1 load the kml separately 3.2 parse the kml file manually to extract the data you need 3.3 use omnivore.kml.parse to parse the akctual kml

3.1 Should any web-developer be able to perform using some library

3.2 can be done using something like this

var xmlDoc = new DOMParser().parseFromString(xmlString, 'text/xml')
var name xmlDoc.getElementsByTagName('folder')[0].getElementsByTagName('name')[0].innerHTML;

3.3 is just a matter of using omnivore.kml.parse

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.