UNPKG

loaders.gl

Version:

Framework-independent loaders for 3D graphics formats

820 lines (685 loc) 23.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * Author - Nick Blackwell * License - MIT * Description - Defines a class, KMLParser which is a container for * static kml parsing methods. */ /** * KMLParser Class parses standard kml documents and returns objects * representiong it's data. * the optional transformations define the data within these objects, * ie, documentTransform (for Geolive) * will create a Layer object from its contents, and pull out the items * which will be transformed aswell as MapItems. */ /* global console */ /* eslint-disable no-console */ var KMLParser = /*#__PURE__*/ function () { function KMLParser(xml) { _classCallCheck(this, KMLParser); this.kml = xml; } _createClass(KMLParser, [{ key: "parse", value: function parse() { return { documents: this._filter(KMLParser.ParseDomDocuments(this.kml)), folders: this._filter(KMLParser.ParseDomFolders(this.kml)), markers: this._filter(KMLParser.ParseDomMarkers(this.kml)), polygons: this._filter(KMLParser.ParseDomPolygons(this.kml)), lines: this._filter(KMLParser.ParseDomLines(this.kml)), overlays: this._filter(KMLParser.ParseDomGroundOverlays(this.kml)), links: this._filter(KMLParser.ParseDomLinks(this.kml)) }; } }, { key: "parseDocuments", value: function parseDocuments(callback) { var _this = this; var documentData = this._filter(KMLParser.ParseDomDocuments(this.kml)); documentData.forEach(function (p, i) { return callback(p, _this.kml, documentData, i); }); return this; } }, { key: "parseFolders", value: function parseFolders(callback) { var _this2 = this; var folderData = this._filter(KMLParser.ParseDomFolders(this.kml)); folderData.forEach(function (p, i) { return callback(p, _this2.kml, folderData, i); }); return this; } }, { key: "parseMarkers", value: function parseMarkers(callback) { var _this3 = this; var markerData = this._filter(KMLParser.ParseDomMarkers(this.kml)); markerData.forEach(function (p, i) { return callback(p, _this3.kml, markerData, i); }); return this; } }, { key: "parsePolygons", value: function parsePolygons(callback) { var _this4 = this; var polygonData = this._filter(KMLParser.ParseDomPolygons(this.kml)); polygonData.forEach(function (p, i) { return callback(p, _this4.kml, polygonData, i); }); return this; } }, { key: "parseLines", value: function parseLines(callback) { var _this5 = this; var lineData = this._filter(KMLParser.ParseDomLines(this.kml)); lineData.forEach(function (p, i) { return callback(p, _this5.kml, lineData, i); }); return this; } }, { key: "parseGroundOverlays", value: function parseGroundOverlays(callback) { var _this6 = this; var overlayData = this._filter(KMLParser.ParseDomGroundOverlays(this.kml)); overlayData.forEach(function (o, i) { return callback(o, _this6.kml, overlayData, i); }); return this; } }, { key: "parseNetworklinks", value: function parseNetworklinks(callback) { var _this7 = this; var linkData = this._filter(KMLParser.ParseDomLinks(this.kml)); linkData.forEach(function (p, i) { return callback(p, _this7.kml, linkData, i); }); return this; } }, { key: "_filter", value: function _filter(a) { var _this8 = this; var filtered = []; if (this._filters && a && a.length) { a.forEach(function (item) { var bool = true; _this8._filters.forEach(function (f) { if (f(item) === false) { bool = false; } }); if (bool) { filtered.push(item); } }); return filtered; } return a; } }, { key: "addFilter", value: function addFilter(filter) { if (!this._filters) { this._filters = []; } this._filters.push(filter); return this; } }], [{ key: "ParseDomDocuments", value: function ParseDomDocuments(xmlDom) { var docs = []; var docsDomNodes = xmlDom.getElementsByTagName('Document'); for (var i = 0; i < docsDomNodes.length; i++) { var node = docsDomNodes.item(i); var docsData = Object.assign({}, KMLParser.ParseDomDoc(node), KMLParser.ParseNonSpatialDomData(node, {})); var transform = function transform(options) { return options; }; docs.push(transform(docsData)); } return docs; } }, { key: "ParseDomDoc", value: function ParseDomDoc(xmlDom) { return {}; } }, { key: "ParseDomFolders", value: function ParseDomFolders(xmlDom) { var folders = []; var folderDomNodes = KMLParser.ParseDomItems(xmlDom, 'Folder'); for (var i = 0; i < folderDomNodes.length; i++) { var node = folderDomNodes[i]; var folderData = Object.assign({ type: 'folder' }, KMLParser.ParseDomFolder(node), KMLParser.ParseNonSpatialDomData(node, {})); var transform = function transform(options) { return options; }; folders.push(transform(folderData)); } return folders; } }, { key: "ParseDomLinks", value: function ParseDomLinks(xmlDom) { var links = []; var linkDomNodes = xmlDom.getElementsByTagName('NetworkLink'); for (var i = 0; i < linkDomNodes.length; i++) { var node = linkDomNodes.item(i); var linkData = Object.assign({}, KMLParser.ParseDomLink(node), KMLParser.ParseNonSpatialDomData(node, {})); var transform = function transform(options) { return options; }; links.push(transform(linkData)); } return links; } }, { key: "ParseDomFolder", value: function ParseDomFolder(xmlDom) { return {}; } }, { key: "ParseDomLink", value: function ParseDomLink(xmlDom) { var urls = xmlDom.getElementsByTagName('href'); var link = { type: 'link' }; if (urls.length > 0) { var url = urls.item(0); link.url = KMLParser.Value(url); } return link; } }, { key: "ParseDomLines", value: function ParseDomLines(xmlDom) { var lines = []; var lineDomNodes = KMLParser.ParseDomItems(xmlDom, 'LineString'); for (var i = 0; i < lineDomNodes.length; i++) { var node = lineDomNodes[i]; var polygonData = Object.assign({ type: 'line', lineColor: '#FF000000', // black lineWidth: 1, polyColor: '#77000000', // black semitransparent, coordinates: KMLParser.ParseDomCoordinates(node) // returns an array of GLatLngs }, KMLParser.ParseNonSpatialDomData(node, {}), KMLParser.ResolveDomStyle(KMLParser.ParseDomStyle(node), xmlDom)); var rgb = KMLParser.convertKMLColorToRGB(polygonData.lineColor); polygonData.lineOpacity = rgb.opacity; polygonData.lineColor = rgb.color; lines.push(polygonData); } return lines; } }, { key: "ParseDomGroundOverlays", value: function ParseDomGroundOverlays(xmlDom) { var lines = []; var lineDomNodes = KMLParser.ParseDomItems(xmlDom, 'GroundOverlay'); for (var i = 0; i < lineDomNodes.length; i++) { var node = lineDomNodes[i]; var polygonData = Object.assign({ type: 'imageoverlay', icon: KMLParser.ParseDomIcon(node), bounds: KMLParser.ParseDomBounds(node) }, KMLParser.ParseNonSpatialDomData(node, {})); lines.push(polygonData); } return lines; } }, { key: "ParseDomPolygons", value: function ParseDomPolygons(xmlDom) { var polygons = []; var polygonDomNodes = KMLParser.ParseDomItems(xmlDom, 'Polygon'); for (var i = 0; i < polygonDomNodes.length; i++) { var node = polygonDomNodes[i]; var polygonData = Object.assign({ type: 'polygon', fill: true, lineColor: '#FF000000', // black lineWidth: 1, polyColor: '#77000000', // black semitransparent, coordinates: KMLParser.ParseDomCoordinates(node) // returns an array of google.maps.LatLng }, KMLParser.ParseNonSpatialDomData(node, {}), KMLParser.ResolveDomStyle(KMLParser.ParseDomStyle(node), xmlDom)); var lineRGB = KMLParser.convertKMLColorToRGB(polygonData.lineColor); polygonData.lineOpacity = lineRGB.opacity; polygonData.lineColor = lineRGB.color; var polyRGB = KMLParser.convertKMLColorToRGB(polygonData.polyColor); polygonData.polyOpacity = polygonData.fill ? polyRGB.opacity : 0; polygonData.polyColor = polyRGB.color; polygons.push(polygonData); } return polygons; } }, { key: "ParseDomMarkers", value: function ParseDomMarkers(xmlDom) { var markers = []; var markerDomNodes = KMLParser.ParseDomItems(xmlDom, 'Point'); for (var i = 0; i < markerDomNodes.length; i++) { var node = markerDomNodes[i]; var coords = KMLParser.ParseDomCoordinates(node); var marker = Object.assign({ type: 'point', coordinates: coords[0] // returns an array of google.maps.LatLng }, KMLParser.ParseNonSpatialDomData(node, {})); var icon = KMLParser.ParseDomStyle(node); if (icon.charAt(0) === '#') { icon = KMLParser.ResolveDomStyle(icon, xmlDom).icon; } if (icon) { // better to not have any hint of an icon (ie: icon:null) so default can be used by caller marker.icon = icon; } markers.push(marker); } return markers; } }, { key: "ParseDomCoordinates", value: function ParseDomCoordinates(xmlDom) { var coordNodes = xmlDom.getElementsByTagName('coordinates'); if (!coordNodes.length) { console.warn(['KMLParser. DOM Node did not contain coordinates!', { node: xmlDom }]); return null; } var node = coordNodes.item(0); var s = KMLParser.Value(node); s = s.trim(); var coordStrings = s.split(' '); var coordinates = []; Object.values(coordStrings).forEach(function (coord) { var c = coord.split(','); if (c.length > 1) { // JSConsole([c[1],c[0]]); coordinates.push([c[1], c[0]]); } }); return coordinates; } /* eslint-disable max-statements */ }, { key: "ParseDomBounds", value: function ParseDomBounds(xmlDom) { var coordNodes = xmlDom.getElementsByTagName('LatLonBox'); if (!coordNodes.length) { console.warn(['KMLParser. DOM Node did not contain coordinates!', { node: xmlDom }]); return null; } var node = coordNodes.item(0); var norths = node.getElementsByTagName('north'); var souths = node.getElementsByTagName('south'); var easts = node.getElementsByTagName('east'); var wests = node.getElementsByTagName('west'); var north = null; var south = null; var east = null; var west = null; if (!norths.length) { console.warn(['KMLParser. DOM LatLngBox Node did not contain north!', { node: xmlDom }]); } else { north = parseFloat(KMLParser.Value(norths.item(0))); } if (!souths.length) { console.warn(['KMLParser. DOM LatLngBox Node did not contain south!', { node: xmlDom }]); } else { south = parseFloat(KMLParser.Value(souths.item(0))); } if (!easts.length) { console.warn(['KMLParser. DOM LatLngBox Node did not contain east!', { node: xmlDom }]); } else { east = parseFloat(KMLParser.Value(easts.item(0))); } if (!wests.length) { console.warn(['KMLParser. DOM LatLngBox Node did not contain west!', { node: xmlDom }]); } else { west = parseFloat(KMLParser.Value(wests.item(0))); } return { north: north, south: south, east: east, west: west }; } /* eslint-enable max-statements */ }, { key: "ParseNonSpatialDomData", value: function ParseNonSpatialDomData(xmlDom, options) { var config = Object.assign({}, { maxOffset: 2 }, options); var data = { name: '', description: null, tags: {} }; var names = xmlDom.getElementsByTagName('name'); for (var i = 0; i < names.length; i++) { if (KMLParser.WithinOffsetDom(xmlDom, names.item(i), config.maxOffset)) { data.name = KMLParser.Value(names.item(i)); break; } } var descriptions = xmlDom.getElementsByTagName('description'); for (var _i = 0; _i < descriptions.length; _i++) { if (KMLParser.WithinOffsetDom(xmlDom, descriptions.item(_i), config.maxOffset)) { data.description = KMLParser.Value(descriptions.item(_i)); break; } } if (xmlDom.hasAttribute('id')) { data.id = parseInt(xmlDom.getAttribute('id'), 10); } var extendedDatas = xmlDom.getElementsByTagName('ExtendedData'); for (var _i2 = 0; _i2 < extendedDatas.length; _i2++) { if (KMLParser.WithinOffsetDom(xmlDom, extendedDatas.item(_i2), config.maxOffset)) { for (var j = 0; j < extendedDatas.item(_i2).childNodes.length; j++) { var c = extendedDatas.item(_i2).childNodes.item(j); var t = KMLParser.ParseTag(c); if (t.name !== '#text') { // eslint-disable-line data.tags[t.name] = t.value; } } } } return data; } }, { key: "ParseTag", value: function ParseTag(xmlDom) { var tags = { name: null, value: {} }; switch (xmlDom.nodeName) { case 'Data': case 'data': // TODO: add data tags... break; case 'ID': tags.name = 'ID'; tags.value = KMLParser.Value(xmlDom); break; default: tags.name = xmlDom.nodeName; tags.value = KMLParser.Value(xmlDom); break; } return tags; } }, { key: "WithinOffsetDom", value: function WithinOffsetDom(parent, child, max) { var current = child.parentNode; for (var i = 0; i < max; i++) { if (current.nodeName === (typeof parent === 'string' ? parent : parent.nodeName)) { return true; } current = current.parentNode; } console.error(['KMLParser. Could not find parent node within expected bounds.', { parentNode: parent, childNode: child, bounds: max }]); return false; } }, { key: "ParseDomStyle", value: function ParseDomStyle(xmlDom, options) { var config = Object.assign({}, { defaultStyle: 'default' }, options); var styles = xmlDom.getElementsByTagName('styleUrl'); var style = config.defaultStyle; if (styles.length === 0) { console.warn(['KMLParser. DOM Node did not contain styleUrl!', { node: xmlDom, options: config }]); } else { var node = styles.item(0); style = KMLParser.Value(node); } return style; } }, { key: "ParseDomIcon", value: function ParseDomIcon(xmlDom, options) { var config = Object.assign({}, { defaultIcon: false, defaultScale: 1.0 }, options); var icons = xmlDom.getElementsByTagName('Icon'); var icon = config.defaultStyle; var scale = config.defaultScale; if (icons.length === 0) { console.warn(['KMLParser. DOM Node did not contain Icon!', { node: xmlDom, options: config }]); } else { var node = icons.item(0); var urls = node.getElementsByTagName('href'); if (urls.length === 0) { console.warn(['KMLParser. DOM Icon Node did not contain href!', { node: xmlDom, options: config }]); } else { var hrefNode = urls.item(0); icon = KMLParser.Value(hrefNode); } var scales = node.getElementsByTagName('viewBoundScale'); if (scales.length === 0) { console.warn(['KMLParser. DOM Icon Node did not contain viewBoundScale!', { node: xmlDom, options: config }]); } else { var scaleNode = scales.item(0); scale = parseFloat(KMLParser.Value(scaleNode)); } } return { url: icon, scale: scale }; } /* eslint-disable max-depth, max-statements */ }, { key: "ResolveDomStyle", value: function ResolveDomStyle(style, xmlDom) { var data = {}; var name = style.charAt(0) === '#' ? style.substring(1, style.length) : style; var styles = xmlDom.getElementsByTagName('Style'); for (var i = 0; i < styles.length; i++) { var node = styles.item(i); var id = node.getAttribute('id'); if (id === name) { var lineStyles = node.getElementsByTagName('LineStyle'); var polyStyles = node.getElementsByTagName('PolyStyle'); var iconStyles = node.getElementsByTagName('href'); if (lineStyles.length > 0) { var lineStyle = lineStyles.item(0); var colors = lineStyle.getElementsByTagName('color'); if (colors.length > 0) { var color = colors.item(0); data.lineColor = KMLParser.Value(color); } var widths = lineStyle.getElementsByTagName('width'); if (widths.length > 0) { var width = widths.item(0); data.lineWidth = KMLParser.Value(width); } } if (polyStyles.length > 0) { var polyStyle = polyStyles.item(0); var _colors = polyStyle.getElementsByTagName('color'); if (_colors.length > 0) { var _color = _colors.item(0); data.polyColor = KMLParser.Value(_color); } var outlines = polyStyle.getElementsByTagName('outline'); if (outlines.length > 0) { var outline = outlines.item(0); var o = KMLParser.Value(outline); data.outline = Boolean(o); } } if (iconStyles.length > 0) { var iconStyle = iconStyles.item(0); var icon = KMLParser.Value(iconStyle); data.icon = icon; } } } return data; } /* eslint-enable max-depth, max-statements */ /* eslint-disable */ }, { key: "ParseDomItems", value: function ParseDomItems(xmlDom, tag) { var tagName = tag || 'Point'; var items = []; var markerDomNodes = xmlDom.getElementsByTagName(tagName); for (var i = 0; i < markerDomNodes.length; i++) { var node = markerDomNodes.item(i); if (tag === 'GroundOverlay') { items.push(node); continue; } var parent = node.parentNode.nodeName === 'Placemark' ? node.parentNode : node.parentNode.parentNode.nodeName === 'Placemark' ? node.parentNode.parentNode : null; if (parent === null) { console.error(['Failed to find ParentNode for Element - ' + tagName, { node: xmlDom }]); // (); } else { items.push(parent); } } return items; } // KML Color is defined similar to RGB except it is in the opposite order and starts with opacity, // #OOBBGGRR }, { key: "convertKMLColorToRGB", value: function convertKMLColorToRGB(colorString) { var colorStr = colorString.replace('#', ''); while (colorStr.length < 6) { colorStr = (_readOnlyError("colorStr"), '0' + colorStr); } // make sure line is dark! while (colorStr.length < 8) { colorStr = (_readOnlyError("colorStr"), 'F' + colorStr); } // make sure opacity is a large fraction if (colorStr.length > 8) { colorStr = (_readOnlyError("colorStr"), colorStr.substring(0, 8)); } var color = colorStr.substring(6, 8) + colorStr.substring(4, 6) + colorStr.substring(2, 4); var opacity = parseInt(colorStr.substring(0, 2), 16) * 1.000 / parseInt('FF', 16); var rgbVal = { color: '#' + color, opacity: opacity }; return rgbVal; } }, { key: "RGBColorToKML", value: function RGBColorToKML(rgb, opacity) { var colorStr = rgb.replace('#', ''); while (colorStr.length < 6) { colorStr = (_readOnlyError("colorStr"), '0' + colorStr); } //make sure line is dark! if (colorStr.length > 6) { colorStr = (_readOnlyError("colorStr"), colorStr.substring(0, 6)); } if (opacity != null) { if (opacity >= 0.0 && opacity <= 1.0) { var _opacityNum = opacity; } else if (parseInt(opacity) >= 0.0 && parseInt(opacity) <= 1.0) { var _opacityNum2 = parseInt(opacity); } } if (opacityNum === null) { var _opacityNum3 = 1.0; } var opacityNum = opacityNum * 255.0; var opacityStr = opacityNum.toString(16); var kmlStr = opacityStr.substring(0, 2) + '' + colorStr.substring(4, 6) + colorStr.substring(2, 4) + colorStr.substring(0, 2); return kmlStr; } }, { key: "Value", value: function Value(node) { var value = node.nodeValue; if (value) return value; var str = ''; try { if (node.childNodes && node.childNodes.length) { Object.values(KMLParser.ChildNodesArray(node)).forEach(function (c) { str += KMLParser.Value(c); }); } } catch (e) { console.error(['SimpleKML Parser Exception', e]); } return str; } }, { key: "ChildNodesArray", value: function ChildNodesArray(node) { var array = []; if (node.childNodes && node.childNodes.length > 0) { for (var i = 0; i < node.childNodes.length; i++) { array.push(node.childNodes.item(i)); } } return array; } }]); return KMLParser; }(); exports.default = KMLParser; //# sourceMappingURL=kml-parser.js.map