@loaders.gl/json 4.0.0-alpha.4 → 4.0.0-alpha.6
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/dist/bundle.d.ts +2 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +2 -2
- package/dist/dist.min.js +3094 -0
- package/dist/es5/bundle.js +6 -0
- package/dist/es5/bundle.js.map +1 -0
- package/dist/es5/geojson-loader.js +157 -0
- package/dist/es5/geojson-loader.js.map +1 -0
- package/dist/es5/geojson-writer.js +27 -0
- package/dist/es5/geojson-writer.js.map +1 -0
- package/dist/es5/index.js +69 -0
- package/dist/es5/index.js.map +1 -0
- package/dist/es5/json-loader.js +67 -0
- package/dist/es5/json-loader.js.map +1 -0
- package/dist/es5/json-writer.js +42 -0
- package/dist/es5/json-writer.js.map +1 -0
- package/dist/es5/lib/clarinet/clarinet.js +446 -0
- package/dist/es5/lib/clarinet/clarinet.js.map +1 -0
- package/dist/es5/lib/encoders/encode-utils.js +42 -0
- package/dist/es5/lib/encoders/encode-utils.js.map +1 -0
- package/dist/es5/lib/encoders/geojson-encoder.js +178 -0
- package/dist/es5/lib/encoders/geojson-encoder.js.map +1 -0
- package/dist/es5/lib/encoders/json-encoder.js +30 -0
- package/dist/es5/lib/encoders/json-encoder.js.map +1 -0
- package/dist/es5/lib/encoders/utf8-encoder.js +54 -0
- package/dist/es5/lib/encoders/utf8-encoder.js.map +1 -0
- package/dist/es5/lib/json-parser/json-parser.js +140 -0
- package/dist/es5/lib/json-parser/json-parser.js.map +1 -0
- package/dist/es5/lib/json-parser/streaming-json-parser.js +123 -0
- package/dist/es5/lib/json-parser/streaming-json-parser.js.map +1 -0
- package/dist/es5/lib/jsonpath/jsonpath.js +119 -0
- package/dist/es5/lib/jsonpath/jsonpath.js.map +1 -0
- package/dist/es5/lib/parsers/parse-json-in-batches.js +206 -0
- package/dist/es5/lib/parsers/parse-json-in-batches.js.map +1 -0
- package/dist/es5/lib/parsers/parse-json.js +38 -0
- package/dist/es5/lib/parsers/parse-json.js.map +1 -0
- package/dist/es5/lib/parsers/parse-ndjson-in-batches.js +114 -0
- package/dist/es5/lib/parsers/parse-ndjson-in-batches.js.map +1 -0
- package/dist/es5/lib/parsers/parse-ndjson.js +19 -0
- package/dist/es5/lib/parsers/parse-ndjson.js.map +1 -0
- package/dist/es5/ndgeoson-loader.js +54 -0
- package/dist/es5/ndgeoson-loader.js.map +1 -0
- package/dist/es5/ndjson-loader.js +44 -0
- package/dist/es5/ndjson-loader.js.map +1 -0
- package/dist/es5/workers/geojson-worker.js +6 -0
- package/dist/es5/workers/geojson-worker.js.map +1 -0
- package/dist/esm/bundle.js +4 -0
- package/dist/esm/bundle.js.map +1 -0
- package/dist/esm/geojson-loader.js +79 -0
- package/dist/esm/geojson-loader.js.map +1 -0
- package/dist/esm/geojson-writer.js +18 -0
- package/dist/esm/geojson-writer.js.map +1 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/json-loader.js +48 -0
- package/dist/esm/json-loader.js.map +1 -0
- package/dist/esm/json-writer.js +14 -0
- package/dist/esm/json-writer.js.map +1 -0
- package/dist/esm/lib/clarinet/LICENSE +28 -0
- package/dist/esm/lib/clarinet/clarinet.js +415 -0
- package/dist/esm/lib/clarinet/clarinet.js.map +1 -0
- package/dist/esm/lib/encoders/encode-utils.js +31 -0
- package/dist/esm/lib/encoders/encode-utils.js.map +1 -0
- package/dist/esm/lib/encoders/geojson-encoder.js +98 -0
- package/dist/esm/lib/encoders/geojson-encoder.js.map +1 -0
- package/dist/esm/lib/encoders/json-encoder.js +12 -0
- package/dist/esm/lib/encoders/json-encoder.js.map +1 -0
- package/dist/esm/lib/encoders/utf8-encoder.js +32 -0
- package/dist/esm/lib/encoders/utf8-encoder.js.map +1 -0
- package/dist/{lib/parser → esm/lib/json-parser}/json-parser.js +4 -22
- package/dist/esm/lib/json-parser/json-parser.js.map +1 -0
- package/dist/{lib/parser → esm/lib/json-parser}/streaming-json-parser.js +2 -23
- package/dist/esm/lib/json-parser/streaming-json-parser.js.map +1 -0
- package/dist/esm/lib/jsonpath/jsonpath.js +67 -0
- package/dist/esm/lib/jsonpath/jsonpath.js.map +1 -0
- package/dist/{lib → esm/lib/parsers}/parse-json-in-batches.js +19 -15
- package/dist/esm/lib/parsers/parse-json-in-batches.js.map +1 -0
- package/dist/{lib → esm/lib/parsers}/parse-json.js +4 -9
- package/dist/esm/lib/parsers/parse-json.js.map +1 -0
- package/dist/{lib → esm/lib/parsers}/parse-ndjson-in-batches.js +3 -6
- package/dist/esm/lib/parsers/parse-ndjson-in-batches.js.map +1 -0
- package/dist/esm/lib/parsers/parse-ndjson.js +13 -0
- package/dist/esm/lib/parsers/parse-ndjson.js.map +1 -0
- package/dist/esm/ndgeoson-loader.js +27 -0
- package/dist/esm/ndgeoson-loader.js.map +1 -0
- package/dist/esm/ndjson-loader.js +18 -0
- package/dist/esm/ndjson-loader.js.map +1 -0
- package/dist/esm/workers/geojson-worker.js +4 -0
- package/dist/esm/workers/geojson-worker.js.map +1 -0
- package/dist/geojson-loader.d.ts +16 -0
- package/dist/geojson-loader.d.ts.map +1 -0
- package/dist/geojson-loader.js +65 -69
- package/dist/geojson-worker.js +1016 -232
- package/dist/geojson-writer.d.ts +6 -0
- package/dist/geojson-writer.d.ts.map +1 -0
- package/dist/geojson-writer.js +22 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -6
- package/dist/json-loader.d.ts +17 -0
- package/dist/json-loader.d.ts.map +1 -0
- package/dist/json-loader.js +33 -38
- package/dist/json-writer.d.ts +6 -0
- package/dist/json-writer.d.ts.map +1 -0
- package/dist/json-writer.js +18 -0
- package/dist/lib/clarinet/clarinet.d.ts +74 -0
- package/dist/lib/clarinet/clarinet.d.ts.map +1 -0
- package/dist/lib/clarinet/clarinet.js +510 -493
- package/dist/lib/encoders/encode-utils.d.ts +19 -0
- package/dist/lib/encoders/encode-utils.d.ts.map +1 -0
- package/dist/lib/encoders/encode-utils.js +47 -0
- package/dist/lib/encoders/geojson-encoder.d.ts +14 -0
- package/dist/lib/encoders/geojson-encoder.d.ts.map +1 -0
- package/dist/lib/encoders/geojson-encoder.js +104 -0
- package/dist/lib/encoders/json-encoder.d.ts +16 -0
- package/dist/lib/encoders/json-encoder.d.ts.map +1 -0
- package/dist/lib/encoders/json-encoder.js +22 -0
- package/dist/lib/encoders/utf8-encoder.d.ts +12 -0
- package/dist/lib/encoders/utf8-encoder.d.ts.map +1 -0
- package/dist/lib/encoders/utf8-encoder.js +32 -0
- package/dist/lib/json-parser/json-parser.d.ts +22 -0
- package/dist/lib/json-parser/json-parser.d.ts.map +1 -0
- package/dist/lib/json-parser/json-parser.js +98 -0
- package/dist/lib/json-parser/streaming-json-parser.d.ts +37 -0
- package/dist/lib/json-parser/streaming-json-parser.d.ts.map +1 -0
- package/dist/lib/json-parser/streaming-json-parser.js +100 -0
- package/dist/lib/jsonpath/jsonpath.d.ts +32 -0
- package/dist/lib/jsonpath/jsonpath.d.ts.map +1 -0
- package/dist/lib/jsonpath/jsonpath.js +81 -78
- package/dist/lib/parsers/parse-json-in-batches.d.ts +5 -0
- package/dist/lib/parsers/parse-json-in-batches.d.ts.map +1 -0
- package/dist/lib/parsers/parse-json-in-batches.js +100 -0
- package/dist/lib/parsers/parse-json.d.ts +4 -0
- package/dist/lib/parsers/parse-json.d.ts.map +1 -0
- package/dist/lib/parsers/parse-json.js +32 -0
- package/dist/lib/parsers/parse-ndjson-in-batches.d.ts +4 -0
- package/dist/lib/parsers/parse-ndjson-in-batches.d.ts.map +1 -0
- package/dist/lib/parsers/parse-ndjson-in-batches.js +36 -0
- package/dist/lib/parsers/parse-ndjson.d.ts +3 -0
- package/dist/lib/parsers/parse-ndjson.d.ts.map +1 -0
- package/dist/lib/parsers/parse-ndjson.js +17 -0
- package/dist/ndgeoson-loader.d.ts +34 -0
- package/dist/ndgeoson-loader.d.ts.map +1 -0
- package/dist/ndgeoson-loader.js +37 -0
- package/dist/ndjson-loader.d.ts +4 -0
- package/dist/ndjson-loader.d.ts.map +1 -0
- package/dist/ndjson-loader.js +26 -31
- package/dist/workers/geojson-worker.d.ts +2 -0
- package/dist/workers/geojson-worker.d.ts.map +1 -0
- package/dist/workers/geojson-worker.js +5 -4
- package/package.json +10 -10
- package/src/geojson-loader.ts +10 -6
- package/src/geojson-writer.ts +27 -0
- package/src/index.ts +10 -0
- package/src/json-loader.ts +15 -24
- package/src/json-writer.ts +24 -0
- package/src/lib/encoders/encode-utils.ts +54 -0
- package/src/lib/encoders/geojson-encoder.ts +139 -0
- package/src/lib/encoders/json-encoder.ts +30 -0
- package/src/lib/encoders/utf8-encoder.ts +35 -0
- package/src/lib/{parse-json-in-batches.ts → parsers/parse-json-in-batches.ts} +30 -8
- package/src/lib/{parse-json.ts → parsers/parse-json.ts} +7 -3
- package/src/lib/{parse-ndjson-in-batches.ts → parsers/parse-ndjson-in-batches.ts} +1 -1
- package/src/lib/parsers/parse-ndjson.ts +15 -0
- package/src/ndgeoson-loader.ts +48 -0
- package/src/ndjson-loader.ts +20 -27
- package/dist/bundle.js.map +0 -1
- package/dist/geojson-loader.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/json-loader.js.map +0 -1
- package/dist/jsonl-loader.js +0 -2
- package/dist/jsonl-loader.js.map +0 -1
- package/dist/lib/clarinet/clarinet.js.map +0 -1
- package/dist/lib/jsonpath/jsonpath.js.map +0 -1
- package/dist/lib/parse-json-in-batches.js.map +0 -1
- package/dist/lib/parse-json.js.map +0 -1
- package/dist/lib/parse-ndjson-in-batches.js.map +0 -1
- package/dist/lib/parse-ndjson.js +0 -11
- package/dist/lib/parse-ndjson.js.map +0 -1
- package/dist/lib/parser/json-parser.js.map +0 -1
- package/dist/lib/parser/streaming-json-parser.js.map +0 -1
- package/dist/ndjson-loader.js.map +0 -1
- package/dist/workers/geojson-worker.js.map +0 -1
- package/src/jsonl-loader.ts +0 -53
- package/src/lib/parse-ndjson.ts +0 -10
- /package/dist/{lib → es5/lib}/clarinet/LICENSE +0 -0
- /package/src/lib/{parser → json-parser}/json-parser.ts +0 -0
- /package/src/lib/{parser → json-parser}/streaming-json-parser.ts +0 -0
package/dist/geojson-worker.js
CHANGED
|
@@ -35,16 +35,33 @@
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// ../worker-utils/src/lib/worker-farm/worker-body.ts
|
|
38
|
+
function getParentPort() {
|
|
39
|
+
let parentPort;
|
|
40
|
+
try {
|
|
41
|
+
eval("globalThis.parentPort = require('worker_threads').parentPort");
|
|
42
|
+
parentPort = globalThis.parentPort;
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
return parentPort;
|
|
46
|
+
}
|
|
38
47
|
var onMessageWrapperMap = new Map();
|
|
39
48
|
var WorkerBody = class {
|
|
49
|
+
static inWorkerThread() {
|
|
50
|
+
return typeof self !== "undefined" || Boolean(getParentPort());
|
|
51
|
+
}
|
|
40
52
|
static set onmessage(onMessage) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
const { type, payload } = message.data;
|
|
53
|
+
function handleMessage(message) {
|
|
54
|
+
const parentPort3 = getParentPort();
|
|
55
|
+
const { type, payload } = parentPort3 ? message : message.data;
|
|
46
56
|
onMessage(type, payload);
|
|
47
|
-
}
|
|
57
|
+
}
|
|
58
|
+
const parentPort2 = getParentPort();
|
|
59
|
+
if (parentPort2) {
|
|
60
|
+
parentPort2.on("message", handleMessage);
|
|
61
|
+
parentPort2.on("exit", () => console.debug("Node worker closing"));
|
|
62
|
+
} else {
|
|
63
|
+
globalThis.onmessage = handleMessage;
|
|
64
|
+
}
|
|
48
65
|
}
|
|
49
66
|
static addEventListener(onMessage) {
|
|
50
67
|
let onMessageWrapper = onMessageWrapperMap.get(onMessage);
|
|
@@ -53,22 +70,36 @@
|
|
|
53
70
|
if (!isKnownMessage(message)) {
|
|
54
71
|
return;
|
|
55
72
|
}
|
|
56
|
-
const
|
|
73
|
+
const parentPort3 = getParentPort();
|
|
74
|
+
const { type, payload } = parentPort3 ? message : message.data;
|
|
57
75
|
onMessage(type, payload);
|
|
58
76
|
};
|
|
59
77
|
}
|
|
60
|
-
|
|
78
|
+
const parentPort2 = getParentPort();
|
|
79
|
+
if (parentPort2) {
|
|
80
|
+
console.error("not implemented");
|
|
81
|
+
} else {
|
|
82
|
+
globalThis.addEventListener("message", onMessageWrapper);
|
|
83
|
+
}
|
|
61
84
|
}
|
|
62
85
|
static removeEventListener(onMessage) {
|
|
63
86
|
const onMessageWrapper = onMessageWrapperMap.get(onMessage);
|
|
64
87
|
onMessageWrapperMap.delete(onMessage);
|
|
65
|
-
|
|
88
|
+
const parentPort2 = getParentPort();
|
|
89
|
+
if (parentPort2) {
|
|
90
|
+
console.error("not implemented");
|
|
91
|
+
} else {
|
|
92
|
+
globalThis.removeEventListener("message", onMessageWrapper);
|
|
93
|
+
}
|
|
66
94
|
}
|
|
67
95
|
static postMessage(type, payload) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
96
|
+
const data = { source: "loaders.gl", type, payload };
|
|
97
|
+
const transferList = getTransferList(payload);
|
|
98
|
+
const parentPort2 = getParentPort();
|
|
99
|
+
if (parentPort2) {
|
|
100
|
+
parentPort2.postMessage(data, transferList);
|
|
101
|
+
} else {
|
|
102
|
+
globalThis.postMessage(data, transferList);
|
|
72
103
|
}
|
|
73
104
|
}
|
|
74
105
|
};
|
|
@@ -80,19 +111,20 @@
|
|
|
80
111
|
// ../loader-utils/src/lib/worker-loader-utils/create-loader-worker.ts
|
|
81
112
|
var requestId = 0;
|
|
82
113
|
function createLoaderWorker(loader) {
|
|
83
|
-
if (
|
|
114
|
+
if (!WorkerBody.inWorkerThread()) {
|
|
84
115
|
return;
|
|
85
116
|
}
|
|
86
117
|
WorkerBody.onmessage = async (type, payload) => {
|
|
87
118
|
switch (type) {
|
|
88
119
|
case "process":
|
|
89
120
|
try {
|
|
90
|
-
const { input, options = {} } = payload;
|
|
121
|
+
const { input, options = {}, context = {} } = payload;
|
|
91
122
|
const result = await parseData({
|
|
92
123
|
loader,
|
|
93
124
|
arrayBuffer: input,
|
|
94
125
|
options,
|
|
95
126
|
context: {
|
|
127
|
+
...context,
|
|
96
128
|
parse: parseOnMainThread
|
|
97
129
|
}
|
|
98
130
|
});
|
|
@@ -159,105 +191,518 @@
|
|
|
159
191
|
}
|
|
160
192
|
}
|
|
161
193
|
|
|
162
|
-
//
|
|
163
|
-
function
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
194
|
+
// ../../node_modules/@math.gl/polygon/dist/esm/polygon-utils.js
|
|
195
|
+
function getPolygonSignedArea(points, options = {}) {
|
|
196
|
+
const {
|
|
197
|
+
start = 0,
|
|
198
|
+
end = points.length
|
|
199
|
+
} = options;
|
|
200
|
+
const dim = options.size || 2;
|
|
201
|
+
let area2 = 0;
|
|
202
|
+
for (let i = start, j = end - dim; i < end; i += dim) {
|
|
203
|
+
area2 += (points[i] - points[j]) * (points[i + 1] + points[j + 1]);
|
|
204
|
+
j = i;
|
|
205
|
+
}
|
|
206
|
+
return area2 / 2;
|
|
170
207
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
let
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
208
|
+
|
|
209
|
+
// ../../node_modules/@math.gl/polygon/dist/esm/earcut.js
|
|
210
|
+
function earcut(positions, holeIndices, dim = 2, areas) {
|
|
211
|
+
const hasHoles = holeIndices && holeIndices.length;
|
|
212
|
+
const outerLen = hasHoles ? holeIndices[0] * dim : positions.length;
|
|
213
|
+
let outerNode = linkedList(positions, 0, outerLen, dim, true, areas && areas[0]);
|
|
214
|
+
const triangles = [];
|
|
215
|
+
if (!outerNode || outerNode.next === outerNode.prev)
|
|
216
|
+
return triangles;
|
|
217
|
+
let invSize;
|
|
218
|
+
let maxX;
|
|
219
|
+
let maxY;
|
|
220
|
+
let minX;
|
|
221
|
+
let minY;
|
|
222
|
+
let x;
|
|
223
|
+
let y;
|
|
224
|
+
if (hasHoles)
|
|
225
|
+
outerNode = eliminateHoles(positions, holeIndices, outerNode, dim, areas);
|
|
226
|
+
if (positions.length > 80 * dim) {
|
|
227
|
+
minX = maxX = positions[0];
|
|
228
|
+
minY = maxY = positions[1];
|
|
229
|
+
for (let i = dim; i < outerLen; i += dim) {
|
|
230
|
+
x = positions[i];
|
|
231
|
+
y = positions[i + 1];
|
|
232
|
+
if (x < minX)
|
|
233
|
+
minX = x;
|
|
234
|
+
if (y < minY)
|
|
235
|
+
minY = y;
|
|
236
|
+
if (x > maxX)
|
|
237
|
+
maxX = x;
|
|
238
|
+
if (y > maxY)
|
|
239
|
+
maxY = y;
|
|
240
|
+
}
|
|
241
|
+
invSize = Math.max(maxX - minX, maxY - minY);
|
|
242
|
+
invSize = invSize !== 0 ? 1 / invSize : 0;
|
|
243
|
+
}
|
|
244
|
+
earcutLinked(outerNode, triangles, dim, minX, minY, invSize);
|
|
245
|
+
return triangles;
|
|
246
|
+
}
|
|
247
|
+
function linkedList(data, start, end, dim, clockwise, area2) {
|
|
248
|
+
let i;
|
|
249
|
+
let last;
|
|
250
|
+
if (area2 === void 0) {
|
|
251
|
+
area2 = getPolygonSignedArea(data, {
|
|
252
|
+
start,
|
|
253
|
+
end,
|
|
254
|
+
size: dim
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
if (clockwise === area2 < 0) {
|
|
258
|
+
for (i = start; i < end; i += dim)
|
|
259
|
+
last = insertNode(i, data[i], data[i + 1], last);
|
|
260
|
+
} else {
|
|
261
|
+
for (i = end - dim; i >= start; i -= dim)
|
|
262
|
+
last = insertNode(i, data[i], data[i + 1], last);
|
|
263
|
+
}
|
|
264
|
+
if (last && equals(last, last.next)) {
|
|
265
|
+
removeNode(last);
|
|
266
|
+
last = last.next;
|
|
267
|
+
}
|
|
268
|
+
return last;
|
|
269
|
+
}
|
|
270
|
+
function filterPoints(start, end) {
|
|
271
|
+
if (!start)
|
|
272
|
+
return start;
|
|
273
|
+
if (!end)
|
|
274
|
+
end = start;
|
|
275
|
+
let p = start;
|
|
276
|
+
let again;
|
|
277
|
+
do {
|
|
278
|
+
again = false;
|
|
279
|
+
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
|
|
280
|
+
removeNode(p);
|
|
281
|
+
p = end = p.prev;
|
|
282
|
+
if (p === p.next)
|
|
215
283
|
break;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
284
|
+
again = true;
|
|
285
|
+
} else {
|
|
286
|
+
p = p.next;
|
|
287
|
+
}
|
|
288
|
+
} while (again || p !== end);
|
|
289
|
+
return end;
|
|
290
|
+
}
|
|
291
|
+
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
|
|
292
|
+
if (!ear)
|
|
293
|
+
return;
|
|
294
|
+
if (!pass && invSize)
|
|
295
|
+
indexCurve(ear, minX, minY, invSize);
|
|
296
|
+
let stop = ear;
|
|
297
|
+
let prev;
|
|
298
|
+
let next;
|
|
299
|
+
while (ear.prev !== ear.next) {
|
|
300
|
+
prev = ear.prev;
|
|
301
|
+
next = ear.next;
|
|
302
|
+
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
|
|
303
|
+
triangles.push(prev.i / dim);
|
|
304
|
+
triangles.push(ear.i / dim);
|
|
305
|
+
triangles.push(next.i / dim);
|
|
306
|
+
removeNode(ear);
|
|
307
|
+
ear = next.next;
|
|
308
|
+
stop = next.next;
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
ear = next;
|
|
312
|
+
if (ear === stop) {
|
|
313
|
+
if (!pass) {
|
|
314
|
+
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
|
|
315
|
+
} else if (pass === 1) {
|
|
316
|
+
ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
|
|
317
|
+
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
|
|
318
|
+
} else if (pass === 2) {
|
|
319
|
+
splitEarcut(ear, triangles, dim, minX, minY, invSize);
|
|
320
|
+
}
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function isEar(ear) {
|
|
326
|
+
const a = ear.prev;
|
|
327
|
+
const b = ear;
|
|
328
|
+
const c = ear.next;
|
|
329
|
+
if (area(a, b, c) >= 0)
|
|
330
|
+
return false;
|
|
331
|
+
let p = ear.next.next;
|
|
332
|
+
while (p !== ear.prev) {
|
|
333
|
+
if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0)
|
|
334
|
+
return false;
|
|
335
|
+
p = p.next;
|
|
336
|
+
}
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
function isEarHashed(ear, minX, minY, invSize) {
|
|
340
|
+
const a = ear.prev;
|
|
341
|
+
const b = ear;
|
|
342
|
+
const c = ear.next;
|
|
343
|
+
if (area(a, b, c) >= 0)
|
|
344
|
+
return false;
|
|
345
|
+
const minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x;
|
|
346
|
+
const minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y;
|
|
347
|
+
const maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x;
|
|
348
|
+
const maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y;
|
|
349
|
+
const minZ = zOrder(minTX, minTY, minX, minY, invSize);
|
|
350
|
+
const maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);
|
|
351
|
+
let p = ear.prevZ;
|
|
352
|
+
let n = ear.nextZ;
|
|
353
|
+
while (p && p.z >= minZ && n && n.z <= maxZ) {
|
|
354
|
+
if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0)
|
|
355
|
+
return false;
|
|
356
|
+
p = p.prevZ;
|
|
357
|
+
if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0)
|
|
358
|
+
return false;
|
|
359
|
+
n = n.nextZ;
|
|
360
|
+
}
|
|
361
|
+
while (p && p.z >= minZ) {
|
|
362
|
+
if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0)
|
|
363
|
+
return false;
|
|
364
|
+
p = p.prevZ;
|
|
365
|
+
}
|
|
366
|
+
while (n && n.z <= maxZ) {
|
|
367
|
+
if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0)
|
|
368
|
+
return false;
|
|
369
|
+
n = n.nextZ;
|
|
370
|
+
}
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
function cureLocalIntersections(start, triangles, dim) {
|
|
374
|
+
let p = start;
|
|
375
|
+
do {
|
|
376
|
+
const a = p.prev;
|
|
377
|
+
const b = p.next.next;
|
|
378
|
+
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
|
|
379
|
+
triangles.push(a.i / dim);
|
|
380
|
+
triangles.push(p.i / dim);
|
|
381
|
+
triangles.push(b.i / dim);
|
|
382
|
+
removeNode(p);
|
|
383
|
+
removeNode(p.next);
|
|
384
|
+
p = start = b;
|
|
385
|
+
}
|
|
386
|
+
p = p.next;
|
|
387
|
+
} while (p !== start);
|
|
388
|
+
return filterPoints(p);
|
|
389
|
+
}
|
|
390
|
+
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
|
|
391
|
+
let a = start;
|
|
392
|
+
do {
|
|
393
|
+
let b = a.next.next;
|
|
394
|
+
while (b !== a.prev) {
|
|
395
|
+
if (a.i !== b.i && isValidDiagonal(a, b)) {
|
|
396
|
+
let c = splitPolygon(a, b);
|
|
397
|
+
a = filterPoints(a, a.next);
|
|
398
|
+
c = filterPoints(c, c.next);
|
|
399
|
+
earcutLinked(a, triangles, dim, minX, minY, invSize);
|
|
400
|
+
earcutLinked(c, triangles, dim, minX, minY, invSize);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
b = b.next;
|
|
404
|
+
}
|
|
405
|
+
a = a.next;
|
|
406
|
+
} while (a !== start);
|
|
407
|
+
}
|
|
408
|
+
function eliminateHoles(data, holeIndices, outerNode, dim, areas) {
|
|
409
|
+
const queue = [];
|
|
410
|
+
let i;
|
|
411
|
+
let len;
|
|
412
|
+
let start;
|
|
413
|
+
let end;
|
|
414
|
+
let list;
|
|
415
|
+
for (i = 0, len = holeIndices.length; i < len; i++) {
|
|
416
|
+
start = holeIndices[i] * dim;
|
|
417
|
+
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
|
418
|
+
list = linkedList(data, start, end, dim, false, areas && areas[i + 1]);
|
|
419
|
+
if (list === list.next)
|
|
420
|
+
list.steiner = true;
|
|
421
|
+
queue.push(getLeftmost(list));
|
|
422
|
+
}
|
|
423
|
+
queue.sort(compareX);
|
|
424
|
+
for (i = 0; i < queue.length; i++) {
|
|
425
|
+
eliminateHole(queue[i], outerNode);
|
|
426
|
+
outerNode = filterPoints(outerNode, outerNode.next);
|
|
427
|
+
}
|
|
428
|
+
return outerNode;
|
|
429
|
+
}
|
|
430
|
+
function compareX(a, b) {
|
|
431
|
+
return a.x - b.x;
|
|
432
|
+
}
|
|
433
|
+
function eliminateHole(hole, outerNode) {
|
|
434
|
+
outerNode = findHoleBridge(hole, outerNode);
|
|
435
|
+
if (outerNode) {
|
|
436
|
+
const b = splitPolygon(outerNode, hole);
|
|
437
|
+
filterPoints(outerNode, outerNode.next);
|
|
438
|
+
filterPoints(b, b.next);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function findHoleBridge(hole, outerNode) {
|
|
442
|
+
let p = outerNode;
|
|
443
|
+
const hx = hole.x;
|
|
444
|
+
const hy = hole.y;
|
|
445
|
+
let qx = -Infinity;
|
|
446
|
+
let m;
|
|
447
|
+
do {
|
|
448
|
+
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
|
449
|
+
const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
|
|
450
|
+
if (x <= hx && x > qx) {
|
|
451
|
+
qx = x;
|
|
452
|
+
if (x === hx) {
|
|
453
|
+
if (hy === p.y)
|
|
454
|
+
return p;
|
|
455
|
+
if (hy === p.next.y)
|
|
456
|
+
return p.next;
|
|
223
457
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
458
|
+
m = p.x < p.next.x ? p : p.next;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
p = p.next;
|
|
462
|
+
} while (p !== outerNode);
|
|
463
|
+
if (!m)
|
|
464
|
+
return null;
|
|
465
|
+
if (hx === qx)
|
|
466
|
+
return m;
|
|
467
|
+
const stop = m;
|
|
468
|
+
const mx = m.x;
|
|
469
|
+
const my = m.y;
|
|
470
|
+
let tanMin = Infinity;
|
|
471
|
+
let tan;
|
|
472
|
+
p = m;
|
|
473
|
+
do {
|
|
474
|
+
if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
|
|
475
|
+
tan = Math.abs(hy - p.y) / (hx - p.x);
|
|
476
|
+
if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
|
|
477
|
+
m = p;
|
|
478
|
+
tanMin = tan;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
p = p.next;
|
|
482
|
+
} while (p !== stop);
|
|
483
|
+
return m;
|
|
484
|
+
}
|
|
485
|
+
function sectorContainsSector(m, p) {
|
|
486
|
+
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
|
|
487
|
+
}
|
|
488
|
+
function indexCurve(start, minX, minY, invSize) {
|
|
489
|
+
let p = start;
|
|
490
|
+
do {
|
|
491
|
+
if (p.z === null)
|
|
492
|
+
p.z = zOrder(p.x, p.y, minX, minY, invSize);
|
|
493
|
+
p.prevZ = p.prev;
|
|
494
|
+
p.nextZ = p.next;
|
|
495
|
+
p = p.next;
|
|
496
|
+
} while (p !== start);
|
|
497
|
+
p.prevZ.nextZ = null;
|
|
498
|
+
p.prevZ = null;
|
|
499
|
+
sortLinked(p);
|
|
500
|
+
}
|
|
501
|
+
function sortLinked(list) {
|
|
502
|
+
let e;
|
|
503
|
+
let i;
|
|
504
|
+
let inSize = 1;
|
|
505
|
+
let numMerges;
|
|
506
|
+
let p;
|
|
507
|
+
let pSize;
|
|
508
|
+
let q;
|
|
509
|
+
let qSize;
|
|
510
|
+
let tail;
|
|
511
|
+
do {
|
|
512
|
+
p = list;
|
|
513
|
+
list = null;
|
|
514
|
+
tail = null;
|
|
515
|
+
numMerges = 0;
|
|
516
|
+
while (p) {
|
|
517
|
+
numMerges++;
|
|
518
|
+
q = p;
|
|
519
|
+
pSize = 0;
|
|
520
|
+
for (i = 0; i < inSize; i++) {
|
|
521
|
+
pSize++;
|
|
522
|
+
q = q.nextZ;
|
|
523
|
+
if (!q)
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
qSize = inSize;
|
|
527
|
+
while (pSize > 0 || qSize > 0 && q) {
|
|
528
|
+
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
|
|
529
|
+
e = p;
|
|
530
|
+
p = p.nextZ;
|
|
531
|
+
pSize--;
|
|
532
|
+
} else {
|
|
533
|
+
e = q;
|
|
534
|
+
q = q.nextZ;
|
|
535
|
+
qSize--;
|
|
234
536
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
537
|
+
if (tail)
|
|
538
|
+
tail.nextZ = e;
|
|
539
|
+
else
|
|
540
|
+
list = e;
|
|
541
|
+
e.prevZ = tail;
|
|
542
|
+
tail = e;
|
|
543
|
+
}
|
|
544
|
+
p = q;
|
|
238
545
|
}
|
|
546
|
+
tail.nextZ = null;
|
|
547
|
+
inSize *= 2;
|
|
548
|
+
} while (numMerges > 1);
|
|
549
|
+
return list;
|
|
550
|
+
}
|
|
551
|
+
function zOrder(x, y, minX, minY, invSize) {
|
|
552
|
+
x = 32767 * (x - minX) * invSize;
|
|
553
|
+
y = 32767 * (y - minY) * invSize;
|
|
554
|
+
x = (x | x << 8) & 16711935;
|
|
555
|
+
x = (x | x << 4) & 252645135;
|
|
556
|
+
x = (x | x << 2) & 858993459;
|
|
557
|
+
x = (x | x << 1) & 1431655765;
|
|
558
|
+
y = (y | y << 8) & 16711935;
|
|
559
|
+
y = (y | y << 4) & 252645135;
|
|
560
|
+
y = (y | y << 2) & 858993459;
|
|
561
|
+
y = (y | y << 1) & 1431655765;
|
|
562
|
+
return x | y << 1;
|
|
563
|
+
}
|
|
564
|
+
function getLeftmost(start) {
|
|
565
|
+
let p = start;
|
|
566
|
+
let leftmost = start;
|
|
567
|
+
do {
|
|
568
|
+
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y)
|
|
569
|
+
leftmost = p;
|
|
570
|
+
p = p.next;
|
|
571
|
+
} while (p !== start);
|
|
572
|
+
return leftmost;
|
|
573
|
+
}
|
|
574
|
+
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
|
|
575
|
+
return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
|
|
576
|
+
}
|
|
577
|
+
function isValidDiagonal(a, b) {
|
|
578
|
+
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && (area(a.prev, a, b.prev) || area(a, b.prev, b)) || equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
|
|
579
|
+
}
|
|
580
|
+
function area(p, q, r) {
|
|
581
|
+
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
582
|
+
}
|
|
583
|
+
function equals(p1, p2) {
|
|
584
|
+
return p1.x === p2.x && p1.y === p2.y;
|
|
585
|
+
}
|
|
586
|
+
function intersects(p1, q1, p2, q2) {
|
|
587
|
+
const o1 = sign(area(p1, q1, p2));
|
|
588
|
+
const o2 = sign(area(p1, q1, q2));
|
|
589
|
+
const o3 = sign(area(p2, q2, p1));
|
|
590
|
+
const o4 = sign(area(p2, q2, q1));
|
|
591
|
+
if (o1 !== o2 && o3 !== o4)
|
|
592
|
+
return true;
|
|
593
|
+
if (o1 === 0 && onSegment(p1, p2, q1))
|
|
594
|
+
return true;
|
|
595
|
+
if (o2 === 0 && onSegment(p1, q2, q1))
|
|
596
|
+
return true;
|
|
597
|
+
if (o3 === 0 && onSegment(p2, p1, q2))
|
|
598
|
+
return true;
|
|
599
|
+
if (o4 === 0 && onSegment(p2, q1, q2))
|
|
600
|
+
return true;
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
function onSegment(p, q, r) {
|
|
604
|
+
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
605
|
+
}
|
|
606
|
+
function sign(num) {
|
|
607
|
+
return num > 0 ? 1 : num < 0 ? -1 : 0;
|
|
608
|
+
}
|
|
609
|
+
function intersectsPolygon(a, b) {
|
|
610
|
+
let p = a;
|
|
611
|
+
do {
|
|
612
|
+
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b))
|
|
613
|
+
return true;
|
|
614
|
+
p = p.next;
|
|
615
|
+
} while (p !== a);
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
function locallyInside(a, b) {
|
|
619
|
+
return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
|
|
620
|
+
}
|
|
621
|
+
function middleInside(a, b) {
|
|
622
|
+
let p = a;
|
|
623
|
+
let inside = false;
|
|
624
|
+
const px = (a.x + b.x) / 2;
|
|
625
|
+
const py = (a.y + b.y) / 2;
|
|
626
|
+
do {
|
|
627
|
+
if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
|
|
628
|
+
inside = !inside;
|
|
629
|
+
p = p.next;
|
|
630
|
+
} while (p !== a);
|
|
631
|
+
return inside;
|
|
632
|
+
}
|
|
633
|
+
function splitPolygon(a, b) {
|
|
634
|
+
const a2 = new Node(a.i, a.x, a.y);
|
|
635
|
+
const b2 = new Node(b.i, b.x, b.y);
|
|
636
|
+
const an = a.next;
|
|
637
|
+
const bp = b.prev;
|
|
638
|
+
a.next = b;
|
|
639
|
+
b.prev = a;
|
|
640
|
+
a2.next = an;
|
|
641
|
+
an.prev = a2;
|
|
642
|
+
b2.next = a2;
|
|
643
|
+
a2.prev = b2;
|
|
644
|
+
bp.next = b2;
|
|
645
|
+
b2.prev = bp;
|
|
646
|
+
return b2;
|
|
647
|
+
}
|
|
648
|
+
function insertNode(i, x, y, last) {
|
|
649
|
+
const p = new Node(i, x, y);
|
|
650
|
+
if (!last) {
|
|
651
|
+
p.prev = p;
|
|
652
|
+
p.next = p;
|
|
653
|
+
} else {
|
|
654
|
+
p.next = last.next;
|
|
655
|
+
p.prev = last;
|
|
656
|
+
last.next.prev = p;
|
|
657
|
+
last.next = p;
|
|
658
|
+
}
|
|
659
|
+
return p;
|
|
660
|
+
}
|
|
661
|
+
function removeNode(p) {
|
|
662
|
+
p.next.prev = p.prev;
|
|
663
|
+
p.prev.next = p.next;
|
|
664
|
+
if (p.prevZ)
|
|
665
|
+
p.prevZ.nextZ = p.nextZ;
|
|
666
|
+
if (p.nextZ)
|
|
667
|
+
p.nextZ.prevZ = p.prevZ;
|
|
668
|
+
}
|
|
669
|
+
function Node(i, x, y) {
|
|
670
|
+
this.i = i;
|
|
671
|
+
this.x = x;
|
|
672
|
+
this.y = y;
|
|
673
|
+
this.prev = null;
|
|
674
|
+
this.next = null;
|
|
675
|
+
this.z = null;
|
|
676
|
+
this.prevZ = null;
|
|
677
|
+
this.nextZ = null;
|
|
678
|
+
this.steiner = false;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// ../gis/src/lib/flat-geojson-to-binary.ts
|
|
682
|
+
function flatGeojsonToBinary(features, geometryInfo, options) {
|
|
683
|
+
const propArrayTypes = extractNumericPropTypes(features);
|
|
684
|
+
const numericPropKeys = Object.keys(propArrayTypes).filter((k) => propArrayTypes[k] !== Array);
|
|
685
|
+
return fillArrays(features, {
|
|
686
|
+
propArrayTypes,
|
|
687
|
+
...geometryInfo
|
|
688
|
+
}, {
|
|
689
|
+
numericPropKeys: options && options.numericPropKeys || numericPropKeys,
|
|
690
|
+
PositionDataType: options ? options.PositionDataType : Float32Array
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
function extractNumericPropTypes(features) {
|
|
694
|
+
const propArrayTypes = {};
|
|
695
|
+
for (const feature of features) {
|
|
239
696
|
if (feature.properties) {
|
|
240
697
|
for (const key in feature.properties) {
|
|
241
698
|
const val = feature.properties[key];
|
|
242
|
-
|
|
699
|
+
propArrayTypes[key] = deduceArrayType(val, propArrayTypes[key]);
|
|
243
700
|
}
|
|
244
701
|
}
|
|
245
702
|
}
|
|
246
|
-
return
|
|
247
|
-
coordLength: coordLengths.size > 0 ? Math.max(...coordLengths) : 2,
|
|
248
|
-
pointPositionsCount,
|
|
249
|
-
pointFeaturesCount,
|
|
250
|
-
linePositionsCount,
|
|
251
|
-
linePathsCount,
|
|
252
|
-
lineFeaturesCount,
|
|
253
|
-
polygonPositionsCount,
|
|
254
|
-
polygonObjectsCount,
|
|
255
|
-
polygonRingsCount,
|
|
256
|
-
polygonFeaturesCount,
|
|
257
|
-
numericPropKeys: Object.keys(numericPropKeys).filter((k) => numericPropKeys[k])
|
|
258
|
-
};
|
|
703
|
+
return propArrayTypes;
|
|
259
704
|
}
|
|
260
|
-
function
|
|
705
|
+
function fillArrays(features, geometryInfo, options) {
|
|
261
706
|
const {
|
|
262
707
|
pointPositionsCount,
|
|
263
708
|
pointFeaturesCount,
|
|
@@ -267,40 +712,48 @@
|
|
|
267
712
|
polygonPositionsCount,
|
|
268
713
|
polygonObjectsCount,
|
|
269
714
|
polygonRingsCount,
|
|
270
|
-
polygonFeaturesCount
|
|
271
|
-
|
|
272
|
-
|
|
715
|
+
polygonFeaturesCount,
|
|
716
|
+
propArrayTypes,
|
|
717
|
+
coordLength
|
|
718
|
+
} = geometryInfo;
|
|
719
|
+
const { numericPropKeys = [], PositionDataType = Float32Array } = options;
|
|
720
|
+
const hasGlobalId = features[0] && "id" in features[0];
|
|
273
721
|
const GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array;
|
|
274
722
|
const points = {
|
|
723
|
+
type: "Point",
|
|
275
724
|
positions: new PositionDataType(pointPositionsCount * coordLength),
|
|
276
725
|
globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount),
|
|
277
726
|
featureIds: pointFeaturesCount > 65535 ? new Uint32Array(pointPositionsCount) : new Uint16Array(pointPositionsCount),
|
|
278
727
|
numericProps: {},
|
|
279
|
-
properties:
|
|
280
|
-
fields:
|
|
728
|
+
properties: [],
|
|
729
|
+
fields: []
|
|
281
730
|
};
|
|
282
731
|
const lines = {
|
|
283
|
-
|
|
732
|
+
type: "LineString",
|
|
284
733
|
pathIndices: linePositionsCount > 65535 ? new Uint32Array(linePathsCount + 1) : new Uint16Array(linePathsCount + 1),
|
|
734
|
+
positions: new PositionDataType(linePositionsCount * coordLength),
|
|
285
735
|
globalFeatureIds: new GlobalFeatureIdsDataType(linePositionsCount),
|
|
286
736
|
featureIds: lineFeaturesCount > 65535 ? new Uint32Array(linePositionsCount) : new Uint16Array(linePositionsCount),
|
|
287
737
|
numericProps: {},
|
|
288
|
-
properties:
|
|
289
|
-
fields:
|
|
738
|
+
properties: [],
|
|
739
|
+
fields: []
|
|
290
740
|
};
|
|
291
741
|
const polygons = {
|
|
292
|
-
|
|
742
|
+
type: "Polygon",
|
|
293
743
|
polygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonObjectsCount + 1) : new Uint16Array(polygonObjectsCount + 1),
|
|
294
744
|
primitivePolygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonRingsCount + 1) : new Uint16Array(polygonRingsCount + 1),
|
|
745
|
+
positions: new PositionDataType(polygonPositionsCount * coordLength),
|
|
746
|
+
triangles: [],
|
|
295
747
|
globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount),
|
|
296
748
|
featureIds: polygonFeaturesCount > 65535 ? new Uint32Array(polygonPositionsCount) : new Uint16Array(polygonPositionsCount),
|
|
297
749
|
numericProps: {},
|
|
298
|
-
properties:
|
|
299
|
-
fields:
|
|
750
|
+
properties: [],
|
|
751
|
+
fields: []
|
|
300
752
|
};
|
|
301
753
|
for (const object of [points, lines, polygons]) {
|
|
302
|
-
for (const propName of numericPropKeys
|
|
303
|
-
|
|
754
|
+
for (const propName of numericPropKeys) {
|
|
755
|
+
const T = propArrayTypes[propName];
|
|
756
|
+
object.numericProps[propName] = new T(object.positions.length / coordLength);
|
|
304
757
|
}
|
|
305
758
|
}
|
|
306
759
|
lines.pathIndices[linePathsCount] = linePositionsCount;
|
|
@@ -323,33 +776,27 @@
|
|
|
323
776
|
const properties = feature.properties || {};
|
|
324
777
|
switch (geometry.type) {
|
|
325
778
|
case "Point":
|
|
326
|
-
handlePoint(geometry
|
|
327
|
-
points.properties.push(keepStringProperties(properties, numericPropKeys));
|
|
328
|
-
indexMap.pointFeature++;
|
|
329
|
-
break;
|
|
330
|
-
case "MultiPoint":
|
|
331
|
-
handleMultiPoint(geometry.coordinates, points, indexMap, coordLength, properties);
|
|
779
|
+
handlePoint(geometry, points, indexMap, coordLength, properties);
|
|
332
780
|
points.properties.push(keepStringProperties(properties, numericPropKeys));
|
|
781
|
+
if (hasGlobalId) {
|
|
782
|
+
points.fields.push({ id: feature.id });
|
|
783
|
+
}
|
|
333
784
|
indexMap.pointFeature++;
|
|
334
785
|
break;
|
|
335
786
|
case "LineString":
|
|
336
|
-
handleLineString(geometry
|
|
337
|
-
lines.properties.push(keepStringProperties(properties, numericPropKeys));
|
|
338
|
-
indexMap.lineFeature++;
|
|
339
|
-
break;
|
|
340
|
-
case "MultiLineString":
|
|
341
|
-
handleMultiLineString(geometry.coordinates, lines, indexMap, coordLength, properties);
|
|
787
|
+
handleLineString(geometry, lines, indexMap, coordLength, properties);
|
|
342
788
|
lines.properties.push(keepStringProperties(properties, numericPropKeys));
|
|
789
|
+
if (hasGlobalId) {
|
|
790
|
+
lines.fields.push({ id: feature.id });
|
|
791
|
+
}
|
|
343
792
|
indexMap.lineFeature++;
|
|
344
793
|
break;
|
|
345
794
|
case "Polygon":
|
|
346
|
-
handlePolygon(geometry
|
|
347
|
-
polygons.properties.push(keepStringProperties(properties, numericPropKeys));
|
|
348
|
-
indexMap.polygonFeature++;
|
|
349
|
-
break;
|
|
350
|
-
case "MultiPolygon":
|
|
351
|
-
handleMultiPolygon(geometry.coordinates, polygons, indexMap, coordLength, properties);
|
|
795
|
+
handlePolygon(geometry, polygons, indexMap, coordLength, properties);
|
|
352
796
|
polygons.properties.push(keepStringProperties(properties, numericPropKeys));
|
|
797
|
+
if (hasGlobalId) {
|
|
798
|
+
polygons.fields.push({ id: feature.id });
|
|
799
|
+
}
|
|
353
800
|
indexMap.polygonFeature++;
|
|
354
801
|
break;
|
|
355
802
|
default:
|
|
@@ -359,93 +806,105 @@
|
|
|
359
806
|
}
|
|
360
807
|
return makeAccessorObjects(points, lines, polygons, coordLength);
|
|
361
808
|
}
|
|
362
|
-
function handlePoint(
|
|
363
|
-
points.positions.set(
|
|
364
|
-
|
|
365
|
-
points
|
|
366
|
-
|
|
367
|
-
indexMap.pointPosition
|
|
368
|
-
|
|
369
|
-
function handleMultiPoint(coords, points, indexMap, coordLength, properties) {
|
|
370
|
-
for (const point of coords) {
|
|
371
|
-
handlePoint(point, points, indexMap, coordLength, properties);
|
|
372
|
-
}
|
|
809
|
+
function handlePoint(geometry, points, indexMap, coordLength, properties) {
|
|
810
|
+
points.positions.set(geometry.data, indexMap.pointPosition * coordLength);
|
|
811
|
+
const nPositions = geometry.data.length / coordLength;
|
|
812
|
+
fillNumericProperties(points, properties, indexMap.pointPosition, nPositions);
|
|
813
|
+
points.globalFeatureIds.fill(indexMap.feature, indexMap.pointPosition, indexMap.pointPosition + nPositions);
|
|
814
|
+
points.featureIds.fill(indexMap.pointFeature, indexMap.pointPosition, indexMap.pointPosition + nPositions);
|
|
815
|
+
indexMap.pointPosition += nPositions;
|
|
373
816
|
}
|
|
374
|
-
function handleLineString(
|
|
375
|
-
lines.
|
|
376
|
-
|
|
377
|
-
fillCoords(lines.positions, coords, indexMap.linePosition, coordLength);
|
|
378
|
-
const nPositions = coords.length;
|
|
817
|
+
function handleLineString(geometry, lines, indexMap, coordLength, properties) {
|
|
818
|
+
lines.positions.set(geometry.data, indexMap.linePosition * coordLength);
|
|
819
|
+
const nPositions = geometry.data.length / coordLength;
|
|
379
820
|
fillNumericProperties(lines, properties, indexMap.linePosition, nPositions);
|
|
380
|
-
lines.globalFeatureIds.
|
|
381
|
-
lines.featureIds.
|
|
382
|
-
|
|
821
|
+
lines.globalFeatureIds.fill(indexMap.feature, indexMap.linePosition, indexMap.linePosition + nPositions);
|
|
822
|
+
lines.featureIds.fill(indexMap.lineFeature, indexMap.linePosition, indexMap.linePosition + nPositions);
|
|
823
|
+
for (let i = 0, il = geometry.indices.length; i < il; ++i) {
|
|
824
|
+
const start = geometry.indices[i];
|
|
825
|
+
const end = i === il - 1 ? geometry.data.length : geometry.indices[i + 1];
|
|
826
|
+
lines.pathIndices[indexMap.linePath++] = indexMap.linePosition;
|
|
827
|
+
indexMap.linePosition += (end - start) / coordLength;
|
|
828
|
+
}
|
|
383
829
|
}
|
|
384
|
-
function
|
|
385
|
-
|
|
386
|
-
|
|
830
|
+
function handlePolygon(geometry, polygons, indexMap, coordLength, properties) {
|
|
831
|
+
polygons.positions.set(geometry.data, indexMap.polygonPosition * coordLength);
|
|
832
|
+
const nPositions = geometry.data.length / coordLength;
|
|
833
|
+
fillNumericProperties(polygons, properties, indexMap.polygonPosition, nPositions);
|
|
834
|
+
polygons.globalFeatureIds.fill(indexMap.feature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions);
|
|
835
|
+
polygons.featureIds.fill(indexMap.polygonFeature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions);
|
|
836
|
+
for (let l = 0, ll = geometry.indices.length; l < ll; ++l) {
|
|
837
|
+
const startPosition = indexMap.polygonPosition;
|
|
838
|
+
polygons.polygonIndices[indexMap.polygonObject++] = startPosition;
|
|
839
|
+
const areas = geometry.areas[l];
|
|
840
|
+
const indices = geometry.indices[l];
|
|
841
|
+
const nextIndices = geometry.indices[l + 1];
|
|
842
|
+
for (let i = 0, il = indices.length; i < il; ++i) {
|
|
843
|
+
const start = indices[i];
|
|
844
|
+
const end = i === il - 1 ? nextIndices === void 0 ? geometry.data.length : nextIndices[0] : indices[i + 1];
|
|
845
|
+
polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition;
|
|
846
|
+
indexMap.polygonPosition += (end - start) / coordLength;
|
|
847
|
+
}
|
|
848
|
+
const endPosition = indexMap.polygonPosition;
|
|
849
|
+
triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength });
|
|
387
850
|
}
|
|
388
851
|
}
|
|
389
|
-
function
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
852
|
+
function triangulatePolygon(polygons, areas, indices, {
|
|
853
|
+
startPosition,
|
|
854
|
+
endPosition,
|
|
855
|
+
coordLength
|
|
856
|
+
}) {
|
|
857
|
+
const start = startPosition * coordLength;
|
|
858
|
+
const end = endPosition * coordLength;
|
|
859
|
+
const polygonPositions = polygons.positions.subarray(start, end);
|
|
860
|
+
const offset = indices[0];
|
|
861
|
+
const holes = indices.slice(1).map((n) => (n - offset) / coordLength);
|
|
862
|
+
const triangles = earcut(polygonPositions, holes, coordLength, areas);
|
|
863
|
+
for (let t = 0, tl = triangles.length; t < tl; ++t) {
|
|
864
|
+
polygons.triangles.push(startPosition + triangles[t]);
|
|
401
865
|
}
|
|
402
866
|
}
|
|
403
|
-
function
|
|
404
|
-
|
|
405
|
-
|
|
867
|
+
function wrapProps(obj, size) {
|
|
868
|
+
const returnObj = {};
|
|
869
|
+
for (const key in obj) {
|
|
870
|
+
returnObj[key] = { value: obj[key], size };
|
|
406
871
|
}
|
|
872
|
+
return returnObj;
|
|
407
873
|
}
|
|
408
874
|
function makeAccessorObjects(points, lines, polygons, coordLength) {
|
|
409
|
-
|
|
875
|
+
return {
|
|
410
876
|
points: {
|
|
411
877
|
...points,
|
|
412
878
|
positions: { value: points.positions, size: coordLength },
|
|
413
879
|
globalFeatureIds: { value: points.globalFeatureIds, size: 1 },
|
|
414
880
|
featureIds: { value: points.featureIds, size: 1 },
|
|
415
|
-
|
|
881
|
+
numericProps: wrapProps(points.numericProps, 1)
|
|
416
882
|
},
|
|
417
883
|
lines: {
|
|
418
884
|
...lines,
|
|
419
|
-
pathIndices: { value: lines.pathIndices, size: 1 },
|
|
420
885
|
positions: { value: lines.positions, size: coordLength },
|
|
886
|
+
pathIndices: { value: lines.pathIndices, size: 1 },
|
|
421
887
|
globalFeatureIds: { value: lines.globalFeatureIds, size: 1 },
|
|
422
888
|
featureIds: { value: lines.featureIds, size: 1 },
|
|
423
|
-
|
|
889
|
+
numericProps: wrapProps(lines.numericProps, 1)
|
|
424
890
|
},
|
|
425
891
|
polygons: {
|
|
426
892
|
...polygons,
|
|
893
|
+
positions: { value: polygons.positions, size: coordLength },
|
|
427
894
|
polygonIndices: { value: polygons.polygonIndices, size: 1 },
|
|
428
895
|
primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 },
|
|
429
|
-
|
|
896
|
+
triangles: { value: new Uint32Array(polygons.triangles), size: 1 },
|
|
430
897
|
globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 },
|
|
431
898
|
featureIds: { value: polygons.featureIds, size: 1 },
|
|
432
|
-
|
|
899
|
+
numericProps: wrapProps(polygons.numericProps, 1)
|
|
433
900
|
}
|
|
434
901
|
};
|
|
435
|
-
for (const geomType in returnObj) {
|
|
436
|
-
for (const numericProp in returnObj[geomType].numericProps) {
|
|
437
|
-
returnObj[geomType].numericProps[numericProp] = {
|
|
438
|
-
value: returnObj[geomType].numericProps[numericProp],
|
|
439
|
-
size: 1
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
return returnObj;
|
|
444
902
|
}
|
|
445
903
|
function fillNumericProperties(object, properties, index, length) {
|
|
446
904
|
for (const numericPropName in object.numericProps) {
|
|
447
905
|
if (numericPropName in properties) {
|
|
448
|
-
|
|
906
|
+
const value = properties[numericPropName];
|
|
907
|
+
object.numericProps[numericPropName].fill(value, index, index + length);
|
|
449
908
|
}
|
|
450
909
|
}
|
|
451
910
|
}
|
|
@@ -458,50 +917,196 @@
|
|
|
458
917
|
}
|
|
459
918
|
return props;
|
|
460
919
|
}
|
|
461
|
-
function
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
array.set(coord, index);
|
|
465
|
-
index += coordLength;
|
|
920
|
+
function deduceArrayType(x, constructor) {
|
|
921
|
+
if (constructor === Array || !Number.isFinite(x)) {
|
|
922
|
+
return Array;
|
|
466
923
|
}
|
|
467
|
-
|
|
468
|
-
function flatten(arrays) {
|
|
469
|
-
return [].concat(...arrays);
|
|
470
|
-
}
|
|
471
|
-
function isNumeric(x) {
|
|
472
|
-
return Number.isFinite(x);
|
|
924
|
+
return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array;
|
|
473
925
|
}
|
|
474
926
|
|
|
475
|
-
// src/lib/
|
|
476
|
-
function
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
927
|
+
// ../gis/src/lib/extract-geometry-info.ts
|
|
928
|
+
function extractGeometryInfo(features) {
|
|
929
|
+
let pointPositionsCount = 0;
|
|
930
|
+
let pointFeaturesCount = 0;
|
|
931
|
+
let linePositionsCount = 0;
|
|
932
|
+
let linePathsCount = 0;
|
|
933
|
+
let lineFeaturesCount = 0;
|
|
934
|
+
let polygonPositionsCount = 0;
|
|
935
|
+
let polygonObjectsCount = 0;
|
|
936
|
+
let polygonRingsCount = 0;
|
|
937
|
+
let polygonFeaturesCount = 0;
|
|
938
|
+
const coordLengths = new Set();
|
|
939
|
+
for (const feature of features) {
|
|
940
|
+
const geometry = feature.geometry;
|
|
941
|
+
switch (geometry.type) {
|
|
942
|
+
case "Point":
|
|
943
|
+
pointFeaturesCount++;
|
|
944
|
+
pointPositionsCount++;
|
|
945
|
+
coordLengths.add(geometry.coordinates.length);
|
|
946
|
+
break;
|
|
947
|
+
case "MultiPoint":
|
|
948
|
+
pointFeaturesCount++;
|
|
949
|
+
pointPositionsCount += geometry.coordinates.length;
|
|
950
|
+
for (const point of geometry.coordinates) {
|
|
951
|
+
coordLengths.add(point.length);
|
|
952
|
+
}
|
|
953
|
+
break;
|
|
954
|
+
case "LineString":
|
|
955
|
+
lineFeaturesCount++;
|
|
956
|
+
linePositionsCount += geometry.coordinates.length;
|
|
957
|
+
linePathsCount++;
|
|
958
|
+
for (const coord of geometry.coordinates) {
|
|
959
|
+
coordLengths.add(coord.length);
|
|
960
|
+
}
|
|
961
|
+
break;
|
|
962
|
+
case "MultiLineString":
|
|
963
|
+
lineFeaturesCount++;
|
|
964
|
+
for (const line of geometry.coordinates) {
|
|
965
|
+
linePositionsCount += line.length;
|
|
966
|
+
linePathsCount++;
|
|
967
|
+
for (const coord of line) {
|
|
968
|
+
coordLengths.add(coord.length);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
break;
|
|
972
|
+
case "Polygon":
|
|
973
|
+
polygonFeaturesCount++;
|
|
974
|
+
polygonObjectsCount++;
|
|
975
|
+
polygonRingsCount += geometry.coordinates.length;
|
|
976
|
+
const flattened = geometry.coordinates.flat();
|
|
977
|
+
polygonPositionsCount += flattened.length;
|
|
978
|
+
for (const coord of flattened) {
|
|
979
|
+
coordLengths.add(coord.length);
|
|
980
|
+
}
|
|
981
|
+
break;
|
|
982
|
+
case "MultiPolygon":
|
|
983
|
+
polygonFeaturesCount++;
|
|
984
|
+
for (const polygon of geometry.coordinates) {
|
|
985
|
+
polygonObjectsCount++;
|
|
986
|
+
polygonRingsCount += polygon.length;
|
|
987
|
+
const flattened2 = polygon.flat();
|
|
988
|
+
polygonPositionsCount += flattened2.length;
|
|
989
|
+
for (const coord of flattened2) {
|
|
990
|
+
coordLengths.add(coord.length);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
break;
|
|
994
|
+
default:
|
|
995
|
+
throw new Error(`Unsupported geometry type: ${geometry.type}`);
|
|
481
996
|
}
|
|
482
|
-
return json;
|
|
483
|
-
} catch (error) {
|
|
484
|
-
throw new Error("JSONLoader: failed to parse JSON");
|
|
485
997
|
}
|
|
998
|
+
return {
|
|
999
|
+
coordLength: coordLengths.size > 0 ? Math.max(...coordLengths) : 2,
|
|
1000
|
+
pointPositionsCount,
|
|
1001
|
+
pointFeaturesCount,
|
|
1002
|
+
linePositionsCount,
|
|
1003
|
+
linePathsCount,
|
|
1004
|
+
lineFeaturesCount,
|
|
1005
|
+
polygonPositionsCount,
|
|
1006
|
+
polygonObjectsCount,
|
|
1007
|
+
polygonRingsCount,
|
|
1008
|
+
polygonFeaturesCount
|
|
1009
|
+
};
|
|
486
1010
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
1011
|
+
|
|
1012
|
+
// ../gis/src/lib/geojson-to-flat-geojson.ts
|
|
1013
|
+
function geojsonToFlatGeojson(features, options = { coordLength: 2, fixRingWinding: true }) {
|
|
1014
|
+
return features.map((feature) => flattenFeature(feature, options));
|
|
1015
|
+
}
|
|
1016
|
+
function flattenPoint(coordinates, data, indices, options) {
|
|
1017
|
+
indices.push(data.length);
|
|
1018
|
+
data.push(...coordinates);
|
|
1019
|
+
for (let i = coordinates.length; i < options.coordLength; i++) {
|
|
1020
|
+
data.push(0);
|
|
490
1021
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
1022
|
+
}
|
|
1023
|
+
function flattenLineString(coordinates, data, indices, options) {
|
|
1024
|
+
indices.push(data.length);
|
|
1025
|
+
for (const c of coordinates) {
|
|
1026
|
+
data.push(...c);
|
|
1027
|
+
for (let i = c.length; i < options.coordLength; i++) {
|
|
1028
|
+
data.push(0);
|
|
497
1029
|
}
|
|
498
1030
|
}
|
|
499
|
-
|
|
1031
|
+
}
|
|
1032
|
+
function flattenPolygon(coordinates, data, indices, areas, options) {
|
|
1033
|
+
let count = 0;
|
|
1034
|
+
const ringAreas = [];
|
|
1035
|
+
const polygons = [];
|
|
1036
|
+
for (const lineString of coordinates) {
|
|
1037
|
+
const lineString2d = lineString.map((p) => p.slice(0, 2));
|
|
1038
|
+
let area2 = getPolygonSignedArea(lineString2d.flat());
|
|
1039
|
+
const ccw = area2 < 0;
|
|
1040
|
+
if (options.fixRingWinding && (count === 0 && !ccw || count > 0 && ccw)) {
|
|
1041
|
+
lineString.reverse();
|
|
1042
|
+
area2 = -area2;
|
|
1043
|
+
}
|
|
1044
|
+
ringAreas.push(area2);
|
|
1045
|
+
flattenLineString(lineString, data, polygons, options);
|
|
1046
|
+
count++;
|
|
1047
|
+
}
|
|
1048
|
+
if (count > 0) {
|
|
1049
|
+
areas.push(ringAreas);
|
|
1050
|
+
indices.push(polygons);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
function flattenFeature(feature, options) {
|
|
1054
|
+
const { geometry } = feature;
|
|
1055
|
+
if (geometry.type === "GeometryCollection") {
|
|
1056
|
+
throw new Error("GeometryCollection type not supported");
|
|
1057
|
+
}
|
|
1058
|
+
const data = [];
|
|
1059
|
+
const indices = [];
|
|
1060
|
+
let areas;
|
|
1061
|
+
let type;
|
|
1062
|
+
switch (geometry.type) {
|
|
1063
|
+
case "Point":
|
|
1064
|
+
type = "Point";
|
|
1065
|
+
flattenPoint(geometry.coordinates, data, indices, options);
|
|
1066
|
+
break;
|
|
1067
|
+
case "MultiPoint":
|
|
1068
|
+
type = "Point";
|
|
1069
|
+
geometry.coordinates.map((c) => flattenPoint(c, data, indices, options));
|
|
1070
|
+
break;
|
|
1071
|
+
case "LineString":
|
|
1072
|
+
type = "LineString";
|
|
1073
|
+
flattenLineString(geometry.coordinates, data, indices, options);
|
|
1074
|
+
break;
|
|
1075
|
+
case "MultiLineString":
|
|
1076
|
+
type = "LineString";
|
|
1077
|
+
geometry.coordinates.map((c) => flattenLineString(c, data, indices, options));
|
|
1078
|
+
break;
|
|
1079
|
+
case "Polygon":
|
|
1080
|
+
type = "Polygon";
|
|
1081
|
+
areas = [];
|
|
1082
|
+
flattenPolygon(geometry.coordinates, data, indices, areas, options);
|
|
1083
|
+
break;
|
|
1084
|
+
case "MultiPolygon":
|
|
1085
|
+
type = "Polygon";
|
|
1086
|
+
areas = [];
|
|
1087
|
+
geometry.coordinates.map((c) => flattenPolygon(c, data, indices, areas, options));
|
|
1088
|
+
break;
|
|
1089
|
+
default:
|
|
1090
|
+
throw new Error(`Unknown type: ${type}`);
|
|
1091
|
+
}
|
|
1092
|
+
return { ...feature, geometry: { type, indices, data, areas } };
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// ../gis/src/lib/geojson-to-binary.ts
|
|
1096
|
+
function geojsonToBinary(features, options = { fixRingWinding: true }) {
|
|
1097
|
+
const geometryInfo = extractGeometryInfo(features);
|
|
1098
|
+
const coordLength = geometryInfo.coordLength;
|
|
1099
|
+
const { fixRingWinding } = options;
|
|
1100
|
+
const flatFeatures = geojsonToFlatGeojson(features, { coordLength, fixRingWinding });
|
|
1101
|
+
return flatGeojsonToBinary(flatFeatures, geometryInfo, {
|
|
1102
|
+
numericPropKeys: options.numericPropKeys,
|
|
1103
|
+
PositionDataType: options.PositionDataType || Float32Array
|
|
1104
|
+
});
|
|
500
1105
|
}
|
|
501
1106
|
|
|
502
|
-
// ../schema/src/lib/batches/base-table-batch-aggregator.ts
|
|
1107
|
+
// ../schema/src/lib/table/batches/base-table-batch-aggregator.ts
|
|
503
1108
|
var DEFAULT_ROW_COUNT = 100;
|
|
504
|
-
var
|
|
1109
|
+
var BaseTableBatchAggregator = class {
|
|
505
1110
|
constructor(schema, options) {
|
|
506
1111
|
this.length = 0;
|
|
507
1112
|
this.rows = null;
|
|
@@ -554,7 +1159,7 @@
|
|
|
554
1159
|
}
|
|
555
1160
|
};
|
|
556
1161
|
|
|
557
|
-
// ../schema/src/lib/
|
|
1162
|
+
// ../schema/src/lib/table/simple-table/row-utils.ts
|
|
558
1163
|
function convertToObjectRow(arrayRow, headers) {
|
|
559
1164
|
if (!arrayRow) {
|
|
560
1165
|
throw new Error("null row");
|
|
@@ -582,9 +1187,9 @@
|
|
|
582
1187
|
return arrayRow;
|
|
583
1188
|
}
|
|
584
1189
|
|
|
585
|
-
// ../schema/src/lib/batches/row-table-batch-aggregator.ts
|
|
1190
|
+
// ../schema/src/lib/table/batches/row-table-batch-aggregator.ts
|
|
586
1191
|
var DEFAULT_ROW_COUNT2 = 100;
|
|
587
|
-
var
|
|
1192
|
+
var RowTableBatchAggregator = class {
|
|
588
1193
|
constructor(schema, options) {
|
|
589
1194
|
this.length = 0;
|
|
590
1195
|
this.objectRows = null;
|
|
@@ -654,7 +1259,7 @@
|
|
|
654
1259
|
}
|
|
655
1260
|
};
|
|
656
1261
|
|
|
657
|
-
// ../schema/src/lib/batches/columnar-table-batch-aggregator.ts
|
|
1262
|
+
// ../schema/src/lib/table/batches/columnar-table-batch-aggregator.ts
|
|
658
1263
|
var DEFAULT_ROW_COUNT3 = 100;
|
|
659
1264
|
var ColumnarTableBatchAggregator = class {
|
|
660
1265
|
constructor(schema, options) {
|
|
@@ -730,7 +1335,7 @@
|
|
|
730
1335
|
}
|
|
731
1336
|
};
|
|
732
1337
|
|
|
733
|
-
// ../schema/src/lib/batches/table-batch-builder.ts
|
|
1338
|
+
// ../schema/src/lib/table/batches/table-batch-builder.ts
|
|
734
1339
|
var DEFAULT_OPTIONS = {
|
|
735
1340
|
shape: "array-row-table",
|
|
736
1341
|
batchSize: "auto",
|
|
@@ -842,10 +1447,10 @@
|
|
|
842
1447
|
_getTableBatchType() {
|
|
843
1448
|
switch (this.options.shape) {
|
|
844
1449
|
case "row-table":
|
|
845
|
-
return
|
|
1450
|
+
return BaseTableBatchAggregator;
|
|
846
1451
|
case "array-row-table":
|
|
847
1452
|
case "object-row-table":
|
|
848
|
-
return
|
|
1453
|
+
return RowTableBatchAggregator;
|
|
849
1454
|
case "columnar-table":
|
|
850
1455
|
return ColumnarTableBatchAggregator;
|
|
851
1456
|
case "arrow-table":
|
|
@@ -859,6 +1464,184 @@
|
|
|
859
1464
|
}
|
|
860
1465
|
};
|
|
861
1466
|
|
|
1467
|
+
// ../schema/src/lib/table/simple-table/data-type.ts
|
|
1468
|
+
function getDataTypeFromValue(value, defaultNumberType = "float32") {
|
|
1469
|
+
if (value instanceof Date) {
|
|
1470
|
+
return "date-millisecond";
|
|
1471
|
+
}
|
|
1472
|
+
if (value instanceof Number) {
|
|
1473
|
+
return defaultNumberType;
|
|
1474
|
+
}
|
|
1475
|
+
if (typeof value === "string") {
|
|
1476
|
+
return "utf8";
|
|
1477
|
+
}
|
|
1478
|
+
if (value === null || value === "undefined") {
|
|
1479
|
+
return "null";
|
|
1480
|
+
}
|
|
1481
|
+
return "null";
|
|
1482
|
+
}
|
|
1483
|
+
function getDataTypeFromArray(array) {
|
|
1484
|
+
let type = getDataTypeFromTypedArray(array);
|
|
1485
|
+
if (type !== "null") {
|
|
1486
|
+
return { type, nullable: false };
|
|
1487
|
+
}
|
|
1488
|
+
if (array.length > 0) {
|
|
1489
|
+
type = getDataTypeFromValue(array[0]);
|
|
1490
|
+
return { type, nullable: true };
|
|
1491
|
+
}
|
|
1492
|
+
return { type: "null", nullable: true };
|
|
1493
|
+
}
|
|
1494
|
+
function getDataTypeFromTypedArray(array) {
|
|
1495
|
+
switch (array.constructor) {
|
|
1496
|
+
case Int8Array:
|
|
1497
|
+
return "int8";
|
|
1498
|
+
case Uint8Array:
|
|
1499
|
+
case Uint8ClampedArray:
|
|
1500
|
+
return "uint8";
|
|
1501
|
+
case Int16Array:
|
|
1502
|
+
return "int16";
|
|
1503
|
+
case Uint16Array:
|
|
1504
|
+
return "uint16";
|
|
1505
|
+
case Int32Array:
|
|
1506
|
+
return "int32";
|
|
1507
|
+
case Uint32Array:
|
|
1508
|
+
return "uint32";
|
|
1509
|
+
case Float32Array:
|
|
1510
|
+
return "float32";
|
|
1511
|
+
case Float64Array:
|
|
1512
|
+
return "float64";
|
|
1513
|
+
default:
|
|
1514
|
+
return "null";
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
// ../schema/src/lib/table/simple-table/table-schema.ts
|
|
1519
|
+
function deduceTableSchema(table) {
|
|
1520
|
+
switch (table.shape) {
|
|
1521
|
+
case "array-row-table":
|
|
1522
|
+
case "object-row-table":
|
|
1523
|
+
return deduceSchemaFromRows(table.data);
|
|
1524
|
+
case "columnar-table":
|
|
1525
|
+
return deduceSchemaFromColumns(table.data);
|
|
1526
|
+
case "arrow-table":
|
|
1527
|
+
default:
|
|
1528
|
+
throw new Error("Deduce schema");
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
function deduceSchemaFromColumns(columnarTable) {
|
|
1532
|
+
const fields = [];
|
|
1533
|
+
for (const [columnName, column] of Object.entries(columnarTable)) {
|
|
1534
|
+
const field = deduceFieldFromColumn(column, columnName);
|
|
1535
|
+
fields.push(field);
|
|
1536
|
+
}
|
|
1537
|
+
return { fields, metadata: {} };
|
|
1538
|
+
}
|
|
1539
|
+
function deduceSchemaFromRows(rowTable) {
|
|
1540
|
+
if (!rowTable.length) {
|
|
1541
|
+
throw new Error("deduce from empty table");
|
|
1542
|
+
}
|
|
1543
|
+
const fields = [];
|
|
1544
|
+
const row0 = rowTable[0];
|
|
1545
|
+
for (const [columnName, value] of Object.entries(row0)) {
|
|
1546
|
+
fields.push(deduceFieldFromValue(value, columnName));
|
|
1547
|
+
}
|
|
1548
|
+
return { fields, metadata: {} };
|
|
1549
|
+
}
|
|
1550
|
+
function deduceFieldFromColumn(column, name) {
|
|
1551
|
+
if (ArrayBuffer.isView(column)) {
|
|
1552
|
+
const type = getDataTypeFromArray(column);
|
|
1553
|
+
return {
|
|
1554
|
+
name,
|
|
1555
|
+
type: type.type || "null",
|
|
1556
|
+
nullable: type.nullable
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
if (Array.isArray(column) && column.length > 0) {
|
|
1560
|
+
const value = column[0];
|
|
1561
|
+
const type = getDataTypeFromValue(value);
|
|
1562
|
+
return {
|
|
1563
|
+
name,
|
|
1564
|
+
type,
|
|
1565
|
+
nullable: true
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
throw new Error("empty table");
|
|
1569
|
+
}
|
|
1570
|
+
function deduceFieldFromValue(value, name) {
|
|
1571
|
+
const type = getDataTypeFromValue(value);
|
|
1572
|
+
return {
|
|
1573
|
+
name,
|
|
1574
|
+
type,
|
|
1575
|
+
nullable: true
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
// ../schema/src/lib/table/simple-table/make-table.ts
|
|
1580
|
+
function makeTableFromData(data) {
|
|
1581
|
+
let table;
|
|
1582
|
+
switch (getTableShapeFromData(data)) {
|
|
1583
|
+
case "array-row-table":
|
|
1584
|
+
table = { shape: "array-row-table", data };
|
|
1585
|
+
break;
|
|
1586
|
+
case "object-row-table":
|
|
1587
|
+
table = { shape: "object-row-table", data };
|
|
1588
|
+
break;
|
|
1589
|
+
case "columnar-table":
|
|
1590
|
+
table = { shape: "columnar-table", data };
|
|
1591
|
+
break;
|
|
1592
|
+
default:
|
|
1593
|
+
throw new Error("table");
|
|
1594
|
+
}
|
|
1595
|
+
const schema = deduceTableSchema(table);
|
|
1596
|
+
return { ...table, schema };
|
|
1597
|
+
}
|
|
1598
|
+
function getTableShapeFromData(data) {
|
|
1599
|
+
if (Array.isArray(data)) {
|
|
1600
|
+
if (data.length === 0) {
|
|
1601
|
+
throw new Error("cannot deduce type of empty table");
|
|
1602
|
+
}
|
|
1603
|
+
const firstRow = data[0];
|
|
1604
|
+
if (Array.isArray(firstRow)) {
|
|
1605
|
+
return "array-row-table";
|
|
1606
|
+
}
|
|
1607
|
+
if (firstRow && typeof firstRow === "object") {
|
|
1608
|
+
return "object-row-table";
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
if (data && typeof data === "object") {
|
|
1612
|
+
return "columnar-table";
|
|
1613
|
+
}
|
|
1614
|
+
throw new Error("invalid table");
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
// src/lib/parsers/parse-json.ts
|
|
1618
|
+
function parseJSONSync(jsonText, options) {
|
|
1619
|
+
try {
|
|
1620
|
+
const json = JSON.parse(jsonText);
|
|
1621
|
+
if (options.json?.table) {
|
|
1622
|
+
const data = getFirstArray(json) || json;
|
|
1623
|
+
return makeTableFromData(data);
|
|
1624
|
+
}
|
|
1625
|
+
return json;
|
|
1626
|
+
} catch (error) {
|
|
1627
|
+
throw new Error("JSONLoader: failed to parse JSON");
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
function getFirstArray(json) {
|
|
1631
|
+
if (Array.isArray(json)) {
|
|
1632
|
+
return json;
|
|
1633
|
+
}
|
|
1634
|
+
if (json && typeof json === "object") {
|
|
1635
|
+
for (const value of Object.values(json)) {
|
|
1636
|
+
const array = getFirstArray(value);
|
|
1637
|
+
if (array) {
|
|
1638
|
+
return array;
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
return null;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
862
1645
|
// src/lib/clarinet/clarinet.ts
|
|
863
1646
|
var MAX_BUFFER_LENGTH = Number.MAX_SAFE_INTEGER;
|
|
864
1647
|
var STATE;
|
|
@@ -1415,7 +2198,7 @@ Char: ${this.c}`;
|
|
|
1415
2198
|
}
|
|
1416
2199
|
};
|
|
1417
2200
|
|
|
1418
|
-
// src/lib/parser/json-parser.ts
|
|
2201
|
+
// src/lib/json-parser/json-parser.ts
|
|
1419
2202
|
var JSONParser = class {
|
|
1420
2203
|
constructor(options) {
|
|
1421
2204
|
this.result = void 0;
|
|
@@ -1503,7 +2286,7 @@ Char: ${this.c}`;
|
|
|
1503
2286
|
}
|
|
1504
2287
|
};
|
|
1505
2288
|
|
|
1506
|
-
// src/lib/parser/streaming-json-parser.ts
|
|
2289
|
+
// src/lib/json-parser/streaming-json-parser.ts
|
|
1507
2290
|
var StreamingJSONParser = class extends JSONParser {
|
|
1508
2291
|
constructor(options = {}) {
|
|
1509
2292
|
super({
|
|
@@ -1571,7 +2354,7 @@ Char: ${this.c}`;
|
|
|
1571
2354
|
}
|
|
1572
2355
|
};
|
|
1573
2356
|
|
|
1574
|
-
// src/lib/parse-json-in-batches.ts
|
|
2357
|
+
// src/lib/parsers/parse-json-in-batches.ts
|
|
1575
2358
|
async function* parseJSONInBatches(binaryAsyncIterator, options) {
|
|
1576
2359
|
const asyncIterator = makeTextDecoderIterator(binaryAsyncIterator);
|
|
1577
2360
|
const { metadata } = options;
|
|
@@ -1634,7 +2417,7 @@ Char: ${this.c}`;
|
|
|
1634
2417
|
}
|
|
1635
2418
|
|
|
1636
2419
|
// src/geojson-loader.ts
|
|
1637
|
-
var VERSION =
|
|
2420
|
+
var VERSION = true ? "4.0.0-alpha.6" : "latest";
|
|
1638
2421
|
var DEFAULT_GEOJSON_LOADER_OPTIONS = {
|
|
1639
2422
|
geojson: {
|
|
1640
2423
|
shape: "object-row-table"
|
|
@@ -1671,12 +2454,13 @@ Char: ${this.c}`;
|
|
|
1671
2454
|
options = { ...DEFAULT_GEOJSON_LOADER_OPTIONS, ...options };
|
|
1672
2455
|
options.json = { ...DEFAULT_GEOJSON_LOADER_OPTIONS.geojson, ...options.geojson };
|
|
1673
2456
|
options.gis = options.gis || {};
|
|
1674
|
-
const
|
|
2457
|
+
const table = parseJSONSync(text, options);
|
|
2458
|
+
table.shape = "geojson-row-table";
|
|
1675
2459
|
switch (options.gis.format) {
|
|
1676
2460
|
case "binary":
|
|
1677
|
-
return geojsonToBinary(
|
|
2461
|
+
return geojsonToBinary(table.data);
|
|
1678
2462
|
default:
|
|
1679
|
-
return
|
|
2463
|
+
return table;
|
|
1680
2464
|
}
|
|
1681
2465
|
}
|
|
1682
2466
|
function parseInBatches(asyncIterator, options) {
|