umap-project 2.4.2__py3-none-any.whl → 2.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- umap/__init__.py +1 -1
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +100 -50
- umap/static/umap/base.css +4 -1
- umap/static/umap/css/contextmenu.css +11 -0
- umap/static/umap/css/dialog.css +24 -3
- umap/static/umap/css/panel.css +4 -2
- umap/static/umap/css/slideshow.css +69 -0
- umap/static/umap/css/tableeditor.css +69 -0
- umap/static/umap/css/tooltip.css +3 -3
- umap/static/umap/img/16-white.svg +4 -0
- umap/static/umap/img/source/16-white.svg +5 -1
- umap/static/umap/js/components/alerts/alert.css +10 -10
- umap/static/umap/js/modules/autocomplete.js +23 -1
- umap/static/umap/js/modules/browser.js +14 -8
- umap/static/umap/js/modules/facets.js +40 -10
- umap/static/umap/js/modules/formatter.js +153 -0
- umap/static/umap/js/modules/global.js +10 -1
- umap/static/umap/js/modules/help.js +25 -25
- umap/static/umap/js/modules/importer.js +4 -4
- umap/static/umap/js/modules/importers/communesfr.js +3 -1
- umap/static/umap/js/modules/importers/datasets.js +8 -6
- umap/static/umap/js/modules/importers/geodatamine.js +10 -10
- umap/static/umap/js/modules/importers/overpass.js +18 -14
- umap/static/umap/js/modules/rules.js +13 -1
- umap/static/umap/js/modules/schema.js +16 -12
- umap/static/umap/js/{umap.share.js → modules/share.js} +60 -99
- umap/static/umap/js/modules/slideshow.js +141 -0
- umap/static/umap/js/modules/tableeditor.js +329 -0
- umap/static/umap/js/modules/ui/base.js +93 -0
- umap/static/umap/js/modules/ui/contextmenu.js +50 -0
- umap/static/umap/js/modules/ui/dialog.js +169 -31
- umap/static/umap/js/modules/ui/panel.js +6 -4
- umap/static/umap/js/modules/ui/tooltip.js +5 -75
- umap/static/umap/js/modules/utils.js +20 -0
- umap/static/umap/js/umap.controls.js +1 -1
- umap/static/umap/js/umap.features.js +22 -14
- umap/static/umap/js/umap.forms.js +157 -154
- umap/static/umap/js/umap.js +48 -34
- umap/static/umap/js/umap.layer.js +232 -164
- umap/static/umap/js/umap.permissions.js +1 -1
- umap/static/umap/js/umap.popup.js +1 -1
- umap/static/umap/locale/am_ET.js +22 -5
- umap/static/umap/locale/am_ET.json +19 -5
- umap/static/umap/locale/ar.js +22 -5
- umap/static/umap/locale/ar.json +19 -5
- umap/static/umap/locale/ast.js +22 -5
- umap/static/umap/locale/ast.json +19 -5
- umap/static/umap/locale/bg.js +22 -5
- umap/static/umap/locale/bg.json +19 -5
- umap/static/umap/locale/br.js +22 -5
- umap/static/umap/locale/br.json +19 -5
- umap/static/umap/locale/ca.js +56 -39
- umap/static/umap/locale/ca.json +53 -39
- umap/static/umap/locale/cs_CZ.js +22 -5
- umap/static/umap/locale/cs_CZ.json +19 -5
- umap/static/umap/locale/da.js +22 -5
- umap/static/umap/locale/da.json +19 -5
- umap/static/umap/locale/de.js +22 -5
- umap/static/umap/locale/de.json +19 -5
- umap/static/umap/locale/el.js +27 -10
- umap/static/umap/locale/el.json +19 -5
- umap/static/umap/locale/en.js +22 -6
- umap/static/umap/locale/en.json +19 -5
- umap/static/umap/locale/en_US.json +19 -5
- umap/static/umap/locale/es.js +22 -6
- umap/static/umap/locale/es.json +19 -5
- umap/static/umap/locale/et.js +22 -5
- umap/static/umap/locale/et.json +19 -5
- umap/static/umap/locale/eu.js +167 -150
- umap/static/umap/locale/eu.json +167 -150
- umap/static/umap/locale/fa_IR.js +22 -5
- umap/static/umap/locale/fa_IR.json +19 -5
- umap/static/umap/locale/fi.js +22 -5
- umap/static/umap/locale/fi.json +19 -5
- umap/static/umap/locale/fr.js +22 -6
- umap/static/umap/locale/fr.json +19 -5
- umap/static/umap/locale/gl.js +22 -5
- umap/static/umap/locale/gl.json +19 -5
- umap/static/umap/locale/he.js +22 -5
- umap/static/umap/locale/he.json +19 -5
- umap/static/umap/locale/hr.js +22 -5
- umap/static/umap/locale/hr.json +19 -5
- umap/static/umap/locale/hu.js +89 -72
- umap/static/umap/locale/hu.json +89 -75
- umap/static/umap/locale/id.js +22 -5
- umap/static/umap/locale/id.json +19 -5
- umap/static/umap/locale/is.js +22 -5
- umap/static/umap/locale/is.json +19 -5
- umap/static/umap/locale/it.js +22 -5
- umap/static/umap/locale/it.json +19 -5
- umap/static/umap/locale/ja.js +22 -5
- umap/static/umap/locale/ja.json +19 -5
- umap/static/umap/locale/ko.js +22 -5
- umap/static/umap/locale/ko.json +19 -5
- umap/static/umap/locale/lt.js +22 -5
- umap/static/umap/locale/lt.json +19 -5
- umap/static/umap/locale/ms.js +22 -5
- umap/static/umap/locale/ms.json +19 -5
- umap/static/umap/locale/nl.js +22 -5
- umap/static/umap/locale/nl.json +19 -5
- umap/static/umap/locale/no.js +22 -5
- umap/static/umap/locale/no.json +19 -5
- umap/static/umap/locale/pl.js +22 -5
- umap/static/umap/locale/pl.json +19 -5
- umap/static/umap/locale/pl_PL.json +19 -5
- umap/static/umap/locale/pt.js +22 -6
- umap/static/umap/locale/pt.json +21 -7
- umap/static/umap/locale/pt_BR.js +22 -5
- umap/static/umap/locale/pt_BR.json +19 -5
- umap/static/umap/locale/pt_PT.js +22 -5
- umap/static/umap/locale/pt_PT.json +19 -5
- umap/static/umap/locale/ro.js +22 -5
- umap/static/umap/locale/ro.json +19 -5
- umap/static/umap/locale/ru.js +22 -5
- umap/static/umap/locale/ru.json +19 -5
- umap/static/umap/locale/sk_SK.js +22 -5
- umap/static/umap/locale/sk_SK.json +19 -5
- umap/static/umap/locale/sl.js +22 -5
- umap/static/umap/locale/sl.json +19 -5
- umap/static/umap/locale/sr.js +22 -5
- umap/static/umap/locale/sr.json +19 -5
- umap/static/umap/locale/sv.js +22 -5
- umap/static/umap/locale/sv.json +19 -5
- umap/static/umap/locale/th_TH.js +22 -5
- umap/static/umap/locale/th_TH.json +19 -5
- umap/static/umap/locale/tr.js +22 -5
- umap/static/umap/locale/tr.json +19 -5
- umap/static/umap/locale/uk_UA.js +22 -5
- umap/static/umap/locale/uk_UA.json +19 -5
- umap/static/umap/locale/vi.js +22 -5
- umap/static/umap/locale/vi.json +19 -5
- umap/static/umap/locale/vi_VN.json +19 -5
- umap/static/umap/locale/zh.js +22 -5
- umap/static/umap/locale/zh.json +19 -5
- umap/static/umap/locale/zh_CN.json +19 -5
- umap/static/umap/locale/zh_TW.Big5.json +19 -5
- umap/static/umap/locale/zh_TW.js +22 -5
- umap/static/umap/locale/zh_TW.json +19 -5
- umap/static/umap/map.css +2 -145
- umap/static/umap/vars.css +5 -0
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +410 -428
- umap/static/umap/vendors/geojson-to-gpx/index.js +155 -0
- umap/static/umap/vendors/osmtogeojson/osmtogeojson.js +1 -2
- umap/static/umap/vendors/togeojson/togeojson.es.js +1109 -0
- umap/static/umap/vendors/togeojson/{togeojson.umd.js.map → togeojson.es.mjs.map} +1 -1
- umap/static/umap/vendors/tokml/tokml.es.js +895 -0
- umap/static/umap/vendors/tokml/tokml.es.mjs.map +1 -0
- umap/storage.py +5 -1
- umap/templates/umap/components/alerts/alert.html +3 -3
- umap/templates/umap/css.html +3 -0
- umap/templates/umap/js.html +0 -6
- umap/tests/fixtures/categorized_highway.geojson +1 -0
- umap/tests/fixtures/test_import_osm_relation.json +130 -0
- umap/tests/integration/conftest.py +8 -1
- umap/tests/integration/test_browser.py +3 -2
- umap/tests/integration/test_categorized_layer.py +141 -0
- umap/tests/integration/test_conditional_rules.py +21 -0
- umap/tests/integration/test_datalayer.py +9 -4
- umap/tests/integration/test_edit_datalayer.py +1 -0
- umap/tests/integration/test_edit_polygon.py +1 -1
- umap/tests/integration/test_export_map.py +2 -3
- umap/tests/integration/test_import.py +22 -0
- umap/tests/integration/test_tableeditor.py +158 -4
- umap/tests/integration/test_websocket_sync.py +2 -2
- {umap_project-2.4.2.dist-info → umap_project-2.5.0.dist-info}/METADATA +8 -8
- {umap_project-2.4.2.dist-info → umap_project-2.5.0.dist-info}/RECORD +172 -162
- umap/static/umap/js/umap.slideshow.js +0 -163
- umap/static/umap/js/umap.tableeditor.js +0 -118
- umap/static/umap/vendors/togeojson/togeojson.umd.js +0 -2
- umap/static/umap/vendors/togpx/togpx.js +0 -547
- umap/static/umap/vendors/tokml/tokml.js +0 -343
- {umap_project-2.4.2.dist-info → umap_project-2.5.0.dist-info}/WHEEL +0 -0
- {umap_project-2.4.2.dist-info → umap_project-2.5.0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.4.2.dist-info → umap_project-2.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,895 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('unist').Node} Node
|
|
3
|
+
* @typedef {import('unist').Parent} Parent
|
|
4
|
+
* @typedef {import('unist').Literal} Literal
|
|
5
|
+
* @typedef {Object.<string, unknown>} Props
|
|
6
|
+
* @typedef {Array.<Node>|string} ChildrenOrValue
|
|
7
|
+
*
|
|
8
|
+
* @typedef {(<T extends string, P extends Record<string, unknown>, C extends Node[]>(type: T, props: P, children: C) => {type: T, children: C} & P)} BuildParentWithProps
|
|
9
|
+
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P, value: string) => {type: T, value: string} & P)} BuildLiteralWithProps
|
|
10
|
+
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P) => {type: T} & P)} BuildVoidWithProps
|
|
11
|
+
* @typedef {(<T extends string, C extends Node[]>(type: T, children: C) => {type: T, children: C})} BuildParent
|
|
12
|
+
* @typedef {(<T extends string>(type: T, value: string) => {type: T, value: string})} BuildLiteral
|
|
13
|
+
* @typedef {(<T extends string>(type: T) => {type: T})} BuildVoid
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var u = /**
|
|
17
|
+
* @type {BuildVoid & BuildVoidWithProps & BuildLiteral & BuildLiteralWithProps & BuildParent & BuildParentWithProps}
|
|
18
|
+
*/ (
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} type Type of node
|
|
21
|
+
* @param {Props|ChildrenOrValue} [props] Additional properties for node (or `children` or `value`)
|
|
22
|
+
* @param {ChildrenOrValue} [value] `children` or `value` of node
|
|
23
|
+
* @returns {Node}
|
|
24
|
+
*/
|
|
25
|
+
function (type, props, value) {
|
|
26
|
+
/** @type {Node} */
|
|
27
|
+
var node = {type: String(type)};
|
|
28
|
+
|
|
29
|
+
if (
|
|
30
|
+
(value === undefined || value === null) &&
|
|
31
|
+
(typeof props === 'string' || Array.isArray(props))
|
|
32
|
+
) {
|
|
33
|
+
value = props;
|
|
34
|
+
} else {
|
|
35
|
+
Object.assign(node, props);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (Array.isArray(value)) {
|
|
39
|
+
node.children = value;
|
|
40
|
+
} else if (value !== undefined && value !== null) {
|
|
41
|
+
node.value = String(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return node
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @typedef {import('xast').Root} Root
|
|
50
|
+
* @typedef {import('xast').Element} Element
|
|
51
|
+
* @typedef {Root['children'][number]} Child
|
|
52
|
+
* @typedef {Child|Root} Node
|
|
53
|
+
* @typedef {Root|Element} XResult
|
|
54
|
+
* @typedef {string|number|boolean|null|undefined} XValue
|
|
55
|
+
* @typedef {{[attribute: string]: XValue}} XAttributes Attributes to support JS primitive types
|
|
56
|
+
*
|
|
57
|
+
* @typedef {string|number|null|undefined} XPrimitiveChild
|
|
58
|
+
* @typedef {Array.<Node|XPrimitiveChild>} XArrayChild
|
|
59
|
+
* @typedef {Node|XPrimitiveChild|XArrayChild} XChild
|
|
60
|
+
* @typedef {import('./jsx-classic').Element} x.JSX.Element
|
|
61
|
+
* @typedef {import('./jsx-classic').IntrinsicAttributes} x.JSX.IntrinsicAttributes
|
|
62
|
+
* @typedef {import('./jsx-classic').IntrinsicElements} x.JSX.IntrinsicElements
|
|
63
|
+
* @typedef {import('./jsx-classic').ElementChildrenAttribute} x.JSX.ElementChildrenAttribute
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Create XML trees in xast.
|
|
68
|
+
*
|
|
69
|
+
* @param name Qualified name. Case sensitive and can contain a namespace prefix (such as `rdf:RDF`). Pass `null|undefined` to build a root.
|
|
70
|
+
* @param attributes Map of attributes. Nullish (null or undefined) or NaN values are ignored, other values (strings, booleans) are cast to strings.
|
|
71
|
+
* @param children (Lists of) child nodes. When strings are encountered, they are mapped to Text nodes.
|
|
72
|
+
*/
|
|
73
|
+
const x =
|
|
74
|
+
/**
|
|
75
|
+
* @type {{
|
|
76
|
+
* (): Root
|
|
77
|
+
* (name: null|undefined, ...children: XChild[]): Root
|
|
78
|
+
* (name: string, attributes: XAttributes, ...children: XChild[]): Element
|
|
79
|
+
* (name: string, ...children: XChild[]): Element
|
|
80
|
+
* }}
|
|
81
|
+
*/
|
|
82
|
+
(
|
|
83
|
+
/**
|
|
84
|
+
* Hyperscript compatible DSL for creating virtual xast trees.
|
|
85
|
+
*
|
|
86
|
+
* @param {string|null} [name]
|
|
87
|
+
* @param {XAttributes|XChild} [attributes]
|
|
88
|
+
* @param {XChild[]} children
|
|
89
|
+
* @returns {XResult}
|
|
90
|
+
*/
|
|
91
|
+
function (name, attributes, ...children) {
|
|
92
|
+
var index = -1;
|
|
93
|
+
/** @type {XResult} */
|
|
94
|
+
var node;
|
|
95
|
+
/** @type {string} */
|
|
96
|
+
var key;
|
|
97
|
+
|
|
98
|
+
if (name === undefined || name === null) {
|
|
99
|
+
node = {type: 'root', children: []};
|
|
100
|
+
// @ts-ignore Root builder doesn’t accept attributes.
|
|
101
|
+
children.unshift(attributes);
|
|
102
|
+
} else if (typeof name === 'string') {
|
|
103
|
+
node = {type: 'element', name, attributes: {}, children: []};
|
|
104
|
+
|
|
105
|
+
if (isAttributes(attributes)) {
|
|
106
|
+
for (key in attributes) {
|
|
107
|
+
// Ignore nullish and NaN values.
|
|
108
|
+
if (
|
|
109
|
+
attributes[key] !== undefined &&
|
|
110
|
+
attributes[key] !== null &&
|
|
111
|
+
(typeof attributes[key] !== 'number' ||
|
|
112
|
+
!Number.isNaN(attributes[key]))
|
|
113
|
+
) {
|
|
114
|
+
// @ts-ignore Pretty sure we just set it.
|
|
115
|
+
node.attributes[key] = String(attributes[key]);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
children.unshift(attributes);
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
throw new TypeError('Expected element name, got `' + name + '`')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Handle children.
|
|
126
|
+
while (++index < children.length) {
|
|
127
|
+
addChild(node.children, children[index]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return node
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @param {Array.<Child>} nodes
|
|
136
|
+
* @param {XChild} value
|
|
137
|
+
*/
|
|
138
|
+
function addChild(nodes, value) {
|
|
139
|
+
var index = -1;
|
|
140
|
+
|
|
141
|
+
if (value === undefined || value === null) ; else if (typeof value === 'string' || typeof value === 'number') {
|
|
142
|
+
nodes.push({type: 'text', value: String(value)});
|
|
143
|
+
} else if (Array.isArray(value)) {
|
|
144
|
+
while (++index < value.length) {
|
|
145
|
+
addChild(nodes, value[index]);
|
|
146
|
+
}
|
|
147
|
+
} else if (typeof value === 'object' && 'type' in value) {
|
|
148
|
+
if (value.type === 'root') {
|
|
149
|
+
addChild(nodes, value.children);
|
|
150
|
+
} else {
|
|
151
|
+
nodes.push(value);
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
throw new TypeError('Expected node, nodes, string, got `' + value + '`')
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @param {XAttributes|XChild} value
|
|
160
|
+
* @returns {value is XAttributes}
|
|
161
|
+
*/
|
|
162
|
+
function isAttributes(value) {
|
|
163
|
+
if (
|
|
164
|
+
value === null ||
|
|
165
|
+
value === undefined ||
|
|
166
|
+
typeof value !== 'object' ||
|
|
167
|
+
Array.isArray(value)
|
|
168
|
+
) {
|
|
169
|
+
return false
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return true
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @typedef {import('./index.js').Parent} Parent
|
|
177
|
+
* @typedef {import('./index.js').Context} Context
|
|
178
|
+
* @typedef {import('./index.js').Child} Child
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Serialize all children of `parent`.
|
|
183
|
+
*
|
|
184
|
+
* @param {Parent} parent
|
|
185
|
+
* @param {Context} ctx
|
|
186
|
+
* @returns {string}
|
|
187
|
+
*
|
|
188
|
+
*/
|
|
189
|
+
function all(parent, ctx) {
|
|
190
|
+
/** @type {Array.<Child>} */
|
|
191
|
+
var children = (parent && parent.children) || [];
|
|
192
|
+
var index = -1;
|
|
193
|
+
/** @type {Array.<string>} */
|
|
194
|
+
var results = [];
|
|
195
|
+
|
|
196
|
+
while (++index < children.length) {
|
|
197
|
+
results[index] = one(children[index], ctx);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return results.join('')
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @typedef {Object} CoreOptions
|
|
205
|
+
* @property {string[]} [subset=[]]
|
|
206
|
+
* Whether to only escape the given subset of characters.
|
|
207
|
+
* @property {boolean} [escapeOnly=false]
|
|
208
|
+
* Whether to only escape possibly dangerous characters.
|
|
209
|
+
* Those characters are `"`, `&`, `'`, `<`, `>`, and `` ` ``.
|
|
210
|
+
*
|
|
211
|
+
* @typedef {Object} FormatOptions
|
|
212
|
+
* @property {(code: number, next: number, options: CoreWithFormatOptions) => string} format
|
|
213
|
+
* Format strategy.
|
|
214
|
+
*
|
|
215
|
+
* @typedef {CoreOptions & FormatOptions & import('./util/format-smart.js').FormatSmartOptions} CoreWithFormatOptions
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Encode certain characters in `value`.
|
|
220
|
+
*
|
|
221
|
+
* @param {string} value
|
|
222
|
+
* @param {CoreWithFormatOptions} options
|
|
223
|
+
* @returns {string}
|
|
224
|
+
*/
|
|
225
|
+
function core(value, options) {
|
|
226
|
+
value = value.replace(
|
|
227
|
+
options.subset ? charactersToExpression(options.subset) : /["&'<>`]/g,
|
|
228
|
+
basic
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
if (options.subset || options.escapeOnly) {
|
|
232
|
+
return value
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
value
|
|
237
|
+
// Surrogate pairs.
|
|
238
|
+
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, surrogate)
|
|
239
|
+
// BMP control characters (C0 except for LF, CR, SP; DEL; and some more
|
|
240
|
+
// non-ASCII ones).
|
|
241
|
+
.replace(
|
|
242
|
+
// eslint-disable-next-line no-control-regex, unicorn/no-hex-escape
|
|
243
|
+
/[\x01-\t\v\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g,
|
|
244
|
+
basic
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {string} pair
|
|
250
|
+
* @param {number} index
|
|
251
|
+
* @param {string} all
|
|
252
|
+
*/
|
|
253
|
+
function surrogate(pair, index, all) {
|
|
254
|
+
return options.format(
|
|
255
|
+
(pair.charCodeAt(0) - 0xd800) * 0x400 +
|
|
256
|
+
pair.charCodeAt(1) -
|
|
257
|
+
0xdc00 +
|
|
258
|
+
0x10000,
|
|
259
|
+
all.charCodeAt(index + 2),
|
|
260
|
+
options
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @param {string} character
|
|
266
|
+
* @param {number} index
|
|
267
|
+
* @param {string} all
|
|
268
|
+
*/
|
|
269
|
+
function basic(character, index, all) {
|
|
270
|
+
return options.format(
|
|
271
|
+
character.charCodeAt(0),
|
|
272
|
+
all.charCodeAt(index + 1),
|
|
273
|
+
options
|
|
274
|
+
)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* @param {string[]} subset
|
|
280
|
+
* @returns {RegExp}
|
|
281
|
+
*/
|
|
282
|
+
function charactersToExpression(subset) {
|
|
283
|
+
/** @type {string[]} */
|
|
284
|
+
const groups = [];
|
|
285
|
+
let index = -1;
|
|
286
|
+
|
|
287
|
+
while (++index < subset.length) {
|
|
288
|
+
groups.push(subset[index].replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return new RegExp('(?:' + groups.join('|') + ')', 'g')
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* The smallest way to encode a character.
|
|
296
|
+
*
|
|
297
|
+
* @param {number} code
|
|
298
|
+
* @returns {string}
|
|
299
|
+
*/
|
|
300
|
+
function formatBasic(code) {
|
|
301
|
+
return '&#x' + code.toString(16).toUpperCase() + ';'
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* @typedef {import('./core.js').CoreOptions & import('./util/format-smart.js').FormatSmartOptions} Options
|
|
306
|
+
* @typedef {import('./core.js').CoreOptions} LightOptions
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Encode special characters in `value` as hexadecimals.
|
|
311
|
+
*
|
|
312
|
+
* @param {string} value
|
|
313
|
+
* Value to encode.
|
|
314
|
+
* @param {LightOptions} [options]
|
|
315
|
+
* Configuration.
|
|
316
|
+
* @returns {string}
|
|
317
|
+
* Encoded value.
|
|
318
|
+
*/
|
|
319
|
+
function stringifyEntitiesLight(value, options) {
|
|
320
|
+
return core(value, Object.assign({format: formatBasic}, options))
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
var noncharacter = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Escape a string.
|
|
327
|
+
*
|
|
328
|
+
* @param {string} value
|
|
329
|
+
* @param {Array.<string>} subset
|
|
330
|
+
* @param {RegExp} [unsafe]
|
|
331
|
+
* @returns {string}
|
|
332
|
+
*/
|
|
333
|
+
function escape(value, subset, unsafe) {
|
|
334
|
+
var result = clean(value);
|
|
335
|
+
|
|
336
|
+
return unsafe ? result.replace(unsafe, encode) : encode(result)
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* @param {string} $0
|
|
340
|
+
* @returns {string}
|
|
341
|
+
*/
|
|
342
|
+
function encode($0) {
|
|
343
|
+
return stringifyEntitiesLight($0, {subset})
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* @param {string} value
|
|
349
|
+
* @returns {string}
|
|
350
|
+
*/
|
|
351
|
+
function clean(value) {
|
|
352
|
+
return String(value || '').replace(noncharacter, '')
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
var subset$3 = ['\t', '\n', ' ', '"', '&', "'", '/', '<', '=', '>'];
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Serialize a node name.
|
|
359
|
+
*
|
|
360
|
+
* @param {string} value
|
|
361
|
+
* @returns {string}
|
|
362
|
+
*/
|
|
363
|
+
function name(value) {
|
|
364
|
+
return escape(value, subset$3)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Count how often a character (or substring) is used in a string.
|
|
369
|
+
*
|
|
370
|
+
* @param {string} value
|
|
371
|
+
* Value to search in.
|
|
372
|
+
* @param {string} character
|
|
373
|
+
* Character (or substring) to look for.
|
|
374
|
+
* @return {number}
|
|
375
|
+
* Number of times `character` occurred in `value`.
|
|
376
|
+
*/
|
|
377
|
+
function ccount(value, character) {
|
|
378
|
+
const source = String(value);
|
|
379
|
+
|
|
380
|
+
if (typeof character !== 'string') {
|
|
381
|
+
throw new TypeError('Expected character')
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
let count = 0;
|
|
385
|
+
let index = source.indexOf(character);
|
|
386
|
+
|
|
387
|
+
while (index !== -1) {
|
|
388
|
+
count++;
|
|
389
|
+
index = source.indexOf(character, index + character.length);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return count
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @typedef {import('./index.js').Context} Context
|
|
397
|
+
*/
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Serialize an attribute value.
|
|
401
|
+
*
|
|
402
|
+
* @param {string} value
|
|
403
|
+
* @param {Context} ctx
|
|
404
|
+
* @returns {string}
|
|
405
|
+
*/
|
|
406
|
+
function value(value, ctx) {
|
|
407
|
+
var primary = ctx.quote;
|
|
408
|
+
var secondary = ctx.alternative;
|
|
409
|
+
var result = String(value);
|
|
410
|
+
var quote =
|
|
411
|
+
secondary && ccount(result, primary) > ccount(result, secondary)
|
|
412
|
+
? secondary
|
|
413
|
+
: primary;
|
|
414
|
+
|
|
415
|
+
return quote + escape(result, ['<', '&', quote]) + quote
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
420
|
+
* @typedef {import('./index.js').Element} Element
|
|
421
|
+
* @typedef {import('./index.js').Attributes} Attributes
|
|
422
|
+
*/
|
|
423
|
+
|
|
424
|
+
var own$1 = {}.hasOwnProperty;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Serialize an element.
|
|
428
|
+
*
|
|
429
|
+
* @type {Handle}
|
|
430
|
+
* @param {Element} node
|
|
431
|
+
*/
|
|
432
|
+
function element(node, ctx) {
|
|
433
|
+
var nodeName = name(node.name);
|
|
434
|
+
var content = all(node, ctx);
|
|
435
|
+
/** @type {Attributes} */
|
|
436
|
+
var attributes = node.attributes || {};
|
|
437
|
+
var close = content ? false : ctx.close;
|
|
438
|
+
/** @type {Array.<string>} */
|
|
439
|
+
var attrs = [];
|
|
440
|
+
/** @type {string} */
|
|
441
|
+
var key;
|
|
442
|
+
/** @type {Attributes[keyof Attributes]} */
|
|
443
|
+
var result;
|
|
444
|
+
|
|
445
|
+
for (key in attributes) {
|
|
446
|
+
if (own$1.call(attributes, key)) {
|
|
447
|
+
result = attributes[key];
|
|
448
|
+
|
|
449
|
+
if (result !== null && result !== undefined) {
|
|
450
|
+
attrs.push(name(key) + '=' + value(result, ctx));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return (
|
|
456
|
+
'<' +
|
|
457
|
+
nodeName +
|
|
458
|
+
(attrs.length === 0 ? '' : ' ' + attrs.join(' ')) +
|
|
459
|
+
(close ? (ctx.tight ? '' : ' ') + '/' : '') +
|
|
460
|
+
'>' +
|
|
461
|
+
content +
|
|
462
|
+
(close ? '' : '</' + nodeName + '>')
|
|
463
|
+
)
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
468
|
+
* @typedef {import('./index.js').Text} Text
|
|
469
|
+
*/
|
|
470
|
+
|
|
471
|
+
var subset$2 = ['&', '<'];
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Serialize a text.
|
|
475
|
+
*
|
|
476
|
+
* @type {Handle}
|
|
477
|
+
* @param {Text} node
|
|
478
|
+
*/
|
|
479
|
+
function text(node) {
|
|
480
|
+
return escape(node.value, subset$2)
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
485
|
+
* @typedef {import('./index.js').Comment} Comment
|
|
486
|
+
*/
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Serialize a comment.
|
|
490
|
+
*
|
|
491
|
+
* @type {Handle}
|
|
492
|
+
* @param {Comment} node
|
|
493
|
+
*/
|
|
494
|
+
function comment(node) {
|
|
495
|
+
return '<!--' + escape(node.value, ['-']) + '-->'
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
500
|
+
* @typedef {import('./index.js').Doctype} Doctype
|
|
501
|
+
*/
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Serialize a doctype.
|
|
505
|
+
*
|
|
506
|
+
* @type {Handle}
|
|
507
|
+
* @param {Doctype} node
|
|
508
|
+
*/
|
|
509
|
+
function doctype(node, ctx) {
|
|
510
|
+
var nodeName = name(node.name);
|
|
511
|
+
var pub = node.public;
|
|
512
|
+
var sys = node.system;
|
|
513
|
+
var result = '<!DOCTYPE';
|
|
514
|
+
|
|
515
|
+
if (nodeName !== '') {
|
|
516
|
+
result += ' ' + nodeName;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if (pub !== null && pub !== undefined && pub !== '') {
|
|
520
|
+
result += ' PUBLIC ' + value(pub, ctx);
|
|
521
|
+
} else if (sys !== null && sys !== undefined && sys !== '') {
|
|
522
|
+
result += ' SYSTEM';
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (sys !== null && sys !== undefined && sys !== '') {
|
|
526
|
+
result += ' ' + value(sys, ctx);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return result + '>'
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
534
|
+
* @typedef {import('./index.js').Instruction} Instruction
|
|
535
|
+
*/
|
|
536
|
+
|
|
537
|
+
var unsafe$1 = /\?>/g;
|
|
538
|
+
var subset$1 = ['>'];
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Serialize an instruction.
|
|
542
|
+
*
|
|
543
|
+
* @type {Handle}
|
|
544
|
+
* @param {Instruction} node
|
|
545
|
+
*/
|
|
546
|
+
function instruction(node) {
|
|
547
|
+
var nodeName = name(node.name) || 'x';
|
|
548
|
+
var result = escape(node.value, subset$1, unsafe$1);
|
|
549
|
+
return '<?' + nodeName + (result ? ' ' + result : '') + '?>'
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
554
|
+
* @typedef {import('./index.js').Cdata} Cdata
|
|
555
|
+
*/
|
|
556
|
+
|
|
557
|
+
var unsafe = /]]>/g;
|
|
558
|
+
var subset = ['>'];
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Serialize a CDATA section.
|
|
562
|
+
*
|
|
563
|
+
* @type {Handle}
|
|
564
|
+
* @param {Cdata} node
|
|
565
|
+
*/
|
|
566
|
+
function cdata(node) {
|
|
567
|
+
return '<![CDATA[' + escape(node.value, subset, unsafe) + ']]>'
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
572
|
+
* @typedef {import('./index.js').Raw} Raw
|
|
573
|
+
*/
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Serialize a (non-standard) raw.
|
|
577
|
+
*
|
|
578
|
+
* @type {Handle}
|
|
579
|
+
* @param {Raw} node
|
|
580
|
+
*/
|
|
581
|
+
function raw(node, ctx) {
|
|
582
|
+
// @ts-ignore Looks like a text.
|
|
583
|
+
return ctx.dangerous ? node.value : text(node)
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* @typedef {import('./index.js').Handle} Handle
|
|
588
|
+
*/
|
|
589
|
+
|
|
590
|
+
var own = {}.hasOwnProperty;
|
|
591
|
+
|
|
592
|
+
var handlers = {
|
|
593
|
+
root: all,
|
|
594
|
+
element,
|
|
595
|
+
text,
|
|
596
|
+
comment,
|
|
597
|
+
doctype,
|
|
598
|
+
instruction,
|
|
599
|
+
cdata,
|
|
600
|
+
raw
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Serialize a node.
|
|
605
|
+
*
|
|
606
|
+
* @type {Handle}
|
|
607
|
+
*/
|
|
608
|
+
function one(node, ctx) {
|
|
609
|
+
var type = node && node.type;
|
|
610
|
+
|
|
611
|
+
if (!type) {
|
|
612
|
+
throw new Error('Expected node, not `' + node + '`')
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if (!own.call(handlers, type)) {
|
|
616
|
+
throw new Error('Cannot compile unknown node `' + type + '`')
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// @ts-ignore Hush, it works.
|
|
620
|
+
return handlers[type](node, ctx)
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* @typedef {import('xast').Root} Root
|
|
625
|
+
* @typedef {import('xast').Element} Element
|
|
626
|
+
* @typedef {import('xast').Cdata} Cdata
|
|
627
|
+
* @typedef {import('xast').Comment} Comment
|
|
628
|
+
* @typedef {import('xast').Doctype} Doctype
|
|
629
|
+
* @typedef {import('xast').Instruction} Instruction
|
|
630
|
+
* @typedef {import('xast').Text} Text
|
|
631
|
+
* @typedef {import('xast').Literal & {type: 'raw'}} Raw
|
|
632
|
+
* @typedef {Root|Element} Parent
|
|
633
|
+
* @typedef {import('xast').Attributes} Attributes
|
|
634
|
+
* @typedef {Root['children'][number]} Child
|
|
635
|
+
* @typedef {Child|Root} Node
|
|
636
|
+
*
|
|
637
|
+
* @typedef {'"'|"'"} Quote
|
|
638
|
+
*
|
|
639
|
+
* @typedef Options
|
|
640
|
+
* @property {Quote} [quote='"'] Preferred quote to use
|
|
641
|
+
* @property {boolean} [quoteSmart=false] Use the other quote if that results in
|
|
642
|
+
* less bytes
|
|
643
|
+
* @property {boolean} [closeEmptyElements=false] Close elements without any
|
|
644
|
+
* content with slash (/) on the opening tag instead of an end tag:
|
|
645
|
+
* `<circle />` instead of `<circle></circle>`.
|
|
646
|
+
* See `tightClose` to control whether a space is used before the slash.
|
|
647
|
+
* @property {boolean} [tightClose=false] Do not use an extra space when closing
|
|
648
|
+
* self-closing elements: `<circle/>` instead of `<circle />`.
|
|
649
|
+
* @property {boolean} [allowDangerousXml=false] Allow `raw` nodes and insert
|
|
650
|
+
* them as raw XML. When falsey, encodes `raw` nodes.
|
|
651
|
+
* Only set this if you completely trust the content!
|
|
652
|
+
*
|
|
653
|
+
* @typedef Context
|
|
654
|
+
* @property {Quote} quote
|
|
655
|
+
* @property {Quote} alternative
|
|
656
|
+
* @property {boolean} close
|
|
657
|
+
* @property {boolean} tight
|
|
658
|
+
* @property {boolean} dangerous
|
|
659
|
+
*
|
|
660
|
+
* @callback Handle
|
|
661
|
+
* @param {Node} node
|
|
662
|
+
* @param {Context} context
|
|
663
|
+
* @returns {string}
|
|
664
|
+
*/
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Serialize the given xast tree (or list of nodes).
|
|
668
|
+
*
|
|
669
|
+
* @param {Node|Array.<Node>} node
|
|
670
|
+
* @param {Options} [options]
|
|
671
|
+
* @returns {string}
|
|
672
|
+
*/
|
|
673
|
+
function toXml(node, options = {}) {
|
|
674
|
+
var quote = options.quote || '"';
|
|
675
|
+
/** @type {Quote} */
|
|
676
|
+
var alternative = quote === '"' ? "'" : '"';
|
|
677
|
+
var smart = options.quoteSmart;
|
|
678
|
+
/** @type {Node} */
|
|
679
|
+
// @ts-ignore Assume no `root` in `node`.
|
|
680
|
+
var value = Array.isArray(node) ? {type: 'root', children: node} : node;
|
|
681
|
+
|
|
682
|
+
if (quote !== '"' && quote !== "'") {
|
|
683
|
+
throw new Error('Invalid quote `' + quote + '`, expected `\'` or `"`')
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
return one(value, {
|
|
687
|
+
dangerous: options.allowDangerousXml,
|
|
688
|
+
close: options.closeEmptyElements,
|
|
689
|
+
tight: options.tightClose,
|
|
690
|
+
quote,
|
|
691
|
+
alternative: smart ? alternative : null
|
|
692
|
+
})
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const BR = u('text', '\n');
|
|
696
|
+
const TAB = u('text', ' ');
|
|
697
|
+
/**
|
|
698
|
+
* Convert nested folder structure to KML. This expects
|
|
699
|
+
* input that follows the same patterns as [toGeoJSON](https://github.com/placemark/togeojson)'s
|
|
700
|
+
* kmlWithFolders method: a tree of folders and features,
|
|
701
|
+
* starting with a root element.
|
|
702
|
+
*/
|
|
703
|
+
function foldersToKML(root) {
|
|
704
|
+
return toXml(u('root', [
|
|
705
|
+
x('kml', { xmlns: 'http://www.opengis.net/kml/2.2' }, x('Document', root.children.flatMap((child) => convertChild(child)))),
|
|
706
|
+
]));
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Convert a GeoJSON FeatureCollection to a string of
|
|
710
|
+
* KML data.
|
|
711
|
+
*/
|
|
712
|
+
function toKML(featureCollection) {
|
|
713
|
+
return toXml(u('root', [
|
|
714
|
+
x('kml', { xmlns: 'http://www.opengis.net/kml/2.2' }, x('Document', featureCollection.features.flatMap((feature) => convertFeature(feature)))),
|
|
715
|
+
]));
|
|
716
|
+
}
|
|
717
|
+
function convertChild(child) {
|
|
718
|
+
switch (child.type) {
|
|
719
|
+
case 'Feature':
|
|
720
|
+
return convertFeature(child);
|
|
721
|
+
case 'folder':
|
|
722
|
+
return convertFolder(child);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function convertFolder(folder) {
|
|
726
|
+
const id = ['string', 'number'].includes(typeof folder.meta.id)
|
|
727
|
+
? {
|
|
728
|
+
id: String(folder.meta.id),
|
|
729
|
+
}
|
|
730
|
+
: {};
|
|
731
|
+
return [
|
|
732
|
+
BR,
|
|
733
|
+
x('Folder', id, [
|
|
734
|
+
BR,
|
|
735
|
+
...folderMeta(folder.meta),
|
|
736
|
+
BR,
|
|
737
|
+
TAB,
|
|
738
|
+
...folder.children.flatMap((child) => convertChild(child)),
|
|
739
|
+
]),
|
|
740
|
+
];
|
|
741
|
+
}
|
|
742
|
+
const META_PROPERTIES = [
|
|
743
|
+
'address',
|
|
744
|
+
'description',
|
|
745
|
+
'name',
|
|
746
|
+
'open',
|
|
747
|
+
'visibility',
|
|
748
|
+
'phoneNumber',
|
|
749
|
+
];
|
|
750
|
+
function folderMeta(meta) {
|
|
751
|
+
return META_PROPERTIES.filter((p) => meta[p] !== undefined).map((p) => {
|
|
752
|
+
return x(p, [u('text', String(meta[p]))]);
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
function convertFeature(feature) {
|
|
756
|
+
const { id } = feature;
|
|
757
|
+
const idMember = ['string', 'number'].includes(typeof id)
|
|
758
|
+
? {
|
|
759
|
+
id: id,
|
|
760
|
+
}
|
|
761
|
+
: {};
|
|
762
|
+
return [
|
|
763
|
+
BR,
|
|
764
|
+
x('Placemark', idMember, [
|
|
765
|
+
BR,
|
|
766
|
+
...propertiesToTags(feature.properties),
|
|
767
|
+
BR,
|
|
768
|
+
TAB,
|
|
769
|
+
...(feature.geometry ? [convertGeometry(feature.geometry)] : []),
|
|
770
|
+
]),
|
|
771
|
+
];
|
|
772
|
+
}
|
|
773
|
+
function join(position) {
|
|
774
|
+
return `${position[0]},${position[1]}`;
|
|
775
|
+
}
|
|
776
|
+
function coord1(coordinates) {
|
|
777
|
+
return x('coordinates', [u('text', join(coordinates))]);
|
|
778
|
+
}
|
|
779
|
+
function coord2(coordinates) {
|
|
780
|
+
return x('coordinates', [u('text', coordinates.map(join).join('\n'))]);
|
|
781
|
+
}
|
|
782
|
+
function toString(value) {
|
|
783
|
+
switch (typeof value) {
|
|
784
|
+
case 'string': {
|
|
785
|
+
return value;
|
|
786
|
+
}
|
|
787
|
+
case 'boolean':
|
|
788
|
+
case 'number': {
|
|
789
|
+
return String(value);
|
|
790
|
+
}
|
|
791
|
+
case 'object': {
|
|
792
|
+
try {
|
|
793
|
+
return JSON.stringify(value);
|
|
794
|
+
}
|
|
795
|
+
catch (e) {
|
|
796
|
+
return '';
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return '';
|
|
801
|
+
}
|
|
802
|
+
function maybeCData(value) {
|
|
803
|
+
if (value &&
|
|
804
|
+
typeof value === 'object' &&
|
|
805
|
+
'@type' in value &&
|
|
806
|
+
value['@type'] === 'html' &&
|
|
807
|
+
'value' in value &&
|
|
808
|
+
typeof value.value === 'string') {
|
|
809
|
+
return u('cdata', value.value);
|
|
810
|
+
}
|
|
811
|
+
return toString(value);
|
|
812
|
+
}
|
|
813
|
+
function propertiesToTags(properties) {
|
|
814
|
+
if (!properties)
|
|
815
|
+
return [];
|
|
816
|
+
const { name, description, visibility, ...otherProperties } = properties;
|
|
817
|
+
return [
|
|
818
|
+
name && x('name', [u('text', toString(name))]),
|
|
819
|
+
description && x('description', [u('text', maybeCData(description))]),
|
|
820
|
+
visibility !== undefined &&
|
|
821
|
+
x('visibility', [u('text', visibility ? '1' : '0')]),
|
|
822
|
+
x('ExtendedData', Object.entries(otherProperties).flatMap(([name, value]) => [
|
|
823
|
+
BR,
|
|
824
|
+
TAB,
|
|
825
|
+
x('Data', { name: name }, [
|
|
826
|
+
x('value', [
|
|
827
|
+
u('text', typeof value === 'string' ? value : JSON.stringify(value)),
|
|
828
|
+
]),
|
|
829
|
+
]),
|
|
830
|
+
])),
|
|
831
|
+
].filter(Boolean);
|
|
832
|
+
}
|
|
833
|
+
const linearRing = (ring) => x('LinearRing', [coord2(ring)]);
|
|
834
|
+
function convertMultiPoint(geometry) {
|
|
835
|
+
return x('MultiGeometry', geometry.coordinates.flatMap((coordinates) => [
|
|
836
|
+
BR,
|
|
837
|
+
convertGeometry({
|
|
838
|
+
type: 'Point',
|
|
839
|
+
coordinates,
|
|
840
|
+
}),
|
|
841
|
+
]));
|
|
842
|
+
}
|
|
843
|
+
function convertMultiLineString(geometry) {
|
|
844
|
+
return x('MultiGeometry', geometry.coordinates.flatMap((coordinates) => [
|
|
845
|
+
BR,
|
|
846
|
+
convertGeometry({
|
|
847
|
+
type: 'LineString',
|
|
848
|
+
coordinates,
|
|
849
|
+
}),
|
|
850
|
+
]));
|
|
851
|
+
}
|
|
852
|
+
function convertMultiPolygon(geometry) {
|
|
853
|
+
return x('MultiGeometry', geometry.coordinates.flatMap((coordinates) => [
|
|
854
|
+
BR,
|
|
855
|
+
convertGeometry({
|
|
856
|
+
type: 'Polygon',
|
|
857
|
+
coordinates,
|
|
858
|
+
}),
|
|
859
|
+
]));
|
|
860
|
+
}
|
|
861
|
+
function convertPolygon(geometry) {
|
|
862
|
+
const [outerBoundary, ...innerRings] = geometry.coordinates;
|
|
863
|
+
return x('Polygon', [
|
|
864
|
+
BR,
|
|
865
|
+
x('outerBoundaryIs', [BR, TAB, linearRing(outerBoundary)]),
|
|
866
|
+
...innerRings.flatMap((innerRing) => [
|
|
867
|
+
BR,
|
|
868
|
+
x('innerBoundaryIs', [BR, TAB, linearRing(innerRing)]),
|
|
869
|
+
]),
|
|
870
|
+
]);
|
|
871
|
+
}
|
|
872
|
+
function convertGeometry(geometry) {
|
|
873
|
+
switch (geometry.type) {
|
|
874
|
+
case 'Point':
|
|
875
|
+
return x('Point', [coord1(geometry.coordinates)]);
|
|
876
|
+
case 'MultiPoint':
|
|
877
|
+
return convertMultiPoint(geometry);
|
|
878
|
+
case 'LineString':
|
|
879
|
+
return x('LineString', [coord2(geometry.coordinates)]);
|
|
880
|
+
case 'MultiLineString':
|
|
881
|
+
return convertMultiLineString(geometry);
|
|
882
|
+
case 'Polygon':
|
|
883
|
+
return convertPolygon(geometry);
|
|
884
|
+
case 'MultiPolygon':
|
|
885
|
+
return convertMultiPolygon(geometry);
|
|
886
|
+
case 'GeometryCollection':
|
|
887
|
+
return x('MultiGeometry', geometry.geometries.flatMap((geometry) => [
|
|
888
|
+
BR,
|
|
889
|
+
convertGeometry(geometry),
|
|
890
|
+
]));
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
export { foldersToKML, toKML };
|
|
895
|
+
//# sourceMappingURL=tokml.es.mjs.map
|