refactor and add unit tests

This commit is contained in:
--t-bo-- 2022-05-27 16:34:49 -07:00
parent b2120f40c3
commit d37f34b7be
5 changed files with 177 additions and 140 deletions

View File

@ -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<Entity>}
*/
/*
_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

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>notmar</name>
<open>1</open>
<Style id="yellowLineGreenPoly20">
<LineStyle>
<color>7fffffff</color>
<width>4</width>
</LineStyle>
<PolyStyle>
<color>7f00ff00</color>
</PolyStyle>
</Style>
<Style id="yellowLineGreenPoly000">
<LineStyle>
<color>7fffffff</color>
<width>4</width>
</LineStyle>
<PolyStyle>
<color>7f00ff00</color>
</PolyStyle>
</Style>
<StyleMap id="yellowLineGreenPoly100">
<Pair>
<key>normal</key>
<styleUrl>#yellowLineGreenPoly20</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#yellowLineGreenPoly000</styleUrl>
</Pair>
</StyleMap>
<Placemark>
<name>Absolute Extruded</name>
<description>Transparent green wall with yellow outlines</description>
<styleUrl>#yellowLineGreenPoly100</styleUrl>
<LineString>
<extrude>1</extrude>
<tessellate>1</tessellate>
<gx:altitudeMode>clampToSeaFloor</gx:altitudeMode>
<coordinates>
-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
</coordinates>
</LineString>
</Placemark>
</Document>
</kml>

View File

@ -0,0 +1,23 @@
<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://www.opengis.net/kml/2.2'>
<Document>
<open>1</open>
<Folder>
<open>1</open>
<Placemark>
<Style>
<IconStyle>
<color>FFDB8966</color>
<Icon>
<href>./plane.png</href>
</Icon>
</IconStyle>
</Style>
<name>LFPT</name>
<Point>
<coordinates>2.039,49.090</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>

View File

@ -8,16 +8,15 @@
<Placemark>
<Style>
<LineStyle>
<color>ff000000</color>
<color>7f9f7fe0</color>
<width>5</width>
</LineStyle>
<PolyStyle>
<color>7f9f7fe0</color>
<color>ff000000</color>
<width>6</width>
</PolyStyle>
</Style>
<MultiGeometry>
<Point>
<coordinates>138.600000,-34.910000</coordinates>
</Point>
<Polygon>
<outerBoundaryIs>
<LinearRing>

View File

@ -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)
})
})