UNPKG

4.97 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const jszip_1 = __importDefault(require("jszip"));
7const tools_1 = require("@toba/tools");
8const xmldom_1 = require("xmldom");
9const xml_1 = require("./xml");
10const xmlConfig = {
11 locator: {},
12 errorHandler: {
13 warning: () => { },
14 error: console.error,
15 fatalError: console.error
16 }
17};
18const roundFromString = (places) => (n) => parseFloat(parseFloat(n).toFixed(places));
19function coordinates(node, name) {
20 const lines = node.getElementsByTagName(name);
21 if (lines != null && lines.length > 0) {
22 const segments = [];
23 for (let i = 0; i < lines.length; i++) {
24 const coordinates = xml_1.xml.firstValue(lines[i], 'coordinates');
25 if (coordinates != null) {
26 const locations = [];
27 const points = coordinates.trim().split(' ');
28 points.forEach(p => {
29 const location = [];
30 const parts = p.split(',').map(roundFromString(6));
31 if (parts.length >= 2) {
32 location[0] = parts[0];
33 location[1] = parts[1];
34 if (parts.length >= 3) {
35 location[2] = parts[2];
36 }
37 locations.push(location);
38 }
39 });
40 if (locations.length > 0) {
41 segments.push(locations);
42 }
43 }
44 }
45 if (segments.length > 0) {
46 return segments;
47 }
48 }
49 return null;
50}
51function location(node) {
52 const locations = coordinates(node, 'Point');
53 if (locations != null && locations.length > 0) {
54 if (locations.length > 1) {
55 return locations[0][0];
56 }
57 else {
58 return locations[0][0];
59 }
60 }
61 return null;
62}
63function line(node) {
64 const l = coordinates(node, 'LineString');
65 return l == null || l.length == 0 ? null : l;
66}
67const clean = (text) => tools_1.is.value(text)
68 ? text
69 .replace(/[\r\n]/g, '')
70 .replace('&lt;Null&gt;', '')
71 .replace('<Null>', '')
72 : null;
73function parseDescription(properties) {
74 if (tools_1.is.defined(properties, 'description') &&
75 /<html/.test(properties.description)) {
76 const source = properties
77 .description.replace(/^<!\[CDATA\[/, '')
78 .replace(/\]\]>$/, '');
79 let html = null;
80 try {
81 html = new xmldom_1.DOMParser(xmlConfig).parseFromString(source, "text/xml");
82 }
83 catch (ex) {
84 return properties;
85 }
86 const tables = html.getElementsByTagName('table');
87 let most = 0;
88 let index = -1;
89 for (let i = 0; i < tables.length; i++) {
90 const t = tables[i];
91 if (t.childNodes.length > most) {
92 most = t.childNodes.length;
93 index = i;
94 }
95 }
96 if (index > 0) {
97 const rows = tables[index].getElementsByTagName('tr');
98 for (let i = 0; i < rows.length; i++) {
99 const cols = rows[i].getElementsByTagName('td');
100 const key = clean(xml_1.xml.value(cols[0]));
101 const value = tools_1.maybeNumber(clean(xml_1.xml.value(cols[1])));
102 if (key !== null && value !== null) {
103 properties[key.replace(' ', '_')] = value;
104 }
105 }
106 delete properties['description'];
107 }
108 }
109 return properties;
110}
111async function fromKMZ(data) {
112 const zip = new jszip_1.default();
113 const archive = await zip.loadAsync(data);
114 for (const name in archive.files) {
115 if (name.endsWith('.kml')) {
116 const text = await archive.files[name].async('text');
117 return new xmldom_1.DOMParser(xmlConfig).parseFromString(text, "text/xml");
118 }
119 }
120 return null;
121}
122function properties(node, extras = []) {
123 const names = extras.concat(['name', 'description']);
124 const properties = {};
125 for (const key of names) {
126 let value = xml_1.xml.firstValue(node, key);
127 if (!tools_1.is.empty(value)) {
128 switch (key) {
129 case 'name':
130 value = tools_1.titleCase(value);
131 break;
132 case 'description':
133 value = value.replace(/[\n\r]/g, ' ').replace(/\s{2,}/g, ' ');
134 break;
135 default:
136 break;
137 }
138 properties[key] = tools_1.maybeNumber(value);
139 }
140 }
141 return parseDescription(properties);
142}
143exports.kml = {
144 fromKMZ,
145 location,
146 line,
147 coordinates,
148 properties,
149 parseDescription
150};
151
\No newline at end of file