osm2geojson-lite 1.2.0 → 2.0.1
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.
- package/README.md +5 -0
- package/dist/cli.mjs +36 -0
- package/dist/index.d.ts +203 -0
- package/dist/index.js +924 -0
- package/dist/index.mjs +924 -0
- package/package.json +43 -56
- package/dist/node/index.d.ts +0 -25
- package/dist/node/index.js +0 -196
- package/dist/node/late-binder.d.ts +0 -8
- package/dist/node/late-binder.js +0 -24
- package/dist/node/node.d.ts +0 -14
- package/dist/node/node.js +0 -31
- package/dist/node/osm-object.d.ts +0 -25
- package/dist/node/osm-object.js +0 -38
- package/dist/node/ref-elements.d.ts +0 -9
- package/dist/node/ref-elements.js +0 -19
- package/dist/node/relation.d.ts +0 -21
- package/dist/node/relation.js +0 -220
- package/dist/node/utils.d.ts +0 -22
- package/dist/node/utils.js +0 -97
- package/dist/node/way-collection.d.ts +0 -14
- package/dist/node/way-collection.js +0 -109
- package/dist/node/way.d.ts +0 -21
- package/dist/node/way.js +0 -87
- package/dist/node/xmlparser.d.ts +0 -32
- package/dist/node/xmlparser.js +0 -161
- package/dist/web/osm2geojson-lite.js +0 -1
- /package/dist/{node/polytags.json → polytags.json} +0 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,924 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
3
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/utils.ts
|
|
6
|
+
function purgeProps(obj, blacklist) {
|
|
7
|
+
if (obj) {
|
|
8
|
+
const rs = Object.assign({}, obj);
|
|
9
|
+
if (blacklist) for (const prop of blacklist) delete rs[prop];
|
|
10
|
+
return rs;
|
|
11
|
+
}
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
function first(a) {
|
|
15
|
+
return a[0];
|
|
16
|
+
}
|
|
17
|
+
function last(a) {
|
|
18
|
+
return a[a.length - 1];
|
|
19
|
+
}
|
|
20
|
+
function coordsToKey(a) {
|
|
21
|
+
return a.join(",");
|
|
22
|
+
}
|
|
23
|
+
function addToMap(m, k, v) {
|
|
24
|
+
const a = m[k];
|
|
25
|
+
if (a) a.push(v);
|
|
26
|
+
else m[k] = [v];
|
|
27
|
+
}
|
|
28
|
+
function removeFromMap(m, k, v) {
|
|
29
|
+
const a = m[k];
|
|
30
|
+
let idx = -1;
|
|
31
|
+
if (a) idx = a.indexOf(v);
|
|
32
|
+
if (idx >= 0) a.splice(idx, 1);
|
|
33
|
+
}
|
|
34
|
+
function getFirstFromMap(m, k) {
|
|
35
|
+
const a = m[k];
|
|
36
|
+
if (a && a.length > 0) return a[0];
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
function isRing(a) {
|
|
40
|
+
return a.length > 3 && coordsToKey(first(a)) === coordsToKey(last(a));
|
|
41
|
+
}
|
|
42
|
+
function ringDirection(a, xIdx, yIdx) {
|
|
43
|
+
xIdx = xIdx || 0, yIdx = yIdx || 1;
|
|
44
|
+
const m = a.reduce((maxxIdx, v, idx) => a[maxxIdx][xIdx || 0] > v[xIdx || 0] ? maxxIdx : idx, 0);
|
|
45
|
+
const l = m <= 0 ? a.length - 2 : m - 1;
|
|
46
|
+
const r = m >= a.length - 1 ? 1 : m + 1;
|
|
47
|
+
const xa = a[l][xIdx];
|
|
48
|
+
const xb = a[m][xIdx];
|
|
49
|
+
const xc = a[r][xIdx];
|
|
50
|
+
const ya = a[l][yIdx];
|
|
51
|
+
const yb = a[m][yIdx];
|
|
52
|
+
const yc = a[r][yIdx];
|
|
53
|
+
return (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya) < 0 ? "clockwise" : "counterclockwise";
|
|
54
|
+
}
|
|
55
|
+
function pointInsidePolygon(pt, polygon, xIdx, yIdx) {
|
|
56
|
+
xIdx = xIdx || 0, yIdx = yIdx || 1;
|
|
57
|
+
let result = false;
|
|
58
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) if ((polygon[i][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[j][xIdx] || polygon[j][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[i][xIdx]) && pt[yIdx] < (polygon[j][yIdx] - polygon[i][yIdx]) * (pt[xIdx] - polygon[i][xIdx]) / (polygon[j][xIdx] - polygon[i][xIdx]) + polygon[i][yIdx]) result = !result;
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
function strArrayArrayToFloat(el) {
|
|
62
|
+
return el.map(strArrayToFloat);
|
|
63
|
+
}
|
|
64
|
+
function strArrayToFloat(el) {
|
|
65
|
+
return el.map(parseFloat);
|
|
66
|
+
}
|
|
67
|
+
var init_utils = __esmMin((() => {}));
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/xmlparser.ts
|
|
70
|
+
function conditioned(evt) {
|
|
71
|
+
return evt.match(/^(.+?)\[(.+?)\]>$/g) !== null;
|
|
72
|
+
}
|
|
73
|
+
function parseEvent(evt) {
|
|
74
|
+
const match = /^(.+?)\[(.+?)\]>$/g.exec(evt);
|
|
75
|
+
if (match) return {
|
|
76
|
+
evt: match[1] + ">",
|
|
77
|
+
exp: match[2]
|
|
78
|
+
};
|
|
79
|
+
return { evt };
|
|
80
|
+
}
|
|
81
|
+
function genConditionFunc(cond) {
|
|
82
|
+
const body = "return " + cond.replace(/(\$.+?)(?=[=!.])/g, "node.$&") + ";";
|
|
83
|
+
return new Function("node", body);
|
|
84
|
+
}
|
|
85
|
+
var XmlParser;
|
|
86
|
+
var init_xmlparser = __esmMin((() => {
|
|
87
|
+
XmlParser = class {
|
|
88
|
+
constructor(opts) {
|
|
89
|
+
this.queryParent = false;
|
|
90
|
+
this.progressive = false;
|
|
91
|
+
this.parentMap = /* @__PURE__ */ new WeakMap();
|
|
92
|
+
if (opts) {
|
|
93
|
+
this.queryParent = opts.queryParent ? true : false;
|
|
94
|
+
this.progressive = opts.progressive;
|
|
95
|
+
if (this.queryParent) this.parentMap = /* @__PURE__ */ new WeakMap();
|
|
96
|
+
}
|
|
97
|
+
this.evtListeners = {};
|
|
98
|
+
}
|
|
99
|
+
parse(xml, parent, dir) {
|
|
100
|
+
dir = dir ? dir + "." : "";
|
|
101
|
+
const nodeRegEx = /<([^ >\/]+)(.*?)>/gm;
|
|
102
|
+
const nodes = [];
|
|
103
|
+
let nodeMatch = nodeRegEx.exec(xml);
|
|
104
|
+
while (nodeMatch) {
|
|
105
|
+
const tag = nodeMatch[1];
|
|
106
|
+
const node = { $tag: tag };
|
|
107
|
+
const fullTag = dir + tag;
|
|
108
|
+
const attrText = nodeMatch[2].trim();
|
|
109
|
+
let closed = false;
|
|
110
|
+
if (attrText.endsWith("/") || tag.startsWith("?") || tag.startsWith("!")) closed = true;
|
|
111
|
+
const attRegEx1 = /([^ ]+?)="(.+?)"/g;
|
|
112
|
+
const attRegEx2 = /([^ ]+?)='(.+?)'/g;
|
|
113
|
+
let attMatch = attRegEx1.exec(attrText);
|
|
114
|
+
let hasAttrs = false;
|
|
115
|
+
while (attMatch) {
|
|
116
|
+
hasAttrs = true;
|
|
117
|
+
node[attMatch[1]] = attMatch[2];
|
|
118
|
+
attMatch = attRegEx1.exec(attrText);
|
|
119
|
+
}
|
|
120
|
+
if (!hasAttrs) {
|
|
121
|
+
attMatch = attRegEx2.exec(attrText);
|
|
122
|
+
while (attMatch) {
|
|
123
|
+
hasAttrs = true;
|
|
124
|
+
node[attMatch[1]] = attMatch[2];
|
|
125
|
+
attMatch = attRegEx2.exec(attrText);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (!hasAttrs && attrText !== "") node.text = attrText;
|
|
129
|
+
if (this.progressive) this.emit(`<${fullTag}>`, node, parent);
|
|
130
|
+
if (!closed) {
|
|
131
|
+
const innerRegEx = new RegExp(`([^]+?)<\/${tag}>`, "g");
|
|
132
|
+
innerRegEx.lastIndex = nodeRegEx.lastIndex;
|
|
133
|
+
const innerMatch = innerRegEx.exec(xml);
|
|
134
|
+
if (innerMatch && innerMatch[1]) {
|
|
135
|
+
nodeRegEx.lastIndex = innerRegEx.lastIndex;
|
|
136
|
+
const innerNodes = this.parse(innerMatch[1], node, fullTag);
|
|
137
|
+
if (innerNodes.length > 0) node.$innerNodes = innerNodes;
|
|
138
|
+
else node.$innerText = innerMatch[1];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (this.queryParent && parent) this.parentMap.set(node, parent);
|
|
142
|
+
if (this.progressive) this.emit(`</${fullTag}>`, node, parent);
|
|
143
|
+
nodes.push(node);
|
|
144
|
+
nodeMatch = nodeRegEx.exec(xml);
|
|
145
|
+
}
|
|
146
|
+
return nodes;
|
|
147
|
+
}
|
|
148
|
+
getParent(node) {
|
|
149
|
+
if (this.queryParent) return this.parentMap.get(node);
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
addListener(evt, func) {
|
|
153
|
+
if (conditioned(evt)) {
|
|
154
|
+
const ev = parseEvent(evt);
|
|
155
|
+
if (ev.exp) func.condition = genConditionFunc(ev.exp);
|
|
156
|
+
evt = ev.evt;
|
|
157
|
+
}
|
|
158
|
+
this.$addListener(evt, func);
|
|
159
|
+
}
|
|
160
|
+
removeListener(evt, func) {
|
|
161
|
+
if (conditioned(evt)) evt = parseEvent(evt).evt;
|
|
162
|
+
this.$removeListener(evt, func);
|
|
163
|
+
}
|
|
164
|
+
on(evt, func) {
|
|
165
|
+
this.addListener(evt, func);
|
|
166
|
+
}
|
|
167
|
+
off(evt, func) {
|
|
168
|
+
this.removeListener(evt, func);
|
|
169
|
+
}
|
|
170
|
+
$addListener(evt, func) {
|
|
171
|
+
const funcs = this.evtListeners[evt];
|
|
172
|
+
if (funcs) funcs.push(func);
|
|
173
|
+
else this.evtListeners[evt] = [func];
|
|
174
|
+
}
|
|
175
|
+
$removeListener(evt, func) {
|
|
176
|
+
const funcs = this.evtListeners[evt];
|
|
177
|
+
let idx = -1;
|
|
178
|
+
if (funcs) idx = funcs.indexOf(func);
|
|
179
|
+
if (idx >= 0) funcs.splice(idx, 1);
|
|
180
|
+
}
|
|
181
|
+
emit(evt, ...args) {
|
|
182
|
+
const funcs = this.evtListeners[evt];
|
|
183
|
+
if (funcs) for (const func of funcs) if (func.condition) {
|
|
184
|
+
if (func.condition.apply(null, args) === true) func.apply(null, args);
|
|
185
|
+
} else func.apply(null, args);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}));
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/osm-object.ts
|
|
191
|
+
var OsmObject;
|
|
192
|
+
var init_osm_object = __esmMin((() => {
|
|
193
|
+
OsmObject = class {
|
|
194
|
+
constructor(type, id, refElems) {
|
|
195
|
+
this.type = type;
|
|
196
|
+
this.id = id;
|
|
197
|
+
this.refElems = refElems;
|
|
198
|
+
this.tags = {};
|
|
199
|
+
this.props = { id: this.getCompositeId() };
|
|
200
|
+
this.refCount = 0;
|
|
201
|
+
this.hasTag = false;
|
|
202
|
+
if (refElems) refElems.add(this.getCompositeId(), this);
|
|
203
|
+
}
|
|
204
|
+
addTags(tags) {
|
|
205
|
+
this.tags = Object.assign(this.tags, tags);
|
|
206
|
+
this.hasTag = true;
|
|
207
|
+
}
|
|
208
|
+
addTag(k, v) {
|
|
209
|
+
this.tags[k] = v;
|
|
210
|
+
this.hasTag = true;
|
|
211
|
+
}
|
|
212
|
+
addProp(k, v) {
|
|
213
|
+
this.props[k] = v;
|
|
214
|
+
}
|
|
215
|
+
addProps(props) {
|
|
216
|
+
this.props = Object.assign(this.props, props);
|
|
217
|
+
}
|
|
218
|
+
getCompositeId() {
|
|
219
|
+
return `${this.type}/${this.id}`;
|
|
220
|
+
}
|
|
221
|
+
getProps() {
|
|
222
|
+
return Object.assign(this.props, this.tags);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}));
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/node.ts
|
|
228
|
+
var Node;
|
|
229
|
+
var init_node = __esmMin((() => {
|
|
230
|
+
init_osm_object();
|
|
231
|
+
init_utils();
|
|
232
|
+
Node = class extends OsmObject {
|
|
233
|
+
constructor(id, refElems) {
|
|
234
|
+
super("node", id, refElems);
|
|
235
|
+
}
|
|
236
|
+
setLatLng(latLng) {
|
|
237
|
+
this.latLng = latLng;
|
|
238
|
+
}
|
|
239
|
+
toFeatureArray() {
|
|
240
|
+
if (this.latLng) return [{
|
|
241
|
+
type: "Feature",
|
|
242
|
+
id: this.getCompositeId(),
|
|
243
|
+
properties: this.getProps(),
|
|
244
|
+
geometry: {
|
|
245
|
+
type: "Point",
|
|
246
|
+
coordinates: strArrayToFloat([this.latLng.lon, this.latLng.lat])
|
|
247
|
+
}
|
|
248
|
+
}];
|
|
249
|
+
return [];
|
|
250
|
+
}
|
|
251
|
+
getLatLng() {
|
|
252
|
+
return this.latLng;
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
}));
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region src/late-binder.ts
|
|
258
|
+
var LateBinder;
|
|
259
|
+
var init_late_binder = __esmMin((() => {
|
|
260
|
+
LateBinder = class {
|
|
261
|
+
constructor(container, valueFunc, ctx, args) {
|
|
262
|
+
this.container = container;
|
|
263
|
+
this.valueFunc = valueFunc;
|
|
264
|
+
this.ctx = ctx;
|
|
265
|
+
this.args = args;
|
|
266
|
+
}
|
|
267
|
+
bind() {
|
|
268
|
+
const v = this.valueFunc.apply(this.ctx, this.args);
|
|
269
|
+
const idx = this.container.indexOf(this);
|
|
270
|
+
if (idx < 0) return;
|
|
271
|
+
const args = [idx, 1];
|
|
272
|
+
if (v) args.push(v);
|
|
273
|
+
Array.prototype.splice.apply(this.container, args);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}));
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/polytags.json
|
|
279
|
+
init_xmlparser();
|
|
280
|
+
init_node();
|
|
281
|
+
init_late_binder();
|
|
282
|
+
var polytags_default = {
|
|
283
|
+
building: {},
|
|
284
|
+
highway: { "whitelist": [
|
|
285
|
+
"services",
|
|
286
|
+
"rest_area",
|
|
287
|
+
"escape",
|
|
288
|
+
"elevator"
|
|
289
|
+
] },
|
|
290
|
+
natural: { "blacklist": [
|
|
291
|
+
"coastline",
|
|
292
|
+
"cliff",
|
|
293
|
+
"ridge",
|
|
294
|
+
"arete",
|
|
295
|
+
"tree_row"
|
|
296
|
+
] },
|
|
297
|
+
landuse: {},
|
|
298
|
+
waterway: { "whitelist": [
|
|
299
|
+
"riverbank",
|
|
300
|
+
"dock",
|
|
301
|
+
"boatyard",
|
|
302
|
+
"dam"
|
|
303
|
+
] },
|
|
304
|
+
amenity: {},
|
|
305
|
+
leisure: {},
|
|
306
|
+
barrier: { "whitelist": [
|
|
307
|
+
"city_wall",
|
|
308
|
+
"ditch",
|
|
309
|
+
"hedge",
|
|
310
|
+
"retaining_wall",
|
|
311
|
+
"wall",
|
|
312
|
+
"spikes"
|
|
313
|
+
] },
|
|
314
|
+
railway: { "whitelist": [
|
|
315
|
+
"station",
|
|
316
|
+
"turntable",
|
|
317
|
+
"roundhouse",
|
|
318
|
+
"platform"
|
|
319
|
+
] },
|
|
320
|
+
area: {},
|
|
321
|
+
boundary: {},
|
|
322
|
+
man_made: { "blacklist": [
|
|
323
|
+
"cutline",
|
|
324
|
+
"embankment",
|
|
325
|
+
"pipeline"
|
|
326
|
+
] },
|
|
327
|
+
power: { "whitelist": [
|
|
328
|
+
"plant",
|
|
329
|
+
"substation",
|
|
330
|
+
"generator",
|
|
331
|
+
"transformer"
|
|
332
|
+
] },
|
|
333
|
+
place: {},
|
|
334
|
+
shop: {},
|
|
335
|
+
aeroway: { "blacklist": ["taxiway"] },
|
|
336
|
+
tourism: {},
|
|
337
|
+
historic: {},
|
|
338
|
+
public_transport: {},
|
|
339
|
+
office: {},
|
|
340
|
+
"building:part": {},
|
|
341
|
+
military: {},
|
|
342
|
+
ruins: {},
|
|
343
|
+
"area:highway": {},
|
|
344
|
+
craft: {},
|
|
345
|
+
golf: {},
|
|
346
|
+
indoor: {}
|
|
347
|
+
};
|
|
348
|
+
//#endregion
|
|
349
|
+
//#region src/way.ts
|
|
350
|
+
var Way;
|
|
351
|
+
var init_way = __esmMin((() => {
|
|
352
|
+
init_osm_object();
|
|
353
|
+
init_utils();
|
|
354
|
+
Way = class extends OsmObject {
|
|
355
|
+
constructor(id, refElems) {
|
|
356
|
+
super("way", id, refElems);
|
|
357
|
+
this.latLngArray = [];
|
|
358
|
+
this.isPolygon = false;
|
|
359
|
+
}
|
|
360
|
+
addLatLng(latLng) {
|
|
361
|
+
this.latLngArray.push(latLng);
|
|
362
|
+
}
|
|
363
|
+
setLatLngArray(latLngArray) {
|
|
364
|
+
this.latLngArray = latLngArray;
|
|
365
|
+
}
|
|
366
|
+
addNodeRef(ref) {
|
|
367
|
+
const binder = new LateBinder(this.latLngArray, (id) => {
|
|
368
|
+
const node = this.refElems.get(`node/${id}`);
|
|
369
|
+
if (node) {
|
|
370
|
+
node.refCount++;
|
|
371
|
+
return node.getLatLng();
|
|
372
|
+
}
|
|
373
|
+
}, this, [ref]);
|
|
374
|
+
this.latLngArray.push(binder);
|
|
375
|
+
this.refElems.addBinder(binder);
|
|
376
|
+
}
|
|
377
|
+
addTags(tags) {
|
|
378
|
+
super.addTags(tags);
|
|
379
|
+
for (const [k, v] of Object.entries(tags)) this.analyzeTag(k, v);
|
|
380
|
+
}
|
|
381
|
+
addTag(k, v) {
|
|
382
|
+
super.addTag(k, v);
|
|
383
|
+
this.analyzeTag(k, v);
|
|
384
|
+
}
|
|
385
|
+
toCoordsArray() {
|
|
386
|
+
return this.latLngArray.map((latLng) => [latLng.lon, latLng.lat]);
|
|
387
|
+
}
|
|
388
|
+
toFeatureArray() {
|
|
389
|
+
let coordsArrayString = this.toCoordsArray();
|
|
390
|
+
if (coordsArrayString.length > 1) {
|
|
391
|
+
const coordsArray = strArrayArrayToFloat(coordsArrayString);
|
|
392
|
+
const feature = {
|
|
393
|
+
type: "Feature",
|
|
394
|
+
id: this.getCompositeId(),
|
|
395
|
+
properties: this.getProps(),
|
|
396
|
+
geometry: {
|
|
397
|
+
type: "LineString",
|
|
398
|
+
coordinates: coordsArray
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
if (this.isPolygon && isRing(coordsArray)) {
|
|
402
|
+
if (ringDirection(coordsArray) !== "counterclockwise") coordsArray.reverse();
|
|
403
|
+
feature.geometry = {
|
|
404
|
+
type: "Polygon",
|
|
405
|
+
coordinates: [coordsArray]
|
|
406
|
+
};
|
|
407
|
+
return [feature];
|
|
408
|
+
}
|
|
409
|
+
return [feature];
|
|
410
|
+
}
|
|
411
|
+
return [];
|
|
412
|
+
}
|
|
413
|
+
analyzeTag(k, v) {
|
|
414
|
+
const o = polytags_default[k];
|
|
415
|
+
if (o) {
|
|
416
|
+
this.isPolygon = true;
|
|
417
|
+
if (o.whitelist) this.isPolygon = o.whitelist.indexOf(v) >= 0 ? true : false;
|
|
418
|
+
else if (o.blacklist) this.isPolygon = o.blacklist.indexOf(v) >= 0 ? false : true;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
}));
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/way-collection.ts
|
|
425
|
+
var WayCollection;
|
|
426
|
+
var init_way_collection = __esmMin((() => {
|
|
427
|
+
init_utils();
|
|
428
|
+
WayCollection = class extends Array {
|
|
429
|
+
constructor() {
|
|
430
|
+
super();
|
|
431
|
+
this.firstMap = {};
|
|
432
|
+
this.lastMap = {};
|
|
433
|
+
}
|
|
434
|
+
addWay(way) {
|
|
435
|
+
const w = way.toCoordsArray();
|
|
436
|
+
if (w.length > 0) {
|
|
437
|
+
this.push(w);
|
|
438
|
+
addToMap(this.firstMap, coordsToKey(first(w)), w);
|
|
439
|
+
addToMap(this.lastMap, coordsToKey(last(w)), w);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
mergeWays() {
|
|
443
|
+
const strings = [];
|
|
444
|
+
let way = this.shift();
|
|
445
|
+
while (way) {
|
|
446
|
+
removeFromMap(this.firstMap, coordsToKey(first(way)), way);
|
|
447
|
+
removeFromMap(this.lastMap, coordsToKey(last(way)), way);
|
|
448
|
+
let current = way;
|
|
449
|
+
let next;
|
|
450
|
+
do {
|
|
451
|
+
let nextWay = this.getNextWay(current);
|
|
452
|
+
next = nextWay.next;
|
|
453
|
+
let mergeType = nextWay.mergeType;
|
|
454
|
+
if (!next) continue;
|
|
455
|
+
this.splice(this.indexOf(next), 1);
|
|
456
|
+
removeFromMap(this.firstMap, coordsToKey(first(next)), next);
|
|
457
|
+
removeFromMap(this.lastMap, coordsToKey(last(next)), next);
|
|
458
|
+
switch (mergeType) {
|
|
459
|
+
case 0:
|
|
460
|
+
current = current.concat(next.slice(1));
|
|
461
|
+
break;
|
|
462
|
+
case 1:
|
|
463
|
+
next.reverse();
|
|
464
|
+
current = current.concat(next.slice(1));
|
|
465
|
+
break;
|
|
466
|
+
case 2:
|
|
467
|
+
current.reverse();
|
|
468
|
+
current = current.concat(next.slice(1));
|
|
469
|
+
break;
|
|
470
|
+
case 3:
|
|
471
|
+
current = next.concat(current.slice(1));
|
|
472
|
+
current.reverse();
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
} while (next);
|
|
476
|
+
strings.push(strArrayArrayToFloat(current));
|
|
477
|
+
way = this.shift();
|
|
478
|
+
}
|
|
479
|
+
return strings;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Try to find the next way to add to the current way.
|
|
483
|
+
* It first tries the next way in the array, and if this doesn't work, try any other way.
|
|
484
|
+
*/
|
|
485
|
+
getNextWay(current) {
|
|
486
|
+
const lastKey = coordsToKey(last(current));
|
|
487
|
+
const firstKey = coordsToKey(first(current));
|
|
488
|
+
let next = this.length > 0 ? this[0] : null;
|
|
489
|
+
if (next) {
|
|
490
|
+
const nextFirstKey = coordsToKey(first(next));
|
|
491
|
+
const nextLastKey = coordsToKey(last(next));
|
|
492
|
+
if (lastKey === nextFirstKey) return {
|
|
493
|
+
next,
|
|
494
|
+
mergeType: 0
|
|
495
|
+
};
|
|
496
|
+
if (lastKey === nextLastKey) return {
|
|
497
|
+
next,
|
|
498
|
+
mergeType: 1
|
|
499
|
+
};
|
|
500
|
+
if (firstKey === nextFirstKey) return {
|
|
501
|
+
next,
|
|
502
|
+
mergeType: 2
|
|
503
|
+
};
|
|
504
|
+
if (firstKey === nextLastKey) return {
|
|
505
|
+
next,
|
|
506
|
+
mergeType: 3
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
next = getFirstFromMap(this.firstMap, lastKey);
|
|
510
|
+
if (next) return {
|
|
511
|
+
next,
|
|
512
|
+
mergeType: 0
|
|
513
|
+
};
|
|
514
|
+
next = getFirstFromMap(this.lastMap, lastKey);
|
|
515
|
+
return {
|
|
516
|
+
next,
|
|
517
|
+
mergeType: 1
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
toRings(direction) {
|
|
521
|
+
const strings = this.mergeWays();
|
|
522
|
+
const rings = [];
|
|
523
|
+
let str = strings.shift();
|
|
524
|
+
while (str) {
|
|
525
|
+
if (isRing(str)) {
|
|
526
|
+
if (ringDirection(str) !== direction) str.reverse();
|
|
527
|
+
rings.push(str);
|
|
528
|
+
}
|
|
529
|
+
str = strings.shift();
|
|
530
|
+
}
|
|
531
|
+
return rings;
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
}));
|
|
535
|
+
//#endregion
|
|
536
|
+
//#region src/relation.ts
|
|
537
|
+
var Relation;
|
|
538
|
+
var init_relation = __esmMin((() => {
|
|
539
|
+
init_osm_object();
|
|
540
|
+
init_way();
|
|
541
|
+
init_way_collection();
|
|
542
|
+
init_late_binder();
|
|
543
|
+
init_utils();
|
|
544
|
+
Relation = class extends OsmObject {
|
|
545
|
+
constructor(id, refElems) {
|
|
546
|
+
super("relation", id, refElems);
|
|
547
|
+
this.relations = [];
|
|
548
|
+
this.nodes = [];
|
|
549
|
+
this.bounds = void 0;
|
|
550
|
+
this.ways = [];
|
|
551
|
+
this.roles = [];
|
|
552
|
+
}
|
|
553
|
+
setBounds(bounds) {
|
|
554
|
+
this.bounds = bounds;
|
|
555
|
+
}
|
|
556
|
+
addMember(member) {
|
|
557
|
+
switch (member.type) {
|
|
558
|
+
case "relation":
|
|
559
|
+
let binder = new LateBinder(this.relations, (id) => {
|
|
560
|
+
const relation = this.refElems.get(`relation/${id}`);
|
|
561
|
+
if (relation) {
|
|
562
|
+
relation.refCount++;
|
|
563
|
+
return relation;
|
|
564
|
+
}
|
|
565
|
+
}, this, [member.ref]);
|
|
566
|
+
this.relations.push(binder);
|
|
567
|
+
this.refElems.addBinder(binder);
|
|
568
|
+
break;
|
|
569
|
+
case "way":
|
|
570
|
+
if (!member.role) member.role = "";
|
|
571
|
+
if (member.geometry) {
|
|
572
|
+
const way = new Way(member.ref, this.refElems);
|
|
573
|
+
way.setLatLngArray(member.geometry);
|
|
574
|
+
way.refCount++;
|
|
575
|
+
this.ways.push(way);
|
|
576
|
+
this.roles.push(member.role);
|
|
577
|
+
} else if (member.nodes) {
|
|
578
|
+
const way = new Way(member.ref, this.refElems);
|
|
579
|
+
for (const nid of member.nodes) way.addNodeRef(nid);
|
|
580
|
+
way.refCount++;
|
|
581
|
+
this.ways.push(way);
|
|
582
|
+
this.roles.push(member.role);
|
|
583
|
+
} else {
|
|
584
|
+
let binder = new LateBinder(this.ways, (nid) => {
|
|
585
|
+
const way = this.refElems.get(`way/${nid}`);
|
|
586
|
+
if (way) {
|
|
587
|
+
way.refCount++;
|
|
588
|
+
return way;
|
|
589
|
+
}
|
|
590
|
+
}, this, [member.ref]);
|
|
591
|
+
this.ways.push(binder);
|
|
592
|
+
this.roles.push(member.role);
|
|
593
|
+
this.refElems.addBinder(binder);
|
|
594
|
+
}
|
|
595
|
+
break;
|
|
596
|
+
case "node":
|
|
597
|
+
let node = null;
|
|
598
|
+
if (member.lat && member.lon) {
|
|
599
|
+
node = new Node(member.ref, this.refElems);
|
|
600
|
+
node.setLatLng({
|
|
601
|
+
lon: member.lon,
|
|
602
|
+
lat: member.lat
|
|
603
|
+
});
|
|
604
|
+
if (member.tags) node.addTags(member.tags);
|
|
605
|
+
for (const [k, v] of Object.entries(member)) if ([
|
|
606
|
+
"id",
|
|
607
|
+
"type",
|
|
608
|
+
"lat",
|
|
609
|
+
"lon"
|
|
610
|
+
].indexOf(k) < 0) node.addProp(k, v);
|
|
611
|
+
node.refCount++;
|
|
612
|
+
this.nodes.push(node);
|
|
613
|
+
} else {
|
|
614
|
+
let binder = new LateBinder(this.nodes, (id) => {
|
|
615
|
+
const nn = this.refElems.get(`node/${id}`);
|
|
616
|
+
if (nn) {
|
|
617
|
+
nn.refCount++;
|
|
618
|
+
return nn;
|
|
619
|
+
}
|
|
620
|
+
}, this, [member.ref]);
|
|
621
|
+
this.nodes.push(binder);
|
|
622
|
+
this.refElems.addBinder(binder);
|
|
623
|
+
}
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
constructStringGeometry(ws) {
|
|
628
|
+
const strings = ws ? ws.mergeWays() : [];
|
|
629
|
+
if (strings.length === 0) return null;
|
|
630
|
+
return {
|
|
631
|
+
type: "MultiLineString",
|
|
632
|
+
coordinates: strings
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
constructPolygonGeometry(ows, iws) {
|
|
636
|
+
const outerRings = ows ? ows.toRings("counterclockwise") : [];
|
|
637
|
+
const innerRings = iws ? iws.toRings("clockwise") : [];
|
|
638
|
+
if (outerRings.length > 0) {
|
|
639
|
+
const compositPolyons = [];
|
|
640
|
+
let ring;
|
|
641
|
+
for (ring of outerRings) compositPolyons.push([ring]);
|
|
642
|
+
ring = innerRings.shift();
|
|
643
|
+
while (ring) {
|
|
644
|
+
for (const idx in outerRings) if (pointInsidePolygon(first(ring), outerRings[idx])) {
|
|
645
|
+
compositPolyons[idx].push(ring);
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
648
|
+
ring = innerRings.shift();
|
|
649
|
+
}
|
|
650
|
+
if (compositPolyons.length === 1) return {
|
|
651
|
+
type: "Polygon",
|
|
652
|
+
coordinates: compositPolyons[0]
|
|
653
|
+
};
|
|
654
|
+
return {
|
|
655
|
+
type: "MultiPolygon",
|
|
656
|
+
coordinates: compositPolyons
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
return null;
|
|
660
|
+
}
|
|
661
|
+
collectAllWaysForRelation(relation, relationToWaysMap) {
|
|
662
|
+
const ways = [...relation.ways];
|
|
663
|
+
const roles = [...relation.roles];
|
|
664
|
+
if (relation.relations.length === 0) {
|
|
665
|
+
relationToWaysMap.set(relation.id, {
|
|
666
|
+
ways,
|
|
667
|
+
roles
|
|
668
|
+
});
|
|
669
|
+
return {
|
|
670
|
+
ways,
|
|
671
|
+
roles
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
for (const subRelation of relation.relations) {
|
|
675
|
+
if (!subRelation) continue;
|
|
676
|
+
if (!relationToWaysMap.has(subRelation.id)) this.collectAllWaysForRelation(subRelation, relationToWaysMap);
|
|
677
|
+
const entry = relationToWaysMap.get(subRelation.id);
|
|
678
|
+
for (let i = 0; i < entry.ways.length; i++) {
|
|
679
|
+
ways.push(entry.ways[i]);
|
|
680
|
+
roles.push(entry.roles[i]);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
relationToWaysMap.set(relation.id, {
|
|
684
|
+
ways,
|
|
685
|
+
roles
|
|
686
|
+
});
|
|
687
|
+
return {
|
|
688
|
+
ways,
|
|
689
|
+
roles
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
toFeatureArray() {
|
|
693
|
+
const polygonFeatures = [];
|
|
694
|
+
const stringFeatures = [];
|
|
695
|
+
let pointFeatures = [];
|
|
696
|
+
const relationToWaysMap = /* @__PURE__ */ new Map();
|
|
697
|
+
const waysAndRoles = this.collectAllWaysForRelation(this, relationToWaysMap);
|
|
698
|
+
let templateFeature = {
|
|
699
|
+
type: "Feature",
|
|
700
|
+
id: this.getCompositeId(),
|
|
701
|
+
bbox: this.bounds,
|
|
702
|
+
properties: this.getProps(),
|
|
703
|
+
geometry: null
|
|
704
|
+
};
|
|
705
|
+
if (!this.bounds) delete templateFeature.bbox;
|
|
706
|
+
if (this.roles.some((r) => r === "outer")) {
|
|
707
|
+
const outerWayCollection = new WayCollection();
|
|
708
|
+
const innerWayCollection = new WayCollection();
|
|
709
|
+
for (let i = 0; i < waysAndRoles.ways.length; i++) {
|
|
710
|
+
const way = waysAndRoles.ways[i];
|
|
711
|
+
const role = waysAndRoles.roles[i];
|
|
712
|
+
if (role === "outer") outerWayCollection.addWay(way);
|
|
713
|
+
else if (role === "inner") innerWayCollection.addWay(way);
|
|
714
|
+
}
|
|
715
|
+
let feature = Object.assign({}, templateFeature);
|
|
716
|
+
let geometry = this.constructPolygonGeometry(outerWayCollection, innerWayCollection);
|
|
717
|
+
if (geometry) {
|
|
718
|
+
feature.geometry = geometry;
|
|
719
|
+
polygonFeatures.push(feature);
|
|
720
|
+
}
|
|
721
|
+
} else {
|
|
722
|
+
const wayCollection = new WayCollection();
|
|
723
|
+
for (let way of waysAndRoles.ways) wayCollection.addWay(way);
|
|
724
|
+
let geometry = this.constructStringGeometry(wayCollection);
|
|
725
|
+
if (geometry) {
|
|
726
|
+
let feature = Object.assign({}, templateFeature);
|
|
727
|
+
feature.geometry = geometry;
|
|
728
|
+
stringFeatures.push(feature);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
for (let node of this.nodes) pointFeatures = pointFeatures.concat(node.toFeatureArray());
|
|
732
|
+
return [
|
|
733
|
+
...polygonFeatures,
|
|
734
|
+
...stringFeatures,
|
|
735
|
+
...pointFeatures
|
|
736
|
+
];
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
}));
|
|
740
|
+
//#endregion
|
|
741
|
+
//#region src/ref-elements.ts
|
|
742
|
+
var RefElements;
|
|
743
|
+
var init_ref_elements = __esmMin((() => {
|
|
744
|
+
RefElements = class extends Map {
|
|
745
|
+
constructor() {
|
|
746
|
+
super();
|
|
747
|
+
this.binders = [];
|
|
748
|
+
}
|
|
749
|
+
add(k, v) {
|
|
750
|
+
this.set(k, v);
|
|
751
|
+
}
|
|
752
|
+
addBinder(binder) {
|
|
753
|
+
this.binders.push(binder);
|
|
754
|
+
}
|
|
755
|
+
bindAll() {
|
|
756
|
+
this.binders.forEach((binder) => binder.bind());
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
}));
|
|
760
|
+
//#endregion
|
|
761
|
+
//#region src/index.ts
|
|
762
|
+
var require_src = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
763
|
+
init_utils();
|
|
764
|
+
init_node();
|
|
765
|
+
init_way();
|
|
766
|
+
init_relation();
|
|
767
|
+
init_ref_elements();
|
|
768
|
+
function parseOptions(options) {
|
|
769
|
+
if (!options) return {
|
|
770
|
+
completeFeature: false,
|
|
771
|
+
renderTagged: false,
|
|
772
|
+
excludeWay: true
|
|
773
|
+
};
|
|
774
|
+
let excludeWay = options.excludeWay === void 0 || options.excludeWay;
|
|
775
|
+
return {
|
|
776
|
+
completeFeature: options.completeFeature ? true : false,
|
|
777
|
+
renderTagged: options.renderTagged ? true : false,
|
|
778
|
+
excludeWay
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
function detectFormat(o) {
|
|
782
|
+
if (o.elements) return "json";
|
|
783
|
+
if (o.indexOf("<osm") >= 0) return "xml";
|
|
784
|
+
if (o.trim().startsWith("{")) return "json-raw";
|
|
785
|
+
return "invalid";
|
|
786
|
+
}
|
|
787
|
+
function analyzeFeaturesFromJson(osm, refElements) {
|
|
788
|
+
for (const elem of osm.elements) switch (elem.type) {
|
|
789
|
+
case "node":
|
|
790
|
+
const node = new Node(elem.id, refElements);
|
|
791
|
+
if (elem.tags) node.addTags(elem.tags);
|
|
792
|
+
node.addProps(purgeProps(elem, [
|
|
793
|
+
"id",
|
|
794
|
+
"type",
|
|
795
|
+
"tags",
|
|
796
|
+
"lat",
|
|
797
|
+
"lon"
|
|
798
|
+
]));
|
|
799
|
+
node.setLatLng(elem);
|
|
800
|
+
break;
|
|
801
|
+
case "way":
|
|
802
|
+
const way = new Way(elem.id, refElements);
|
|
803
|
+
if (elem.tags) way.addTags(elem.tags);
|
|
804
|
+
way.addProps(purgeProps(elem, [
|
|
805
|
+
"id",
|
|
806
|
+
"type",
|
|
807
|
+
"tags",
|
|
808
|
+
"nodes",
|
|
809
|
+
"geometry"
|
|
810
|
+
]));
|
|
811
|
+
if (elem.geometry) way.setLatLngArray(elem.geometry);
|
|
812
|
+
else if (elem.nodes) for (const n of elem.nodes) way.addNodeRef(n);
|
|
813
|
+
break;
|
|
814
|
+
case "relation":
|
|
815
|
+
const relation = new Relation(elem.id, refElements);
|
|
816
|
+
if (elem.bounds) relation.setBounds([
|
|
817
|
+
parseFloat(elem.bounds.minlon),
|
|
818
|
+
parseFloat(elem.bounds.minlat),
|
|
819
|
+
parseFloat(elem.bounds.maxlon),
|
|
820
|
+
parseFloat(elem.bounds.maxlat)
|
|
821
|
+
]);
|
|
822
|
+
if (elem.tags) relation.addTags(elem.tags);
|
|
823
|
+
relation.addProps(purgeProps(elem, [
|
|
824
|
+
"id",
|
|
825
|
+
"type",
|
|
826
|
+
"tags",
|
|
827
|
+
"bounds",
|
|
828
|
+
"members"
|
|
829
|
+
]));
|
|
830
|
+
if (elem.members) for (const member of elem.members) relation.addMember(member);
|
|
831
|
+
default: break;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
function analyzeFeaturesFromXml(osm, refElements) {
|
|
835
|
+
const xmlParser = new XmlParser({ progressive: true });
|
|
836
|
+
xmlParser.on("</osm.node>", (node) => {
|
|
837
|
+
const nd = new Node(node.id, refElements);
|
|
838
|
+
for (const [k, v] of Object.entries(node)) if (!k.startsWith("$") && [
|
|
839
|
+
"id",
|
|
840
|
+
"lon",
|
|
841
|
+
"lat"
|
|
842
|
+
].indexOf(k) < 0) nd.addProp(k, v);
|
|
843
|
+
nd.setLatLng(node);
|
|
844
|
+
if (node.$innerNodes) {
|
|
845
|
+
for (const ind of node.$innerNodes) if (ind.$tag === "tag") nd.addTag(ind.k, ind.v);
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
xmlParser.on("</osm.way>", (node) => {
|
|
849
|
+
const way = new Way(node.id, refElements);
|
|
850
|
+
for (const [k, v] of Object.entries(node)) if (!k.startsWith("$") && ["id"].indexOf(k) < 0) way.addProp(k, v);
|
|
851
|
+
if (node.$innerNodes) {
|
|
852
|
+
for (const ind of node.$innerNodes) if (ind.$tag === "nd") {
|
|
853
|
+
if (ind.lon && ind.lat) way.addLatLng(ind);
|
|
854
|
+
else if (ind.ref) way.addNodeRef(ind.ref);
|
|
855
|
+
} else if (ind.$tag === "tag") way.addTag(ind.k, ind.v);
|
|
856
|
+
}
|
|
857
|
+
});
|
|
858
|
+
xmlParser.on("<osm.relation>", (node) => new Relation(node.id, refElements));
|
|
859
|
+
xmlParser.on("</osm.relation.member>", (node, parent) => {
|
|
860
|
+
const relation = refElements.get(`relation/${parent?.id}`);
|
|
861
|
+
const member = {
|
|
862
|
+
type: node.type,
|
|
863
|
+
role: node.role ? node.role : "",
|
|
864
|
+
ref: node.ref
|
|
865
|
+
};
|
|
866
|
+
if (node.lat && node.lon) {
|
|
867
|
+
member.lat = node.lat, member.lon = node.lon, member.tags = {};
|
|
868
|
+
for (const [k, v] of Object.entries(node)) if (!k.startsWith("$") && [
|
|
869
|
+
"type",
|
|
870
|
+
"lat",
|
|
871
|
+
"lon"
|
|
872
|
+
].indexOf(k) < 0) member[k] = v;
|
|
873
|
+
}
|
|
874
|
+
if (node.$innerNodes) {
|
|
875
|
+
const geometry = [];
|
|
876
|
+
const nodes = [];
|
|
877
|
+
for (const ind of node.$innerNodes) if (ind.lat && ind.lon) geometry.push(ind);
|
|
878
|
+
else if (ind.ref) nodes.push(ind.ref);
|
|
879
|
+
if (geometry.length > 0) member.geometry = geometry;
|
|
880
|
+
else if (nodes.length > 0) member.nodes = nodes;
|
|
881
|
+
}
|
|
882
|
+
relation.addMember(member);
|
|
883
|
+
});
|
|
884
|
+
xmlParser.on("</osm.relation.bounds>", (node, parent) => {
|
|
885
|
+
refElements.get(`relation/${parent?.id}`).setBounds([
|
|
886
|
+
parseFloat(node.minlon),
|
|
887
|
+
parseFloat(node.minlat),
|
|
888
|
+
parseFloat(node.maxlon),
|
|
889
|
+
parseFloat(node.maxlat)
|
|
890
|
+
]);
|
|
891
|
+
});
|
|
892
|
+
xmlParser.on("</osm.relation.tag>", (node, parent) => {
|
|
893
|
+
refElements.get(`relation/${parent?.id}`).addTag(node.k, node.v);
|
|
894
|
+
});
|
|
895
|
+
xmlParser.parse(osm);
|
|
896
|
+
}
|
|
897
|
+
function osm2geojson(osm, opts) {
|
|
898
|
+
let { completeFeature, renderTagged, excludeWay } = parseOptions(opts);
|
|
899
|
+
let format = detectFormat(osm);
|
|
900
|
+
const refElements = new RefElements();
|
|
901
|
+
let featureArray = [];
|
|
902
|
+
if (format === "json-raw") {
|
|
903
|
+
osm = JSON.parse(osm);
|
|
904
|
+
if (osm.elements) format = "json";
|
|
905
|
+
else format = "invalid";
|
|
906
|
+
}
|
|
907
|
+
if (format === "json") analyzeFeaturesFromJson(osm, refElements);
|
|
908
|
+
else if (format === "xml") analyzeFeaturesFromXml(osm, refElements);
|
|
909
|
+
refElements.bindAll();
|
|
910
|
+
for (const v of refElements.values()) {
|
|
911
|
+
if (v.refCount > 0 && (!v.hasTag || !renderTagged || v instanceof Way && excludeWay)) continue;
|
|
912
|
+
const features = v.toFeatureArray();
|
|
913
|
+
if (v instanceof Relation && !completeFeature && features.length > 0) return features[0].geometry;
|
|
914
|
+
featureArray = featureArray.concat(features);
|
|
915
|
+
}
|
|
916
|
+
return {
|
|
917
|
+
type: "FeatureCollection",
|
|
918
|
+
features: featureArray
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
module.exports = osm2geojson;
|
|
922
|
+
}));
|
|
923
|
+
//#endregion
|
|
924
|
+
export default require_src();
|