/*global L: true */ L.KML = L.FeatureGroup.extend({ options: { async: true }, initialize: function(kml, options) { L.Util.setOptions(this, options); this._kml = kml; this._layers = {}; if (kml) { this.addKML(kml, options, this.options.async); } }, loadXML: function(url, cb, options, async) { if (async == undefined) async = this.options.async; if (options == undefined) options = this.options; var req = new window.XMLHttpRequest(); req.open('GET', url, async); try { req.overrideMimeType('text/xml'); // unsupported by IE } catch(e) {} req.onreadystatechange = function() { if (req.readyState != 4) return; if(req.status == 200) cb(req.responseXML, options); }; req.send(null); }, addKML: function(url, options, async) { var _this = this; var cb = function(gpx, options) { _this._addKML(gpx, options) }; this.loadXML(url, cb, options, async); }, _addKML: function(xml, options) { var layers = L.KML.parseKML(xml); if (!layers || !layers.length) return; for (var i = 0; i < layers.length; i++) { this.fire('addlayer', { layer: layers[i] }); this.addLayer(layers[i]); } this.latLngs = L.KML.getLatLngs(xml); this.fire("loaded"); }, latLngs: [] }); L.Util.extend(L.KML, { parseKML: function (xml) { var style = this.parseStyle(xml); var el = xml.getElementsByTagName("Folder"); var layers = [], l; for (var i = 0; i < el.length; i++) { if (!this._check_folder(el[i])) { continue; } l = this.parseFolder(el[i], style); if (l) { layers.push(l); } } el = xml.getElementsByTagName('Placemark'); for (var j = 0; j < el.length; j++) { if (!this._check_folder(el[j])) { continue; } l = this.parsePlacemark(el[j], xml, style); if (l) { layers.push(l); } } return layers; }, // Return false if e's first parent Folder is not [folder] // - returns true if no parent Folders _check_folder: function (e, folder) { e = e.parentElement; while (e && e.tagName !== "Folder") { e = e.parentElement; } return !e || e === folder; }, parseStyle: function (xml) { var style = {}; var sl = xml.getElementsByTagName("Style"); //for (var i = 0; i < sl.length; i++) { var attributes = {color: true, width: true, Icon: true, href: true, hotSpot: true}; function _parse(xml) { var options = {}; for (var i = 0; i < xml.childNodes.length; i++) { var e = xml.childNodes[i]; var key = e.tagName; if (!attributes[key]) { continue; } if (key === 'hotSpot') { for (var j = 0; j < e.attributes.length; j++) { options[e.attributes[j].name] = e.attributes[j].nodeValue; } } else { var value = e.childNodes[0].nodeValue; if (key === 'color') { options.opacity = parseInt(value.substring(0, 2), 16) / 255.0; options.color = "#" + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4); } else if (key === 'width') { options.weight = value; } else if (key === 'Icon') { ioptions = _parse(e); if (ioptions.href) { options.href = ioptions.href; } } else if (key === 'href') { options.href = value; } } } return options; } for (var i = 0; i < sl.length; i++) { var e = sl[i], el; var options = {}, poptions = {}, ioptions = {}; el = e.getElementsByTagName("LineStyle"); if (el && el[0]) { options = _parse(el[0]); } el = e.getElementsByTagName("PolyStyle"); if (el && el[0]) { poptions = _parse(el[0]); } if (poptions.color) { options.fillColor = poptions.color; } if (poptions.opacity) { options.fillOpacity = poptions.opacity; } el = e.getElementsByTagName("IconStyle"); if (el && el[0]) { ioptions = _parse(el[0]); } if (ioptions.href) { // save anchor info until the image is loaded options.icon = new L.KMLIcon({ iconUrl: ioptions.href, shadowUrl: null, iconAnchorRef: {x: ioptions.x, y: ioptions.y}, iconAnchorType: {x: ioptions.xunits, y: ioptions.yunits} }); } style['#' + e.getAttribute('id')] = options; } return style; }, parseFolder: function (xml, style) { var el, layers = [], l; el = xml.getElementsByTagName('Folder'); for (var i = 0; i < el.length; i++) { if (!this._check_folder(el[i], xml)) { continue; } l = this.parseFolder(el[i], style); if (l) { layers.push(l); } } el = xml.getElementsByTagName('Placemark'); for (var j = 0; j < el.length; j++) { if (!this._check_folder(el[j], xml)) { continue; } l = this.parsePlacemark(el[j], xml, style); if (l) { layers.push(l); } } if (!layers.length) { return; } if (layers.length === 1) { return layers[0]; } return new L.FeatureGroup(layers); }, parsePlacemark: function (place, xml, style) { var i, j, el, options = {}; el = place.getElementsByTagName('styleUrl'); for (i = 0; i < el.length; i++) { var url = el[i].childNodes[0].nodeValue; for (var a in style[url]) { // for jshint if (true) { options[a] = style[url][a]; } } } var layers = []; var parse = ['LineString', 'Polygon', 'Point']; for (j in parse) { // for jshint if (true) { var tag = parse[j]; el = place.getElementsByTagName(tag); for (i = 0; i < el.length; i++) { var l = this["parse" + tag](el[i], xml, options); if (l) { layers.push(l); } } } } if (!layers.length) { return; } var layer = layers[0]; if (layers.length > 1) { layer = new L.FeatureGroup(layers); } var name, descr = ""; el = place.getElementsByTagName('name'); if (el.length) { name = el[0].childNodes[0].nodeValue; } el = place.getElementsByTagName('description'); for (i = 0; i < el.length; i++) { for (j = 0; j < el[i].childNodes.length; j++) { descr = descr + el[i].childNodes[j].nodeValue; } } if (name) { layer.bindPopup("