osm2geojson-lite 0.8.13 → 0.9.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/Makefile +1 -1
- package/index.html +7 -3
- package/lib/index.d.ts +21 -0
- package/lib/index.js +51 -59
- package/lib/osmobjs.js +1 -1
- package/lib/xmlparser.js +1 -1
- package/osm2geojson-lite +10 -0
- package/package.json +12 -2
- package/ts/release/index.js +195 -0
- package/ts/release/osmobjs.js +348 -0
- package/ts/release/utils.js +213 -0
- package/ts/release/xmlparser.js +157 -0
- package/ts/src/index.d.ts +17 -0
- package/ts/src/index.ts +217 -169
- package/ts/src/osmobjs.ts +400 -365
- package/ts/src/typings.d.ts +1 -1
- package/ts/src/utils.ts +207 -170
- package/ts/src/xmlparser.ts +173 -132
- package/ts/tsconfig.json +4 -0
- package/ts/tslint.json +24 -0
- package/ts/types/imports.d.ts +1 -0
package/ts/src/typings.d.ts
CHANGED
package/ts/src/utils.ts
CHANGED
|
@@ -1,198 +1,235 @@
|
|
|
1
|
-
import {Way} from
|
|
2
|
-
|
|
3
|
-
export function purgeProps(obj:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import {Way} from './osmobjs';
|
|
2
|
+
|
|
3
|
+
export function purgeProps(obj: {[k: string]: any}, blacklist: string[]): {[k: string]: any} {
|
|
4
|
+
if (obj) {
|
|
5
|
+
const rs = Object.assign({}, obj);
|
|
6
|
+
if (blacklist) {
|
|
7
|
+
for (const prop of blacklist) {
|
|
8
|
+
delete rs[prop];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return rs;
|
|
12
|
+
}
|
|
13
|
+
return {};
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
export function mergeProps(obj1:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
export function mergeProps(obj1: {[k: string]: any}, obj2: {[k: string]: any}): {[k: string]: any} {
|
|
17
|
+
obj1 = obj1 ? obj1 : {};
|
|
18
|
+
obj2 = obj2 ? obj2 : {};
|
|
19
|
+
return Object.assign(obj1, obj2);
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
export function addPropToFeature(f: any, k: string, v:
|
|
20
|
-
|
|
22
|
+
export function addPropToFeature(f: {[k: string]: any}, k: string, v: any) {
|
|
23
|
+
if (f.properties && k && v) {
|
|
24
|
+
f.properties[k] = v;
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
export function addPropToFeatures(fs:
|
|
24
|
-
|
|
28
|
+
export function addPropToFeatures(fs: Array<{[k: string]: any}>, k: string, v: any) {
|
|
29
|
+
for (const f of fs) {
|
|
30
|
+
addPropToFeature(f, k, v);
|
|
31
|
+
}
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
export const first = a => a[0];
|
|
28
|
-
export const last = a => a[a.length - 1];
|
|
29
|
-
export const coordsToKey = a => a.join(',');
|
|
30
|
-
|
|
31
|
-
export function addToMap(m:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
export const first = <T>(a: T[]): T => a[0];
|
|
35
|
+
export const last = <T>(a: T[]): T => a[a.length - 1];
|
|
36
|
+
export const coordsToKey = <T>(a: T[]): string => a.join(',');
|
|
37
|
+
|
|
38
|
+
export function addToMap<T>(m: {[k: string]: T[]}, k: string, v: T): void {
|
|
39
|
+
const a = m[k];
|
|
40
|
+
if (a) {
|
|
41
|
+
a.push(v);
|
|
42
|
+
} else {
|
|
43
|
+
m[k] = [v];
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
export function removeFromMap(m:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
export function removeFromMap<T>(m: {[k: string]: T[]}, k: string, v: T): void {
|
|
48
|
+
const a = m[k];
|
|
49
|
+
let idx = -1;
|
|
50
|
+
if (a) {
|
|
51
|
+
idx = a.indexOf(v);
|
|
52
|
+
}
|
|
53
|
+
if (idx >= 0) {
|
|
54
|
+
a.splice(idx, 1);
|
|
55
|
+
}
|
|
42
56
|
}
|
|
43
57
|
|
|
44
|
-
export function getFirstFromMap(m:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
58
|
+
export function getFirstFromMap<T>(m: {[k: string]: T[]}, k: string): T | undefined {
|
|
59
|
+
const a = m[k];
|
|
60
|
+
if (a && a.length > 0) {
|
|
61
|
+
return a[0];
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
48
64
|
}
|
|
49
65
|
|
|
50
66
|
// need 3+ different points to form a ring, here using > 3 is 'coz a the first and the last points are actually the same
|
|
51
|
-
export const isRing = a => a.length > 3 && coordsToKey(first(a)) === coordsToKey(last(a));
|
|
52
|
-
|
|
53
|
-
export const ringDirection = (a, xIdx
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
67
|
+
export const isRing = (a: number[][]): boolean => a.length > 3 && coordsToKey(first(a)) === coordsToKey(last(a));
|
|
68
|
+
|
|
69
|
+
export const ringDirection = (a: number[][], xIdx?: number, yIdx?: number): string => {
|
|
70
|
+
xIdx = xIdx || 0, yIdx = yIdx || 1;
|
|
71
|
+
// get the index of the point which has the maximum x value
|
|
72
|
+
const m = a.reduce((maxxIdx: number, v: number[], idx: number): number => a[maxxIdx][xIdx || 0] > v[xIdx || 0] ? maxxIdx : idx, 0);
|
|
73
|
+
// 'coz the first point is virtually the same one as the last point,
|
|
74
|
+
// we need to skip a.length - 1 for left when m = 0,
|
|
75
|
+
// and skip 0 for right when m = a.length - 1;
|
|
76
|
+
const l = m <= 0 ? a.length - 2 : m - 1;
|
|
77
|
+
const r = m >= a.length - 1 ? 1 : m + 1;
|
|
78
|
+
const xa = a[l][xIdx];
|
|
79
|
+
const xb = a[m][xIdx];
|
|
80
|
+
const xc = a[r][xIdx];
|
|
81
|
+
const ya = a[l][yIdx];
|
|
82
|
+
const yb = a[m][yIdx];
|
|
83
|
+
const yc = a[r][yIdx];
|
|
84
|
+
const det = (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya);
|
|
85
|
+
return det < 0 ? 'clockwise' : 'counterclockwise';
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const ptInsidePolygon = (pt: number[], polygon: number[][], xIdx?: number, yIdx?: number): boolean => {
|
|
89
|
+
xIdx = xIdx || 0, yIdx = yIdx || 1;
|
|
90
|
+
let result = false;
|
|
91
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
92
|
+
if ((polygon[i][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[j][xIdx] ||
|
|
93
|
+
polygon[j][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[i][xIdx]) &&
|
|
94
|
+
pt[yIdx] < (polygon[j][yIdx] - polygon[i][yIdx]) * (pt[xIdx] - polygon[i][xIdx]) / (polygon[j][xIdx] - polygon[i][xIdx]) + polygon[i][yIdx]) {
|
|
95
|
+
result = !result;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const strToFloat = (el: any[] | string): any => el instanceof Array ? el.map(strToFloat) : parseFloat(el);
|
|
80
102
|
|
|
81
103
|
export class LateBinder {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
private container: any[] | {[k: string]: any};
|
|
105
|
+
private valueFunc: (...args) => any;
|
|
106
|
+
private ctx: any;
|
|
107
|
+
private args: any[];
|
|
108
|
+
|
|
109
|
+
constructor(container: any[] | {[k: string]: any}, valueFunc: (...args) => any, ctx: any, args: any[]) {
|
|
110
|
+
this.container = container;
|
|
111
|
+
this.valueFunc = valueFunc;
|
|
112
|
+
this.ctx = ctx;
|
|
113
|
+
this.args = args;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public bind() {
|
|
117
|
+
const v = this.valueFunc.apply(this.ctx, this.args);
|
|
118
|
+
if (this.container instanceof Array) {
|
|
119
|
+
const idx = this.container.indexOf(this);
|
|
120
|
+
if (idx >= 0) {
|
|
121
|
+
const args = [idx, 1];
|
|
122
|
+
if (v) {
|
|
123
|
+
args.push(v);
|
|
124
|
+
}
|
|
125
|
+
[].splice.apply(this.container, args);
|
|
126
|
+
}
|
|
127
|
+
} else if (typeof this.container === 'object') {
|
|
128
|
+
const k = Object.keys(this.container).find((nv) => this.container[nv] === this);
|
|
129
|
+
if (k) {
|
|
130
|
+
if (v) {
|
|
131
|
+
this.container[k] = v;
|
|
132
|
+
} else {
|
|
133
|
+
delete this.container[k];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
110
138
|
}
|
|
111
139
|
|
|
112
140
|
export class RefElements extends Map {
|
|
113
|
-
|
|
141
|
+
private binders: LateBinder[];
|
|
114
142
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
143
|
+
constructor() {
|
|
144
|
+
super();
|
|
145
|
+
this.binders = [];
|
|
146
|
+
}
|
|
119
147
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
148
|
+
public add(k: string, v: any) {
|
|
149
|
+
this.set(k, v);
|
|
150
|
+
}
|
|
123
151
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
152
|
+
public addBinder(binder: LateBinder) {
|
|
153
|
+
this.binders.push(binder);
|
|
154
|
+
}
|
|
127
155
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
156
|
+
public bindAll() {
|
|
157
|
+
this.binders.forEach((binder) => binder.bind());
|
|
158
|
+
}
|
|
131
159
|
}
|
|
132
160
|
|
|
133
161
|
export class WayCollection extends Array {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
162
|
+
private firstMap: {[k: string]: any};
|
|
163
|
+
private lastMap: {[k: string]: any};
|
|
164
|
+
|
|
165
|
+
constructor() {
|
|
166
|
+
super();
|
|
167
|
+
this.firstMap = {};
|
|
168
|
+
this.lastMap = {};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public addWay(way: Way) {
|
|
172
|
+
const w = way.toCoordsArray();
|
|
173
|
+
if (w.length > 0) {
|
|
174
|
+
this.push(way);
|
|
175
|
+
addToMap(this.firstMap, coordsToKey(first(w)), w);
|
|
176
|
+
addToMap(this.lastMap, coordsToKey(last(w)), w);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public toStrings(): number[][][] {
|
|
181
|
+
const strings: any[] = [];
|
|
182
|
+
let way = this.shift();
|
|
183
|
+
while (way) {
|
|
184
|
+
removeFromMap(this.firstMap, coordsToKey(first(way)), way);
|
|
185
|
+
removeFromMap(this.lastMap, coordsToKey(last(way)), way);
|
|
186
|
+
let current: any[] = way;
|
|
187
|
+
let next: any[] | undefined;
|
|
188
|
+
do {
|
|
189
|
+
const key = coordsToKey(last(current));
|
|
190
|
+
let shouldReverse = false;
|
|
191
|
+
|
|
192
|
+
next = getFirstFromMap(this.firstMap, key);
|
|
193
|
+
if (!next) {
|
|
194
|
+
next = getFirstFromMap(this.lastMap, key);
|
|
195
|
+
shouldReverse = true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (next) {
|
|
199
|
+
this.splice(this.indexOf(next), 1);
|
|
200
|
+
removeFromMap(this.firstMap, coordsToKey(first(next)), next);
|
|
201
|
+
removeFromMap(this.lastMap, coordsToKey(last(next)), next);
|
|
202
|
+
if (shouldReverse) {
|
|
203
|
+
// always reverse shorter one to save time
|
|
204
|
+
if (next.length > current.length) {
|
|
205
|
+
[current, next] = [next, current];
|
|
206
|
+
}
|
|
207
|
+
next.reverse();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
current = current.concat(next.slice(1));
|
|
211
|
+
}
|
|
212
|
+
} while (next);
|
|
213
|
+
strings.push(strToFloat(current));
|
|
214
|
+
way = this.shift();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return strings;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
public toRings(direction: string): number[][][] {
|
|
221
|
+
const strings = this.toStrings();
|
|
222
|
+
const rings: number[][][] = [];
|
|
223
|
+
let str = strings.shift();
|
|
224
|
+
while (str) {
|
|
225
|
+
if (isRing(str)) {
|
|
226
|
+
if (ringDirection(str) !== direction) {
|
|
227
|
+
str.reverse();
|
|
228
|
+
}
|
|
229
|
+
rings.push(str);
|
|
230
|
+
}
|
|
231
|
+
str = strings.shift();
|
|
232
|
+
}
|
|
233
|
+
return rings;
|
|
234
|
+
}
|
|
198
235
|
}
|