osm2geojson-lite 1.0.3 → 1.1.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 CHANGED
@@ -1,18 +1,15 @@
1
1
  osm2geojson-lite
2
2
  ============
3
3
 
4
+ [![NPM Version](https://img.shields.io/npm/v/osm2geojson-lite)](https://www.npmjs.com/package/osm2geojson-lite) [![Codecov](https://img.shields.io/codecov/c/github/tibetty/osm2geojson-lite/master.svg)](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
- const osm2geojson = require('osm2geojson-lite');
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/allFeatures`: 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.
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 `suppressWay` changes its behavior a bit; otherwise only the unreferenced ones get returned.
51
- - `suppressWay/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.
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 bench
62
- $ node o2gl-bench.js
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` ~~will automatically call `geojsonlint` validation service directly after each conversion, you can wait for a while to see the validation result after click the conversion button.~~ - because the CORS limitation, the direct post to geojsonlint was blocked, so I added a "copy to clipboard" button for you to ease the validation.
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
- Copyleft
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
 
@@ -1,10 +1,23 @@
1
- import { FeatureCollection, GeometryObject } from 'geojson';
1
+ import type { FeatureCollection, GeometryObject } from 'geojson';
2
2
  interface IOptions {
3
+ /**
4
+ * When it's set to `true`, the returned geojson will include all elements that meet the specified conditions in `FeatureCollection` format;
5
+ * otherwise, only the bare geometry of the first `relation` element will be returned.
6
+ * @default false
7
+ */
3
8
  completeFeature?: boolean;
4
- allFeatures?: boolean;
9
+ /**
10
+ * When it's set to `true`, the returned geojson will include all elements with tags (i.e., tagged)
11
+ * until `suppressWay` changes its behavior a bit; otherwise only the unreferenced ones get returned.
12
+ * @default false
13
+ */
5
14
  renderTagged?: boolean;
15
+ /**
16
+ * When it's set to `true`, the returned `FeatureCollection` will exclude all referenced `way`s even though they are tagged;
17
+ * otherwise the features of those `way`s will be included in the resulted result as well.
18
+ * @default true
19
+ */
6
20
  excludeWay?: boolean;
7
- suppressWay?: boolean;
8
21
  }
9
22
  declare function osm2geojson(osm: string | {
10
23
  [k: string]: any;
@@ -1,172 +1,168 @@
1
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
2
  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);
3
+ const xmlparser_1 = require("./xmlparser");
4
+ const node_1 = require("./node");
5
+ const way_1 = require("./way");
6
+ const relation_1 = require("./relation");
7
+ const ref_elements_1 = require("./ref-elements");
8
+ function parseOptions(options) {
9
+ if (!options) {
10
+ return { completeFeature: false, renderTagged: false, excludeWay: true };
24
11
  }
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);
12
+ let excludeWay = options.excludeWay === undefined || options.excludeWay;
13
+ let completeFeature = options.completeFeature ? true : false;
14
+ let renderTagged = options.renderTagged ? true : false;
15
+ return { completeFeature, renderTagged, excludeWay };
16
+ }
17
+ function detectFormat(o) {
18
+ if (o.elements) {
19
+ return 'json';
20
+ }
21
+ if (o.indexOf('<osm') >= 0) {
22
+ return 'xml';
23
+ }
24
+ if (o.trim().startsWith('{')) {
25
+ return 'json-raw';
26
+ }
27
+ return 'invalid';
28
+ }
29
+ ;
30
+ function analyzeFeaturesFromJson(osm, refElements) {
31
+ for (const elem of osm.elements) {
32
+ switch (elem.type) {
33
+ case 'node':
34
+ const node = new node_1.Node(elem.id, refElements);
35
+ if (elem.tags) {
36
+ node.addTags(elem.tags);
92
37
  }
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
- }
38
+ node.addProps((0, utils_1.purgeProps)(elem, ['id', 'type', 'tags', 'lat', 'lon']));
39
+ node.setLatLng(elem);
40
+ break;
41
+ case 'way':
42
+ const way = new way_1.Way(elem.id, refElements);
43
+ if (elem.tags) {
44
+ way.addTags(elem.tags);
100
45
  }
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);
46
+ way.addProps((0, utils_1.purgeProps)(elem, ['id', 'type', 'tags', 'nodes', 'geometry']));
47
+ if (elem.geometry) {
48
+ way.setLatLngArray(elem.geometry);
108
49
  }
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
- }
50
+ else if (elem.nodes) {
51
+ for (const n of elem.nodes) {
52
+ way.addNodeRef(n);
119
53
  }
120
- else if (ind.$tag === 'tag') {
121
- way.addTag(ind.k, ind.v);
54
+ }
55
+ break;
56
+ case 'relation':
57
+ const relation = new relation_1.Relation(elem.id, refElements);
58
+ if (elem.bounds) {
59
+ relation.setBounds([parseFloat(elem.bounds.minlon), parseFloat(elem.bounds.minlat), parseFloat(elem.bounds.maxlon), parseFloat(elem.bounds.maxlat)]);
60
+ }
61
+ if (elem.tags) {
62
+ relation.addTags(elem.tags);
63
+ }
64
+ relation.addProps((0, utils_1.purgeProps)(elem, ['id', 'type', 'tags', 'bounds', 'members']));
65
+ if (elem.members) {
66
+ for (const member of elem.members) {
67
+ relation.addMember(member);
122
68
  }
123
69
  }
70
+ default:
71
+ break;
72
+ }
73
+ }
74
+ }
75
+ function analyzeFeaturesFromXml(osm, refElements) {
76
+ const xmlParser = new xmlparser_1.XmlParser({ progressive: true });
77
+ xmlParser.on('</osm.node>', (node) => {
78
+ const nd = new node_1.Node(node.id, refElements);
79
+ for (const [k, v] of Object.entries(node)) {
80
+ if (!k.startsWith('$') && ['id', 'lon', 'lat'].indexOf(k) < 0) {
81
+ nd.addProp(k, v);
124
82
  }
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
- }
83
+ }
84
+ nd.setLatLng(node);
85
+ if (node.$innerNodes) {
86
+ for (const ind of node.$innerNodes) {
87
+ if (ind.$tag === 'tag') {
88
+ nd.addTag(ind.k, ind.v);
140
89
  }
141
90
  }
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);
91
+ }
92
+ });
93
+ xmlParser.on('</osm.way>', (node) => {
94
+ const way = new way_1.Way(node.id, refElements);
95
+ for (const [k, v] of Object.entries(node)) {
96
+ if (!k.startsWith('$') && ['id'].indexOf(k) < 0) {
97
+ way.addProp(k, v);
98
+ }
99
+ }
100
+ if (node.$innerNodes) {
101
+ for (const ind of node.$innerNodes) {
102
+ if (ind.$tag === 'nd') {
103
+ if (ind.lon && ind.lat) {
104
+ way.addLatLng(ind);
148
105
  }
149
106
  else if (ind.ref) {
150
- nodes.push(ind.ref);
107
+ way.addNodeRef(ind.ref);
151
108
  }
152
109
  }
153
- if (geometry.length > 0) {
154
- member.geometry = geometry;
110
+ else if (ind.$tag === 'tag') {
111
+ way.addTag(ind.k, ind.v);
112
+ }
113
+ }
114
+ }
115
+ });
116
+ xmlParser.on('<osm.relation>', (node) => new relation_1.Relation(node.id, refElements));
117
+ xmlParser.on('</osm.relation.member>', (node, parent) => {
118
+ const relation = refElements.get(`relation/${parent === null || parent === void 0 ? void 0 : parent.id}`);
119
+ const member = {
120
+ type: node.type,
121
+ role: node.role ? node.role : '',
122
+ ref: node.ref,
123
+ };
124
+ if (node.lat && node.lon) {
125
+ member.lat = node.lat, member.lon = node.lon, member.tags = {};
126
+ for (const [k, v] of Object.entries(node)) {
127
+ if (!k.startsWith('$') && ['type', 'lat', 'lon'].indexOf(k) < 0) {
128
+ member[k] = v;
129
+ }
130
+ }
131
+ }
132
+ if (node.$innerNodes) {
133
+ const geometry = [];
134
+ const nodes = [];
135
+ for (const ind of node.$innerNodes) {
136
+ if (ind.lat && ind.lon) {
137
+ geometry.push(ind);
155
138
  }
156
- else if (nodes.length > 0) {
157
- member.nodes = nodes;
139
+ else if (ind.ref) {
140
+ nodes.push(ind.ref);
158
141
  }
159
142
  }
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
- };
143
+ if (geometry.length > 0) {
144
+ member.geometry = geometry;
145
+ }
146
+ else if (nodes.length > 0) {
147
+ member.nodes = nodes;
148
+ }
149
+ }
150
+ relation.addMember(member);
151
+ });
152
+ xmlParser.on('</osm.relation.bounds>', (node, parent) => {
153
+ 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)]);
154
+ });
155
+ xmlParser.on('</osm.relation.tag>', (node, parent) => {
156
+ refElements.get(`relation/${parent === null || parent === void 0 ? void 0 : parent.id}`).addTag(node.k, node.v);
157
+ });
158
+ xmlParser.parse(osm);
159
+ }
160
+ ;
161
+ function osm2geojson(osm, opts) {
162
+ let { completeFeature, renderTagged, excludeWay } = parseOptions(opts);
163
+ let format = detectFormat(osm);
164
+ const refElements = new ref_elements_1.RefElements();
165
+ let featureArray = [];
170
166
  if (format === 'json-raw') {
171
167
  osm = JSON.parse(osm);
172
168
  if (osm.elements) {
@@ -177,21 +173,22 @@ function osm2geojson(osm, opts) {
177
173
  }
178
174
  }
179
175
  if (format === 'json') {
180
- analyzeFeaturesFromJson(osm);
176
+ analyzeFeaturesFromJson(osm, refElements);
181
177
  }
182
178
  else if (format === 'xml') {
183
- analyzeFeaturesFromXml(osm);
179
+ analyzeFeaturesFromXml(osm, refElements);
184
180
  }
185
181
  refElements.bindAll();
186
182
  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);
183
+ if (v.refCount > 0 && (!v.hasTag || !renderTagged || (v instanceof way_1.Way && excludeWay))) {
184
+ continue;
185
+ }
186
+ const features = v.toFeatureArray();
187
+ // return the first geometry of the first relation element
188
+ if (v instanceof relation_1.Relation && !completeFeature && features.length > 0) {
189
+ return features[0].geometry;
194
190
  }
191
+ featureArray = featureArray.concat(features);
195
192
  }
196
193
  return { type: 'FeatureCollection', features: featureArray };
197
194
  }
@@ -0,0 +1,8 @@
1
+ export declare class LateBinder<T> {
2
+ private container;
3
+ private valueFunc;
4
+ private ctx;
5
+ private args;
6
+ constructor(container: (T | LateBinder<T>)[], valueFunc: (...args: any[]) => T | undefined, ctx: any, args: any[]);
7
+ bind(): void;
8
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LateBinder = void 0;
4
+ class LateBinder {
5
+ constructor(container, valueFunc, ctx, args) {
6
+ this.container = container;
7
+ this.valueFunc = valueFunc;
8
+ this.ctx = ctx;
9
+ this.args = args;
10
+ }
11
+ bind() {
12
+ const v = this.valueFunc.apply(this.ctx, this.args);
13
+ const idx = this.container.indexOf(this);
14
+ if (idx < 0) {
15
+ return;
16
+ }
17
+ const args = [idx, 1];
18
+ if (v) {
19
+ args.push(v);
20
+ }
21
+ Array.prototype.splice.apply(this.container, args);
22
+ }
23
+ }
24
+ exports.LateBinder = LateBinder;
@@ -0,0 +1,14 @@
1
+ import { OsmObject } from "./osm-object";
2
+ import type { RefElements } from "./ref-elements";
3
+ import type { Feature } from "geojson";
4
+ export type LatLon = {
5
+ lat: string;
6
+ lon: string;
7
+ };
8
+ export declare class Node extends OsmObject {
9
+ private latLng;
10
+ constructor(id: string, refElems: RefElements);
11
+ setLatLng(latLng: LatLon): void;
12
+ toFeatureArray(): Array<Feature<any, any>>;
13
+ getLatLng(): LatLon | undefined;
14
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Node = void 0;
4
+ const osm_object_1 = require("./osm-object");
5
+ const utils_1 = require("./utils");
6
+ class Node extends osm_object_1.OsmObject {
7
+ constructor(id, refElems) {
8
+ super('node', id, refElems);
9
+ }
10
+ setLatLng(latLng) {
11
+ this.latLng = latLng;
12
+ }
13
+ toFeatureArray() {
14
+ if (this.latLng) {
15
+ return [{
16
+ type: 'Feature',
17
+ id: this.getCompositeId(),
18
+ properties: this.getProps(),
19
+ geometry: {
20
+ type: 'Point',
21
+ coordinates: (0, utils_1.strArrayToFloat)([this.latLng.lon, this.latLng.lat]),
22
+ },
23
+ }];
24
+ }
25
+ return [];
26
+ }
27
+ getLatLng() {
28
+ return this.latLng;
29
+ }
30
+ }
31
+ exports.Node = Node;
@@ -0,0 +1,25 @@
1
+ import type { RefElements } from './ref-elements';
2
+ import type { Feature } from 'geojson';
3
+ export declare abstract class OsmObject {
4
+ refCount: number;
5
+ hasTag: boolean;
6
+ protected refElems: RefElements;
7
+ private type;
8
+ private id;
9
+ private tags;
10
+ private props;
11
+ constructor(type: string, id: string, refElems: RefElements);
12
+ addTags(tags: {
13
+ [k: string]: string;
14
+ }): void;
15
+ addTag(k: string, v: string): void;
16
+ addProp(k: string, v: any): void;
17
+ addProps(props: {
18
+ [k: string]: string;
19
+ }): void;
20
+ getCompositeId(): string;
21
+ getProps(): {
22
+ [k: string]: string;
23
+ };
24
+ abstract toFeatureArray(): Array<Feature<any, any>>;
25
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OsmObject = void 0;
4
+ class OsmObject {
5
+ constructor(type, id, refElems) {
6
+ this.type = type;
7
+ this.id = id;
8
+ this.refElems = refElems;
9
+ this.tags = {};
10
+ this.props = { id: this.getCompositeId() };
11
+ this.refCount = 0;
12
+ this.hasTag = false;
13
+ if (refElems) {
14
+ refElems.add(this.getCompositeId(), this);
15
+ }
16
+ }
17
+ addTags(tags) {
18
+ this.tags = Object.assign(this.tags, tags);
19
+ this.hasTag = true;
20
+ }
21
+ addTag(k, v) {
22
+ this.tags[k] = v;
23
+ this.hasTag = true;
24
+ }
25
+ addProp(k, v) {
26
+ this.props[k] = v;
27
+ }
28
+ addProps(props) {
29
+ this.props = Object.assign(this.props, props);
30
+ }
31
+ getCompositeId() {
32
+ return `${this.type}/${this.id}`;
33
+ }
34
+ getProps() {
35
+ return Object.assign(this.props, this.tags);
36
+ }
37
+ }
38
+ exports.OsmObject = OsmObject;
@@ -0,0 +1,9 @@
1
+ import { LateBinder } from "./late-binder";
2
+ import type { OsmObject } from "./osm-object";
3
+ export declare class RefElements extends Map<string, OsmObject> {
4
+ private binders;
5
+ constructor();
6
+ add(k: string, v: OsmObject): void;
7
+ addBinder(binder: LateBinder<any>): void;
8
+ bindAll(): void;
9
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RefElements = void 0;
4
+ class RefElements extends Map {
5
+ constructor() {
6
+ super();
7
+ this.binders = [];
8
+ }
9
+ add(k, v) {
10
+ this.set(k, v);
11
+ }
12
+ addBinder(binder) {
13
+ this.binders.push(binder);
14
+ }
15
+ bindAll() {
16
+ this.binders.forEach((binder) => binder.bind());
17
+ }
18
+ }
19
+ exports.RefElements = RefElements;
@@ -0,0 +1,20 @@
1
+ import { OsmObject } from "./osm-object";
2
+ import { Way } from "./way";
3
+ import { LateBinder } from "./late-binder";
4
+ import type { RefElements } from "./ref-elements";
5
+ import type { Feature } from "geojson";
6
+ export declare class Relation extends OsmObject {
7
+ private relations;
8
+ private nodes;
9
+ private bounds;
10
+ ways: (LateBinder<Way> | Way)[];
11
+ roles: string[];
12
+ constructor(id: string, refElems: RefElements);
13
+ setBounds(bounds: any[]): void;
14
+ addMember(member: {
15
+ [k: string]: any;
16
+ }): void;
17
+ private constructStringGeometry;
18
+ private constructPolygonGeometry;
19
+ toFeatureArray(): Array<Feature<any, any>>;
20
+ }