osm2geojson-lite 1.0.2 → 1.1.0
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 +13 -17
- package/package.json +11 -5
- package/dist/node/index.js +0 -199
- package/dist/node/osmobjs.js +0 -377
- package/dist/node/polytags.json +0 -84
- package/dist/node/utils.js +0 -222
- package/dist/node/xmlparser.js +0 -160
- package/dist/web/osm2geojson-lite.js +0 -1
package/README.md
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
osm2geojson-lite
|
|
2
2
|
============
|
|
3
3
|
|
|
4
|
+
[](https://www.npmjs.com/package/osm2geojson-lite) [](https://codecov.io/gh/tibetty/osm2geojson-lite/)
|
|
5
|
+
|
|
6
|
+
|
|
4
7
|
A lightweight (not as lightweight as xml2geojson though) yet faster convertor for [OSM](http://openstreetmap.org) [data](http://wiki.openstreetmap.org/wiki/OSM_XML) whatever in XML or JSON formats to [GeoJSON](http://www.geojson.org/) - much faster (the more complex the data source is, the more performance advantages it posesses) than osmtogeojson in most situations - implemented in pure JavaScript without any 3rd party dependency.
|
|
5
8
|
|
|
6
9
|
History
|
|
7
10
|
-----
|
|
8
11
|
An internal function inside [query-geo-boundary](https://www.npmjs.com/package/query-geo-boundary) → stripped out to handle OSM XML only [xml2geojson-lite](https://www.npmjs.com/package/xml2geojson-lite) → this library that supports both OSM XML and OSM/Overpass JSON
|
|
9
12
|
|
|
10
|
-
Changelog:
|
|
11
|
-
-----
|
|
12
|
-
* Late 2018: this repository was created and the initial version was pushed to github - almost around specific usages for myself.
|
|
13
|
-
* 2019-2025: quite a few contributors had fixed quite a few bugs and also contributed some good ideas - thanks for their efforts!
|
|
14
|
-
* 2025-03-03: fixed a few bugs around non-*Polygon features processing and convert it to a pure TypeScript project (codes published to [NPM](https://npmjs.org/) have become TSC compiled from now on).
|
|
15
|
-
|
|
16
13
|
Usage
|
|
17
14
|
-----
|
|
18
15
|
|
|
@@ -25,7 +22,7 @@ Installation:
|
|
|
25
22
|
Usage:
|
|
26
23
|
|
|
27
24
|
```js
|
|
28
|
-
|
|
25
|
+
import osm2geojson from 'osm2geojson-lite';
|
|
29
26
|
let geojson = osm2geojson(osm, opts);
|
|
30
27
|
```
|
|
31
28
|
|
|
@@ -46,9 +43,9 @@ Converts OSM data (XML/JSON) to GeoJSON.
|
|
|
46
43
|
|
|
47
44
|
* `osm`: the OSM XML data in String, or OSM/Overpass JSON as object or in String
|
|
48
45
|
* `opts?`: optional, the options object, right now supports below properties/fields:
|
|
49
|
-
- `completeFeature
|
|
50
|
-
- `renderTagged`: the default value is `false`. When it's set to `true`, the returned geojson will include all elements with tags (i.e., tagged) until `
|
|
51
|
-
- `
|
|
46
|
+
- `completeFeature`: the default value is `false`. When it's set to `true`, the returned geojson will include all elements that meet the specified conditions in `FeatureCollection` format; otherwise, only the bare geometry of the first `relation` element will be returned.
|
|
47
|
+
- `renderTagged`: the default value is `false`. When it's set to `true`, the returned geojson will include all elements with tags (i.e., tagged) until `excludeWay` changes its behavior a bit; otherwise only the unreferenced ones get returned.
|
|
48
|
+
- `excludeWay`: the default value is `true`. When it's set to `true`, the returned `FeatureCollection` will exclude all referenced `way`s even though they are tagged; otherwise the features of those `way`s will be included in the resulted result as well.
|
|
52
49
|
|
|
53
50
|
|
|
54
51
|
Performance
|
|
@@ -58,9 +55,8 @@ Performance
|
|
|
58
55
|
3. For each script, run as many as times seperately and then calculate the average cost time (ACT for short)
|
|
59
56
|
4. The # listed in the table below are coarse lowest values of dividing the ACT of `osmtogeojson` by the one of this library
|
|
60
57
|
```
|
|
61
|
-
$ cd
|
|
62
|
-
$
|
|
63
|
-
$ node otg-bench.js
|
|
58
|
+
$ cd test
|
|
59
|
+
$ npm run bench
|
|
64
60
|
```
|
|
65
61
|
1. XML
|
|
66
62
|
|
|
@@ -79,7 +75,7 @@ Correctness
|
|
|
79
75
|
---
|
|
80
76
|
You can copy the converted results to [geojsonlint](http://geojsonlint.com) for the correctness validation. Up until now, `osm2geojson-lite` behaves pretty well with all the samples (also quite representative) in the `data` subfolers under `test` and `bench` directories, which also outperforms `osmtogeojson`.
|
|
81
77
|
|
|
82
|
-
The client side example shipped along with this package, `test/index.html`
|
|
78
|
+
The client side example shipped along with this package, `test/index.html` - due to CORS limitation, the direct post to geojsonlint is blocked, so there's a "copy to clipboard" button for you to ease the validation.
|
|
83
79
|
|
|
84
80
|
Node.JS version
|
|
85
81
|
---
|
|
@@ -91,10 +87,10 @@ Dependencies
|
|
|
91
87
|
|
|
92
88
|
License
|
|
93
89
|
---
|
|
94
|
-
|
|
90
|
+
MIT
|
|
95
91
|
|
|
96
92
|
Collaborators
|
|
97
93
|
---
|
|
98
|
-
* tibetty
|
|
99
|
-
* HarelM
|
|
94
|
+
* [tibetty](https://github.com/tibetty/)
|
|
95
|
+
* [HarelM](https://github.com/HarelM)
|
|
100
96
|
|
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"bugs": {
|
|
26
26
|
"url": "https://github.com/tibetty/osm2geojson-lite/issues"
|
|
27
27
|
},
|
|
28
|
-
"bundleDependencies":
|
|
28
|
+
"bundleDependencies": [],
|
|
29
29
|
"deprecated": false,
|
|
30
30
|
"description": "a lightweight yet faster osm (either in xml or in json formats) to geojson convertor - 4x faster than xmldom + osmtogeojson in most situations - implemented in pure JavaScript without any 3rd party dependency",
|
|
31
31
|
"homepage": "https://github.com/tibetty/osm2geojson-lite#readme",
|
|
@@ -53,23 +53,29 @@
|
|
|
53
53
|
"url": "git+https://github.com/tibetty/osm2geojson-lite.git"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
|
-
"build": "
|
|
57
|
-
"
|
|
56
|
+
"build-node": "tsc --declaration && cp src/polytags.json dist/node",
|
|
57
|
+
"build-web": "mkdir -p dist/web && browserify -s osm2geojson dist/node/index.js | uglifyjs -c -m -o dist/web/osm2geojson-lite.js",
|
|
58
|
+
"build": "npm run build-node && npm run build-web",
|
|
59
|
+
"test": "vitest test/e2e.test.ts --coverage"
|
|
58
60
|
},
|
|
59
61
|
"optionalDependencies": {
|
|
60
62
|
"@types/geojson": "^7946.0.16"
|
|
61
63
|
},
|
|
62
|
-
"version": "1.0
|
|
64
|
+
"version": "1.1.0",
|
|
63
65
|
"directories": {
|
|
64
66
|
"lib": "lib",
|
|
65
67
|
"test": "test"
|
|
66
68
|
},
|
|
67
69
|
"devDependencies": {
|
|
70
|
+
"@vitest/coverage-v8": "^3.1.3",
|
|
68
71
|
"browserify": "^17.0.1",
|
|
69
|
-
"
|
|
72
|
+
"typescript": "^5.8.3",
|
|
73
|
+
"uglify-js": "^3.19.3",
|
|
74
|
+
"vitest": "^3.1.3"
|
|
70
75
|
},
|
|
71
76
|
"files": [
|
|
72
77
|
"dist/**/*.js",
|
|
78
|
+
"dist/**/*.ts",
|
|
73
79
|
"dist/**/*.json"
|
|
74
80
|
]
|
|
75
81
|
}
|
package/dist/node/index.js
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
const osmobjs_1 = require("./osmobjs");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
const xmlparser_1 = __importDefault(require("./xmlparser"));
|
|
8
|
-
function osm2geojson(osm, opts) {
|
|
9
|
-
let completeFeature = false;
|
|
10
|
-
let renderTagged = false;
|
|
11
|
-
let excludeWay = true;
|
|
12
|
-
const parseOpts = (os) => {
|
|
13
|
-
if (os) {
|
|
14
|
-
completeFeature = os.completeFeature || os.allFeatures ? true : false;
|
|
15
|
-
renderTagged = os.renderTagged ? true : false;
|
|
16
|
-
const wayOpt = os.suppressWay || os.excludeWay;
|
|
17
|
-
if (wayOpt !== undefined && !wayOpt) {
|
|
18
|
-
excludeWay = false;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
if (opts) {
|
|
23
|
-
parseOpts(opts);
|
|
24
|
-
}
|
|
25
|
-
const detectFormat = (o) => {
|
|
26
|
-
if (o.elements) {
|
|
27
|
-
return 'json';
|
|
28
|
-
}
|
|
29
|
-
if (o.indexOf('<osm') >= 0) {
|
|
30
|
-
return 'xml';
|
|
31
|
-
}
|
|
32
|
-
if (o.trim().startsWith('{')) {
|
|
33
|
-
return 'json-raw';
|
|
34
|
-
}
|
|
35
|
-
return 'invalid';
|
|
36
|
-
};
|
|
37
|
-
let format = detectFormat(osm);
|
|
38
|
-
const refElements = new utils_1.RefElements();
|
|
39
|
-
let featureArray = [];
|
|
40
|
-
const analyzeFeaturesFromJson = (o) => {
|
|
41
|
-
for (const elem of osm.elements) {
|
|
42
|
-
switch (elem.type) {
|
|
43
|
-
case 'node':
|
|
44
|
-
const node = new osmobjs_1.Node(elem.id, refElements);
|
|
45
|
-
if (elem.tags) {
|
|
46
|
-
node.addTags(elem.tags);
|
|
47
|
-
}
|
|
48
|
-
node.addProps((0, utils_1.purgeProps)(elem, ['id', 'type', 'tags', 'lat', 'lon']));
|
|
49
|
-
node.setLatLng(elem);
|
|
50
|
-
break;
|
|
51
|
-
case 'way':
|
|
52
|
-
const way = new osmobjs_1.Way(elem.id, refElements);
|
|
53
|
-
if (elem.tags) {
|
|
54
|
-
way.addTags(elem.tags);
|
|
55
|
-
}
|
|
56
|
-
way.addProps((0, utils_1.purgeProps)(elem, ['id', 'type', 'tags', 'nodes', 'geometry']));
|
|
57
|
-
if (elem.geometry) {
|
|
58
|
-
way.setLatLngArray(elem.geometry);
|
|
59
|
-
}
|
|
60
|
-
else if (elem.nodes) {
|
|
61
|
-
for (const n of elem.nodes) {
|
|
62
|
-
way.addNodeRef(n);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
break;
|
|
66
|
-
case 'relation':
|
|
67
|
-
const relation = new osmobjs_1.Relation(elem.id, refElements);
|
|
68
|
-
if (elem.bounds) {
|
|
69
|
-
relation.setBounds([parseFloat(elem.bounds.minlon), parseFloat(elem.bounds.minlat), parseFloat(elem.bounds.maxlon), parseFloat(elem.bounds.maxlat)]);
|
|
70
|
-
}
|
|
71
|
-
if (elem.tags) {
|
|
72
|
-
relation.addTags(elem.tags);
|
|
73
|
-
}
|
|
74
|
-
relation.addProps((0, utils_1.purgeProps)(elem, ['id', 'type', 'tags', 'bounds', 'members']));
|
|
75
|
-
if (elem.members) {
|
|
76
|
-
for (const member of elem.members) {
|
|
77
|
-
relation.addMember(member);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
default:
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
const analyzeFeaturesFromXml = (o) => {
|
|
86
|
-
const xmlParser = new xmlparser_1.default({ progressive: true });
|
|
87
|
-
xmlParser.on('</osm.node>', (node) => {
|
|
88
|
-
const nd = new osmobjs_1.Node(node.id, refElements);
|
|
89
|
-
for (const [k, v] of Object.entries(node)) {
|
|
90
|
-
if (!k.startsWith('$') && ['id', 'lon', 'lat'].indexOf(k) < 0) {
|
|
91
|
-
nd.addProp(k, v);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
nd.setLatLng(node);
|
|
95
|
-
if (node.$innerNodes) {
|
|
96
|
-
for (const ind of node.$innerNodes) {
|
|
97
|
-
if (ind.$tag === 'tag') {
|
|
98
|
-
nd.addTag(ind.k, ind.v);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
xmlParser.on('</osm.way>', (node) => {
|
|
104
|
-
const way = new osmobjs_1.Way(node.id, refElements);
|
|
105
|
-
for (const [k, v] of Object.entries(node)) {
|
|
106
|
-
if (!k.startsWith('$') && ['id'].indexOf(k) < 0) {
|
|
107
|
-
way.addProp(k, v);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (node.$innerNodes) {
|
|
111
|
-
for (const ind of node.$innerNodes) {
|
|
112
|
-
if (ind.$tag === 'nd') {
|
|
113
|
-
if (ind.lon && ind.lat) {
|
|
114
|
-
way.addLatLng(ind);
|
|
115
|
-
}
|
|
116
|
-
else if (ind.ref) {
|
|
117
|
-
way.addNodeRef(ind.ref);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
else if (ind.$tag === 'tag') {
|
|
121
|
-
way.addTag(ind.k, ind.v);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
xmlParser.on('<osm.relation>', (node) => new osmobjs_1.Relation(node.id, refElements));
|
|
127
|
-
xmlParser.on('</osm.relation.member>', (node, parent) => {
|
|
128
|
-
const relation = refElements.get(`relation/${parent === null || parent === void 0 ? void 0 : parent.id}`);
|
|
129
|
-
const member = {
|
|
130
|
-
type: node.type,
|
|
131
|
-
role: node.role ? node.role : '',
|
|
132
|
-
ref: node.ref,
|
|
133
|
-
};
|
|
134
|
-
if (node.lat && node.lon) {
|
|
135
|
-
member.lat = node.lat, member.lon = node.lon, member.tags = {};
|
|
136
|
-
for (const [k, v] of Object.entries(node)) {
|
|
137
|
-
if (!k.startsWith('$') && ['type', 'lat', 'lon'].indexOf(k) < 0) {
|
|
138
|
-
member[k] = v;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (node.$innerNodes) {
|
|
143
|
-
const geometry = [];
|
|
144
|
-
const nodes = [];
|
|
145
|
-
for (const ind of node.$innerNodes) {
|
|
146
|
-
if (ind.lat && ind.lon) {
|
|
147
|
-
geometry.push(ind);
|
|
148
|
-
}
|
|
149
|
-
else if (ind.ref) {
|
|
150
|
-
nodes.push(ind.ref);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
if (geometry.length > 0) {
|
|
154
|
-
member.geometry = geometry;
|
|
155
|
-
}
|
|
156
|
-
else if (nodes.length > 0) {
|
|
157
|
-
member.nodes = nodes;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
relation.addMember(member);
|
|
161
|
-
});
|
|
162
|
-
xmlParser.on('</osm.relation.bounds>', (node, parent) => {
|
|
163
|
-
refElements.get(`relation/${parent === null || parent === void 0 ? void 0 : parent.id}`).setBounds([parseFloat(node.minlon), parseFloat(node.minlat), parseFloat(node.maxlon), parseFloat(node.maxlat)]);
|
|
164
|
-
});
|
|
165
|
-
xmlParser.on('</osm.relation.tag>', (node, parent) => {
|
|
166
|
-
refElements.get(`relation/${parent === null || parent === void 0 ? void 0 : parent.id}`).addTag(node.k, node.v);
|
|
167
|
-
});
|
|
168
|
-
xmlParser.parse(o);
|
|
169
|
-
};
|
|
170
|
-
if (format === 'json-raw') {
|
|
171
|
-
osm = JSON.parse(osm);
|
|
172
|
-
if (osm.elements) {
|
|
173
|
-
format = 'json';
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
format = 'invalid';
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
if (format === 'json') {
|
|
180
|
-
analyzeFeaturesFromJson(osm);
|
|
181
|
-
}
|
|
182
|
-
else if (format === 'xml') {
|
|
183
|
-
analyzeFeaturesFromXml(osm);
|
|
184
|
-
}
|
|
185
|
-
refElements.bindAll();
|
|
186
|
-
for (const v of refElements.values()) {
|
|
187
|
-
if (v.refCount <= 0 || (v.hasTag && renderTagged && !(v instanceof osmobjs_1.Way && excludeWay))) {
|
|
188
|
-
const features = v.toFeatureArray();
|
|
189
|
-
// return the first geometry of the first relation element
|
|
190
|
-
if (v instanceof osmobjs_1.Relation && !completeFeature && features.length > 0) {
|
|
191
|
-
return features[0].geometry;
|
|
192
|
-
}
|
|
193
|
-
featureArray = featureArray.concat(features);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return { type: 'FeatureCollection', features: featureArray };
|
|
197
|
-
}
|
|
198
|
-
;
|
|
199
|
-
module.exports = osm2geojson;
|
package/dist/node/osmobjs.js
DELETED
|
@@ -1,377 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Relation = exports.Way = exports.Node = void 0;
|
|
7
|
-
const utils_1 = require("./utils");
|
|
8
|
-
const utils_2 = require("./utils");
|
|
9
|
-
const polytags_json_1 = __importDefault(require("./polytags.json"));
|
|
10
|
-
class OsmObject {
|
|
11
|
-
constructor(type, id, refElems) {
|
|
12
|
-
this.type = type;
|
|
13
|
-
this.id = id;
|
|
14
|
-
this.refElems = refElems;
|
|
15
|
-
this.tags = {};
|
|
16
|
-
this.props = { id: this.getCompositeId() };
|
|
17
|
-
this.refCount = 0;
|
|
18
|
-
this.hasTag = false;
|
|
19
|
-
if (refElems) {
|
|
20
|
-
refElems.add(this.getCompositeId(), this);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
addTags(tags) {
|
|
24
|
-
this.tags = Object.assign(this.tags, tags);
|
|
25
|
-
this.hasTag = tags ? true : false;
|
|
26
|
-
}
|
|
27
|
-
addTag(k, v) {
|
|
28
|
-
this.tags[k] = v;
|
|
29
|
-
this.hasTag = k ? true : false;
|
|
30
|
-
}
|
|
31
|
-
addProp(k, v) {
|
|
32
|
-
this.props[k] = v;
|
|
33
|
-
}
|
|
34
|
-
addProps(props) {
|
|
35
|
-
this.props = Object.assign(this.props, props);
|
|
36
|
-
}
|
|
37
|
-
getCompositeId() {
|
|
38
|
-
return `${this.type}/${this.id}`;
|
|
39
|
-
}
|
|
40
|
-
getProps() {
|
|
41
|
-
return Object.assign(this.props, this.tags);
|
|
42
|
-
}
|
|
43
|
-
toFeatureArray() {
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
class Node extends OsmObject {
|
|
48
|
-
constructor(id, refElems) {
|
|
49
|
-
super('node', id, refElems);
|
|
50
|
-
this.latLng = null;
|
|
51
|
-
}
|
|
52
|
-
setLatLng(latLng) {
|
|
53
|
-
this.latLng = latLng;
|
|
54
|
-
}
|
|
55
|
-
toFeatureArray() {
|
|
56
|
-
if (this.latLng) {
|
|
57
|
-
return [{
|
|
58
|
-
type: 'Feature',
|
|
59
|
-
id: this.getCompositeId(),
|
|
60
|
-
properties: this.getProps(),
|
|
61
|
-
geometry: {
|
|
62
|
-
type: 'Point',
|
|
63
|
-
coordinates: (0, utils_1.strToFloat)([this.latLng.lon, this.latLng.lat]),
|
|
64
|
-
},
|
|
65
|
-
}];
|
|
66
|
-
}
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
|
-
getLatLng() {
|
|
70
|
-
return this.latLng;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
exports.Node = Node;
|
|
74
|
-
class Way extends OsmObject {
|
|
75
|
-
constructor(id, refElems) {
|
|
76
|
-
super('way', id, refElems);
|
|
77
|
-
this.latLngArray = [];
|
|
78
|
-
this.isPolygon = false;
|
|
79
|
-
}
|
|
80
|
-
addLatLng(latLng) {
|
|
81
|
-
this.latLngArray.push(latLng);
|
|
82
|
-
}
|
|
83
|
-
setLatLngArray(latLngArray) {
|
|
84
|
-
this.latLngArray = latLngArray;
|
|
85
|
-
}
|
|
86
|
-
addNodeRef(ref) {
|
|
87
|
-
const binder = new utils_2.LateBinder(this.latLngArray, (id) => {
|
|
88
|
-
const node = this.refElems.get(`node/${id}`);
|
|
89
|
-
if (node) {
|
|
90
|
-
node.refCount++;
|
|
91
|
-
return node.getLatLng();
|
|
92
|
-
}
|
|
93
|
-
}, this, [ref]);
|
|
94
|
-
this.latLngArray.push(binder);
|
|
95
|
-
this.refElems.addBinder(binder);
|
|
96
|
-
}
|
|
97
|
-
addTags(tags) {
|
|
98
|
-
super.addTags(tags);
|
|
99
|
-
for (const [k, v] of Object.entries(tags)) {
|
|
100
|
-
this.analyzeTag(k, v);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
addTag(k, v) {
|
|
104
|
-
super.addTag(k, v);
|
|
105
|
-
this.analyzeTag(k, v);
|
|
106
|
-
}
|
|
107
|
-
toCoordsArray() {
|
|
108
|
-
return this.latLngArray.map((latLng) => [latLng.lon, latLng.lat]);
|
|
109
|
-
}
|
|
110
|
-
toFeatureArray() {
|
|
111
|
-
let coordsArray = this.toCoordsArray();
|
|
112
|
-
if (coordsArray.length > 1) {
|
|
113
|
-
coordsArray = (0, utils_1.strToFloat)(coordsArray);
|
|
114
|
-
const feature = {
|
|
115
|
-
type: 'Feature',
|
|
116
|
-
id: this.getCompositeId(),
|
|
117
|
-
properties: this.getProps(),
|
|
118
|
-
geometry: {
|
|
119
|
-
type: 'LineString',
|
|
120
|
-
coordinates: coordsArray,
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
if (this.isPolygon && (0, utils_1.isRing)(coordsArray)) {
|
|
124
|
-
if ((0, utils_1.ringDirection)(coordsArray) !== 'counterclockwise') {
|
|
125
|
-
coordsArray.reverse();
|
|
126
|
-
}
|
|
127
|
-
feature.geometry = {
|
|
128
|
-
type: 'Polygon',
|
|
129
|
-
coordinates: [coordsArray],
|
|
130
|
-
};
|
|
131
|
-
return [feature];
|
|
132
|
-
}
|
|
133
|
-
return [feature];
|
|
134
|
-
}
|
|
135
|
-
return [];
|
|
136
|
-
}
|
|
137
|
-
analyzeTag(k, v) {
|
|
138
|
-
const o = polytags_json_1.default[k];
|
|
139
|
-
if (o) {
|
|
140
|
-
this.isPolygon = true;
|
|
141
|
-
if (o.whitelist) {
|
|
142
|
-
this.isPolygon = o.whitelist.indexOf(v) >= 0 ? true : false;
|
|
143
|
-
}
|
|
144
|
-
else if (o.blacklist) {
|
|
145
|
-
this.isPolygon = o.blacklist.indexOf(v) >= 0 ? false : true;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
exports.Way = Way;
|
|
151
|
-
class Relation extends OsmObject {
|
|
152
|
-
constructor(id, refElems) {
|
|
153
|
-
super('relation', id, refElems);
|
|
154
|
-
this.relations = [];
|
|
155
|
-
this.nodes = [];
|
|
156
|
-
this.bounds = undefined;
|
|
157
|
-
}
|
|
158
|
-
setBounds(bounds) {
|
|
159
|
-
this.bounds = bounds;
|
|
160
|
-
}
|
|
161
|
-
addMember(member) {
|
|
162
|
-
switch (member.type) {
|
|
163
|
-
// super relation, need to do combination
|
|
164
|
-
case 'relation':
|
|
165
|
-
let binder = new utils_2.LateBinder(this.relations, (id) => {
|
|
166
|
-
const relation = this.refElems.get(`relation/${id}`);
|
|
167
|
-
if (relation) {
|
|
168
|
-
relation.refCount++;
|
|
169
|
-
return relation;
|
|
170
|
-
}
|
|
171
|
-
}, this, [member.ref]);
|
|
172
|
-
this.relations.push(binder);
|
|
173
|
-
this.refElems.addBinder(binder);
|
|
174
|
-
break;
|
|
175
|
-
case 'way':
|
|
176
|
-
if (!member.role) {
|
|
177
|
-
member.role = '';
|
|
178
|
-
}
|
|
179
|
-
let ways = this[member.role];
|
|
180
|
-
if (!ways) {
|
|
181
|
-
ways = this[member.role] = [];
|
|
182
|
-
}
|
|
183
|
-
if (member.geometry) {
|
|
184
|
-
const way = new Way(member.ref, this.refElems);
|
|
185
|
-
way.setLatLngArray(member.geometry);
|
|
186
|
-
way.refCount++;
|
|
187
|
-
ways.push(way);
|
|
188
|
-
}
|
|
189
|
-
else if (member.nodes) {
|
|
190
|
-
const way = new Way(member.ref, this.refElems);
|
|
191
|
-
for (const nid of member.nodes) {
|
|
192
|
-
way.addNodeRef(nid);
|
|
193
|
-
}
|
|
194
|
-
way.refCount++;
|
|
195
|
-
ways.push(way);
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
let binder = new utils_2.LateBinder(ways, (nid) => {
|
|
199
|
-
const way = this.refElems.get(`way/${nid}`);
|
|
200
|
-
if (way) {
|
|
201
|
-
way.refCount++;
|
|
202
|
-
return way;
|
|
203
|
-
}
|
|
204
|
-
}, this, [member.ref]);
|
|
205
|
-
ways.push(binder);
|
|
206
|
-
this.refElems.addBinder(binder);
|
|
207
|
-
}
|
|
208
|
-
break;
|
|
209
|
-
case 'node':
|
|
210
|
-
let node = null;
|
|
211
|
-
if (member.lat && member.lon) {
|
|
212
|
-
node = new Node(member.ref, this.refElems);
|
|
213
|
-
node.setLatLng({ lon: member.lon, lat: member.lat });
|
|
214
|
-
if (member.tags) {
|
|
215
|
-
node.addTags(member.tags);
|
|
216
|
-
}
|
|
217
|
-
for (const [k, v] of Object.entries(member)) {
|
|
218
|
-
if (['id', 'type', 'lat', 'lon'].indexOf(k) < 0) {
|
|
219
|
-
node.addProp(k, v);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
node.refCount++;
|
|
223
|
-
this.nodes.push(node);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
let binder = new utils_2.LateBinder(this.nodes, (id) => {
|
|
227
|
-
const nn = this.refElems.get(`node/${id}`);
|
|
228
|
-
if (nn) {
|
|
229
|
-
nn.refCount++;
|
|
230
|
-
return nn;
|
|
231
|
-
}
|
|
232
|
-
}, this, [member.ref]);
|
|
233
|
-
this.nodes.push(binder);
|
|
234
|
-
this.refElems.addBinder(binder);
|
|
235
|
-
}
|
|
236
|
-
default:
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
toFeatureArray() {
|
|
241
|
-
function constructStringGeometry(ws) {
|
|
242
|
-
const strings = ws ? ws.toStrings() : [];
|
|
243
|
-
if (strings.length > 0) {
|
|
244
|
-
if (strings.length === 1) {
|
|
245
|
-
return {
|
|
246
|
-
type: 'LineString',
|
|
247
|
-
coordinates: strings[0],
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
return {
|
|
251
|
-
type: 'MultiLineString',
|
|
252
|
-
coordinates: strings,
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
return null;
|
|
256
|
-
}
|
|
257
|
-
function constructPolygonGeometry(ows, iws) {
|
|
258
|
-
const outerRings = ows ? ows.toRings('counterclockwise') : [];
|
|
259
|
-
const innerRings = iws ? iws.toRings('clockwise') : [];
|
|
260
|
-
if (outerRings.length > 0) {
|
|
261
|
-
const compositPolyons = [];
|
|
262
|
-
let ring;
|
|
263
|
-
for (ring of outerRings) {
|
|
264
|
-
compositPolyons.push([ring]);
|
|
265
|
-
}
|
|
266
|
-
// link inner polygons to outer containers
|
|
267
|
-
ring = innerRings.shift();
|
|
268
|
-
while (ring) {
|
|
269
|
-
for (const idx in outerRings) {
|
|
270
|
-
if ((0, utils_1.ptInsidePolygon)((0, utils_1.first)(ring), outerRings[idx])) {
|
|
271
|
-
compositPolyons[idx].push(ring);
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
ring = innerRings.shift();
|
|
276
|
-
}
|
|
277
|
-
// construct the Polygon/MultiPolygon geometry
|
|
278
|
-
if (compositPolyons.length === 1) {
|
|
279
|
-
return {
|
|
280
|
-
type: 'Polygon',
|
|
281
|
-
coordinates: compositPolyons[0],
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
return {
|
|
285
|
-
type: 'MultiPolygon',
|
|
286
|
-
coordinates: compositPolyons,
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
return null;
|
|
290
|
-
}
|
|
291
|
-
const polygonFeatures = [];
|
|
292
|
-
const stringFeatures = [];
|
|
293
|
-
let pointFeatures = [];
|
|
294
|
-
// need to do combination when there're nested relations
|
|
295
|
-
const notWayFields = ['type', 'id', 'refElems', 'tags', 'props', 'refCount', 'hasTag', 'relations', 'nodes', 'bounds'];
|
|
296
|
-
for (const relation of this.relations) {
|
|
297
|
-
if (relation) {
|
|
298
|
-
let waysFieldNames = Object.keys(relation).filter(fieldName => notWayFields.indexOf(fieldName) < 0);
|
|
299
|
-
for (const fieldName of waysFieldNames) {
|
|
300
|
-
const ways = relation[fieldName];
|
|
301
|
-
if (ways) {
|
|
302
|
-
const thisWays = this[fieldName];
|
|
303
|
-
if (thisWays) {
|
|
304
|
-
thisWays.push(...ways);
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
307
|
-
this[fieldName] = ways;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
let waysFieldNames = Object.keys(this).filter(fieldName => notWayFields.indexOf(fieldName) < 0);
|
|
314
|
-
for (const fieldName of waysFieldNames) {
|
|
315
|
-
const ways = this[fieldName];
|
|
316
|
-
if (ways) {
|
|
317
|
-
this[fieldName] = new utils_2.WayCollection();
|
|
318
|
-
for (const way of ways) {
|
|
319
|
-
this[fieldName].addWay(way);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
let geometry = null;
|
|
324
|
-
let templateFeature = {
|
|
325
|
-
type: 'Feature',
|
|
326
|
-
id: this.getCompositeId(),
|
|
327
|
-
bbox: this.bounds,
|
|
328
|
-
properties: this.getProps(),
|
|
329
|
-
geometry: null
|
|
330
|
-
};
|
|
331
|
-
if (!this.bounds) {
|
|
332
|
-
delete templateFeature.bbox;
|
|
333
|
-
}
|
|
334
|
-
if (this.outer) {
|
|
335
|
-
let feature = Object.assign({}, templateFeature);
|
|
336
|
-
let geometry = constructPolygonGeometry(this.outer, this.inner);
|
|
337
|
-
if (geometry) {
|
|
338
|
-
feature.geometry = geometry;
|
|
339
|
-
polygonFeatures.push(feature);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
else {
|
|
343
|
-
let multiLineGeometry = {
|
|
344
|
-
type: 'MultiLineString',
|
|
345
|
-
coordinates: []
|
|
346
|
-
};
|
|
347
|
-
for (let way of waysFieldNames) {
|
|
348
|
-
if (way != null && way !== 'inner') {
|
|
349
|
-
let ws = this[way];
|
|
350
|
-
if (ws) {
|
|
351
|
-
let geometry = constructStringGeometry(ws);
|
|
352
|
-
if (geometry) {
|
|
353
|
-
if (geometry.type === 'LineString') {
|
|
354
|
-
multiLineGeometry.coordinates.push(geometry.coordinates);
|
|
355
|
-
}
|
|
356
|
-
else if (geometry.type === 'MultiLineString') {
|
|
357
|
-
let feature = Object.assign({}, templateFeature);
|
|
358
|
-
feature.geometry = geometry;
|
|
359
|
-
stringFeatures.push(feature);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
if (multiLineGeometry.coordinates.length > 0) {
|
|
366
|
-
let feature = Object.assign({}, templateFeature);
|
|
367
|
-
feature.geometry = multiLineGeometry;
|
|
368
|
-
stringFeatures.push(feature);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
for (let node of this.nodes) {
|
|
372
|
-
pointFeatures = pointFeatures.concat(node.toFeatureArray());
|
|
373
|
-
}
|
|
374
|
-
return [...polygonFeatures, ...stringFeatures, ...pointFeatures];
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
exports.Relation = Relation;
|
package/dist/node/polytags.json
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"building": {},
|
|
3
|
-
"highway": {
|
|
4
|
-
"whitelist": [
|
|
5
|
-
"services",
|
|
6
|
-
"rest_area",
|
|
7
|
-
"escape",
|
|
8
|
-
"elevator"
|
|
9
|
-
]
|
|
10
|
-
},
|
|
11
|
-
"natural": {
|
|
12
|
-
"blacklist": [
|
|
13
|
-
"coastline",
|
|
14
|
-
"cliff",
|
|
15
|
-
"ridge",
|
|
16
|
-
"arete",
|
|
17
|
-
"tree_row"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
"landuse": {},
|
|
21
|
-
"waterway": {
|
|
22
|
-
"whitelist": [
|
|
23
|
-
"riverbank",
|
|
24
|
-
"dock",
|
|
25
|
-
"boatyard",
|
|
26
|
-
"dam"
|
|
27
|
-
]
|
|
28
|
-
},
|
|
29
|
-
"amenity": {},
|
|
30
|
-
"leisure": {},
|
|
31
|
-
"barrier": {
|
|
32
|
-
"whitelist": [
|
|
33
|
-
"city_wall",
|
|
34
|
-
"ditch",
|
|
35
|
-
"hedge",
|
|
36
|
-
"retaining_wall",
|
|
37
|
-
"wall",
|
|
38
|
-
"spikes"
|
|
39
|
-
]
|
|
40
|
-
},
|
|
41
|
-
"railway": {
|
|
42
|
-
"whitelist": [
|
|
43
|
-
"station",
|
|
44
|
-
"turntable",
|
|
45
|
-
"roundhouse",
|
|
46
|
-
"platform"
|
|
47
|
-
]
|
|
48
|
-
},
|
|
49
|
-
"area": {},
|
|
50
|
-
"boundary": {},
|
|
51
|
-
"man_made": {
|
|
52
|
-
"blacklist": [
|
|
53
|
-
"cutline",
|
|
54
|
-
"embankment",
|
|
55
|
-
"pipeline"
|
|
56
|
-
]
|
|
57
|
-
},
|
|
58
|
-
"power": {
|
|
59
|
-
"whitelist": [
|
|
60
|
-
"plant",
|
|
61
|
-
"substation",
|
|
62
|
-
"generator",
|
|
63
|
-
"transformer"
|
|
64
|
-
]
|
|
65
|
-
},
|
|
66
|
-
"place": {},
|
|
67
|
-
"shop": {},
|
|
68
|
-
"aeroway": {
|
|
69
|
-
"blacklist": [
|
|
70
|
-
"taxiway"
|
|
71
|
-
]
|
|
72
|
-
},
|
|
73
|
-
"tourism": {},
|
|
74
|
-
"historic": {},
|
|
75
|
-
"public_transport": {},
|
|
76
|
-
"office": {},
|
|
77
|
-
"building:part": {},
|
|
78
|
-
"military": {},
|
|
79
|
-
"ruins": {},
|
|
80
|
-
"area:highway": {},
|
|
81
|
-
"craft": {},
|
|
82
|
-
"golf": {},
|
|
83
|
-
"indoor": {}
|
|
84
|
-
}
|
package/dist/node/utils.js
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WayCollection = exports.RefElements = exports.LateBinder = exports.strToFloat = exports.ptInsidePolygon = exports.ringDirection = exports.isRing = exports.coordsToKey = exports.last = exports.first = void 0;
|
|
4
|
-
exports.purgeProps = purgeProps;
|
|
5
|
-
exports.mergeProps = mergeProps;
|
|
6
|
-
exports.addPropToFeature = addPropToFeature;
|
|
7
|
-
exports.addPropToFeatures = addPropToFeatures;
|
|
8
|
-
exports.addToMap = addToMap;
|
|
9
|
-
exports.removeFromMap = removeFromMap;
|
|
10
|
-
exports.getFirstFromMap = getFirstFromMap;
|
|
11
|
-
function purgeProps(obj, blacklist) {
|
|
12
|
-
if (obj) {
|
|
13
|
-
const rs = Object.assign({}, obj);
|
|
14
|
-
if (blacklist) {
|
|
15
|
-
for (const prop of blacklist) {
|
|
16
|
-
delete rs[prop];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return rs;
|
|
20
|
-
}
|
|
21
|
-
return {};
|
|
22
|
-
}
|
|
23
|
-
function mergeProps(obj1, obj2) {
|
|
24
|
-
obj1 = obj1 ? obj1 : {};
|
|
25
|
-
obj2 = obj2 ? obj2 : {};
|
|
26
|
-
return Object.assign(obj1, obj2);
|
|
27
|
-
}
|
|
28
|
-
function addPropToFeature(f, k, v) {
|
|
29
|
-
if (f.properties && k && v) {
|
|
30
|
-
f.properties[k] = v;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function addPropToFeatures(fs, k, v) {
|
|
34
|
-
for (const f of fs) {
|
|
35
|
-
addPropToFeature(f, k, v);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const first = (a) => a[0];
|
|
39
|
-
exports.first = first;
|
|
40
|
-
const last = (a) => a[a.length - 1];
|
|
41
|
-
exports.last = last;
|
|
42
|
-
const coordsToKey = (a) => a.join(',');
|
|
43
|
-
exports.coordsToKey = coordsToKey;
|
|
44
|
-
function addToMap(m, k, v) {
|
|
45
|
-
const a = m[k];
|
|
46
|
-
if (a) {
|
|
47
|
-
a.push(v);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
m[k] = [v];
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function removeFromMap(m, k, v) {
|
|
54
|
-
const a = m[k];
|
|
55
|
-
let idx = -1;
|
|
56
|
-
if (a) {
|
|
57
|
-
idx = a.indexOf(v);
|
|
58
|
-
}
|
|
59
|
-
if (idx >= 0) {
|
|
60
|
-
a.splice(idx, 1);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function getFirstFromMap(m, k) {
|
|
64
|
-
const a = m[k];
|
|
65
|
-
if (a && a.length > 0) {
|
|
66
|
-
return a[0];
|
|
67
|
-
}
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
// need 3+ different points to form a ring, here using > 3 is 'coz a the first and the last points are actually the same
|
|
71
|
-
const isRing = (a) => a.length > 3 && (0, exports.coordsToKey)((0, exports.first)(a)) === (0, exports.coordsToKey)((0, exports.last)(a));
|
|
72
|
-
exports.isRing = isRing;
|
|
73
|
-
const ringDirection = (a, xIdx, yIdx) => {
|
|
74
|
-
xIdx = xIdx || 0, yIdx = yIdx || 1;
|
|
75
|
-
// get the index of the point which has the maximum x value
|
|
76
|
-
const m = a.reduce((maxxIdx, v, idx) => a[maxxIdx][xIdx || 0] > v[xIdx || 0] ? maxxIdx : idx, 0);
|
|
77
|
-
// 'coz the first point is virtually the same one as the last point,
|
|
78
|
-
// we need to skip a.length - 1 for left when m = 0,
|
|
79
|
-
// and skip 0 for right when m = a.length - 1;
|
|
80
|
-
const l = m <= 0 ? a.length - 2 : m - 1;
|
|
81
|
-
const r = m >= a.length - 1 ? 1 : m + 1;
|
|
82
|
-
const xa = a[l][xIdx];
|
|
83
|
-
const xb = a[m][xIdx];
|
|
84
|
-
const xc = a[r][xIdx];
|
|
85
|
-
const ya = a[l][yIdx];
|
|
86
|
-
const yb = a[m][yIdx];
|
|
87
|
-
const yc = a[r][yIdx];
|
|
88
|
-
const det = (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya);
|
|
89
|
-
return det < 0 ? 'clockwise' : 'counterclockwise';
|
|
90
|
-
};
|
|
91
|
-
exports.ringDirection = ringDirection;
|
|
92
|
-
const ptInsidePolygon = (pt, polygon, xIdx, yIdx) => {
|
|
93
|
-
xIdx = xIdx || 0, yIdx = yIdx || 1;
|
|
94
|
-
let result = false;
|
|
95
|
-
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
96
|
-
if ((polygon[i][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[j][xIdx] ||
|
|
97
|
-
polygon[j][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[i][xIdx]) &&
|
|
98
|
-
pt[yIdx] < (polygon[j][yIdx] - polygon[i][yIdx]) * (pt[xIdx] - polygon[i][xIdx]) / (polygon[j][xIdx] - polygon[i][xIdx]) + polygon[i][yIdx]) {
|
|
99
|
-
result = !result;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return result;
|
|
103
|
-
};
|
|
104
|
-
exports.ptInsidePolygon = ptInsidePolygon;
|
|
105
|
-
const strToFloat = (el) => el instanceof Array ? el.map(exports.strToFloat) : parseFloat(el);
|
|
106
|
-
exports.strToFloat = strToFloat;
|
|
107
|
-
class LateBinder {
|
|
108
|
-
constructor(container, valueFunc, ctx, args) {
|
|
109
|
-
this.container = container;
|
|
110
|
-
this.valueFunc = valueFunc;
|
|
111
|
-
this.ctx = ctx;
|
|
112
|
-
this.args = args;
|
|
113
|
-
}
|
|
114
|
-
bind() {
|
|
115
|
-
const v = this.valueFunc.apply(this.ctx, this.args);
|
|
116
|
-
if (this.container instanceof Array) {
|
|
117
|
-
const idx = this.container.indexOf(this);
|
|
118
|
-
if (idx >= 0) {
|
|
119
|
-
const args = [idx, 1];
|
|
120
|
-
if (v) {
|
|
121
|
-
args.push(v);
|
|
122
|
-
}
|
|
123
|
-
Array.prototype.splice.apply(this.container, args);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
else if (typeof this.container === 'object' && !Array.isArray(this.container)) {
|
|
127
|
-
const container = this.container;
|
|
128
|
-
const k = Object.keys(container).find((nv) => container[nv] === this);
|
|
129
|
-
if (k) {
|
|
130
|
-
if (v) {
|
|
131
|
-
container[k] = v;
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
delete container[k];
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
exports.LateBinder = LateBinder;
|
|
141
|
-
class RefElements extends Map {
|
|
142
|
-
constructor() {
|
|
143
|
-
super();
|
|
144
|
-
this.binders = [];
|
|
145
|
-
}
|
|
146
|
-
add(k, v) {
|
|
147
|
-
this.set(k, v);
|
|
148
|
-
}
|
|
149
|
-
addBinder(binder) {
|
|
150
|
-
this.binders.push(binder);
|
|
151
|
-
}
|
|
152
|
-
bindAll() {
|
|
153
|
-
this.binders.forEach((binder) => binder.bind());
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
exports.RefElements = RefElements;
|
|
157
|
-
class WayCollection extends Array {
|
|
158
|
-
constructor() {
|
|
159
|
-
super();
|
|
160
|
-
this.firstMap = {};
|
|
161
|
-
this.lastMap = {};
|
|
162
|
-
}
|
|
163
|
-
addWay(way) {
|
|
164
|
-
const w = way.toCoordsArray();
|
|
165
|
-
if (w.length > 0) {
|
|
166
|
-
this.push(w);
|
|
167
|
-
addToMap(this.firstMap, (0, exports.coordsToKey)((0, exports.first)(w)), w);
|
|
168
|
-
addToMap(this.lastMap, (0, exports.coordsToKey)((0, exports.last)(w)), w);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
toStrings() {
|
|
172
|
-
const strings = [];
|
|
173
|
-
let way = this.shift();
|
|
174
|
-
while (way) {
|
|
175
|
-
removeFromMap(this.firstMap, (0, exports.coordsToKey)((0, exports.first)(way)), way);
|
|
176
|
-
removeFromMap(this.lastMap, (0, exports.coordsToKey)((0, exports.last)(way)), way);
|
|
177
|
-
let current = way;
|
|
178
|
-
let next;
|
|
179
|
-
do {
|
|
180
|
-
const key = (0, exports.coordsToKey)((0, exports.last)(current));
|
|
181
|
-
let shouldReverse = false;
|
|
182
|
-
next = getFirstFromMap(this.firstMap, key);
|
|
183
|
-
if (!next) {
|
|
184
|
-
next = getFirstFromMap(this.lastMap, key);
|
|
185
|
-
shouldReverse = true;
|
|
186
|
-
}
|
|
187
|
-
if (next) {
|
|
188
|
-
this.splice(this.indexOf(next), 1);
|
|
189
|
-
removeFromMap(this.firstMap, (0, exports.coordsToKey)((0, exports.first)(next)), next);
|
|
190
|
-
removeFromMap(this.lastMap, (0, exports.coordsToKey)((0, exports.last)(next)), next);
|
|
191
|
-
if (shouldReverse) {
|
|
192
|
-
// always reverse shorter one to save time
|
|
193
|
-
if (next.length > current.length) {
|
|
194
|
-
[current, next] = [next, current];
|
|
195
|
-
}
|
|
196
|
-
next.reverse();
|
|
197
|
-
}
|
|
198
|
-
current = current.concat(next.slice(1));
|
|
199
|
-
}
|
|
200
|
-
} while (next);
|
|
201
|
-
strings.push((0, exports.strToFloat)(current));
|
|
202
|
-
way = this.shift();
|
|
203
|
-
}
|
|
204
|
-
return strings;
|
|
205
|
-
}
|
|
206
|
-
toRings(direction) {
|
|
207
|
-
const strings = this.toStrings();
|
|
208
|
-
const rings = [];
|
|
209
|
-
let str = strings.shift();
|
|
210
|
-
while (str) {
|
|
211
|
-
if ((0, exports.isRing)(str)) {
|
|
212
|
-
if ((0, exports.ringDirection)(str) !== direction) {
|
|
213
|
-
str.reverse();
|
|
214
|
-
}
|
|
215
|
-
rings.push(str);
|
|
216
|
-
}
|
|
217
|
-
str = strings.shift();
|
|
218
|
-
}
|
|
219
|
-
return rings;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
exports.WayCollection = WayCollection;
|
package/dist/node/xmlparser.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
function conditioned(evt) {
|
|
4
|
-
return evt.match(/^(.+?)\[(.+?)\]>$/g) !== null;
|
|
5
|
-
}
|
|
6
|
-
function parseEvent(evt) {
|
|
7
|
-
const match = /^(.+?)\[(.+?)\]>$/g.exec(evt);
|
|
8
|
-
if (match) {
|
|
9
|
-
return { evt: match[1] + '>', exp: match[2] };
|
|
10
|
-
}
|
|
11
|
-
return { evt };
|
|
12
|
-
}
|
|
13
|
-
function genConditionFunc(cond) {
|
|
14
|
-
const body = 'return ' + cond.replace(/(\$.+?)(?=[=!.])/g, 'node.$&') + ';';
|
|
15
|
-
return new Function('node', body);
|
|
16
|
-
}
|
|
17
|
-
class default_1 {
|
|
18
|
-
constructor(opts) {
|
|
19
|
-
this.queryParent = false;
|
|
20
|
-
this.progressive = false;
|
|
21
|
-
this.parentMap = new WeakMap();
|
|
22
|
-
if (opts) {
|
|
23
|
-
this.queryParent = opts.queryParent ? true : false;
|
|
24
|
-
this.progressive = opts.progressive;
|
|
25
|
-
if (this.queryParent) {
|
|
26
|
-
this.parentMap = new WeakMap();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
this.evtListeners = {};
|
|
30
|
-
}
|
|
31
|
-
parse(xml, parent, dir) {
|
|
32
|
-
dir = dir ? dir + '.' : '';
|
|
33
|
-
const nodeRegEx = /<([^ >\/]+)(.*?)>/mg;
|
|
34
|
-
const nodes = [];
|
|
35
|
-
let nodeMatch = nodeRegEx.exec(xml);
|
|
36
|
-
while (nodeMatch) {
|
|
37
|
-
const tag = nodeMatch[1];
|
|
38
|
-
const node = { $tag: tag };
|
|
39
|
-
const fullTag = dir + tag;
|
|
40
|
-
const attrText = nodeMatch[2].trim();
|
|
41
|
-
let closed = false;
|
|
42
|
-
if (attrText.endsWith('/') || tag.startsWith('?') || tag.startsWith('!')) {
|
|
43
|
-
closed = true;
|
|
44
|
-
}
|
|
45
|
-
const attRegEx1 = /([^ ]+?)="(.+?)"/g;
|
|
46
|
-
const attRegEx2 = /([^ ]+?)='(.+?)'/g;
|
|
47
|
-
let attMatch = attRegEx1.exec(attrText);
|
|
48
|
-
let hasAttrs = false;
|
|
49
|
-
while (attMatch) {
|
|
50
|
-
hasAttrs = true;
|
|
51
|
-
node[attMatch[1]] = attMatch[2];
|
|
52
|
-
attMatch = attRegEx1.exec(attrText);
|
|
53
|
-
}
|
|
54
|
-
if (!hasAttrs) {
|
|
55
|
-
attMatch = attRegEx2.exec(attrText);
|
|
56
|
-
while (attMatch) {
|
|
57
|
-
hasAttrs = true;
|
|
58
|
-
node[attMatch[1]] = attMatch[2];
|
|
59
|
-
attMatch = attRegEx2.exec(attrText);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (!hasAttrs && attrText !== '') {
|
|
63
|
-
node.text = attrText;
|
|
64
|
-
}
|
|
65
|
-
if (this.progressive) {
|
|
66
|
-
this.emit(`<${fullTag}>`, node, parent);
|
|
67
|
-
}
|
|
68
|
-
if (!closed) {
|
|
69
|
-
const innerRegEx = new RegExp(`([^]+?)<\/${tag}>`, 'g');
|
|
70
|
-
innerRegEx.lastIndex = nodeRegEx.lastIndex;
|
|
71
|
-
const innerMatch = innerRegEx.exec(xml);
|
|
72
|
-
if (innerMatch && innerMatch[1]) {
|
|
73
|
-
nodeRegEx.lastIndex = innerRegEx.lastIndex;
|
|
74
|
-
const innerNodes = this.parse(innerMatch[1], node, fullTag);
|
|
75
|
-
if (innerNodes.length > 0) {
|
|
76
|
-
node.$innerNodes = innerNodes;
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
node.$innerText = innerMatch[1];
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (this.queryParent && parent) {
|
|
84
|
-
this.parentMap.set(node, parent);
|
|
85
|
-
}
|
|
86
|
-
if (this.progressive) {
|
|
87
|
-
this.emit(`</${fullTag}>`, node, parent);
|
|
88
|
-
}
|
|
89
|
-
nodes.push(node);
|
|
90
|
-
nodeMatch = nodeRegEx.exec(xml);
|
|
91
|
-
}
|
|
92
|
-
return nodes;
|
|
93
|
-
}
|
|
94
|
-
getParent(node) {
|
|
95
|
-
if (this.queryParent) {
|
|
96
|
-
return this.parentMap.get(node);
|
|
97
|
-
}
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
// support javascript condition for the last tag
|
|
101
|
-
addListener(evt, func) {
|
|
102
|
-
if (conditioned(evt)) {
|
|
103
|
-
// func.prototype = evt;
|
|
104
|
-
const ev = parseEvent(evt);
|
|
105
|
-
if (ev.exp) {
|
|
106
|
-
func.condition = genConditionFunc(ev.exp);
|
|
107
|
-
}
|
|
108
|
-
evt = ev.evt;
|
|
109
|
-
}
|
|
110
|
-
this.$addListener(evt, func);
|
|
111
|
-
}
|
|
112
|
-
removeListener(evt, func) {
|
|
113
|
-
if (conditioned(evt)) {
|
|
114
|
-
const ev = parseEvent(evt);
|
|
115
|
-
evt = ev.evt;
|
|
116
|
-
}
|
|
117
|
-
this.$removeListener(evt, func);
|
|
118
|
-
}
|
|
119
|
-
on(evt, func) {
|
|
120
|
-
this.addListener(evt, func);
|
|
121
|
-
}
|
|
122
|
-
off(evt, func) {
|
|
123
|
-
this.removeListener(evt, func);
|
|
124
|
-
}
|
|
125
|
-
$addListener(evt, func) {
|
|
126
|
-
const funcs = this.evtListeners[evt];
|
|
127
|
-
if (funcs) {
|
|
128
|
-
funcs.push(func);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
this.evtListeners[evt] = [func];
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
$removeListener(evt, func) {
|
|
135
|
-
const funcs = this.evtListeners[evt];
|
|
136
|
-
let idx = -1;
|
|
137
|
-
if (funcs) {
|
|
138
|
-
idx = funcs.indexOf(func);
|
|
139
|
-
}
|
|
140
|
-
if (idx >= 0) {
|
|
141
|
-
funcs.splice(idx, 1);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
emit(evt, ...args) {
|
|
145
|
-
const funcs = this.evtListeners[evt];
|
|
146
|
-
if (funcs) {
|
|
147
|
-
for (const func of funcs) {
|
|
148
|
-
if (func.condition) {
|
|
149
|
-
if (func.condition.apply(null, args) === true) {
|
|
150
|
-
func.apply(null, args);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
func.apply(null, args);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
exports.default = default_1;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).osm2geojson=e()}(function(){return function s(i,o,n){function a(t,e){if(!o[t]){if(!i[t]){var r="function"==typeof require&&require;if(!e&&r)return r(t,!0);if(l)return l(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}r=o[t]={exports:{}},i[t][0].call(r.exports,function(e){return a(i[t][1][e]||e)},r,r.exports,s,i,o,n)}return o[t].exports}for(var l="function"==typeof require&&require,e=0;e<n.length;e++)a(n[e]);return a}({1:[function(e,t,r){let s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}},f=e("./osmobjs"),u=e("./utils"),p=s(e("./xmlparser"));t.exports=function(n,e){let t=!1,r=!1,s=!0,i=(e&&(e=e)&&(t=!(!e.completeFeature&&!e.allFeatures),r=!!e.renderTagged,void 0===(e=e.suppressWay||e.excludeWay)||e||(s=!1)),(e=n).elements?"json":0<=e.indexOf("<osm")?"xml":e.trim().startsWith("{")?"json-raw":"invalid"),l=new u.RefElements,o=[];var a,d;"json-raw"===i&&(n=JSON.parse(n),i=n.elements?"json":"invalid"),"json"===i?(()=>{for(var e of n.elements)switch(e.type){case"node":var t=new f.Node(e.id,l);e.tags&&t.addTags(e.tags),t.addProps((0,u.purgeProps)(e,["id","type","tags","lat","lon"])),t.setLatLng(e);break;case"way":var r=new f.Way(e.id,l);if(e.tags&&r.addTags(e.tags),r.addProps((0,u.purgeProps)(e,["id","type","tags","nodes","geometry"])),e.geometry)r.setLatLngArray(e.geometry);else if(e.nodes)for(var s of e.nodes)r.addNodeRef(s);break;case"relation":var i=new f.Relation(e.id,l);if(e.bounds&&i.setBounds([parseFloat(e.bounds.minlon),parseFloat(e.bounds.minlat),parseFloat(e.bounds.maxlon),parseFloat(e.bounds.maxlat)]),e.tags&&i.addTags(e.tags),i.addProps((0,u.purgeProps)(e,["id","type","tags","bounds","members"])),e.members)for(var o of e.members)i.addMember(o)}})():"xml"===i&&(e=n,(a=new p.default({progressive:!0})).on("</osm.node>",e=>{var t,r,s=new f.Node(e.id,l);for([t,r]of Object.entries(e))!t.startsWith("$")&&["id","lon","lat"].indexOf(t)<0&&s.addProp(t,r);if(s.setLatLng(e),e.$innerNodes)for(var i of e.$innerNodes)"tag"===i.$tag&&s.addTag(i.k,i.v)}),a.on("</osm.way>",e=>{var t,r,s=new f.Way(e.id,l);for([t,r]of Object.entries(e))!t.startsWith("$")&&["id"].indexOf(t)<0&&s.addProp(t,r);if(e.$innerNodes)for(var i of e.$innerNodes)"nd"===i.$tag?i.lon&&i.lat?s.addLatLng(i):i.ref&&s.addNodeRef(i.ref):"tag"===i.$tag&&s.addTag(i.k,i.v)}),a.on("<osm.relation>",e=>new f.Relation(e.id,l)),a.on("</osm.relation.member>",(e,t)=>{var t=l.get("relation/"+(null==t?void 0:t.id)),r={type:e.type,role:e.role||"",ref:e.ref};if(e.lat&&e.lon){r.lat=e.lat,r.lon=e.lon,r.tags={};for(var[s,i]of Object.entries(e))!s.startsWith("$")&&["type","lat","lon"].indexOf(s)<0&&(r[s]=i)}if(e.$innerNodes){var o,n=[],a=[];for(o of e.$innerNodes)o.lat&&o.lon?n.push(o):o.ref&&a.push(o.ref);0<n.length?r.geometry=n:0<a.length&&(r.nodes=a)}t.addMember(r)}),a.on("</osm.relation.bounds>",(e,t)=>{l.get("relation/"+(null==t?void 0:t.id)).setBounds([parseFloat(e.minlon),parseFloat(e.minlat),parseFloat(e.maxlon),parseFloat(e.maxlat)])}),a.on("</osm.relation.tag>",(e,t)=>{l.get("relation/"+(null==t?void 0:t.id)).addTag(e.k,e.v)}),a.parse(e)),l.bindAll();for(d of l.values())if(d.refCount<=0||d.hasTag&&r&&!(d instanceof f.Way&&s)){var h=d.toFeatureArray();if(d instanceof f.Relation&&!t&&0<h.length)return h[0].geometry;o=o.concat(h)}return{type:"FeatureCollection",features:o}}},{"./osmobjs":2,"./utils":4,"./xmlparser":5}],2:[function(e,t,r){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r,"__esModule",{value:!0}),r.Relation=r.Way=r.Node=void 0;let w=e("./utils"),L=e("./utils"),i=s(e("./polytags.json"));class o{constructor(e,t,r){this.type=e,this.id=t,this.refElems=r,this.tags={},this.props={id:this.getCompositeId()},this.refCount=0,this.hasTag=!1,r&&r.add(this.getCompositeId(),this)}addTags(e){this.tags=Object.assign(this.tags,e),this.hasTag=!!e}addTag(e,t){this.tags[e]=t,this.hasTag=!!e}addProp(e,t){this.props[e]=t}addProps(e){this.props=Object.assign(this.props,e)}getCompositeId(){return this.type+"/"+this.id}getProps(){return Object.assign(this.props,this.tags)}toFeatureArray(){return[]}}class l extends o{constructor(e,t){super("node",e,t),this.latLng=null}setLatLng(e){this.latLng=e}toFeatureArray(){return this.latLng?[{type:"Feature",id:this.getCompositeId(),properties:this.getProps(),geometry:{type:"Point",coordinates:(0,w.strToFloat)([this.latLng.lon,this.latLng.lat])}}]:[]}getLatLng(){return this.latLng}}r.Node=l;class d extends o{constructor(e,t){super("way",e,t),this.latLngArray=[],this.isPolygon=!1}addLatLng(e){this.latLngArray.push(e)}setLatLngArray(e){this.latLngArray=e}addNodeRef(e){e=new L.LateBinder(this.latLngArray,e=>{e=this.refElems.get("node/"+e);if(e)return e.refCount++,e.getLatLng()},this,[e]);this.latLngArray.push(e),this.refElems.addBinder(e)}addTags(e){super.addTags(e);for(var[t,r]of Object.entries(e))this.analyzeTag(t,r)}addTag(e,t){super.addTag(e,t),this.analyzeTag(e,t)}toCoordsArray(){return this.latLngArray.map(e=>[e.lon,e.lat])}toFeatureArray(){var e,t=this.toCoordsArray();return 1<t.length?(t=(0,w.strToFloat)(t),e={type:"Feature",id:this.getCompositeId(),properties:this.getProps(),geometry:{type:"LineString",coordinates:t}},this.isPolygon&&(0,w.isRing)(t)&&("counterclockwise"!==(0,w.ringDirection)(t)&&t.reverse(),e.geometry={type:"Polygon",coordinates:[t]}),[e]):[]}analyzeTag(e,t){e=i.default[e];e&&(this.isPolygon=!0,e.whitelist?this.isPolygon=0<=e.whitelist.indexOf(t):e.blacklist&&(this.isPolygon=!(0<=e.blacklist.indexOf(t))))}}r.Way=d;class n extends o{constructor(e,t){super("relation",e,t),this.relations=[],this.nodes=[],this.bounds=void 0}setBounds(e){this.bounds=e}addMember(t){switch(t.type){case"relation":var r=new L.LateBinder(this.relations,e=>{e=this.refElems.get("relation/"+e);if(e)return e.refCount++,e},this,[t.ref]);this.relations.push(r),this.refElems.addBinder(r);break;case"way":t.role||(t.role="");let e=this[t.role];if(e=e||(this[t.role]=[]),t.geometry){r=new d(t.ref,this.refElems);r.setLatLngArray(t.geometry),r.refCount++,e.push(r)}else if(t.nodes){var s,i=new d(t.ref,this.refElems);for(s of t.nodes)i.addNodeRef(s);i.refCount++,e.push(i)}else{r=new L.LateBinder(e,e=>{e=this.refElems.get("way/"+e);if(e)return e.refCount++,e},this,[t.ref]);e.push(r),this.refElems.addBinder(r)}break;case"node":var o=null;if(t.lat&&t.lon){(o=new l(t.ref,this.refElems)).setLatLng({lon:t.lon,lat:t.lat}),t.tags&&o.addTags(t.tags);for(var[n,a]of Object.entries(t))["id","type","lat","lon"].indexOf(n)<0&&o.addProp(n,a);o.refCount++,this.nodes.push(o)}else{r=new L.LateBinder(this.nodes,e=>{e=this.refElems.get("node/"+e);if(e)return e.refCount++,e},this,[t.ref]);this.nodes.push(r),this.refElems.addBinder(r)}}}toFeatureArray(){var e,t,r=[],s=[];let i=[],o=["type","id","refElems","tags","props","refCount","hasTag","relations","nodes","bounds"];for(e of this.relations)if(e)for(t of Object.keys(e).filter(e=>o.indexOf(e)<0)){var n,a=e[t];a&&((n=this[t])?n.push(...a):this[t]=a)}var l,d=Object.keys(this).filter(e=>o.indexOf(e)<0);for(l of d){var h=this[l];if(h){this[l]=new L.WayCollection;for(var f of h)this[l].addWay(f)}}var u,p={type:"Feature",id:this.getCompositeId(),bbox:this.bounds,properties:this.getProps(),geometry:null};if(this.bounds||delete p.bbox,this.outer){var g=Object.assign({},p),c=((e,t)=>{var r=e?e.toRings("counterclockwise"):[],s=t?t.toRings("clockwise"):[];if(0<r.length){var i=[];let e;for(e of r)i.push([e]);for(e=s.shift();e;){for(var o in r)if((0,w.ptInsidePolygon)((0,w.first)(e),r[o])){i[o].push(e);break}e=s.shift()}return 1===i.length?{type:"Polygon",coordinates:i[0]}:{type:"MultiPolygon",coordinates:i}}return null})(this.outer,this.inner);c&&(g.geometry=c,r.push(g))}else{var y,m,v,b={type:"MultiLineString",coordinates:[]};for(y of d)null!=y&&"inner"!==y&&(m=this[y])&&(m=0<(m=(m=m)?m.toStrings():[]).length?1===m.length?{type:"LineString",coordinates:m[0]}:{type:"MultiLineString",coordinates:m}:null)&&("LineString"===m.type?b.coordinates.push(m.coordinates):"MultiLineString"===m.type&&((v=Object.assign({},p)).geometry=m,s.push(v)));0<b.coordinates.length&&((c=Object.assign({},p)).geometry=b,s.push(c))}for(u of this.nodes)i=i.concat(u.toFeatureArray());return[...r,...s,...i]}}r.Relation=n},{"./polytags.json":3,"./utils":4}],3:[function(e,t,r){t.exports={building:{},highway:{whitelist:["services","rest_area","escape","elevator"]},natural:{blacklist:["coastline","cliff","ridge","arete","tree_row"]},landuse:{},waterway:{whitelist:["riverbank","dock","boatyard","dam"]},amenity:{},leisure:{},barrier:{whitelist:["city_wall","ditch","hedge","retaining_wall","wall","spikes"]},railway:{whitelist:["station","turntable","roundhouse","platform"]},area:{},boundary:{},man_made:{blacklist:["cutline","embankment","pipeline"]},power:{whitelist:["plant","substation","generator","transformer"]},place:{},shop:{},aeroway:{blacklist:["taxiway"]},tourism:{},historic:{},public_transport:{},office:{},"building:part":{},military:{},ruins:{},"area:highway":{},craft:{},golf:{},indoor:{}}},{}],4:[function(e,t,o){function i(e,t,r){e.properties&&t&&r&&(e.properties[t]=r)}Object.defineProperty(o,"__esModule",{value:!0}),o.WayCollection=o.RefElements=o.LateBinder=o.strToFloat=o.ptInsidePolygon=o.ringDirection=o.isRing=o.coordsToKey=o.last=o.first=void 0,o.purgeProps=function(e,t){if(e){var r=Object.assign({},e);if(t)for(var s of t)delete r[s];return r}return{}},o.mergeProps=function(e,t){return e=e||{},t=t||{},Object.assign(e,t)},o.addPropToFeature=i,o.addPropToFeatures=function(e,t,r){for(var s of e)i(s,t,r)},o.addToMap=r,o.removeFromMap=n,o.getFirstFromMap=a;o.first=e=>e[0],o.last=e=>e[e.length-1];function r(e,t,r){var s=e[t];s?s.push(r):e[t]=[r]}function n(e,t,r){e=e[t];let s=-1;0<=(s=e?e.indexOf(r):s)&&e.splice(s,1)}function a(e,t){e=e[t];return e&&0<e.length?e[0]:null}o.coordsToKey=e=>e.join(",");o.isRing=e=>3<e.length&&(0,o.coordsToKey)((0,o.first)(e))===(0,o.coordsToKey)((0,o.last)(e)),o.ringDirection=(s,i,e)=>{i=i||0,e=e||1;var t=s.reduce((e,t,r)=>s[e][i||0]>t[i||0]?e:r,0),r=t<=0?s.length-2:t-1,o=t>=s.length-1?1:t+1,n=s[r][i],a=s[t][i],l=s[o][i],r=s[r][e],t=s[t][e];return(a-n)*(s[o][e]-r)-(l-n)*(t-r)<0?"clockwise":"counterclockwise"},o.ptInsidePolygon=(r,s,i,o)=>{i=i||0,o=o||1;let n=!1;for(let e=0,t=s.length-1;e<s.length;t=e++)(s[e][i]<=r[i]&&r[i]<s[t][i]||s[t][i]<=r[i]&&r[i]<s[e][i])&&r[o]<(s[t][o]-s[e][o])*(r[i]-s[e][i])/(s[t][i]-s[e][i])+s[e][o]&&(n=!n);return n};o.strToFloat=e=>e instanceof Array?e.map(o.strToFloat):parseFloat(e);o.LateBinder=class{constructor(e,t,r,s){this.container=e,this.valueFunc=t,this.ctx=r,this.args=s}bind(){var e=this.valueFunc.apply(this.ctx,this.args);if(this.container instanceof Array){var r=this.container.indexOf(this);0<=r&&(r=[r,1],e&&r.push(e),Array.prototype.splice.apply(this.container,r))}else if("object"==typeof this.container&&!Array.isArray(this.container)){let t=this.container;r=Object.keys(t).find(e=>t[e]===this);r&&(e?t[r]=e:delete t[r])}}};class s extends Map{constructor(){super(),this.binders=[]}add(e,t){this.set(e,t)}addBinder(e){this.binders.push(e)}bindAll(){this.binders.forEach(e=>e.bind())}}o.RefElements=s;class l extends Array{constructor(){super(),this.firstMap={},this.lastMap={}}addWay(e){e=e.toCoordsArray();0<e.length&&(this.push(e),r(this.firstMap,(0,o.coordsToKey)((0,o.first)(e)),e),r(this.lastMap,(0,o.coordsToKey)((0,o.last)(e)),e))}toStrings(){var e=[];let s=this.shift();for(;s;){n(this.firstMap,(0,o.coordsToKey)((0,o.first)(s)),s),n(this.lastMap,(0,o.coordsToKey)((0,o.last)(s)),s);let t=s,r;do{var i=(0,o.coordsToKey)((0,o.last)(t));let e=!1;(r=a(this.firstMap,i))||(r=a(this.lastMap,i),e=!0),r&&(this.splice(this.indexOf(r),1),n(this.firstMap,(0,o.coordsToKey)((0,o.first)(r)),r),n(this.lastMap,(0,o.coordsToKey)((0,o.last)(r)),r),e&&(r.length>t.length&&([t,r]=[r,t]),r.reverse()),t=t.concat(r.slice(1)))}while(r);e.push((0,o.strToFloat)(t)),s=this.shift()}return e}toRings(e){var t=this.toStrings(),r=[];let s=t.shift();for(;s;)(0,o.isRing)(s)&&((0,o.ringDirection)(s)!==e&&s.reverse(),r.push(s)),s=t.shift();return r}}o.WayCollection=l},{}],5:[function(e,t,r){function i(e){return null!==e.match(/^(.+?)\[(.+?)\]>$/g)}function o(e){var t=/^(.+?)\[(.+?)\]>$/g.exec(e);return t?{evt:t[1]+">",exp:t[2]}:{evt:e}}Object.defineProperty(r,"__esModule",{value:!0});class s{constructor(e){this.queryParent=!1,this.progressive=!1,this.parentMap=new WeakMap,e&&(this.queryParent=!!e.queryParent,this.progressive=e.progressive,this.queryParent)&&(this.parentMap=new WeakMap),this.evtListeners={}}parse(s,i,o){o=o?o+".":"";var n=/<([^ >\/]+)(.*?)>/gm,a=[];let l=n.exec(s);for(;l;){var d=l[1],h={$tag:d},f=o+d,u=l[2].trim();let e=!1;(u.endsWith("/")||d.startsWith("?")||d.startsWith("!"))&&(e=!0);var p,g=/([^ ]+?)="(.+?)"/g,c=/([^ ]+?)='(.+?)'/g;let t=g.exec(u),r=!1;for(;t;)r=!0,h[t[1]]=t[2],t=g.exec(u);if(!r)for(t=c.exec(u);t;)r=!0,h[t[1]]=t[2],t=c.exec(u);r||""===u||(h.text=u),this.progressive&&this.emit(`<${f}>`,h,i),e||((d=new RegExp(`([^]+?)</${d}>`,"g")).lastIndex=n.lastIndex,(p=d.exec(s))&&p[1]&&(n.lastIndex=d.lastIndex,0<(d=this.parse(p[1],h,f)).length?h.$innerNodes=d:h.$innerText=p[1])),this.queryParent&&i&&this.parentMap.set(h,i),this.progressive&&this.emit(`</${f}>`,h,i),a.push(h),l=n.exec(s)}return a}getParent(e){return this.queryParent?this.parentMap.get(e):null}addListener(e,t){var r,s;i(e)&&((r=o(e)).exp&&(t.condition=(s="return "+(s=r.exp).replace(/(\$.+?)(?=[=!.])/g,"node.$&")+";",new Function("node",s))),e=r.evt),this.$addListener(e,t)}removeListener(e,t){i(e)&&(e=o(e).evt),this.$removeListener(e,t)}on(e,t){this.addListener(e,t)}off(e,t){this.removeListener(e,t)}$addListener(e,t){var r=this.evtListeners[e];r?r.push(t):this.evtListeners[e]=[t]}$removeListener(e,t){e=this.evtListeners[e];let r=-1;0<=(r=e?e.indexOf(t):r)&&e.splice(r,1)}emit(e,...t){e=this.evtListeners[e];if(e)for(var r of e)(!r.condition||!0===r.condition.apply(null,t))&&r.apply(null,t)}}r.default=s},{}]},{},[1])(1)});
|