diff --git a/src/ol/format/kmlformat.js b/src/ol/format/kmlformat.js index 63d4edb66d..de4c4d42aa 100644 --- a/src/ol/format/kmlformat.js +++ b/src/ol/format/kmlformat.js @@ -1130,6 +1130,18 @@ ol.format.KML.outerBoundaryIsParser_ = function(node, objectStack) { }; +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + */ +ol.format.KML.LinkParser_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Link'); + ol.xml.parseNode(ol.format.KML.LINK_PARSERS_, node, objectStack); +}; + + /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. @@ -1331,6 +1343,35 @@ ol.format.KML.GX_MULTITRACK_GEOMETRY_PARSERS_ = ol.xml.makeParsersNS( }); +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.KML.NETWORK_LINK_PARSERS_ = ol.xml.makeParsersNS( + ol.format.KML.NAMESPACE_URIS_, { + 'ExtendedData': ol.format.KML.ExtendedDataParser_, + 'Link': ol.format.KML.LinkParser_, + 'address': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'description': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'open': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean), + 'phoneNumber': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'visibility': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.KML.LINK_PARSERS_ = ol.xml.makeParsersNS( + ol.format.KML.NAMESPACE_URIS_, { + 'href': ol.xml.makeObjectPropertySetter(ol.format.KML.readURI_) + }); + + /** * @const * @type {Object.>} @@ -1711,6 +1752,71 @@ ol.format.KML.prototype.readNameFromNode = function(node) { }; +/** + * @param {Document|Node|string} source Souce. + * @return {Array.} Network links. + * @api + */ +ol.format.KML.prototype.readNetworkLinks = function(source) { + var networkLinks = []; + if (ol.xml.isDocument(source)) { + goog.array.extend(networkLinks, this.readNetworkLinksFromDocument( + /** @type {Document} */ (source))); + } else if (ol.xml.isNode(source)) { + goog.array.extend(networkLinks, this.readNetworkLinksFromNode( + /** @type {Node} */ (source))); + } else if (goog.isString(source)) { + var doc = ol.xml.parse(source); + goog.array.extend(networkLinks, this.readNetworkLinksFromDocument(doc)); + } else { + goog.asserts.fail(); + } + return networkLinks; +}; + + +/** + * @param {Document} doc Document. + * @return {Array.} Network links. + */ +ol.format.KML.prototype.readNetworkLinksFromDocument = function(doc) { + var n, networkLinks = []; + for (n = doc.firstChild; !goog.isNull(n); n = n.nextSibling) { + if (n.nodeType == goog.dom.NodeType.ELEMENT) { + goog.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); + } + } + return networkLinks; +}; + + +/** + * @param {Node} node Node. + * @return {Array.} Network links. + */ +ol.format.KML.prototype.readNetworkLinksFromNode = function(node) { + var n, networkLinks = []; + for (n = node.firstElementChild; !goog.isNull(n); n = n.nextElementSibling) { + if (goog.array.contains(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) && + n.localName == 'NetworkLink') { + var obj = ol.xml.pushParseAndPop({}, ol.format.KML.NETWORK_LINK_PARSERS_, + n, []); + networkLinks.push(obj); + } + } + for (n = node.firstElementChild; !goog.isNull(n); n = n.nextElementSibling) { + var localName = ol.xml.getLocalName(n); + if (goog.array.contains(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) && + (localName == 'Document' || + localName == 'Folder' || + localName == 'kml')) { + goog.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); + } + } + return networkLinks; +}; + + /** * Read the projection from a KML source. * diff --git a/test/spec/ol/format/kmlformat.test.js b/test/spec/ol/format/kmlformat.test.js index ce46fc54b4..ce3c17332c 100644 --- a/test/spec/ol/format/kmlformat.test.js +++ b/test/spec/ol/format/kmlformat.test.js @@ -2489,6 +2489,45 @@ describe('ol.format.KML', function() { }); + describe('#readNetworkLinks', function() { + it('returns empty array if no network links found', function() { + var text = + '' + + ' ' + + ' ' + + ''; + var nl = format.readNetworkLinks(text); + expect(nl).to.have.length(0); + }); + + it('returns an array of network links', function() { + var text = + '' + + ' ' + + ' ' + + ' bar' + + ' ' + + ' bar/bar.kml' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' http://foo.com/foo.kml' + + ' ' + + ' ' + + ' ' + + ''; + var nl = format.readNetworkLinks(text); + expect(nl).to.have.length(2); + expect(nl[0].name).to.be('bar'); + expect(nl[0].href).to.be('bar/bar.kml'); + expect(nl[1].href).to.be('http://foo.com/foo.kml'); + }); + + }); + });