From d37f34b7be870838ff04124e2227b5aa202e172d Mon Sep 17 00:00:00 2001 From: --t-bo-- Date: Fri, 27 May 2022 16:34:49 -0700 Subject: [PATCH] refactor and add unit tests --- src/og/layer/KML.js | 227 +++++++++++++----------------- tests/layer/KML.styled.global.kml | 48 +++++++ tests/layer/KML.styled.icon.kml | 23 +++ tests/layer/KML.styled.kml | 9 +- tests/layer/KML.test.js | 10 +- 5 files changed, 177 insertions(+), 140 deletions(-) create mode 100644 tests/layer/KML.styled.global.kml create mode 100644 tests/layer/KML.styled.icon.kml diff --git a/src/og/layer/KML.js b/src/og/layer/KML.js index a3ffc9af..e954072a 100644 --- a/src/og/layer/KML.js +++ b/src/og/layer/KML.js @@ -82,12 +82,6 @@ export class KML extends Vector { return coordinates; } - /** - * @private - */ - _parseKMLstyle(jobj) { - } - /** * @private */ @@ -97,13 +91,66 @@ export class KML extends Vector { const nameTags = Array.from(placemark.getElementsByTagName("name")) const name = nameTags?.at(0)?.innerHTML?.trim() || ''; + const { iconHeading, iconURL, iconColor, lineWidth, lineColor } = this._extractStyle(placemark); + + // TODO handle MultiGeometry + + const lonLats = []; + for (const coord of placemark.getElementsByTagName("coordinates")) { + const coordinates = this._parseKMLcoordinates(coord) || [[0, 0, 0]] + + for (const lonlatalt of coordinates) { + const lon = lonlatalt[0]; + const lat = lonlatalt[1]; + const alt = lonlatalt[2]; + + lonLats.push(new LonLat(lon, lat, alt)); + + if (lon < extent.southWest.lon) extent.southWest.lon = lon; + if (lat < extent.southWest.lat) extent.southWest.lat = lat; + if (lon > extent.northEast.lon) extent.northEast.lon = lon; + if (lat > extent.northEast.lat) extent.northEast.lat = lat; + } + } + + if (lonLats.length === 1) { + const hdgrad = iconHeading * 0.01745329; // radians + + return new Entity({ + name, + lonlat: lonLats[0], + billboard: { + src: iconURL, + size: [24, 24], + color: iconColor, + rotation: hdgrad + }, + properties: { + color: iconColor, + heading: iconHeading + } + }); + + } else { + return new Entity({ + polyline: { + pathLonLat: [lonLats], + thickness: lineWidth, + color: lineColor, + isClosed: false + } + }); + } + } + + _extractStyle(placemark) { let iconColor; let iconHeading; let iconURL; let lineColor; let lineWidth; - let style = placemark.getElementsByTagName("Style")[0]; + const style = placemark.getElementsByTagName("Style")[0]; if (style) { let iconstyle = style.getElementsByTagName("IconStyle")[0]; if (iconstyle) { @@ -119,18 +166,18 @@ export class KML extends Vector { } let icon = iconstyle.getElementsByTagName("Icon")[0]; - if (icon !== undefined) { + if (icon) { let href = icon.getElementsByTagName("href")[0]; - if (href !== undefined) { + if (href) { iconURL = href.innerHTML.trim(); } } } let linestyle = style.getElementsByTagName("LineStyle")[0]; - if (linestyle !== undefined) { + if (linestyle) { let color = linestyle.getElementsByTagName("color")[0]; - if (color !== undefined) + if (color) lineColor = this._AGBRtoRGBA(color.innerHTML.trim()); let width = linestyle.getElementsByTagName("width")[0]; if (width !== undefined) @@ -138,95 +185,16 @@ export class KML extends Vector { } } - if (iconColor === undefined) - iconColor = "#FFFFFF"; - if (iconHeading === undefined) - iconHeading = 0; - if (iconURL === undefined) - iconURL = "https://openglobus.org/examples/billboards/carrot.png"; + if (!iconColor) iconColor = "#FFFFFF" + if (!iconHeading) iconHeading = 0 + if (!iconURL) iconURL = "https://openglobus.org/examples/billboards/carrot.png" - if (lineColor === undefined) - lineColor = "#FFFFFF"; - if (lineWidth === undefined) - lineWidth = 1; + if (!lineColor) lineColor = "#FFFFFF" + if (!lineWidth) lineWidth = 1 - // TODO handle MultiGeometry - - const lonLats = []; - for (const coord of placemark.getElementsByTagName("coordinates")) { - let coordinates = this._parseKMLcoordinates(coord); - if (coordinates === undefined) - coordinates = [[0, 0, 0]]; - - for (const lonlatalt of coordinates) { - let lon = lonlatalt[0]; - let lat = lonlatalt[1]; - let alt = lonlatalt[2]; - - lonLats.push(new LonLat(lon, lat, alt)); - - if (lon < extent.southWest.lon) extent.southWest.lon = lon; - if (lat < extent.southWest.lat) extent.southWest.lat = lat; - if (lon > extent.northEast.lon) extent.northEast.lon = lon; - if (lat > extent.northEast.lat) extent.northEast.lat = lat; - } - } - - let entity; - - // Point - if (lonLats.length === 1) { - const hdgrad = iconHeading * 0.01745329; // radians - - entity = new Entity({ - name, - lonlat: lonLats[0], - billboard: { - src: iconURL, - size: [24, 24], - color: iconColor, - rotation: hdgrad - }, - properties: { - color: iconColor, - heading: iconHeading - } - }); - - /* - TODO Label rendering doesn't appear to work! - if (name !== undefined) - { - var label = new Label({ - 'text': "PressStart2P-Regular", - 'color': "black", - 'face': "PressStart2P-Regular", - 'outlineColor': "white", - 'size': 24 - }); - entity.setLabel(label); - }; - */ - - } - else // LineString - { - entity = new Entity({ - polyline: { - pathLonLat: [lonLats], - thickness: lineWidth, - color: lineColor, - isClosed: false - } - }); - } - - return entity; + return { iconHeading, iconURL, iconColor, lineWidth, lineColor }; } - /** - * @private - */ _parseKML(xml, extent, entities = undefined) { if (!entities) entities = []; @@ -242,9 +210,6 @@ export class KML extends Vector { return entities; } - /** - * @private - */ _convertKMLintoEntities(xml) { const extent = new Extent(new LonLat(180.0, 90.0), new LonLat(-180.0, -90.0)); const entities = this._parseKML(xml, extent); @@ -259,39 +224,37 @@ export class KML extends Vector { * @param {string} color * @returns {Array} */ - /* - _convertCoordonatesIntoEntities(coordinates, color, billboard) { - const extent = new Extent(new LonLat(180.0, 90.0), new LonLat(-180.0, -90.0)); - const addToExtent = (c) => { - const lon = c[0], - lat = c[1]; - if (lon < extent.southWest.lon) extent.southWest.lon = lon; - if (lat < extent.southWest.lat) extent.southWest.lat = lat; - if (lon > extent.northEast.lon) extent.northEast.lon = lon; - if (lat > extent.northEast.lat) extent.northEast.lat = lat; - }; - const _pathes = []; - coordinates.forEach((kmlFile) => kmlFile.forEach((p) => _pathes.push(p))); - const entities = _pathes.map((path) => { - if (path.length === 1) { - const lonlat = path[0]; - const _entity = new Entity({ lonlat, billboard }); - addToExtent(lonlat); - return _entity; - } else if (path.length > 1) { - const pathLonLat = path.map((item) => { - addToExtent(item); - return new LonLat(item[0], item[1], item[2]); - }); - const _entity = new Entity({ - polyline: { pathLonLat: [pathLonLat], thickness: 3, color, isClosed: false } - }); - return _entity; - } - }); - return { entities, extent }; - } - */ + _convertCoordonatesIntoEntities(coordinates, color, billboard) { + const extent = new Extent(new LonLat(180.0, 90.0), new LonLat(-180.0, -90.0)); + const addToExtent = (c) => { + const lon = c[0], + lat = c[1]; + if (lon < extent.southWest.lon) extent.southWest.lon = lon; + if (lat < extent.southWest.lat) extent.southWest.lat = lat; + if (lon > extent.northEast.lon) extent.northEast.lon = lon; + if (lat > extent.northEast.lat) extent.northEast.lat = lat; + }; + const _pathes = []; + coordinates.forEach((kmlFile) => kmlFile.forEach((p) => _pathes.push(p))); + const entities = _pathes.map((path) => { + if (path.length === 1) { + const lonlat = path[0]; + const _entity = new Entity({ lonlat, billboard }); + addToExtent(lonlat); + return _entity; + } else if (path.length > 1) { + const pathLonLat = path.map((item) => { + addToExtent(item); + return new LonLat(item[0], item[1], item[2]); + }); + const _entity = new Entity({ + polyline: { pathLonLat: [pathLonLat], thickness: 3, color, isClosed: false } + }); + return _entity; + } + }); + return { entities, extent }; + } /** * @public diff --git a/tests/layer/KML.styled.global.kml b/tests/layer/KML.styled.global.kml new file mode 100644 index 00000000..ec0f1583 --- /dev/null +++ b/tests/layer/KML.styled.global.kml @@ -0,0 +1,48 @@ + + + + notmar + 1 + + + + + normal + #yellowLineGreenPoly20 + + + highlight + #yellowLineGreenPoly000 + + + + Absolute Extruded + Transparent green wall with yellow outlines + #yellowLineGreenPoly100 + + 1 + 1 + clampToSeaFloor + + -80.533,28.483,0 -80.117,28.617,0 -78.867,28.833,0 -75.283,29.5,0 -71.433,29.867,0 -63.633,30.233,0 -56.067,30.3,0 -47.05,29.15,0 -47.033,28.85,0 -56.083,29.883,0 -63.43299999999999,30.017,0 -68.333,29.833,0 -71.083,29.483,0 -75.583,29,0 -80.383,28.383,0 -80.566,28.417,0 + + + + + diff --git a/tests/layer/KML.styled.icon.kml b/tests/layer/KML.styled.icon.kml new file mode 100644 index 00000000..43ea1cc8 --- /dev/null +++ b/tests/layer/KML.styled.icon.kml @@ -0,0 +1,23 @@ + + + + 1 + + 1 + + + LFPT + + 2.039,49.090 + + + + + diff --git a/tests/layer/KML.styled.kml b/tests/layer/KML.styled.kml index a3c78e73..94840f59 100644 --- a/tests/layer/KML.styled.kml +++ b/tests/layer/KML.styled.kml @@ -8,16 +8,15 @@ - - 138.600000,-34.910000 - diff --git a/tests/layer/KML.test.js b/tests/layer/KML.test.js index f616b3ce..9eaf88fa 100644 --- a/tests/layer/KML.test.js +++ b/tests/layer/KML.test.js @@ -24,10 +24,14 @@ describe('kml files', () => { const { entities, extent } = kml._convertKMLintoEntities(xmlDoc) expect(entities.length).toBe(1) expect(extent.northEast.lon).toBe(138.64) - expect(extent.northEast.lat).toBe(-34.91) - expect(extent.southWest.lon).toBe(138.6) + expect(extent.northEast.lat).toBe(-34.93) + expect(extent.southWest.lon).toBe(138.62) expect(extent.southWest.lat).toBe(-34.94) - expect(entities.at(0).properties.name).toBe('') + const entity = entities.at(0) + expect(entity.properties.name).toBe('') + expect(entity.polyline.thickness).toBe(5) + const [c0, c1, c2, c3] = entity.polyline._defaultColor + expect(c0).toBe(0.8784313797950745) }) })