@carto/api-client 0.5.0-alpha.6 → 0.5.0-alpha.8
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/build/api-client.cjs +97 -111
- package/build/api-client.d.cts +69 -62
- package/build/api-client.d.ts +69 -62
- package/build/api-client.js +2130 -170
- package/build/worker.js +2119 -4
- package/package.json +5 -5
- package/src/models/common.ts +2 -2
- package/src/sources/h3-tileset-source.ts +1 -8
- package/src/sources/quadbin-tileset-source.ts +1 -8
- package/src/sources/vector-tileset-source.ts +1 -8
- package/src/widget-sources/index.ts +0 -1
- package/src/widget-sources/types.ts +1 -1
- package/src/widget-sources/widget-remote-source.ts +16 -16
- package/src/widget-sources/widget-source.ts +11 -0
- package/src/widget-sources/widget-tileset-source-impl.ts +417 -0
- package/src/widget-sources/widget-tileset-source.ts +192 -331
- package/src/workers/widget-tileset-worker.ts +6 -3
- package/build/chunk-LEI5PI5X.js +0 -2063
- package/src/widget-sources/widget-tileset-worker-source.ts +0 -268
- package/src/workers/utils.ts +0 -33
package/build/api-client.js
CHANGED
|
@@ -1,47 +1,1244 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __commonJS = (cb, mod2) => function __require() {
|
|
9
|
+
return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target,
|
|
25
|
+
mod2
|
|
26
|
+
));
|
|
27
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
28
|
+
|
|
29
|
+
// node_modules/tilebelt/index.js
|
|
30
|
+
var require_tilebelt = __commonJS({
|
|
31
|
+
"node_modules/tilebelt/index.js"(exports, module) {
|
|
32
|
+
"use strict";
|
|
33
|
+
var d2r = Math.PI / 180;
|
|
34
|
+
var r2d = 180 / Math.PI;
|
|
35
|
+
function tileToBBOX(tile) {
|
|
36
|
+
var e = tile2lon(tile[0] + 1, tile[2]);
|
|
37
|
+
var w = tile2lon(tile[0], tile[2]);
|
|
38
|
+
var s = tile2lat(tile[1] + 1, tile[2]);
|
|
39
|
+
var n = tile2lat(tile[1], tile[2]);
|
|
40
|
+
return [w, s, e, n];
|
|
41
|
+
}
|
|
42
|
+
function tileToGeoJSON(tile) {
|
|
43
|
+
var bbox = tileToBBOX(tile);
|
|
44
|
+
var poly = {
|
|
45
|
+
type: "Polygon",
|
|
46
|
+
coordinates: [
|
|
47
|
+
[
|
|
48
|
+
[bbox[0], bbox[1]],
|
|
49
|
+
[bbox[0], bbox[3]],
|
|
50
|
+
[bbox[2], bbox[3]],
|
|
51
|
+
[bbox[2], bbox[1]],
|
|
52
|
+
[bbox[0], bbox[1]]
|
|
53
|
+
]
|
|
54
|
+
]
|
|
55
|
+
};
|
|
56
|
+
return poly;
|
|
57
|
+
}
|
|
58
|
+
function tile2lon(x, z) {
|
|
59
|
+
return x / Math.pow(2, z) * 360 - 180;
|
|
60
|
+
}
|
|
61
|
+
function tile2lat(y, z) {
|
|
62
|
+
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
|
|
63
|
+
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
|
64
|
+
}
|
|
65
|
+
function pointToTile(lon, lat, z) {
|
|
66
|
+
var tile = pointToTileFraction(lon, lat, z);
|
|
67
|
+
tile[0] = Math.floor(tile[0]);
|
|
68
|
+
tile[1] = Math.floor(tile[1]);
|
|
69
|
+
return tile;
|
|
70
|
+
}
|
|
71
|
+
function getChildren(tile) {
|
|
72
|
+
return [
|
|
73
|
+
[tile[0] * 2, tile[1] * 2, tile[2] + 1],
|
|
74
|
+
[tile[0] * 2 + 1, tile[1] * 2, tile[2] + 1],
|
|
75
|
+
[tile[0] * 2 + 1, tile[1] * 2 + 1, tile[2] + 1],
|
|
76
|
+
[tile[0] * 2, tile[1] * 2 + 1, tile[2] + 1]
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
function getParent(tile) {
|
|
80
|
+
if (tile[0] % 2 === 0 && tile[1] % 2 === 0) {
|
|
81
|
+
return [tile[0] / 2, tile[1] / 2, tile[2] - 1];
|
|
82
|
+
} else if (tile[0] % 2 === 0 && !tile[1] % 2 === 0) {
|
|
83
|
+
return [tile[0] / 2, (tile[1] - 1) / 2, tile[2] - 1];
|
|
84
|
+
} else if (!tile[0] % 2 === 0 && tile[1] % 2 === 0) {
|
|
85
|
+
return [(tile[0] - 1) / 2, tile[1] / 2, tile[2] - 1];
|
|
86
|
+
} else {
|
|
87
|
+
return [(tile[0] - 1) / 2, (tile[1] - 1) / 2, tile[2] - 1];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function getSiblings(tile) {
|
|
91
|
+
return getChildren(getParent(tile));
|
|
92
|
+
}
|
|
93
|
+
function hasSiblings(tile, tiles2) {
|
|
94
|
+
var siblings = getSiblings(tile);
|
|
95
|
+
for (var i = 0; i < siblings.length; i++) {
|
|
96
|
+
if (!hasTile(tiles2, siblings[i])) return false;
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
function hasTile(tiles2, tile) {
|
|
101
|
+
for (var i = 0; i < tiles2.length; i++) {
|
|
102
|
+
if (tilesEqual(tiles2[i], tile)) return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
function tilesEqual(tile1, tile2) {
|
|
107
|
+
return tile1[0] === tile2[0] && tile1[1] === tile2[1] && tile1[2] === tile2[2];
|
|
108
|
+
}
|
|
109
|
+
function tileToQuadkey(tile) {
|
|
110
|
+
var index = "";
|
|
111
|
+
for (var z = tile[2]; z > 0; z--) {
|
|
112
|
+
var b = 0;
|
|
113
|
+
var mask = 1 << z - 1;
|
|
114
|
+
if ((tile[0] & mask) !== 0) b++;
|
|
115
|
+
if ((tile[1] & mask) !== 0) b += 2;
|
|
116
|
+
index += b.toString();
|
|
117
|
+
}
|
|
118
|
+
return index;
|
|
119
|
+
}
|
|
120
|
+
function quadkeyToTile(quadkey) {
|
|
121
|
+
var x = 0;
|
|
122
|
+
var y = 0;
|
|
123
|
+
var z = quadkey.length;
|
|
124
|
+
for (var i = z; i > 0; i--) {
|
|
125
|
+
var mask = 1 << i - 1;
|
|
126
|
+
switch (quadkey[z - i]) {
|
|
127
|
+
case "0":
|
|
128
|
+
break;
|
|
129
|
+
case "1":
|
|
130
|
+
x |= mask;
|
|
131
|
+
break;
|
|
132
|
+
case "2":
|
|
133
|
+
y |= mask;
|
|
134
|
+
break;
|
|
135
|
+
case "3":
|
|
136
|
+
x |= mask;
|
|
137
|
+
y |= mask;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return [x, y, z];
|
|
142
|
+
}
|
|
143
|
+
function bboxToTile(bboxCoords) {
|
|
144
|
+
var min2 = pointToTile(bboxCoords[0], bboxCoords[1], 32);
|
|
145
|
+
var max2 = pointToTile(bboxCoords[2], bboxCoords[3], 32);
|
|
146
|
+
var bbox = [min2[0], min2[1], max2[0], max2[1]];
|
|
147
|
+
var z = getBboxZoom(bbox);
|
|
148
|
+
if (z === 0) return [0, 0, 0];
|
|
149
|
+
var x = bbox[0] >>> 32 - z;
|
|
150
|
+
var y = bbox[1] >>> 32 - z;
|
|
151
|
+
return [x, y, z];
|
|
152
|
+
}
|
|
153
|
+
function getBboxZoom(bbox) {
|
|
154
|
+
var MAX_ZOOM = 28;
|
|
155
|
+
for (var z = 0; z < MAX_ZOOM; z++) {
|
|
156
|
+
var mask = 1 << 32 - (z + 1);
|
|
157
|
+
if ((bbox[0] & mask) != (bbox[2] & mask) || (bbox[1] & mask) != (bbox[3] & mask)) {
|
|
158
|
+
return z;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return MAX_ZOOM;
|
|
162
|
+
}
|
|
163
|
+
function pointToTileFraction(lon, lat, z) {
|
|
164
|
+
var sin2 = Math.sin(lat * d2r), z2 = Math.pow(2, z), x = z2 * (lon / 360 + 0.5), y = z2 * (0.5 - 0.25 * Math.log((1 + sin2) / (1 - sin2)) / Math.PI);
|
|
165
|
+
return [x, y, z];
|
|
166
|
+
}
|
|
167
|
+
module.exports = {
|
|
168
|
+
tileToGeoJSON,
|
|
169
|
+
tileToBBOX,
|
|
170
|
+
getChildren,
|
|
171
|
+
getParent,
|
|
172
|
+
getSiblings,
|
|
173
|
+
hasTile,
|
|
174
|
+
hasSiblings,
|
|
175
|
+
tilesEqual,
|
|
176
|
+
tileToQuadkey,
|
|
177
|
+
quadkeyToTile,
|
|
178
|
+
pointToTile,
|
|
179
|
+
bboxToTile,
|
|
180
|
+
pointToTileFraction
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// node_modules/@mapbox/tile-cover/index.js
|
|
186
|
+
var require_tile_cover = __commonJS({
|
|
187
|
+
"node_modules/@mapbox/tile-cover/index.js"(exports) {
|
|
188
|
+
"use strict";
|
|
189
|
+
var tilebelt = require_tilebelt();
|
|
190
|
+
exports.geojson = function(geom, limits) {
|
|
191
|
+
return {
|
|
192
|
+
type: "FeatureCollection",
|
|
193
|
+
features: getTiles(geom, limits).map(tileToFeature)
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
function tileToFeature(t) {
|
|
197
|
+
return {
|
|
198
|
+
type: "Feature",
|
|
199
|
+
geometry: tilebelt.tileToGeoJSON(t),
|
|
200
|
+
properties: {}
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
exports.tiles = getTiles;
|
|
204
|
+
exports.indexes = function(geom, limits) {
|
|
205
|
+
return getTiles(geom, limits).map(tilebelt.tileToQuadkey);
|
|
206
|
+
};
|
|
207
|
+
function getTiles(geom, limits) {
|
|
208
|
+
var i, tile, coords = geom.coordinates, maxZoom = limits.max_zoom, tileHash = {}, tiles2 = [];
|
|
209
|
+
if (geom.type === "Point") {
|
|
210
|
+
return [tilebelt.pointToTile(coords[0], coords[1], maxZoom)];
|
|
211
|
+
} else if (geom.type === "MultiPoint") {
|
|
212
|
+
for (i = 0; i < coords.length; i++) {
|
|
213
|
+
tile = tilebelt.pointToTile(coords[i][0], coords[i][1], maxZoom);
|
|
214
|
+
tileHash[toID(tile[0], tile[1], tile[2])] = true;
|
|
215
|
+
}
|
|
216
|
+
} else if (geom.type === "LineString") {
|
|
217
|
+
lineCover(tileHash, coords, maxZoom);
|
|
218
|
+
} else if (geom.type === "MultiLineString") {
|
|
219
|
+
for (i = 0; i < coords.length; i++) {
|
|
220
|
+
lineCover(tileHash, coords[i], maxZoom);
|
|
221
|
+
}
|
|
222
|
+
} else if (geom.type === "Polygon") {
|
|
223
|
+
polygonCover(tileHash, tiles2, coords, maxZoom);
|
|
224
|
+
} else if (geom.type === "MultiPolygon") {
|
|
225
|
+
for (i = 0; i < coords.length; i++) {
|
|
226
|
+
polygonCover(tileHash, tiles2, coords[i], maxZoom);
|
|
227
|
+
}
|
|
228
|
+
} else {
|
|
229
|
+
throw new Error("Geometry type not implemented");
|
|
230
|
+
}
|
|
231
|
+
if (limits.min_zoom !== maxZoom) {
|
|
232
|
+
var len = tiles2.length;
|
|
233
|
+
appendHashTiles(tileHash, tiles2);
|
|
234
|
+
for (i = 0; i < len; i++) {
|
|
235
|
+
var t = tiles2[i];
|
|
236
|
+
tileHash[toID(t[0], t[1], t[2])] = true;
|
|
237
|
+
}
|
|
238
|
+
return mergeTiles(tileHash, tiles2, limits);
|
|
239
|
+
}
|
|
240
|
+
appendHashTiles(tileHash, tiles2);
|
|
241
|
+
return tiles2;
|
|
242
|
+
}
|
|
243
|
+
function mergeTiles(tileHash, tiles2, limits) {
|
|
244
|
+
var mergedTiles = [];
|
|
245
|
+
for (var z = limits.max_zoom; z > limits.min_zoom; z--) {
|
|
246
|
+
var parentTileHash = {};
|
|
247
|
+
var parentTiles = [];
|
|
248
|
+
for (var i = 0; i < tiles2.length; i++) {
|
|
249
|
+
var t = tiles2[i];
|
|
250
|
+
if (t[0] % 2 === 0 && t[1] % 2 === 0) {
|
|
251
|
+
var id2 = toID(t[0] + 1, t[1], z), id3 = toID(t[0], t[1] + 1, z), id4 = toID(t[0] + 1, t[1] + 1, z);
|
|
252
|
+
if (tileHash[id2] && tileHash[id3] && tileHash[id4]) {
|
|
253
|
+
tileHash[toID(t[0], t[1], t[2])] = false;
|
|
254
|
+
tileHash[id2] = false;
|
|
255
|
+
tileHash[id3] = false;
|
|
256
|
+
tileHash[id4] = false;
|
|
257
|
+
var parentTile = [t[0] / 2, t[1] / 2, z - 1];
|
|
258
|
+
if (z - 1 === limits.min_zoom) mergedTiles.push(parentTile);
|
|
259
|
+
else {
|
|
260
|
+
parentTileHash[toID(t[0] / 2, t[1] / 2, z - 1)] = true;
|
|
261
|
+
parentTiles.push(parentTile);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
for (i = 0; i < tiles2.length; i++) {
|
|
267
|
+
t = tiles2[i];
|
|
268
|
+
if (tileHash[toID(t[0], t[1], t[2])]) mergedTiles.push(t);
|
|
269
|
+
}
|
|
270
|
+
tileHash = parentTileHash;
|
|
271
|
+
tiles2 = parentTiles;
|
|
272
|
+
}
|
|
273
|
+
return mergedTiles;
|
|
274
|
+
}
|
|
275
|
+
function polygonCover(tileHash, tileArray, geom, zoom) {
|
|
276
|
+
var intersections = [];
|
|
277
|
+
for (var i = 0; i < geom.length; i++) {
|
|
278
|
+
var ring = [];
|
|
279
|
+
lineCover(tileHash, geom[i], zoom, ring);
|
|
280
|
+
for (var j = 0, len = ring.length, k = len - 1; j < len; k = j++) {
|
|
281
|
+
var m = (j + 1) % len;
|
|
282
|
+
var y = ring[j][1];
|
|
283
|
+
if ((y > ring[k][1] || y > ring[m][1]) && // not local minimum
|
|
284
|
+
(y < ring[k][1] || y < ring[m][1]) && // not local maximum
|
|
285
|
+
y !== ring[m][1]) intersections.push(ring[j]);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
intersections.sort(compareTiles);
|
|
289
|
+
for (i = 0; i < intersections.length; i += 2) {
|
|
290
|
+
y = intersections[i][1];
|
|
291
|
+
for (var x = intersections[i][0] + 1; x < intersections[i + 1][0]; x++) {
|
|
292
|
+
var id = toID(x, y, zoom);
|
|
293
|
+
if (!tileHash[id]) {
|
|
294
|
+
tileArray.push([x, y, zoom]);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function compareTiles(a, b) {
|
|
300
|
+
return a[1] - b[1] || a[0] - b[0];
|
|
301
|
+
}
|
|
302
|
+
function lineCover(tileHash, coords, maxZoom, ring) {
|
|
303
|
+
var prevX, prevY;
|
|
304
|
+
for (var i = 0; i < coords.length - 1; i++) {
|
|
305
|
+
var start = tilebelt.pointToTileFraction(coords[i][0], coords[i][1], maxZoom), stop = tilebelt.pointToTileFraction(coords[i + 1][0], coords[i + 1][1], maxZoom), x0 = start[0], y0 = start[1], x1 = stop[0], y1 = stop[1], dx = x1 - x0, dy = y1 - y0;
|
|
306
|
+
if (dy === 0 && dx === 0) continue;
|
|
307
|
+
var sx = dx > 0 ? 1 : -1, sy = dy > 0 ? 1 : -1, x = Math.floor(x0), y = Math.floor(y0), tMaxX = dx === 0 ? Infinity : Math.abs(((dx > 0 ? 1 : 0) + x - x0) / dx), tMaxY = dy === 0 ? Infinity : Math.abs(((dy > 0 ? 1 : 0) + y - y0) / dy), tdx = Math.abs(sx / dx), tdy = Math.abs(sy / dy);
|
|
308
|
+
if (x !== prevX || y !== prevY) {
|
|
309
|
+
tileHash[toID(x, y, maxZoom)] = true;
|
|
310
|
+
if (ring && y !== prevY) ring.push([x, y]);
|
|
311
|
+
prevX = x;
|
|
312
|
+
prevY = y;
|
|
313
|
+
}
|
|
314
|
+
while (tMaxX < 1 || tMaxY < 1) {
|
|
315
|
+
if (tMaxX < tMaxY) {
|
|
316
|
+
tMaxX += tdx;
|
|
317
|
+
x += sx;
|
|
318
|
+
} else {
|
|
319
|
+
tMaxY += tdy;
|
|
320
|
+
y += sy;
|
|
321
|
+
}
|
|
322
|
+
tileHash[toID(x, y, maxZoom)] = true;
|
|
323
|
+
if (ring && y !== prevY) ring.push([x, y]);
|
|
324
|
+
prevX = x;
|
|
325
|
+
prevY = y;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (ring && y === ring[0][1]) ring.pop();
|
|
329
|
+
}
|
|
330
|
+
function appendHashTiles(hash, tiles2) {
|
|
331
|
+
var keys = Object.keys(hash);
|
|
332
|
+
for (var i = 0; i < keys.length; i++) {
|
|
333
|
+
tiles2.push(fromID(+keys[i]));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function toID(x, y, z) {
|
|
337
|
+
var dim = 2 * (1 << z);
|
|
338
|
+
return (dim * y + x) * 32 + z;
|
|
339
|
+
}
|
|
340
|
+
function fromID(id) {
|
|
341
|
+
var z = id % 32, dim = 2 * (1 << z), xy = (id - z) / 32, x = xy % dim, y = (xy - x) / dim % dim;
|
|
342
|
+
return [x, y, z];
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// node_modules/thenby/thenBy.module.js
|
|
348
|
+
var require_thenBy_module = __commonJS({
|
|
349
|
+
"node_modules/thenby/thenBy.module.js"(exports, module) {
|
|
350
|
+
"use strict";
|
|
351
|
+
module.exports = function() {
|
|
352
|
+
function identity(v) {
|
|
353
|
+
return v;
|
|
354
|
+
}
|
|
355
|
+
function ignoreCase(v) {
|
|
356
|
+
return typeof v === "string" ? v.toLowerCase() : v;
|
|
357
|
+
}
|
|
358
|
+
function makeCompareFunction(f, opt) {
|
|
359
|
+
opt = typeof opt === "object" ? opt : { direction: opt };
|
|
360
|
+
if (typeof f != "function") {
|
|
361
|
+
var prop = f;
|
|
362
|
+
f = function(v1) {
|
|
363
|
+
return !!v1[prop] ? v1[prop] : "";
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
if (f.length === 1) {
|
|
367
|
+
var uf = f;
|
|
368
|
+
var preprocess = opt.ignoreCase ? ignoreCase : identity;
|
|
369
|
+
var cmp = opt.cmp || function(v1, v2) {
|
|
370
|
+
return v1 < v2 ? -1 : v1 > v2 ? 1 : 0;
|
|
371
|
+
};
|
|
372
|
+
f = function(v1, v2) {
|
|
373
|
+
return cmp(preprocess(uf(v1)), preprocess(uf(v2)));
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
const descTokens = { "-1": "", desc: "" };
|
|
377
|
+
if (opt.direction in descTokens) return function(v1, v2) {
|
|
378
|
+
return -f(v1, v2);
|
|
379
|
+
};
|
|
380
|
+
return f;
|
|
381
|
+
}
|
|
382
|
+
function tb(func, opt) {
|
|
383
|
+
var x = typeof this == "function" && !this.firstBy ? this : false;
|
|
384
|
+
var y = makeCompareFunction(func, opt);
|
|
385
|
+
var f = x ? function(a, b) {
|
|
386
|
+
return x(a, b) || y(a, b);
|
|
387
|
+
} : y;
|
|
388
|
+
f.thenBy = tb;
|
|
389
|
+
return f;
|
|
390
|
+
}
|
|
391
|
+
tb.firstBy = tb;
|
|
392
|
+
return tb;
|
|
393
|
+
}();
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// src/client.ts
|
|
398
|
+
var client = "deck-gl-carto";
|
|
399
|
+
function getClient() {
|
|
400
|
+
return client;
|
|
401
|
+
}
|
|
402
|
+
function setClient(c) {
|
|
403
|
+
client = c;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// src/constants.ts
|
|
407
|
+
var FilterType = /* @__PURE__ */ ((FilterType2) => {
|
|
408
|
+
FilterType2["IN"] = "in";
|
|
409
|
+
FilterType2["BETWEEN"] = "between";
|
|
410
|
+
FilterType2["CLOSED_OPEN"] = "closed_open";
|
|
411
|
+
FilterType2["TIME"] = "time";
|
|
412
|
+
FilterType2["STRING_SEARCH"] = "stringSearch";
|
|
413
|
+
return FilterType2;
|
|
414
|
+
})(FilterType || {});
|
|
415
|
+
var ApiVersion = /* @__PURE__ */ ((ApiVersion2) => {
|
|
416
|
+
ApiVersion2["V1"] = "v1";
|
|
417
|
+
ApiVersion2["V2"] = "v2";
|
|
418
|
+
ApiVersion2["V3"] = "v3";
|
|
419
|
+
return ApiVersion2;
|
|
420
|
+
})(ApiVersion || {});
|
|
421
|
+
var DEFAULT_API_BASE_URL = "https://gcp-us-east1.api.carto.com";
|
|
422
|
+
var TileFormat = /* @__PURE__ */ ((TileFormat2) => {
|
|
423
|
+
TileFormat2["MVT"] = "mvt";
|
|
424
|
+
TileFormat2["JSON"] = "json";
|
|
425
|
+
TileFormat2["GEOJSON"] = "geojson";
|
|
426
|
+
TileFormat2["BINARY"] = "binary";
|
|
427
|
+
return TileFormat2;
|
|
428
|
+
})(TileFormat || {});
|
|
429
|
+
var SpatialIndex = /* @__PURE__ */ ((SpatialIndex2) => {
|
|
430
|
+
SpatialIndex2["H3"] = "h3";
|
|
431
|
+
SpatialIndex2["S2"] = "s2";
|
|
432
|
+
SpatialIndex2["QUADBIN"] = "quadbin";
|
|
433
|
+
return SpatialIndex2;
|
|
434
|
+
})(SpatialIndex || {});
|
|
435
|
+
var Provider = /* @__PURE__ */ ((Provider2) => {
|
|
436
|
+
Provider2["BIGQUERY"] = "bigquery";
|
|
437
|
+
Provider2["REDSHIFT"] = "redshift";
|
|
438
|
+
Provider2["POSTGRES"] = "postgres";
|
|
439
|
+
Provider2["SNOWFLAKE"] = "snowflake";
|
|
440
|
+
Provider2["DATABRICKS"] = "databricks";
|
|
441
|
+
Provider2["DATABRICKS_REST"] = "databricksRest";
|
|
442
|
+
return Provider2;
|
|
443
|
+
})(Provider || {});
|
|
444
|
+
|
|
445
|
+
// src/utils/makeIntervalComplete.ts
|
|
446
|
+
function makeIntervalComplete(intervals) {
|
|
447
|
+
return intervals.map((val) => {
|
|
448
|
+
if (val[0] === void 0 || val[0] === null) {
|
|
449
|
+
return [Number.MIN_SAFE_INTEGER, val[1]];
|
|
450
|
+
}
|
|
451
|
+
if (val[1] === void 0 || val[1] === null) {
|
|
452
|
+
return [val[0], Number.MAX_SAFE_INTEGER];
|
|
453
|
+
}
|
|
454
|
+
return val;
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// src/filters/FilterTypes.ts
|
|
459
|
+
var filterFunctions = {
|
|
460
|
+
["in" /* IN */]: filterIn,
|
|
461
|
+
["between" /* BETWEEN */]: filterBetween,
|
|
462
|
+
["time" /* TIME */]: filterTime,
|
|
463
|
+
["closed_open" /* CLOSED_OPEN */]: filterClosedOpen,
|
|
464
|
+
["stringSearch" /* STRING_SEARCH */]: filterStringSearch
|
|
465
|
+
};
|
|
466
|
+
function filterIn(filterValues, featureValue) {
|
|
467
|
+
return filterValues.includes(featureValue);
|
|
468
|
+
}
|
|
469
|
+
function filterBetween(filterValues, featureValue) {
|
|
470
|
+
const checkRange = (range) => {
|
|
471
|
+
const [lowerBound, upperBound] = range;
|
|
472
|
+
return featureValue >= lowerBound && featureValue <= upperBound;
|
|
473
|
+
};
|
|
474
|
+
return makeIntervalComplete(filterValues).some(
|
|
475
|
+
checkRange
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
function filterTime(filterValues, featureValue) {
|
|
479
|
+
const featureValueAsTimestamp = new Date(featureValue).getTime();
|
|
480
|
+
if (isFinite(featureValueAsTimestamp)) {
|
|
481
|
+
return filterBetween(filterValues, featureValueAsTimestamp);
|
|
482
|
+
} else {
|
|
483
|
+
throw new Error(`Column used to filter by time isn't well formatted.`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function filterClosedOpen(filterValues, featureValue) {
|
|
487
|
+
const checkRange = (range) => {
|
|
488
|
+
const [lowerBound, upperBound] = range;
|
|
489
|
+
return featureValue >= lowerBound && featureValue < upperBound;
|
|
490
|
+
};
|
|
491
|
+
return makeIntervalComplete(filterValues).some(
|
|
492
|
+
checkRange
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
function filterStringSearch(filterValues, featureValue, params = {}) {
|
|
496
|
+
const normalizedFeatureValue = normalize(featureValue, params);
|
|
497
|
+
const stringRegExp = params.useRegExp ? filterValues : filterValues.map((filterValue) => {
|
|
498
|
+
let stringRegExp2 = escapeRegExp(normalize(filterValue, params));
|
|
499
|
+
if (params.mustStart) stringRegExp2 = `^${stringRegExp2}`;
|
|
500
|
+
if (params.mustEnd) stringRegExp2 = `${stringRegExp2}$`;
|
|
501
|
+
return stringRegExp2;
|
|
502
|
+
});
|
|
503
|
+
const regex = new RegExp(
|
|
504
|
+
stringRegExp.join("|"),
|
|
505
|
+
params.caseSensitive ? "g" : "gi"
|
|
506
|
+
);
|
|
507
|
+
return !!normalizedFeatureValue.match(regex);
|
|
508
|
+
}
|
|
509
|
+
var specialCharRegExp = /[.*+?^${}()|[\]\\]/g;
|
|
510
|
+
var normalizeRegExp = /\p{Diacritic}/gu;
|
|
511
|
+
function escapeRegExp(value) {
|
|
512
|
+
return value.replace(specialCharRegExp, "\\$&");
|
|
513
|
+
}
|
|
514
|
+
function normalize(data, params) {
|
|
515
|
+
let normalizedData = String(data);
|
|
516
|
+
if (!params.keepSpecialCharacters)
|
|
517
|
+
normalizedData = normalizedData.normalize("NFD").replace(normalizeRegExp, "");
|
|
518
|
+
return normalizedData;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/filters/Filter.ts
|
|
522
|
+
var LOGICAL_OPERATOR_METHODS = {
|
|
523
|
+
and: "every",
|
|
524
|
+
or: "some"
|
|
525
|
+
};
|
|
526
|
+
function passesFilter(columns, filters, feature2, filtersLogicalOperator) {
|
|
527
|
+
const method = LOGICAL_OPERATOR_METHODS[filtersLogicalOperator];
|
|
528
|
+
return columns[method]((column) => {
|
|
529
|
+
const columnFilters = filters[column];
|
|
530
|
+
const columnFilterTypes = Object.keys(columnFilters);
|
|
531
|
+
if (!feature2 || feature2[column] === null || feature2[column] === void 0) {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
return columnFilterTypes.every((filter) => {
|
|
535
|
+
const filterFunction = filterFunctions[filter];
|
|
536
|
+
if (!filterFunction) {
|
|
537
|
+
throw new Error(`"${filter}" filter is not implemented.`);
|
|
538
|
+
}
|
|
539
|
+
return filterFunction(
|
|
540
|
+
columnFilters[filter].values,
|
|
541
|
+
feature2[column],
|
|
542
|
+
columnFilters[filter].params
|
|
543
|
+
);
|
|
544
|
+
});
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
function _buildFeatureFilter({
|
|
548
|
+
filters = {},
|
|
549
|
+
type = "boolean",
|
|
550
|
+
filtersLogicalOperator = "and"
|
|
551
|
+
}) {
|
|
552
|
+
const columns = Object.keys(filters);
|
|
553
|
+
if (!columns.length) {
|
|
554
|
+
return () => type === "number" ? 1 : true;
|
|
555
|
+
}
|
|
556
|
+
return (feature2) => {
|
|
557
|
+
const f = feature2.properties || feature2;
|
|
558
|
+
const featurePassesFilter = passesFilter(
|
|
559
|
+
columns,
|
|
560
|
+
filters,
|
|
561
|
+
f,
|
|
562
|
+
filtersLogicalOperator
|
|
563
|
+
);
|
|
564
|
+
return type === "number" ? Number(featurePassesFilter) : featurePassesFilter;
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
function applyFilters(features, filters, filtersLogicalOperator) {
|
|
568
|
+
return Object.keys(filters).length ? features.filter(_buildFeatureFilter({ filters, filtersLogicalOperator })) : features;
|
|
569
|
+
}
|
|
570
|
+
function buildBinaryFeatureFilter({ filters = {} }) {
|
|
571
|
+
const columns = Object.keys(filters);
|
|
572
|
+
if (!columns.length) {
|
|
573
|
+
return () => 1;
|
|
574
|
+
}
|
|
575
|
+
return (featureIdIdx, binaryData) => passesFilterUsingBinary(columns, filters, featureIdIdx, binaryData);
|
|
576
|
+
}
|
|
577
|
+
function getValueFromNumericProps(featureIdIdx, binaryData, { column }) {
|
|
578
|
+
return binaryData.numericProps?.[column]?.value[featureIdIdx];
|
|
579
|
+
}
|
|
580
|
+
function getValueFromProperties(featureIdIdx, binaryData, { column }) {
|
|
581
|
+
const propertyIdx = binaryData.featureIds.value[featureIdIdx];
|
|
582
|
+
return binaryData.properties[propertyIdx]?.[column];
|
|
583
|
+
}
|
|
584
|
+
var GET_VALUE_BY_BINARY_PROP = {
|
|
585
|
+
properties: getValueFromProperties,
|
|
586
|
+
numericProps: getValueFromNumericProps
|
|
587
|
+
};
|
|
588
|
+
function getBinaryPropertyByFilterValues(filterValues) {
|
|
589
|
+
return typeof filterValues.flat()[0] === "string" ? "properties" : "numericProps";
|
|
590
|
+
}
|
|
591
|
+
function getFeatureValue(featureIdIdx, binaryData, filter) {
|
|
592
|
+
const { column, values } = filter;
|
|
593
|
+
const binaryProp = getBinaryPropertyByFilterValues(values);
|
|
594
|
+
const getFeatureValueFn = GET_VALUE_BY_BINARY_PROP[binaryProp];
|
|
595
|
+
return getFeatureValueFn(featureIdIdx, binaryData, { column });
|
|
596
|
+
}
|
|
597
|
+
function passesFilterUsingBinary(columns, filters, featureIdIdx, binaryData) {
|
|
598
|
+
return columns.every((column) => {
|
|
599
|
+
const columnFilters = filters[column];
|
|
600
|
+
return Object.entries(columnFilters).every(([type, { values }]) => {
|
|
601
|
+
const filterFn = filterFunctions[type];
|
|
602
|
+
if (!filterFn) {
|
|
603
|
+
throw new Error(`"${type}" filter is not implemented.`);
|
|
604
|
+
}
|
|
605
|
+
if (!values) return 0;
|
|
606
|
+
const featureValue = getFeatureValue(featureIdIdx, binaryData, {
|
|
607
|
+
type,
|
|
608
|
+
column,
|
|
609
|
+
values
|
|
610
|
+
});
|
|
611
|
+
if (featureValue === void 0 || featureValue === null) return 0;
|
|
612
|
+
return filterFn(values, featureValue);
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// src/filters/geosjonFeatures.ts
|
|
618
|
+
import intersects from "@turf/boolean-intersects";
|
|
619
|
+
function geojsonFeatures({
|
|
620
|
+
geojson,
|
|
621
|
+
spatialFilter,
|
|
622
|
+
uniqueIdProperty
|
|
623
|
+
}) {
|
|
624
|
+
let uniqueIdx = 0;
|
|
625
|
+
const map = /* @__PURE__ */ new Map();
|
|
626
|
+
if (!spatialFilter) {
|
|
627
|
+
return [];
|
|
628
|
+
}
|
|
629
|
+
for (const feature2 of geojson.features) {
|
|
630
|
+
const uniqueId = uniqueIdProperty ? feature2.properties[uniqueIdProperty] : ++uniqueIdx;
|
|
631
|
+
if (!map.has(uniqueId) && intersects(spatialFilter, feature2)) {
|
|
632
|
+
map.set(uniqueId, feature2.properties);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return Array.from(map.values());
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// src/filters/tileFeaturesGeometries.ts
|
|
639
|
+
import bboxPolygon from "@turf/bbox-polygon";
|
|
640
|
+
import intersects2 from "@turf/boolean-intersects";
|
|
641
|
+
import booleanWithin from "@turf/boolean-within";
|
|
642
|
+
import intersect from "@turf/intersect";
|
|
643
|
+
|
|
644
|
+
// node_modules/@math.gl/core/dist/lib/common.js
|
|
645
|
+
var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
|
|
646
|
+
var DEGREES_TO_RADIANS = 1 / 180 * Math.PI;
|
|
647
|
+
var DEFAULT_CONFIG = {
|
|
648
|
+
EPSILON: 1e-12,
|
|
649
|
+
debug: false,
|
|
650
|
+
precision: 4,
|
|
651
|
+
printTypes: false,
|
|
652
|
+
printDegrees: false,
|
|
653
|
+
printRowMajor: true,
|
|
654
|
+
_cartographicRadians: false
|
|
655
|
+
};
|
|
656
|
+
globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
|
|
657
|
+
var config = globalThis.mathgl.config;
|
|
658
|
+
function isArray(value) {
|
|
659
|
+
return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
|
|
660
|
+
}
|
|
661
|
+
function lerp(a, b, t) {
|
|
662
|
+
if (isArray(a)) {
|
|
663
|
+
return a.map((ai, i) => lerp(ai, b[i], t));
|
|
664
|
+
}
|
|
665
|
+
return t * b + (1 - t) * a;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// node_modules/@math.gl/web-mercator/dist/assert.js
|
|
669
|
+
function assert(condition, message) {
|
|
670
|
+
if (!condition) {
|
|
671
|
+
throw new Error(message || "@math.gl/web-mercator: assertion failed.");
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// node_modules/@math.gl/web-mercator/dist/web-mercator-utils.js
|
|
676
|
+
var PI = Math.PI;
|
|
677
|
+
var PI_4 = PI / 4;
|
|
678
|
+
var DEGREES_TO_RADIANS2 = PI / 180;
|
|
679
|
+
var RADIANS_TO_DEGREES2 = 180 / PI;
|
|
680
|
+
var TILE_SIZE = 512;
|
|
681
|
+
function lngLatToWorld(lngLat) {
|
|
682
|
+
const [lng, lat] = lngLat;
|
|
683
|
+
assert(Number.isFinite(lng));
|
|
684
|
+
assert(Number.isFinite(lat) && lat >= -90 && lat <= 90, "invalid latitude");
|
|
685
|
+
const lambda2 = lng * DEGREES_TO_RADIANS2;
|
|
686
|
+
const phi2 = lat * DEGREES_TO_RADIANS2;
|
|
687
|
+
const x = TILE_SIZE * (lambda2 + PI) / (2 * PI);
|
|
688
|
+
const y = TILE_SIZE * (PI + Math.log(Math.tan(PI_4 + phi2 * 0.5))) / (2 * PI);
|
|
689
|
+
return [x, y];
|
|
690
|
+
}
|
|
691
|
+
function worldToLngLat(xy) {
|
|
692
|
+
const [x, y] = xy;
|
|
693
|
+
const lambda2 = x / TILE_SIZE * (2 * PI) - PI;
|
|
694
|
+
const phi2 = 2 * (Math.atan(Math.exp(y / TILE_SIZE * (2 * PI) - PI)) - PI_4);
|
|
695
|
+
return [lambda2 * RADIANS_TO_DEGREES2, phi2 * RADIANS_TO_DEGREES2];
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// node_modules/@math.gl/web-mercator/dist/get-bounds.js
|
|
699
|
+
var DEGREES_TO_RADIANS3 = Math.PI / 180;
|
|
700
|
+
|
|
701
|
+
// src/utils/transformToTileCoords.ts
|
|
702
|
+
var TRANSFORM_FN = {
|
|
703
|
+
Point: transformPoint,
|
|
704
|
+
MultiPoint: transformMultiPoint,
|
|
705
|
+
LineString: transformLineString,
|
|
706
|
+
MultiLineString: transformMultiLineString,
|
|
707
|
+
Polygon: transformPolygon,
|
|
708
|
+
MultiPolygon: transformMultiPolygon
|
|
709
|
+
};
|
|
710
|
+
function transformToTileCoords(geometry, bbox) {
|
|
711
|
+
const [west, south, east, north] = bbox;
|
|
712
|
+
const nw = projectFlat([west, north]);
|
|
713
|
+
const se = projectFlat([east, south]);
|
|
714
|
+
const projectedBbox = [nw, se];
|
|
715
|
+
if (geometry.type === "GeometryCollection") {
|
|
716
|
+
throw new Error("Unsupported geometry type GeometryCollection");
|
|
717
|
+
}
|
|
718
|
+
const transformFn = TRANSFORM_FN[geometry.type];
|
|
719
|
+
const coordinates = transformFn(geometry.coordinates, projectedBbox);
|
|
720
|
+
return { ...geometry, coordinates };
|
|
721
|
+
}
|
|
722
|
+
function transformPoint([pointX, pointY], [nw, se]) {
|
|
723
|
+
const x = inverseLerp(nw[0], se[0], pointX);
|
|
724
|
+
const y = inverseLerp(nw[1], se[1], pointY);
|
|
725
|
+
return [x, y];
|
|
726
|
+
}
|
|
727
|
+
function getPoints(geometry, bbox) {
|
|
728
|
+
return geometry.map((g) => transformPoint(projectFlat(g), bbox));
|
|
729
|
+
}
|
|
730
|
+
function transformMultiPoint(multiPoint, bbox) {
|
|
731
|
+
return getPoints(multiPoint, bbox);
|
|
732
|
+
}
|
|
733
|
+
function transformLineString(line, bbox) {
|
|
734
|
+
return getPoints(line, bbox);
|
|
735
|
+
}
|
|
736
|
+
function transformMultiLineString(multiLineString, bbox) {
|
|
737
|
+
return multiLineString.map(
|
|
738
|
+
(lineString) => transformLineString(lineString, bbox)
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
function transformPolygon(polygon2, bbox) {
|
|
742
|
+
return polygon2.map((polygonRing) => getPoints(polygonRing, bbox));
|
|
743
|
+
}
|
|
744
|
+
function transformMultiPolygon(multiPolygon2, bbox) {
|
|
745
|
+
return multiPolygon2.map((polygon2) => transformPolygon(polygon2, bbox));
|
|
746
|
+
}
|
|
747
|
+
function projectFlat(xyz) {
|
|
748
|
+
return lngLatToWorld(xyz);
|
|
749
|
+
}
|
|
750
|
+
function inverseLerp(a, b, x) {
|
|
751
|
+
return (x - a) / (b - a);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// src/utils/transformTileCoordsToWGS84.ts
|
|
755
|
+
var TRANSFORM_FN2 = {
|
|
756
|
+
Point: transformPoint2,
|
|
757
|
+
MultiPoint: transformMultiPoint2,
|
|
758
|
+
LineString: transformLineString2,
|
|
759
|
+
MultiLineString: transformMultiLineString2,
|
|
760
|
+
Polygon: transformPolygon2,
|
|
761
|
+
MultiPolygon: transformMultiPolygon2
|
|
762
|
+
};
|
|
763
|
+
function transformTileCoordsToWGS84(geometry, bbox) {
|
|
764
|
+
const [west, south, east, north] = bbox;
|
|
765
|
+
const nw = lngLatToWorld([west, north]);
|
|
766
|
+
const se = lngLatToWorld([east, south]);
|
|
767
|
+
const projectedBbox = [nw, se];
|
|
768
|
+
if (geometry.type === "GeometryCollection") {
|
|
769
|
+
throw new Error("Unsupported geometry type GeometryCollection");
|
|
770
|
+
}
|
|
771
|
+
const transformFn = TRANSFORM_FN2[geometry.type];
|
|
772
|
+
const coordinates = transformFn(geometry.coordinates, projectedBbox);
|
|
773
|
+
return { ...geometry, coordinates };
|
|
774
|
+
}
|
|
775
|
+
function transformPoint2([pointX, pointY], [nw, se]) {
|
|
776
|
+
const x = lerp(nw[0], se[0], pointX);
|
|
777
|
+
const y = lerp(nw[1], se[1], pointY);
|
|
778
|
+
return worldToLngLat([x, y]);
|
|
779
|
+
}
|
|
780
|
+
function getPoints2(geometry, bbox) {
|
|
781
|
+
return geometry.map((g) => transformPoint2(g, bbox));
|
|
782
|
+
}
|
|
783
|
+
function transformMultiPoint2(multiPoint, bbox) {
|
|
784
|
+
return getPoints2(multiPoint, bbox);
|
|
785
|
+
}
|
|
786
|
+
function transformLineString2(line, bbox) {
|
|
787
|
+
return getPoints2(line, bbox);
|
|
788
|
+
}
|
|
789
|
+
function transformMultiLineString2(multiLineString, bbox) {
|
|
790
|
+
return multiLineString.map(
|
|
791
|
+
(lineString) => transformLineString2(lineString, bbox)
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
function transformPolygon2(polygon2, bbox) {
|
|
795
|
+
return polygon2.map((polygonRing) => getPoints2(polygonRing, bbox));
|
|
796
|
+
}
|
|
797
|
+
function transformMultiPolygon2(multiPolygon2, bbox) {
|
|
798
|
+
return multiPolygon2.map((polygon2) => transformPolygon2(polygon2, bbox));
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// src/filters/tileFeaturesGeometries.ts
|
|
802
|
+
import { featureCollection } from "@turf/helpers";
|
|
803
|
+
var FEATURE_GEOM_PROPERTY = "__geomValue";
|
|
804
|
+
function tileFeaturesGeometries({
|
|
805
|
+
tiles: tiles2,
|
|
806
|
+
tileFormat,
|
|
807
|
+
spatialFilter,
|
|
808
|
+
uniqueIdProperty,
|
|
809
|
+
options
|
|
810
|
+
}) {
|
|
811
|
+
const map = /* @__PURE__ */ new Map();
|
|
812
|
+
for (const tile of tiles2) {
|
|
813
|
+
if (tile.isVisible === false || !tile.data) {
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
const bbox = [
|
|
817
|
+
tile.bbox.west,
|
|
818
|
+
tile.bbox.south,
|
|
819
|
+
tile.bbox.east,
|
|
820
|
+
tile.bbox.north
|
|
821
|
+
];
|
|
822
|
+
const bboxToGeom = bboxPolygon(bbox);
|
|
823
|
+
const tileIsFullyVisible = booleanWithin(bboxToGeom, spatialFilter);
|
|
824
|
+
const spatialFilterFeature = {
|
|
825
|
+
type: "Feature",
|
|
826
|
+
geometry: spatialFilter,
|
|
827
|
+
properties: {}
|
|
828
|
+
};
|
|
829
|
+
const clippedGeometryToIntersect = intersect(
|
|
830
|
+
featureCollection([bboxToGeom, spatialFilterFeature])
|
|
831
|
+
);
|
|
832
|
+
if (!clippedGeometryToIntersect) {
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
const transformedGeometryToIntersect = tileFormat === "mvt" /* MVT */ ? transformToTileCoords(clippedGeometryToIntersect.geometry, bbox) : clippedGeometryToIntersect.geometry;
|
|
836
|
+
createIndicesForPoints(tile.data.points);
|
|
837
|
+
calculateFeatures({
|
|
838
|
+
map,
|
|
839
|
+
tileIsFullyVisible,
|
|
840
|
+
geometryIntersection: transformedGeometryToIntersect,
|
|
841
|
+
data: tile.data.points,
|
|
842
|
+
type: "Point",
|
|
843
|
+
bbox,
|
|
844
|
+
tileFormat,
|
|
845
|
+
uniqueIdProperty,
|
|
846
|
+
options
|
|
847
|
+
});
|
|
848
|
+
calculateFeatures({
|
|
849
|
+
map,
|
|
850
|
+
tileIsFullyVisible,
|
|
851
|
+
geometryIntersection: transformedGeometryToIntersect,
|
|
852
|
+
data: tile.data.lines,
|
|
853
|
+
type: "LineString",
|
|
854
|
+
bbox,
|
|
855
|
+
tileFormat,
|
|
856
|
+
uniqueIdProperty,
|
|
857
|
+
options
|
|
858
|
+
});
|
|
859
|
+
calculateFeatures({
|
|
860
|
+
map,
|
|
861
|
+
tileIsFullyVisible,
|
|
862
|
+
geometryIntersection: transformedGeometryToIntersect,
|
|
863
|
+
data: tile.data.polygons,
|
|
864
|
+
type: "Polygon",
|
|
865
|
+
bbox,
|
|
866
|
+
tileFormat,
|
|
867
|
+
uniqueIdProperty,
|
|
868
|
+
options
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
return Array.from(map.values());
|
|
872
|
+
}
|
|
873
|
+
function processTileFeatureProperties({
|
|
874
|
+
map,
|
|
875
|
+
data,
|
|
876
|
+
startIndex,
|
|
877
|
+
endIndex,
|
|
878
|
+
type,
|
|
879
|
+
bbox,
|
|
880
|
+
tileFormat,
|
|
881
|
+
uniqueIdProperty,
|
|
882
|
+
storeGeometry,
|
|
883
|
+
geometryIntersection
|
|
884
|
+
}) {
|
|
885
|
+
const tileProps = getPropertiesFromTile(data, startIndex);
|
|
886
|
+
const uniquePropertyValue = getUniquePropertyValue(
|
|
887
|
+
tileProps,
|
|
888
|
+
uniqueIdProperty,
|
|
889
|
+
map
|
|
890
|
+
);
|
|
891
|
+
if (!uniquePropertyValue || map.has(uniquePropertyValue)) {
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
let geometry = null;
|
|
895
|
+
if (storeGeometry || geometryIntersection) {
|
|
896
|
+
const { positions } = data;
|
|
897
|
+
const ringCoordinates = getRingCoordinatesFor(
|
|
898
|
+
startIndex,
|
|
899
|
+
endIndex,
|
|
900
|
+
positions
|
|
901
|
+
);
|
|
902
|
+
geometry = getFeatureByType(ringCoordinates, type);
|
|
903
|
+
}
|
|
904
|
+
if (geometry && geometryIntersection && !intersects2(geometry, geometryIntersection)) {
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
const properties = parseProperties(tileProps);
|
|
908
|
+
if (storeGeometry && geometry) {
|
|
909
|
+
properties[FEATURE_GEOM_PROPERTY] = tileFormat === "mvt" /* MVT */ ? transformTileCoordsToWGS84(geometry, bbox) : geometry;
|
|
910
|
+
}
|
|
911
|
+
map.set(uniquePropertyValue, properties);
|
|
912
|
+
}
|
|
913
|
+
function addIntersectedFeaturesInTile({
|
|
914
|
+
map,
|
|
915
|
+
data,
|
|
916
|
+
geometryIntersection,
|
|
917
|
+
type,
|
|
918
|
+
bbox,
|
|
919
|
+
tileFormat,
|
|
920
|
+
uniqueIdProperty,
|
|
921
|
+
options
|
|
922
|
+
}) {
|
|
923
|
+
const indices = getIndices(data);
|
|
924
|
+
const storeGeometry = options?.storeGeometry || false;
|
|
925
|
+
for (let i = 0; i < indices.length - 1; i++) {
|
|
926
|
+
const startIndex = indices[i];
|
|
927
|
+
const endIndex = indices[i + 1];
|
|
928
|
+
processTileFeatureProperties({
|
|
929
|
+
map,
|
|
930
|
+
data,
|
|
931
|
+
startIndex,
|
|
932
|
+
endIndex,
|
|
933
|
+
type,
|
|
934
|
+
bbox,
|
|
935
|
+
tileFormat,
|
|
936
|
+
uniqueIdProperty,
|
|
937
|
+
storeGeometry,
|
|
938
|
+
geometryIntersection
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
function getIndices(data) {
|
|
943
|
+
let indices;
|
|
944
|
+
switch (data.type) {
|
|
945
|
+
case "Point":
|
|
946
|
+
indices = data.pointIndices;
|
|
947
|
+
break;
|
|
948
|
+
case "LineString":
|
|
949
|
+
indices = data.pathIndices;
|
|
950
|
+
break;
|
|
951
|
+
case "Polygon":
|
|
952
|
+
indices = data.primitivePolygonIndices;
|
|
953
|
+
break;
|
|
954
|
+
default:
|
|
955
|
+
throw new Error(`Unexpected type, "${data.type}"`);
|
|
956
|
+
}
|
|
957
|
+
return indices.value;
|
|
958
|
+
}
|
|
959
|
+
function getFeatureId(data, startIndex) {
|
|
960
|
+
return data.featureIds.value[startIndex];
|
|
961
|
+
}
|
|
962
|
+
function getPropertiesFromTile(data, startIndex) {
|
|
963
|
+
const featureId = getFeatureId(data, startIndex);
|
|
964
|
+
const { properties, numericProps, fields } = data;
|
|
965
|
+
const result = {
|
|
966
|
+
uniqueId: fields?.[featureId]?.id,
|
|
967
|
+
properties: properties[featureId],
|
|
968
|
+
numericProps: {}
|
|
969
|
+
};
|
|
970
|
+
for (const key in numericProps) {
|
|
971
|
+
result.numericProps[key] = numericProps[key].value[startIndex];
|
|
972
|
+
}
|
|
973
|
+
return result;
|
|
974
|
+
}
|
|
975
|
+
function parseProperties(tileProps) {
|
|
976
|
+
const { properties, numericProps } = tileProps;
|
|
977
|
+
return Object.assign({}, properties, numericProps);
|
|
978
|
+
}
|
|
979
|
+
function getUniquePropertyValue(tileProps, uniqueIdProperty, map) {
|
|
980
|
+
if (uniqueIdProperty) {
|
|
981
|
+
return getValueFromTileProps(tileProps, uniqueIdProperty);
|
|
982
|
+
}
|
|
983
|
+
if (tileProps.uniqueId) {
|
|
984
|
+
return tileProps.uniqueId;
|
|
985
|
+
}
|
|
986
|
+
const artificialId = map.size + 1;
|
|
987
|
+
return getValueFromTileProps(tileProps, "cartodb_id") || getValueFromTileProps(tileProps, "geoid") || artificialId;
|
|
988
|
+
}
|
|
989
|
+
function getValueFromTileProps(tileProps, propertyName) {
|
|
990
|
+
const { properties, numericProps } = tileProps;
|
|
991
|
+
return numericProps[propertyName] || properties[propertyName];
|
|
992
|
+
}
|
|
993
|
+
function getFeatureByType(coordinates, type) {
|
|
994
|
+
switch (type) {
|
|
995
|
+
case "Polygon":
|
|
996
|
+
return { type: "Polygon", coordinates: [coordinates] };
|
|
997
|
+
case "LineString":
|
|
998
|
+
return { type: "LineString", coordinates };
|
|
999
|
+
case "Point":
|
|
1000
|
+
return { type: "Point", coordinates: coordinates[0] };
|
|
1001
|
+
default:
|
|
1002
|
+
throw new Error("Invalid geometry type");
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
function getRingCoordinatesFor(startIndex, endIndex, positions) {
|
|
1006
|
+
const ringCoordinates = [];
|
|
1007
|
+
for (let j = startIndex; j < endIndex; j++) {
|
|
1008
|
+
ringCoordinates.push(
|
|
1009
|
+
Array.from(
|
|
1010
|
+
positions.value.subarray(j * positions.size, (j + 1) * positions.size)
|
|
1011
|
+
)
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
return ringCoordinates;
|
|
1015
|
+
}
|
|
1016
|
+
function calculateFeatures({
|
|
1017
|
+
map,
|
|
1018
|
+
tileIsFullyVisible,
|
|
1019
|
+
geometryIntersection,
|
|
1020
|
+
data,
|
|
1021
|
+
type,
|
|
1022
|
+
bbox,
|
|
1023
|
+
tileFormat,
|
|
1024
|
+
uniqueIdProperty,
|
|
1025
|
+
options
|
|
1026
|
+
}) {
|
|
1027
|
+
if (!data?.properties.length) {
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
if (tileIsFullyVisible) {
|
|
1031
|
+
addAllFeaturesInTile({
|
|
1032
|
+
map,
|
|
1033
|
+
data,
|
|
1034
|
+
type,
|
|
1035
|
+
bbox,
|
|
1036
|
+
tileFormat,
|
|
1037
|
+
uniqueIdProperty,
|
|
1038
|
+
options
|
|
1039
|
+
});
|
|
1040
|
+
} else {
|
|
1041
|
+
addIntersectedFeaturesInTile({
|
|
1042
|
+
map,
|
|
1043
|
+
data,
|
|
1044
|
+
geometryIntersection,
|
|
1045
|
+
type,
|
|
1046
|
+
bbox,
|
|
1047
|
+
tileFormat,
|
|
1048
|
+
uniqueIdProperty,
|
|
1049
|
+
options
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
function addAllFeaturesInTile({
|
|
1054
|
+
map,
|
|
1055
|
+
data,
|
|
1056
|
+
type,
|
|
1057
|
+
bbox,
|
|
1058
|
+
tileFormat,
|
|
1059
|
+
uniqueIdProperty,
|
|
1060
|
+
options
|
|
1061
|
+
}) {
|
|
1062
|
+
const indices = getIndices(data);
|
|
1063
|
+
const storeGeometry = options?.storeGeometry || false;
|
|
1064
|
+
for (let i = 0; i < indices.length - 1; i++) {
|
|
1065
|
+
const startIndex = indices[i];
|
|
1066
|
+
const endIndex = indices[i + 1];
|
|
1067
|
+
processTileFeatureProperties({
|
|
1068
|
+
map,
|
|
1069
|
+
data,
|
|
1070
|
+
startIndex,
|
|
1071
|
+
endIndex,
|
|
1072
|
+
type,
|
|
1073
|
+
bbox,
|
|
1074
|
+
tileFormat,
|
|
1075
|
+
uniqueIdProperty,
|
|
1076
|
+
storeGeometry
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
function createIndicesForPoints(data) {
|
|
1081
|
+
const featureIds = data.featureIds.value;
|
|
1082
|
+
const lastFeatureId = featureIds[featureIds.length - 1];
|
|
1083
|
+
const PointIndicesArray = featureIds.constructor;
|
|
1084
|
+
const pointIndices = {
|
|
1085
|
+
value: new PointIndicesArray(featureIds.length + 1),
|
|
1086
|
+
size: 1
|
|
1087
|
+
};
|
|
1088
|
+
pointIndices.value.set(featureIds);
|
|
1089
|
+
pointIndices.value.set([lastFeatureId + 1], featureIds.length);
|
|
1090
|
+
data.pointIndices = pointIndices;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
// node_modules/quadbin/dist/esm/index.js
|
|
1094
|
+
var import_tile_cover = __toESM(require_tile_cover(), 1);
|
|
1095
|
+
var B = [
|
|
1096
|
+
0x5555555555555555n,
|
|
1097
|
+
0x3333333333333333n,
|
|
1098
|
+
0x0f0f0f0f0f0f0f0fn,
|
|
1099
|
+
0x00ff00ff00ff00ffn,
|
|
1100
|
+
0x0000ffff0000ffffn,
|
|
1101
|
+
0x00000000ffffffffn
|
|
1102
|
+
];
|
|
1103
|
+
var S = [0n, 1n, 2n, 4n, 8n, 16n];
|
|
1104
|
+
function tileToCell(tile) {
|
|
1105
|
+
if (tile.z < 0 || tile.z > 26) {
|
|
1106
|
+
throw new Error("Wrong zoom");
|
|
1107
|
+
}
|
|
1108
|
+
const z = BigInt(tile.z);
|
|
1109
|
+
let x = BigInt(tile.x) << 32n - z;
|
|
1110
|
+
let y = BigInt(tile.y) << 32n - z;
|
|
1111
|
+
for (let i = 0; i < 5; i++) {
|
|
1112
|
+
const s = S[5 - i];
|
|
1113
|
+
const b = B[4 - i];
|
|
1114
|
+
x = (x | x << s) & b;
|
|
1115
|
+
y = (y | y << s) & b;
|
|
1116
|
+
}
|
|
1117
|
+
const quadbin = 0x4000000000000000n | 1n << 59n | // | (mode << 59) | (mode_dep << 57)
|
|
1118
|
+
z << 52n | (x | y << 1n) >> 12n | 0xfffffffffffffn >> z * 2n;
|
|
1119
|
+
return quadbin;
|
|
1120
|
+
}
|
|
1121
|
+
function getResolution(quadbin) {
|
|
1122
|
+
return quadbin >> 52n & 0x1fn;
|
|
1123
|
+
}
|
|
1124
|
+
function geometryToCells(geometry, resolution) {
|
|
1125
|
+
const zoom = Number(resolution);
|
|
1126
|
+
return (0, import_tile_cover.tiles)(geometry, {
|
|
1127
|
+
min_zoom: zoom,
|
|
1128
|
+
max_zoom: zoom
|
|
1129
|
+
}).map(([x, y, z]) => tileToCell({ x, y, z }));
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// src/filters/tileFeaturesSpatialIndex.ts
|
|
1133
|
+
import bboxClip from "@turf/bbox-clip";
|
|
1134
|
+
import { getResolution as h3GetResolution, polygonToCells } from "h3-js";
|
|
1135
|
+
function tileFeaturesSpatialIndex({
|
|
1136
|
+
tiles: tiles2,
|
|
1137
|
+
spatialFilter,
|
|
1138
|
+
spatialDataColumn,
|
|
1139
|
+
spatialDataType
|
|
1140
|
+
}) {
|
|
1141
|
+
const map = /* @__PURE__ */ new Map();
|
|
1142
|
+
const spatialIndex = getSpatialIndex(spatialDataType);
|
|
1143
|
+
const resolution = getResolution2(tiles2, spatialIndex);
|
|
1144
|
+
const spatialIndexIDName = spatialDataColumn ? spatialDataColumn : spatialIndex;
|
|
1145
|
+
if (!resolution) {
|
|
1146
|
+
return [];
|
|
1147
|
+
}
|
|
1148
|
+
const cells = getCellsCoverGeometry(spatialFilter, spatialIndex, resolution);
|
|
1149
|
+
if (!cells?.length) {
|
|
1150
|
+
return [];
|
|
1151
|
+
}
|
|
1152
|
+
const cellsSet = new Set(cells);
|
|
1153
|
+
for (const tile of tiles2) {
|
|
1154
|
+
if (tile.isVisible === false || !tile.data) {
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
tile.data.forEach((d) => {
|
|
1158
|
+
if (cellsSet.has(d.id)) {
|
|
1159
|
+
map.set(d.id, { ...d.properties, [spatialIndexIDName]: d.id });
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
return Array.from(map.values());
|
|
1164
|
+
}
|
|
1165
|
+
function getResolution2(tiles2, spatialIndex) {
|
|
1166
|
+
const data = tiles2.find((tile) => tile.data?.length)?.data;
|
|
1167
|
+
if (!data) {
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
if (spatialIndex === "quadbin" /* QUADBIN */) {
|
|
1171
|
+
return Number(getResolution(data[0].id));
|
|
1172
|
+
}
|
|
1173
|
+
if (spatialIndex === "h3" /* H3 */) {
|
|
1174
|
+
return h3GetResolution(data[0].id);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
var bboxWest = [-180, -90, 0, 90];
|
|
1178
|
+
var bboxEast = [0, -90, 180, 90];
|
|
1179
|
+
function getCellsCoverGeometry(geometry, spatialIndex, resolution) {
|
|
1180
|
+
if (spatialIndex === "quadbin" /* QUADBIN */) {
|
|
1181
|
+
return geometryToCells(geometry, resolution);
|
|
1182
|
+
}
|
|
1183
|
+
if (spatialIndex === "h3" /* H3 */) {
|
|
1184
|
+
return polygonToCells(
|
|
1185
|
+
bboxClip(geometry, bboxWest).geometry.coordinates,
|
|
1186
|
+
resolution,
|
|
1187
|
+
true
|
|
1188
|
+
).concat(
|
|
1189
|
+
polygonToCells(
|
|
1190
|
+
bboxClip(geometry, bboxEast).geometry.coordinates,
|
|
1191
|
+
resolution,
|
|
1192
|
+
true
|
|
1193
|
+
)
|
|
1194
|
+
);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
function getSpatialIndex(spatialDataType) {
|
|
1198
|
+
switch (spatialDataType) {
|
|
1199
|
+
case "h3":
|
|
1200
|
+
return "h3" /* H3 */;
|
|
1201
|
+
case "quadbin":
|
|
1202
|
+
return "quadbin" /* QUADBIN */;
|
|
1203
|
+
default:
|
|
1204
|
+
throw new Error("Unexpected spatial data type");
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// src/constants-internal.ts
|
|
1209
|
+
var V3_MINOR_VERSION = "3.4";
|
|
1210
|
+
var DEFAULT_GEO_COLUMN = "geom";
|
|
1211
|
+
var DEFAULT_MAX_LENGTH_URL = 7e3;
|
|
1212
|
+
var DEFAULT_TILE_RESOLUTION = 0.5;
|
|
1213
|
+
var DEFAULT_AGGREGATION_RES_LEVEL_H3 = 4;
|
|
1214
|
+
var DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN = 6;
|
|
1215
|
+
|
|
1216
|
+
// src/filters/tileFeatures.ts
|
|
1217
|
+
function tileFeatures({
|
|
1218
|
+
tiles: tiles2,
|
|
1219
|
+
spatialFilter,
|
|
1220
|
+
uniqueIdProperty,
|
|
1221
|
+
tileFormat,
|
|
1222
|
+
spatialDataColumn = DEFAULT_GEO_COLUMN,
|
|
1223
|
+
spatialDataType,
|
|
1224
|
+
options = {}
|
|
1225
|
+
}) {
|
|
1226
|
+
if (spatialDataType !== "geo") {
|
|
1227
|
+
return tileFeaturesSpatialIndex({
|
|
1228
|
+
tiles: tiles2,
|
|
1229
|
+
spatialFilter,
|
|
1230
|
+
spatialDataColumn,
|
|
1231
|
+
spatialDataType
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
return tileFeaturesGeometries({
|
|
1235
|
+
tiles: tiles2,
|
|
1236
|
+
tileFormat,
|
|
1237
|
+
spatialFilter,
|
|
1238
|
+
uniqueIdProperty,
|
|
1239
|
+
options
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
45
1242
|
|
|
46
1243
|
// src/deck/get-data-filter-extension-props.ts
|
|
47
1244
|
function getDataFilterExtensionProps(filters, filtersLogicalOperator, filterSize) {
|
|
@@ -124,6 +1321,64 @@ function getFilterValue(filtersWithoutTimeType, timeColumn, timeFilter, filterSi
|
|
|
124
1321
|
};
|
|
125
1322
|
}
|
|
126
1323
|
|
|
1324
|
+
// src/utils.ts
|
|
1325
|
+
var FILTER_TYPES = new Set(Object.values(FilterType));
|
|
1326
|
+
var isFilterType = (type) => FILTER_TYPES.has(type);
|
|
1327
|
+
function getApplicableFilters(owner, filters) {
|
|
1328
|
+
if (!filters) return {};
|
|
1329
|
+
const applicableFilters = {};
|
|
1330
|
+
for (const column in filters) {
|
|
1331
|
+
for (const type in filters[column]) {
|
|
1332
|
+
if (!isFilterType(type)) continue;
|
|
1333
|
+
const filter = filters[column][type];
|
|
1334
|
+
const isApplicable = !owner || !filter?.owner || filter?.owner !== owner;
|
|
1335
|
+
if (filter && isApplicable) {
|
|
1336
|
+
applicableFilters[column] || (applicableFilters[column] = {});
|
|
1337
|
+
applicableFilters[column][type] = filter;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
return applicableFilters;
|
|
1342
|
+
}
|
|
1343
|
+
function normalizeObjectKeys(el) {
|
|
1344
|
+
if (Array.isArray(el)) {
|
|
1345
|
+
return el.map((value) => normalizeObjectKeys(value));
|
|
1346
|
+
} else if (typeof el !== "object") {
|
|
1347
|
+
return el;
|
|
1348
|
+
}
|
|
1349
|
+
return Object.entries(el).reduce(
|
|
1350
|
+
(acc, [key, value]) => {
|
|
1351
|
+
acc[key.toLowerCase()] = typeof value === "object" && value ? normalizeObjectKeys(value) : value;
|
|
1352
|
+
return acc;
|
|
1353
|
+
},
|
|
1354
|
+
{}
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
function assert2(condition, message) {
|
|
1358
|
+
if (!condition) {
|
|
1359
|
+
throw new Error(message);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
var _InvalidColumnError = class _InvalidColumnError extends Error {
|
|
1363
|
+
constructor(message) {
|
|
1364
|
+
super(`${_InvalidColumnError.NAME}: ${message}`);
|
|
1365
|
+
this.name = _InvalidColumnError.NAME;
|
|
1366
|
+
}
|
|
1367
|
+
static is(error) {
|
|
1368
|
+
return error instanceof _InvalidColumnError || error.message?.includes(_InvalidColumnError.NAME);
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
__publicField(_InvalidColumnError, "NAME", "InvalidColumnError");
|
|
1372
|
+
var InvalidColumnError = _InvalidColumnError;
|
|
1373
|
+
function isEmptyObject(object) {
|
|
1374
|
+
for (const _ in object) {
|
|
1375
|
+
return false;
|
|
1376
|
+
}
|
|
1377
|
+
return true;
|
|
1378
|
+
}
|
|
1379
|
+
var isObject = (x) => x !== null && typeof x === "object";
|
|
1380
|
+
var isPureObject = (x) => isObject(x) && x.constructor === {}.constructor;
|
|
1381
|
+
|
|
127
1382
|
// src/filters.ts
|
|
128
1383
|
function addFilter(filters, { column, type, values, owner }) {
|
|
129
1384
|
if (!filters[column]) {
|
|
@@ -183,16 +1438,16 @@ function getFilter(filters, { column, type, owner }) {
|
|
|
183
1438
|
}
|
|
184
1439
|
|
|
185
1440
|
// src/geo.ts
|
|
186
|
-
import
|
|
187
|
-
import
|
|
1441
|
+
import bboxClip2 from "@turf/bbox-clip";
|
|
1442
|
+
import bboxPolygon2 from "@turf/bbox-polygon";
|
|
188
1443
|
import union from "@turf/union";
|
|
189
1444
|
import { getType } from "@turf/invariant";
|
|
190
|
-
import { polygon, multiPolygon, feature, featureCollection } from "@turf/helpers";
|
|
1445
|
+
import { polygon, multiPolygon, feature, featureCollection as featureCollection2 } from "@turf/helpers";
|
|
191
1446
|
function createViewportSpatialFilter(viewport) {
|
|
192
1447
|
if (_isGlobalViewport(viewport)) {
|
|
193
1448
|
return;
|
|
194
1449
|
}
|
|
195
|
-
return createPolygonSpatialFilter(
|
|
1450
|
+
return createPolygonSpatialFilter(bboxPolygon2(viewport).geometry);
|
|
196
1451
|
}
|
|
197
1452
|
function createPolygonSpatialFilter(spatialFilter) {
|
|
198
1453
|
return spatialFilter && _normalizeGeometry(spatialFilter) || void 0;
|
|
@@ -204,17 +1459,17 @@ function _isGlobalViewport(viewport) {
|
|
|
204
1459
|
function _normalizeGeometry(geometry) {
|
|
205
1460
|
const WORLD = [-180, -90, 180, 90];
|
|
206
1461
|
const worldClip = _clean(
|
|
207
|
-
|
|
1462
|
+
bboxClip2(geometry, WORLD).geometry
|
|
208
1463
|
);
|
|
209
1464
|
const geometryTxWest = _tx(geometry, 360);
|
|
210
1465
|
const geometryTxEast = _tx(geometry, -360);
|
|
211
1466
|
let result = worldClip;
|
|
212
1467
|
if (result && geometryTxWest) {
|
|
213
1468
|
const worldWestClip = _clean(
|
|
214
|
-
|
|
1469
|
+
bboxClip2(geometryTxWest, WORLD).geometry
|
|
215
1470
|
);
|
|
216
1471
|
if (worldWestClip) {
|
|
217
|
-
const collection =
|
|
1472
|
+
const collection = featureCollection2([
|
|
218
1473
|
feature(result),
|
|
219
1474
|
feature(worldWestClip)
|
|
220
1475
|
]);
|
|
@@ -224,10 +1479,10 @@ function _normalizeGeometry(geometry) {
|
|
|
224
1479
|
}
|
|
225
1480
|
if (result && geometryTxEast) {
|
|
226
1481
|
const worldEastClip = _clean(
|
|
227
|
-
|
|
1482
|
+
bboxClip2(geometryTxEast, WORLD).geometry
|
|
228
1483
|
);
|
|
229
1484
|
if (worldEastClip) {
|
|
230
|
-
const collection =
|
|
1485
|
+
const collection = featureCollection2([
|
|
231
1486
|
feature(result),
|
|
232
1487
|
feature(worldEastClip)
|
|
233
1488
|
]);
|
|
@@ -612,6 +1867,108 @@ var boundaryTableSource = async function(options) {
|
|
|
612
1867
|
);
|
|
613
1868
|
};
|
|
614
1869
|
|
|
1870
|
+
// src/spatial-index.ts
|
|
1871
|
+
var DEFAULT_TILE_SIZE = 512;
|
|
1872
|
+
var QUADBIN_ZOOM_MAX_OFFSET = 4;
|
|
1873
|
+
function getSpatialFiltersResolution(source, viewState) {
|
|
1874
|
+
const dataResolution = source.dataResolution ?? Number.MAX_VALUE;
|
|
1875
|
+
const aggregationResLevel = source.aggregationResLevel ?? (source.spatialDataType === "h3" ? DEFAULT_AGGREGATION_RES_LEVEL_H3 : DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN);
|
|
1876
|
+
const aggregationResLevelOffset = Math.max(
|
|
1877
|
+
0,
|
|
1878
|
+
Math.floor(aggregationResLevel)
|
|
1879
|
+
);
|
|
1880
|
+
const currentZoomInt = Math.ceil(viewState.zoom);
|
|
1881
|
+
if (source.spatialDataType === "h3") {
|
|
1882
|
+
const tileSize = DEFAULT_TILE_SIZE;
|
|
1883
|
+
const maxResolutionForZoom = maxH3SpatialFiltersResolutions.find(
|
|
1884
|
+
([zoom]) => zoom === currentZoomInt
|
|
1885
|
+
)?.[1] ?? Math.max(0, currentZoomInt - 3);
|
|
1886
|
+
const maxSpatialFiltersResolution = maxResolutionForZoom ? Math.min(dataResolution, maxResolutionForZoom) : dataResolution;
|
|
1887
|
+
const hexagonResolution = _getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
|
|
1888
|
+
return Math.min(hexagonResolution, maxSpatialFiltersResolution);
|
|
1889
|
+
}
|
|
1890
|
+
if (source.spatialDataType === "quadbin") {
|
|
1891
|
+
const maxResolutionForZoom = currentZoomInt + QUADBIN_ZOOM_MAX_OFFSET;
|
|
1892
|
+
const maxSpatialFiltersResolution = Math.min(
|
|
1893
|
+
dataResolution,
|
|
1894
|
+
maxResolutionForZoom
|
|
1895
|
+
);
|
|
1896
|
+
const quadsResolution = Math.floor(viewState.zoom) + aggregationResLevelOffset;
|
|
1897
|
+
return Math.min(quadsResolution, maxSpatialFiltersResolution);
|
|
1898
|
+
}
|
|
1899
|
+
return void 0;
|
|
1900
|
+
}
|
|
1901
|
+
var maxH3SpatialFiltersResolutions = [
|
|
1902
|
+
[20, 14],
|
|
1903
|
+
[19, 13],
|
|
1904
|
+
[18, 12],
|
|
1905
|
+
[17, 11],
|
|
1906
|
+
[16, 10],
|
|
1907
|
+
[15, 9],
|
|
1908
|
+
[14, 8],
|
|
1909
|
+
[13, 7],
|
|
1910
|
+
[12, 7],
|
|
1911
|
+
[11, 7],
|
|
1912
|
+
[10, 6],
|
|
1913
|
+
[9, 6],
|
|
1914
|
+
[8, 5],
|
|
1915
|
+
[7, 4],
|
|
1916
|
+
[6, 4],
|
|
1917
|
+
[5, 3],
|
|
1918
|
+
[4, 2],
|
|
1919
|
+
[3, 1],
|
|
1920
|
+
[2, 1],
|
|
1921
|
+
[1, 0]
|
|
1922
|
+
];
|
|
1923
|
+
var BIAS = 2;
|
|
1924
|
+
function _getHexagonResolution(viewport, tileSize) {
|
|
1925
|
+
const zoomOffset = Math.log2(tileSize / DEFAULT_TILE_SIZE);
|
|
1926
|
+
const hexagonScaleFactor = 2 / 3 * (viewport.zoom - zoomOffset);
|
|
1927
|
+
const latitudeScaleFactor = Math.log(
|
|
1928
|
+
1 / Math.cos(Math.PI * viewport.latitude / 180)
|
|
1929
|
+
);
|
|
1930
|
+
return Math.max(
|
|
1931
|
+
0,
|
|
1932
|
+
Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS)
|
|
1933
|
+
);
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
// src/widget-sources/widget-source.ts
|
|
1937
|
+
var _WidgetSource = class _WidgetSource {
|
|
1938
|
+
constructor(props) {
|
|
1939
|
+
__publicField(this, "props");
|
|
1940
|
+
this.props = { ..._WidgetSource.defaultProps, ...props };
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Destroys the widget source and releases allocated resources.
|
|
1944
|
+
*
|
|
1945
|
+
* For remote sources (tables, queries) this has no effect, but for local
|
|
1946
|
+
* sources (tilesets, rasters) these resources will affect performance
|
|
1947
|
+
* and stability if many (10+) sources are created and not released.
|
|
1948
|
+
*/
|
|
1949
|
+
destroy() {
|
|
1950
|
+
}
|
|
1951
|
+
_getSpatialFiltersResolution(source, spatialFilter, referenceViewState) {
|
|
1952
|
+
if (!spatialFilter || source.spatialDataType === "geo") {
|
|
1953
|
+
return;
|
|
1954
|
+
}
|
|
1955
|
+
if (!referenceViewState) {
|
|
1956
|
+
throw new Error(
|
|
1957
|
+
'Missing required option, "spatialIndexReferenceViewState".'
|
|
1958
|
+
);
|
|
1959
|
+
}
|
|
1960
|
+
return getSpatialFiltersResolution(source, referenceViewState);
|
|
1961
|
+
}
|
|
1962
|
+
};
|
|
1963
|
+
__publicField(_WidgetSource, "defaultProps", {
|
|
1964
|
+
apiVersion: "v3" /* V3 */,
|
|
1965
|
+
apiBaseUrl: DEFAULT_API_BASE_URL,
|
|
1966
|
+
clientId: getClient(),
|
|
1967
|
+
filters: {},
|
|
1968
|
+
filtersLogicalOperator: "and"
|
|
1969
|
+
});
|
|
1970
|
+
var WidgetSource = _WidgetSource;
|
|
1971
|
+
|
|
615
1972
|
// src/models/common.ts
|
|
616
1973
|
function dealWithApiError({
|
|
617
1974
|
response,
|
|
@@ -653,7 +2010,7 @@ async function makeCall({
|
|
|
653
2010
|
method: opts?.method,
|
|
654
2011
|
body: opts?.body
|
|
655
2012
|
},
|
|
656
|
-
signal: opts?.
|
|
2013
|
+
signal: opts?.signal,
|
|
657
2014
|
...opts?.otherOptions
|
|
658
2015
|
});
|
|
659
2016
|
data = await response.json();
|
|
@@ -681,10 +2038,10 @@ var AVAILABLE_MODELS = [
|
|
|
681
2038
|
var { V3 } = ApiVersion;
|
|
682
2039
|
var REQUEST_GET_MAX_URL_LENGTH = 2048;
|
|
683
2040
|
function executeModel(props) {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
2041
|
+
assert2(props.source, "executeModel: missing source");
|
|
2042
|
+
assert2(props.model, "executeModel: missing model");
|
|
2043
|
+
assert2(props.params, "executeModel: missing params");
|
|
2044
|
+
assert2(
|
|
688
2045
|
AVAILABLE_MODELS.includes(props.model),
|
|
689
2046
|
`executeModel: model provided isn't valid. Available models: ${AVAILABLE_MODELS.join(
|
|
690
2047
|
", "
|
|
@@ -692,10 +2049,10 @@ function executeModel(props) {
|
|
|
692
2049
|
);
|
|
693
2050
|
const { model, source, params, opts } = props;
|
|
694
2051
|
const { type, apiVersion, apiBaseUrl, accessToken, connectionName, clientId } = source;
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
2052
|
+
assert2(apiBaseUrl, "executeModel: missing apiBaseUrl");
|
|
2053
|
+
assert2(accessToken, "executeModel: missing accessToken");
|
|
2054
|
+
assert2(apiVersion === V3, "executeModel: SQL Model API requires CARTO 3+");
|
|
2055
|
+
assert2(type !== "tileset", "executeModel: Tilesets not supported");
|
|
699
2056
|
let url = `${apiBaseUrl}/v3/sql/${connectionName}/model/${model}`;
|
|
700
2057
|
const {
|
|
701
2058
|
data,
|
|
@@ -788,12 +2145,12 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
788
2145
|
}
|
|
789
2146
|
async getCategories(options) {
|
|
790
2147
|
const {
|
|
2148
|
+
signal,
|
|
791
2149
|
filters = this.props.filters,
|
|
792
2150
|
filterOwner,
|
|
793
2151
|
spatialFilter,
|
|
794
2152
|
spatialFiltersMode,
|
|
795
2153
|
spatialIndexReferenceViewState,
|
|
796
|
-
abortController,
|
|
797
2154
|
...params
|
|
798
2155
|
} = options;
|
|
799
2156
|
const { column, operation, operationColumn } = params;
|
|
@@ -816,17 +2173,17 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
816
2173
|
operation,
|
|
817
2174
|
operationColumn: operationColumn || column
|
|
818
2175
|
},
|
|
819
|
-
opts: {
|
|
2176
|
+
opts: { signal, headers: this._headers }
|
|
820
2177
|
}).then((res) => normalizeObjectKeys(res.rows));
|
|
821
2178
|
}
|
|
822
2179
|
async getFeatures(options) {
|
|
823
2180
|
const {
|
|
2181
|
+
signal,
|
|
824
2182
|
filters = this.props.filters,
|
|
825
2183
|
filterOwner,
|
|
826
2184
|
spatialFilter,
|
|
827
2185
|
spatialFiltersMode,
|
|
828
2186
|
spatialIndexReferenceViewState,
|
|
829
|
-
abortController,
|
|
830
2187
|
...params
|
|
831
2188
|
} = options;
|
|
832
2189
|
const { columns, dataType, featureIds, z, limit, tileResolution } = params;
|
|
@@ -852,18 +2209,18 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
852
2209
|
limit: limit || 1e3,
|
|
853
2210
|
tileResolution: tileResolution || DEFAULT_TILE_RESOLUTION
|
|
854
2211
|
},
|
|
855
|
-
opts: {
|
|
2212
|
+
opts: { signal, headers: this._headers }
|
|
856
2213
|
// Avoid `normalizeObjectKeys()`, which changes column names.
|
|
857
2214
|
}).then(({ rows }) => ({ rows }));
|
|
858
2215
|
}
|
|
859
2216
|
async getFormula(options) {
|
|
860
2217
|
const {
|
|
2218
|
+
signal,
|
|
861
2219
|
filters = this.props.filters,
|
|
862
2220
|
filterOwner,
|
|
863
2221
|
spatialFilter,
|
|
864
2222
|
spatialFiltersMode,
|
|
865
2223
|
spatialIndexReferenceViewState,
|
|
866
|
-
abortController,
|
|
867
2224
|
operationExp,
|
|
868
2225
|
...params
|
|
869
2226
|
} = options;
|
|
@@ -887,17 +2244,17 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
887
2244
|
operation: operation ?? "count",
|
|
888
2245
|
operationExp
|
|
889
2246
|
},
|
|
890
|
-
opts: {
|
|
2247
|
+
opts: { signal, headers: this._headers }
|
|
891
2248
|
}).then((res) => normalizeObjectKeys(res.rows[0]));
|
|
892
2249
|
}
|
|
893
2250
|
async getHistogram(options) {
|
|
894
2251
|
const {
|
|
2252
|
+
signal,
|
|
895
2253
|
filters = this.props.filters,
|
|
896
2254
|
filterOwner,
|
|
897
2255
|
spatialFilter,
|
|
898
2256
|
spatialFiltersMode,
|
|
899
2257
|
spatialIndexReferenceViewState,
|
|
900
|
-
abortController,
|
|
901
2258
|
...params
|
|
902
2259
|
} = options;
|
|
903
2260
|
const { column, operation, ticks } = params;
|
|
@@ -916,7 +2273,7 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
916
2273
|
spatialFilter
|
|
917
2274
|
},
|
|
918
2275
|
params: { column, operation, ticks },
|
|
919
|
-
opts: {
|
|
2276
|
+
opts: { signal, headers: this._headers }
|
|
920
2277
|
}).then((res) => normalizeObjectKeys(res.rows));
|
|
921
2278
|
if (data.length) {
|
|
922
2279
|
const result = Array(ticks.length + 1).fill(0);
|
|
@@ -929,12 +2286,12 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
929
2286
|
}
|
|
930
2287
|
async getRange(options) {
|
|
931
2288
|
const {
|
|
2289
|
+
signal,
|
|
932
2290
|
filters = this.props.filters,
|
|
933
2291
|
filterOwner,
|
|
934
2292
|
spatialFilter,
|
|
935
2293
|
spatialFiltersMode,
|
|
936
2294
|
spatialIndexReferenceViewState,
|
|
937
|
-
abortController,
|
|
938
2295
|
...params
|
|
939
2296
|
} = options;
|
|
940
2297
|
const { column } = params;
|
|
@@ -953,17 +2310,17 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
953
2310
|
spatialFilter
|
|
954
2311
|
},
|
|
955
2312
|
params: { column },
|
|
956
|
-
opts: {
|
|
2313
|
+
opts: { signal, headers: this._headers }
|
|
957
2314
|
}).then((res) => normalizeObjectKeys(res.rows[0]));
|
|
958
2315
|
}
|
|
959
2316
|
async getScatter(options) {
|
|
960
2317
|
const {
|
|
2318
|
+
signal,
|
|
961
2319
|
filters = this.props.filters,
|
|
962
2320
|
filterOwner,
|
|
963
2321
|
spatialFilter,
|
|
964
2322
|
spatialFiltersMode,
|
|
965
2323
|
spatialIndexReferenceViewState,
|
|
966
|
-
abortController,
|
|
967
2324
|
...params
|
|
968
2325
|
} = options;
|
|
969
2326
|
const { xAxisColumn, xAxisJoinOperation, yAxisColumn, yAxisJoinOperation } = params;
|
|
@@ -989,17 +2346,17 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
989
2346
|
yAxisJoinOperation,
|
|
990
2347
|
limit: HARD_LIMIT
|
|
991
2348
|
},
|
|
992
|
-
opts: {
|
|
2349
|
+
opts: { signal, headers: this._headers }
|
|
993
2350
|
}).then((res) => normalizeObjectKeys(res.rows)).then((res) => res.map(({ x, y }) => [x, y]));
|
|
994
2351
|
}
|
|
995
2352
|
async getTable(options) {
|
|
996
2353
|
const {
|
|
2354
|
+
signal,
|
|
997
2355
|
filters = this.props.filters,
|
|
998
2356
|
filterOwner,
|
|
999
2357
|
spatialFilter,
|
|
1000
2358
|
spatialFiltersMode,
|
|
1001
2359
|
spatialIndexReferenceViewState,
|
|
1002
|
-
abortController,
|
|
1003
2360
|
...params
|
|
1004
2361
|
} = options;
|
|
1005
2362
|
const { columns, sortBy, sortDirection, offset = 0, limit = 10 } = params;
|
|
@@ -1024,7 +2381,7 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
1024
2381
|
limit,
|
|
1025
2382
|
offset
|
|
1026
2383
|
},
|
|
1027
|
-
opts: {
|
|
2384
|
+
opts: { signal, headers: this._headers }
|
|
1028
2385
|
}).then((res) => ({
|
|
1029
2386
|
// Avoid `normalizeObjectKeys()`, which changes column names.
|
|
1030
2387
|
rows: res.rows ?? res.ROWS,
|
|
@@ -1033,9 +2390,9 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
1033
2390
|
}
|
|
1034
2391
|
async getTimeSeries(options) {
|
|
1035
2392
|
const {
|
|
2393
|
+
signal,
|
|
1036
2394
|
filters = this.props.filters,
|
|
1037
2395
|
filterOwner,
|
|
1038
|
-
abortController,
|
|
1039
2396
|
spatialFilter,
|
|
1040
2397
|
spatialFiltersMode,
|
|
1041
2398
|
spatialIndexReferenceViewState,
|
|
@@ -1077,7 +2434,7 @@ var WidgetRemoteSource = class extends WidgetSource {
|
|
|
1077
2434
|
splitByCategoryLimit,
|
|
1078
2435
|
splitByCategoryValues
|
|
1079
2436
|
},
|
|
1080
|
-
opts: {
|
|
2437
|
+
opts: { signal, headers: this._headers }
|
|
1081
2438
|
}).then((res) => ({
|
|
1082
2439
|
rows: normalizeObjectKeys(res.rows),
|
|
1083
2440
|
categories: res.metadata?.categories
|
|
@@ -1108,39 +2465,682 @@ var WidgetTableSource = class extends WidgetRemoteSource {
|
|
|
1108
2465
|
}
|
|
1109
2466
|
};
|
|
1110
2467
|
|
|
1111
|
-
// src/
|
|
1112
|
-
var
|
|
2468
|
+
// src/operations/aggregation.ts
|
|
2469
|
+
var aggregationFunctions = {
|
|
2470
|
+
count: (values) => values.length,
|
|
2471
|
+
min: (...args) => applyAggregationFunction(min, ...args),
|
|
2472
|
+
max: (...args) => applyAggregationFunction(max, ...args),
|
|
2473
|
+
sum: (...args) => applyAggregationFunction(sum, ...args),
|
|
2474
|
+
avg: (...args) => applyAggregationFunction(avg, ...args)
|
|
2475
|
+
};
|
|
2476
|
+
function aggregate(feature2, keys, operation) {
|
|
2477
|
+
if (!keys?.length) {
|
|
2478
|
+
throw new Error("Cannot aggregate a feature without having keys");
|
|
2479
|
+
} else if (keys.length === 1) {
|
|
2480
|
+
const value = feature2[keys[0]];
|
|
2481
|
+
return isPotentiallyValidNumber(value) ? Number(value) : value;
|
|
2482
|
+
}
|
|
2483
|
+
const aggregationFn = aggregationFunctions[operation];
|
|
2484
|
+
if (!aggregationFn) {
|
|
2485
|
+
throw new Error(`${operation} isn't a valid aggregation function`);
|
|
2486
|
+
}
|
|
2487
|
+
return aggregationFn(
|
|
2488
|
+
keys.map((column) => {
|
|
2489
|
+
const value = feature2[column];
|
|
2490
|
+
return isPotentiallyValidNumber(value) ? Number(value) : value;
|
|
2491
|
+
})
|
|
2492
|
+
);
|
|
2493
|
+
}
|
|
2494
|
+
function isPotentiallyValidNumber(value) {
|
|
2495
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
2496
|
+
}
|
|
2497
|
+
var applyAggregationFunction = (aggFn, values, keys, operation) => {
|
|
2498
|
+
const normalizedKeys = normalizeKeys(keys);
|
|
2499
|
+
const elements = (normalizedKeys?.length || 0) <= 1 ? filterFalsyElements(values, normalizedKeys || []) : values;
|
|
2500
|
+
return aggFn(elements, keys, operation);
|
|
2501
|
+
};
|
|
2502
|
+
function filterFalsyElements(values, keys) {
|
|
2503
|
+
const filterFn = (value) => value !== null && value !== void 0;
|
|
2504
|
+
if (!keys?.length) {
|
|
2505
|
+
return values.filter(filterFn);
|
|
2506
|
+
}
|
|
2507
|
+
return values.filter((v) => filterFn(v[keys[0]]));
|
|
2508
|
+
}
|
|
2509
|
+
function avg(values, keys, joinOperation) {
|
|
2510
|
+
return sum(values, keys, joinOperation) / (values.length || 1);
|
|
2511
|
+
}
|
|
2512
|
+
function sum(values, keys, joinOperation) {
|
|
2513
|
+
const normalizedKeys = normalizeKeys(keys);
|
|
2514
|
+
if (normalizedKeys) {
|
|
2515
|
+
return values.reduce(
|
|
2516
|
+
(a, b) => a + aggregate(b, normalizedKeys, joinOperation),
|
|
2517
|
+
0
|
|
2518
|
+
);
|
|
2519
|
+
}
|
|
2520
|
+
return values.reduce((a, b) => a + b, 0);
|
|
2521
|
+
}
|
|
2522
|
+
function min(values, keys, joinOperation) {
|
|
2523
|
+
const normalizedKeys = normalizeKeys(keys);
|
|
2524
|
+
if (normalizedKeys) {
|
|
2525
|
+
return values.reduce(
|
|
2526
|
+
(a, b) => Math.min(a, aggregate(b, normalizedKeys, joinOperation)),
|
|
2527
|
+
Infinity
|
|
2528
|
+
);
|
|
2529
|
+
}
|
|
2530
|
+
return Math.min(...values);
|
|
2531
|
+
}
|
|
2532
|
+
function max(values, keys, joinOperation) {
|
|
2533
|
+
const normalizedKeys = normalizeKeys(keys);
|
|
2534
|
+
if (normalizedKeys) {
|
|
2535
|
+
return values.reduce(
|
|
2536
|
+
(a, b) => Math.max(a, aggregate(b, normalizedKeys, joinOperation)),
|
|
2537
|
+
-Infinity
|
|
2538
|
+
);
|
|
2539
|
+
}
|
|
2540
|
+
return Math.max(...values);
|
|
2541
|
+
}
|
|
2542
|
+
function normalizeKeys(keys) {
|
|
2543
|
+
return Array.isArray(keys) ? keys : typeof keys === "string" ? [keys] : void 0;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
// src/operations/applySorting.ts
|
|
2547
|
+
var import_thenby = __toESM(require_thenBy_module(), 1);
|
|
2548
|
+
function applySorting(features, {
|
|
2549
|
+
sortBy,
|
|
2550
|
+
sortByDirection = "asc",
|
|
2551
|
+
sortByColumnType = "string"
|
|
2552
|
+
} = {}) {
|
|
2553
|
+
if (sortBy === void 0) {
|
|
2554
|
+
return features;
|
|
2555
|
+
}
|
|
2556
|
+
const isValidSortBy = Array.isArray(sortBy) && sortBy.length || // sortBy can be an array of columns
|
|
2557
|
+
typeof sortBy === "string";
|
|
2558
|
+
if (!isValidSortBy) {
|
|
2559
|
+
throw new Error("Sorting options are bad formatted");
|
|
2560
|
+
}
|
|
2561
|
+
const sortFn = createSortFn({
|
|
2562
|
+
sortBy,
|
|
2563
|
+
sortByDirection,
|
|
2564
|
+
sortByColumnType: sortByColumnType || "string"
|
|
2565
|
+
});
|
|
2566
|
+
return features.sort(sortFn);
|
|
2567
|
+
}
|
|
2568
|
+
function createSortFn({
|
|
2569
|
+
sortBy,
|
|
2570
|
+
sortByDirection,
|
|
2571
|
+
sortByColumnType
|
|
2572
|
+
}) {
|
|
2573
|
+
const [firstSortOption, ...othersSortOptions] = normalizeSortByOptions({
|
|
2574
|
+
sortBy,
|
|
2575
|
+
sortByDirection,
|
|
2576
|
+
sortByColumnType
|
|
2577
|
+
});
|
|
2578
|
+
let sortFn = (0, import_thenby.firstBy)(...firstSortOption);
|
|
2579
|
+
for (const sortOptions of othersSortOptions) {
|
|
2580
|
+
sortFn = sortFn.thenBy(...sortOptions);
|
|
2581
|
+
}
|
|
2582
|
+
return sortFn;
|
|
2583
|
+
}
|
|
2584
|
+
function normalizeSortByOptions({
|
|
2585
|
+
sortBy,
|
|
2586
|
+
sortByDirection,
|
|
2587
|
+
sortByColumnType
|
|
2588
|
+
}) {
|
|
2589
|
+
const numberFormat = sortByColumnType === "number" && {
|
|
2590
|
+
cmp: (a, b) => a - b
|
|
2591
|
+
};
|
|
2592
|
+
if (!Array.isArray(sortBy)) {
|
|
2593
|
+
sortBy = [sortBy];
|
|
2594
|
+
}
|
|
2595
|
+
return sortBy.map((sortByEl) => {
|
|
2596
|
+
if (typeof sortByEl === "string") {
|
|
2597
|
+
return [sortByEl, { direction: sortByDirection, ...numberFormat }];
|
|
2598
|
+
}
|
|
2599
|
+
if (Array.isArray(sortByEl)) {
|
|
2600
|
+
if (sortByEl[1] === void 0) {
|
|
2601
|
+
return [sortByEl, { direction: sortByDirection, ...numberFormat }];
|
|
2602
|
+
}
|
|
2603
|
+
if (typeof sortByEl[1] === "object") {
|
|
2604
|
+
const othersSortOptions = numberFormat ? { ...numberFormat, ...sortByEl[1] } : sortByEl[1];
|
|
2605
|
+
return [
|
|
2606
|
+
sortByEl[0],
|
|
2607
|
+
{ direction: sortByDirection, ...othersSortOptions }
|
|
2608
|
+
];
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
return sortByEl;
|
|
2612
|
+
});
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
// src/operations/groupBy.ts
|
|
2616
|
+
function groupValuesByColumn({
|
|
2617
|
+
data,
|
|
2618
|
+
valuesColumns,
|
|
2619
|
+
joinOperation,
|
|
2620
|
+
keysColumn,
|
|
2621
|
+
operation
|
|
2622
|
+
}) {
|
|
2623
|
+
if (Array.isArray(data) && data.length === 0) {
|
|
2624
|
+
return null;
|
|
2625
|
+
}
|
|
2626
|
+
const groups = data.reduce((accumulator, item) => {
|
|
2627
|
+
const group = item[keysColumn];
|
|
2628
|
+
const values = accumulator.get(group) || [];
|
|
2629
|
+
accumulator.set(group, values);
|
|
2630
|
+
const aggregatedValue = aggregate(item, valuesColumns, joinOperation);
|
|
2631
|
+
const isValid = (operation === "count" ? true : aggregatedValue !== null) && aggregatedValue !== void 0;
|
|
2632
|
+
if (isValid) {
|
|
2633
|
+
values.push(aggregatedValue);
|
|
2634
|
+
accumulator.set(group, values);
|
|
2635
|
+
}
|
|
2636
|
+
return accumulator;
|
|
2637
|
+
}, /* @__PURE__ */ new Map());
|
|
2638
|
+
const targetOperation = aggregationFunctions[operation];
|
|
2639
|
+
if (targetOperation) {
|
|
2640
|
+
return Array.from(groups).map(([name, value]) => ({
|
|
2641
|
+
name,
|
|
2642
|
+
value: targetOperation(value)
|
|
2643
|
+
}));
|
|
2644
|
+
}
|
|
2645
|
+
return [];
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
// src/utils/dateUtils.ts
|
|
2649
|
+
function getUTCMonday(date) {
|
|
2650
|
+
const dateCp = new Date(date);
|
|
2651
|
+
const day = dateCp.getUTCDay();
|
|
2652
|
+
const diff = dateCp.getUTCDate() - day + (day ? 1 : -6);
|
|
2653
|
+
dateCp.setUTCDate(diff);
|
|
2654
|
+
return Date.UTC(
|
|
2655
|
+
dateCp.getUTCFullYear(),
|
|
2656
|
+
dateCp.getUTCMonth(),
|
|
2657
|
+
dateCp.getUTCDate()
|
|
2658
|
+
);
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
// src/operations/groupByDate.ts
|
|
2662
|
+
var GROUP_KEY_FN_MAPPING = {
|
|
2663
|
+
year: (date) => Date.UTC(date.getUTCFullYear()),
|
|
2664
|
+
month: (date) => Date.UTC(date.getUTCFullYear(), date.getUTCMonth()),
|
|
2665
|
+
week: (date) => getUTCMonday(date),
|
|
2666
|
+
day: (date) => Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()),
|
|
2667
|
+
hour: (date) => Date.UTC(
|
|
2668
|
+
date.getUTCFullYear(),
|
|
2669
|
+
date.getUTCMonth(),
|
|
2670
|
+
date.getUTCDate(),
|
|
2671
|
+
date.getUTCHours()
|
|
2672
|
+
),
|
|
2673
|
+
minute: (date) => Date.UTC(
|
|
2674
|
+
date.getUTCFullYear(),
|
|
2675
|
+
date.getUTCMonth(),
|
|
2676
|
+
date.getUTCDate(),
|
|
2677
|
+
date.getUTCHours(),
|
|
2678
|
+
date.getUTCMinutes()
|
|
2679
|
+
),
|
|
2680
|
+
second: (date) => Date.UTC(
|
|
2681
|
+
date.getUTCFullYear(),
|
|
2682
|
+
date.getUTCMonth(),
|
|
2683
|
+
date.getUTCDate(),
|
|
2684
|
+
date.getUTCHours(),
|
|
2685
|
+
date.getUTCMinutes(),
|
|
2686
|
+
date.getUTCSeconds()
|
|
2687
|
+
)
|
|
2688
|
+
};
|
|
2689
|
+
function groupValuesByDateColumn({
|
|
2690
|
+
data,
|
|
2691
|
+
valuesColumns,
|
|
2692
|
+
joinOperation,
|
|
2693
|
+
keysColumn,
|
|
2694
|
+
groupType,
|
|
2695
|
+
operation
|
|
2696
|
+
}) {
|
|
2697
|
+
if (Array.isArray(data) && data.length === 0) {
|
|
2698
|
+
return null;
|
|
2699
|
+
}
|
|
2700
|
+
const groupKeyFn = GROUP_KEY_FN_MAPPING[groupType];
|
|
2701
|
+
if (!groupKeyFn) {
|
|
2702
|
+
return null;
|
|
2703
|
+
}
|
|
2704
|
+
const groups = data.reduce((acc, item) => {
|
|
2705
|
+
const value = item[keysColumn];
|
|
2706
|
+
const formattedValue = new Date(value);
|
|
2707
|
+
const groupKey = groupKeyFn(formattedValue);
|
|
2708
|
+
if (!isNaN(groupKey)) {
|
|
2709
|
+
let groupedValues = acc.get(groupKey);
|
|
2710
|
+
if (!groupedValues) {
|
|
2711
|
+
groupedValues = [];
|
|
2712
|
+
acc.set(groupKey, groupedValues);
|
|
2713
|
+
}
|
|
2714
|
+
const aggregatedValue = aggregate(item, valuesColumns, joinOperation);
|
|
2715
|
+
const isValid = aggregatedValue !== null && aggregatedValue !== void 0;
|
|
2716
|
+
if (isValid) {
|
|
2717
|
+
groupedValues.push(aggregatedValue);
|
|
2718
|
+
acc.set(groupKey, groupedValues);
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
return acc;
|
|
2722
|
+
}, /* @__PURE__ */ new Map());
|
|
2723
|
+
const targetOperation = aggregationFunctions[operation];
|
|
2724
|
+
return [...groups.entries()].map(([name, value]) => ({
|
|
2725
|
+
name,
|
|
2726
|
+
value: targetOperation(value)
|
|
2727
|
+
})).sort((a, b) => a.name - b.name);
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
// src/operations/histogram.ts
|
|
2731
|
+
function histogram({
|
|
2732
|
+
data,
|
|
2733
|
+
valuesColumns,
|
|
2734
|
+
joinOperation,
|
|
2735
|
+
ticks,
|
|
2736
|
+
operation
|
|
2737
|
+
}) {
|
|
2738
|
+
if (Array.isArray(data) && data.length === 0) {
|
|
2739
|
+
return [];
|
|
2740
|
+
}
|
|
2741
|
+
const binsContainer = [Number.MIN_SAFE_INTEGER, ...ticks].map(
|
|
2742
|
+
(tick, index, arr) => ({
|
|
2743
|
+
bin: index,
|
|
2744
|
+
start: tick,
|
|
2745
|
+
end: index === arr.length - 1 ? Number.MAX_SAFE_INTEGER : arr[index + 1],
|
|
2746
|
+
values: []
|
|
2747
|
+
})
|
|
2748
|
+
);
|
|
2749
|
+
data.forEach((feature2) => {
|
|
2750
|
+
const featureValue = aggregate(
|
|
2751
|
+
feature2,
|
|
2752
|
+
valuesColumns,
|
|
2753
|
+
joinOperation
|
|
2754
|
+
);
|
|
2755
|
+
const isValid = featureValue !== null && featureValue !== void 0;
|
|
2756
|
+
if (!isValid) {
|
|
2757
|
+
return;
|
|
2758
|
+
}
|
|
2759
|
+
const binContainer = binsContainer.find(
|
|
2760
|
+
(bin) => bin.start <= featureValue && bin.end > featureValue
|
|
2761
|
+
);
|
|
2762
|
+
if (!binContainer) {
|
|
2763
|
+
return;
|
|
2764
|
+
}
|
|
2765
|
+
binContainer.values.push(featureValue);
|
|
2766
|
+
});
|
|
2767
|
+
const targetOperation = aggregationFunctions[operation];
|
|
2768
|
+
const transformedBins = binsContainer.map(
|
|
2769
|
+
(binContainer) => binContainer.values
|
|
2770
|
+
);
|
|
2771
|
+
return transformedBins.map(
|
|
2772
|
+
(values) => values.length ? targetOperation(values) : 0
|
|
2773
|
+
);
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
// src/operations/scatterPlot.ts
|
|
2777
|
+
function scatterPlot({
|
|
2778
|
+
data,
|
|
2779
|
+
xAxisColumns,
|
|
2780
|
+
xAxisJoinOperation,
|
|
2781
|
+
yAxisColumns,
|
|
2782
|
+
yAxisJoinOperation
|
|
2783
|
+
}) {
|
|
2784
|
+
return data.reduce(
|
|
2785
|
+
(acc, feature2) => {
|
|
2786
|
+
const xValue = aggregate(
|
|
2787
|
+
feature2,
|
|
2788
|
+
xAxisColumns,
|
|
2789
|
+
xAxisJoinOperation
|
|
2790
|
+
);
|
|
2791
|
+
const xIsValid = xValue !== null && xValue !== void 0;
|
|
2792
|
+
const yValue = aggregate(
|
|
2793
|
+
feature2,
|
|
2794
|
+
yAxisColumns,
|
|
2795
|
+
yAxisJoinOperation
|
|
2796
|
+
);
|
|
2797
|
+
const yIsValid = yValue !== null && yValue !== void 0;
|
|
2798
|
+
if (xIsValid && yIsValid) {
|
|
2799
|
+
acc.push([xValue, yValue]);
|
|
2800
|
+
}
|
|
2801
|
+
return acc;
|
|
2802
|
+
},
|
|
2803
|
+
[]
|
|
2804
|
+
);
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
// src/widget-sources/widget-tileset-source-impl.ts
|
|
2808
|
+
import { booleanEqual } from "@turf/boolean-equal";
|
|
2809
|
+
var WidgetTilesetSourceImpl = class extends WidgetSource {
|
|
2810
|
+
constructor() {
|
|
2811
|
+
super(...arguments);
|
|
2812
|
+
__publicField(this, "_tiles", []);
|
|
2813
|
+
__publicField(this, "_features", []);
|
|
2814
|
+
__publicField(this, "_tileFeatureExtractOptions", {});
|
|
2815
|
+
__publicField(this, "_tileFeatureExtractPreviousInputs", {});
|
|
2816
|
+
}
|
|
2817
|
+
/**
|
|
2818
|
+
* Loads features as a list of tiles (typically provided by deck.gl).
|
|
2819
|
+
* After tiles are loaded, {@link extractTileFeatures} must be called
|
|
2820
|
+
* before computing statistics on the tiles.
|
|
2821
|
+
*/
|
|
2822
|
+
loadTiles(tiles2) {
|
|
2823
|
+
this._tiles = tiles2;
|
|
2824
|
+
this._features.length = 0;
|
|
2825
|
+
}
|
|
2826
|
+
/** Configures options used to extract features from tiles. */
|
|
2827
|
+
setTileFeatureExtractOptions(options) {
|
|
2828
|
+
this._tileFeatureExtractOptions = options;
|
|
2829
|
+
this._features.length = 0;
|
|
2830
|
+
}
|
|
2831
|
+
_extractTileFeatures(spatialFilter) {
|
|
2832
|
+
const prevInputs = this._tileFeatureExtractPreviousInputs;
|
|
2833
|
+
if (this._features.length && prevInputs.spatialFilter && booleanEqual(prevInputs.spatialFilter, spatialFilter)) {
|
|
2834
|
+
return;
|
|
2835
|
+
}
|
|
2836
|
+
this._features = tileFeatures({
|
|
2837
|
+
tiles: this._tiles,
|
|
2838
|
+
tileFormat: this.props.tileFormat,
|
|
2839
|
+
...this._tileFeatureExtractOptions,
|
|
2840
|
+
spatialFilter,
|
|
2841
|
+
spatialDataColumn: this.props.spatialDataColumn,
|
|
2842
|
+
spatialDataType: this.props.spatialDataType
|
|
2843
|
+
});
|
|
2844
|
+
prevInputs.spatialFilter = spatialFilter;
|
|
2845
|
+
}
|
|
2846
|
+
/**
|
|
2847
|
+
* Loads features as GeoJSON (used for testing).
|
|
2848
|
+
* @experimental
|
|
2849
|
+
* @internal Not for public use. Spatial filters in other method calls will be ignored.
|
|
2850
|
+
*/
|
|
2851
|
+
loadGeoJSON({
|
|
2852
|
+
geojson,
|
|
2853
|
+
spatialFilter
|
|
2854
|
+
}) {
|
|
2855
|
+
this._features = geojsonFeatures({
|
|
2856
|
+
geojson,
|
|
2857
|
+
spatialFilter,
|
|
2858
|
+
...this._tileFeatureExtractOptions
|
|
2859
|
+
});
|
|
2860
|
+
this._tileFeatureExtractPreviousInputs.spatialFilter = spatialFilter;
|
|
2861
|
+
}
|
|
2862
|
+
async getFeatures() {
|
|
2863
|
+
throw new Error("getFeatures not supported for tilesets");
|
|
2864
|
+
}
|
|
2865
|
+
async getFormula({
|
|
2866
|
+
column = "*",
|
|
2867
|
+
operation = "count",
|
|
2868
|
+
joinOperation,
|
|
2869
|
+
filters,
|
|
2870
|
+
filterOwner,
|
|
2871
|
+
spatialFilter
|
|
2872
|
+
}) {
|
|
2873
|
+
if (operation === "custom") {
|
|
2874
|
+
throw new Error("Custom aggregation not supported for tilesets");
|
|
2875
|
+
}
|
|
2876
|
+
if (column && column !== "*" || operation !== "count") {
|
|
2877
|
+
assertColumn(this._features, column);
|
|
2878
|
+
}
|
|
2879
|
+
const filteredFeatures = this._getFilteredFeatures(
|
|
2880
|
+
spatialFilter,
|
|
2881
|
+
filters,
|
|
2882
|
+
filterOwner
|
|
2883
|
+
);
|
|
2884
|
+
if (filteredFeatures.length === 0 && operation !== "count") {
|
|
2885
|
+
return { value: null };
|
|
2886
|
+
}
|
|
2887
|
+
const targetOperation = aggregationFunctions[operation];
|
|
2888
|
+
return {
|
|
2889
|
+
value: targetOperation(filteredFeatures, column, joinOperation)
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
async getHistogram({
|
|
2893
|
+
operation = "count",
|
|
2894
|
+
ticks,
|
|
2895
|
+
column,
|
|
2896
|
+
joinOperation,
|
|
2897
|
+
filters,
|
|
2898
|
+
filterOwner,
|
|
2899
|
+
spatialFilter
|
|
2900
|
+
}) {
|
|
2901
|
+
const filteredFeatures = this._getFilteredFeatures(
|
|
2902
|
+
spatialFilter,
|
|
2903
|
+
filters,
|
|
2904
|
+
filterOwner
|
|
2905
|
+
);
|
|
2906
|
+
if (!this._features.length) {
|
|
2907
|
+
return [];
|
|
2908
|
+
}
|
|
2909
|
+
assertColumn(this._features, column);
|
|
2910
|
+
return histogram({
|
|
2911
|
+
data: filteredFeatures,
|
|
2912
|
+
valuesColumns: normalizeColumns(column),
|
|
2913
|
+
joinOperation,
|
|
2914
|
+
ticks,
|
|
2915
|
+
operation
|
|
2916
|
+
});
|
|
2917
|
+
}
|
|
2918
|
+
async getCategories({
|
|
2919
|
+
column,
|
|
2920
|
+
operation = "count",
|
|
2921
|
+
operationColumn,
|
|
2922
|
+
joinOperation,
|
|
2923
|
+
filters,
|
|
2924
|
+
filterOwner,
|
|
2925
|
+
spatialFilter
|
|
2926
|
+
}) {
|
|
2927
|
+
const filteredFeatures = this._getFilteredFeatures(
|
|
2928
|
+
spatialFilter,
|
|
2929
|
+
filters,
|
|
2930
|
+
filterOwner
|
|
2931
|
+
);
|
|
2932
|
+
if (!filteredFeatures.length) {
|
|
2933
|
+
return [];
|
|
2934
|
+
}
|
|
2935
|
+
assertColumn(this._features, column, operationColumn);
|
|
2936
|
+
const groups = groupValuesByColumn({
|
|
2937
|
+
data: filteredFeatures,
|
|
2938
|
+
valuesColumns: normalizeColumns(operationColumn || column),
|
|
2939
|
+
joinOperation,
|
|
2940
|
+
keysColumn: column,
|
|
2941
|
+
operation
|
|
2942
|
+
});
|
|
2943
|
+
return groups || [];
|
|
2944
|
+
}
|
|
2945
|
+
async getScatter({
|
|
2946
|
+
xAxisColumn,
|
|
2947
|
+
yAxisColumn,
|
|
2948
|
+
xAxisJoinOperation,
|
|
2949
|
+
yAxisJoinOperation,
|
|
2950
|
+
filters,
|
|
2951
|
+
filterOwner,
|
|
2952
|
+
spatialFilter
|
|
2953
|
+
}) {
|
|
2954
|
+
const filteredFeatures = this._getFilteredFeatures(
|
|
2955
|
+
spatialFilter,
|
|
2956
|
+
filters,
|
|
2957
|
+
filterOwner
|
|
2958
|
+
);
|
|
2959
|
+
if (!filteredFeatures.length) {
|
|
2960
|
+
return [];
|
|
2961
|
+
}
|
|
2962
|
+
assertColumn(this._features, xAxisColumn, yAxisColumn);
|
|
2963
|
+
return scatterPlot({
|
|
2964
|
+
data: filteredFeatures,
|
|
2965
|
+
xAxisColumns: normalizeColumns(xAxisColumn),
|
|
2966
|
+
xAxisJoinOperation,
|
|
2967
|
+
yAxisColumns: normalizeColumns(yAxisColumn),
|
|
2968
|
+
yAxisJoinOperation
|
|
2969
|
+
});
|
|
2970
|
+
}
|
|
2971
|
+
async getTable({
|
|
2972
|
+
columns,
|
|
2973
|
+
searchFilterColumn,
|
|
2974
|
+
searchFilterText,
|
|
2975
|
+
sortBy,
|
|
2976
|
+
sortDirection,
|
|
2977
|
+
sortByColumnType,
|
|
2978
|
+
offset = 0,
|
|
2979
|
+
limit = 10,
|
|
2980
|
+
filters,
|
|
2981
|
+
filterOwner,
|
|
2982
|
+
spatialFilter
|
|
2983
|
+
}) {
|
|
2984
|
+
let filteredFeatures = this._getFilteredFeatures(
|
|
2985
|
+
spatialFilter,
|
|
2986
|
+
filters,
|
|
2987
|
+
filterOwner
|
|
2988
|
+
);
|
|
2989
|
+
if (!filteredFeatures.length) {
|
|
2990
|
+
return { rows: [], totalCount: 0 };
|
|
2991
|
+
}
|
|
2992
|
+
if (searchFilterColumn && searchFilterText) {
|
|
2993
|
+
filteredFeatures = filteredFeatures.filter(
|
|
2994
|
+
(row) => row[searchFilterColumn] && String(row[searchFilterColumn]).toLowerCase().includes(String(searchFilterText).toLowerCase())
|
|
2995
|
+
);
|
|
2996
|
+
}
|
|
2997
|
+
let rows = applySorting(filteredFeatures, {
|
|
2998
|
+
sortBy,
|
|
2999
|
+
sortByDirection: sortDirection,
|
|
3000
|
+
sortByColumnType
|
|
3001
|
+
});
|
|
3002
|
+
const totalCount = rows.length;
|
|
3003
|
+
rows = rows.slice(
|
|
3004
|
+
Math.min(offset, totalCount),
|
|
3005
|
+
Math.min(offset + limit, totalCount)
|
|
3006
|
+
);
|
|
3007
|
+
rows = rows.map((srcRow) => {
|
|
3008
|
+
const dstRow = {};
|
|
3009
|
+
for (const column of columns) {
|
|
3010
|
+
dstRow[column] = srcRow[column];
|
|
3011
|
+
}
|
|
3012
|
+
return dstRow;
|
|
3013
|
+
});
|
|
3014
|
+
return { rows, totalCount };
|
|
3015
|
+
}
|
|
3016
|
+
async getTimeSeries({
|
|
3017
|
+
column,
|
|
3018
|
+
stepSize,
|
|
3019
|
+
operation,
|
|
3020
|
+
operationColumn,
|
|
3021
|
+
joinOperation,
|
|
3022
|
+
filters,
|
|
3023
|
+
filterOwner,
|
|
3024
|
+
spatialFilter
|
|
3025
|
+
}) {
|
|
3026
|
+
const filteredFeatures = this._getFilteredFeatures(
|
|
3027
|
+
spatialFilter,
|
|
3028
|
+
filters,
|
|
3029
|
+
filterOwner
|
|
3030
|
+
);
|
|
3031
|
+
if (!filteredFeatures.length) {
|
|
3032
|
+
return { rows: [] };
|
|
3033
|
+
}
|
|
3034
|
+
assertColumn(this._features, column, operationColumn);
|
|
3035
|
+
const rows = groupValuesByDateColumn({
|
|
3036
|
+
data: filteredFeatures,
|
|
3037
|
+
valuesColumns: normalizeColumns(operationColumn || column),
|
|
3038
|
+
keysColumn: column,
|
|
3039
|
+
groupType: stepSize,
|
|
3040
|
+
operation,
|
|
3041
|
+
joinOperation
|
|
3042
|
+
}) || [];
|
|
3043
|
+
return { rows };
|
|
3044
|
+
}
|
|
3045
|
+
async getRange({
|
|
3046
|
+
column,
|
|
3047
|
+
filters,
|
|
3048
|
+
filterOwner,
|
|
3049
|
+
spatialFilter
|
|
3050
|
+
}) {
|
|
3051
|
+
assertColumn(this._features, column);
|
|
3052
|
+
const filteredFeatures = this._getFilteredFeatures(
|
|
3053
|
+
spatialFilter,
|
|
3054
|
+
filters,
|
|
3055
|
+
filterOwner
|
|
3056
|
+
);
|
|
3057
|
+
if (!this._features.length) {
|
|
3058
|
+
return null;
|
|
3059
|
+
}
|
|
3060
|
+
return {
|
|
3061
|
+
min: aggregationFunctions.min(filteredFeatures, column),
|
|
3062
|
+
max: aggregationFunctions.max(filteredFeatures, column)
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
3065
|
+
/****************************************************************************
|
|
3066
|
+
* INTERNAL
|
|
3067
|
+
*/
|
|
3068
|
+
_getFilteredFeatures(spatialFilter, filters, filterOwner) {
|
|
3069
|
+
assert2(spatialFilter, "spatialFilter required for tilesets");
|
|
3070
|
+
this._extractTileFeatures(spatialFilter);
|
|
3071
|
+
return applyFilters(
|
|
3072
|
+
this._features,
|
|
3073
|
+
getApplicableFilters(filterOwner, filters || this.props.filters),
|
|
3074
|
+
this.props.filtersLogicalOperator || "and"
|
|
3075
|
+
);
|
|
3076
|
+
}
|
|
3077
|
+
};
|
|
3078
|
+
function assertColumn(features, ...columnArgs) {
|
|
3079
|
+
const columns = Array.from(new Set(columnArgs.map(normalizeColumns).flat()));
|
|
3080
|
+
const featureKeys = Object.keys(features[0]);
|
|
3081
|
+
const invalidColumns = columns.filter(
|
|
3082
|
+
(column) => !featureKeys.includes(column)
|
|
3083
|
+
);
|
|
3084
|
+
if (invalidColumns.length) {
|
|
3085
|
+
throw new InvalidColumnError(
|
|
3086
|
+
`Missing column(s): ${invalidColumns.join(", ")}`
|
|
3087
|
+
);
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
function normalizeColumns(columns) {
|
|
3091
|
+
return Array.isArray(columns) ? columns : typeof columns === "string" ? [columns] : [];
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
// src/widget-sources/widget-tileset-source.ts
|
|
3095
|
+
var WidgetTilesetSource = class extends WidgetSource {
|
|
1113
3096
|
constructor(props) {
|
|
1114
3097
|
super(props);
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
__publicField(this, "
|
|
3098
|
+
__publicField(this, "_localImpl", null);
|
|
3099
|
+
__publicField(this, "_workerImpl", null);
|
|
3100
|
+
__publicField(this, "_workerEnabled");
|
|
1118
3101
|
__publicField(this, "_workerNextRequestId", 1);
|
|
3102
|
+
this._workerEnabled = (props.widgetSourceWorker ?? true) && true;
|
|
3103
|
+
this._localImpl = this._workerEnabled ? null : new WidgetTilesetSourceImpl(this.props);
|
|
3104
|
+
}
|
|
3105
|
+
destroy() {
|
|
3106
|
+
this._localImpl?.destroy();
|
|
3107
|
+
this._localImpl = null;
|
|
3108
|
+
this._workerImpl?.terminate();
|
|
3109
|
+
this._workerImpl = null;
|
|
3110
|
+
super.destroy();
|
|
1119
3111
|
}
|
|
3112
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
3113
|
+
// WEB WORKER MANAGEMENT
|
|
1120
3114
|
/**
|
|
1121
3115
|
* Returns an initialized Worker, to be reused for the lifecycle of this
|
|
1122
3116
|
* source instance.
|
|
1123
3117
|
*/
|
|
1124
3118
|
_getWorker() {
|
|
1125
|
-
if (this.
|
|
1126
|
-
return this.
|
|
3119
|
+
if (this._workerImpl || this._localImpl) {
|
|
3120
|
+
return this._workerImpl;
|
|
1127
3121
|
}
|
|
1128
|
-
|
|
1129
|
-
new URL("
|
|
1130
|
-
{
|
|
3122
|
+
try {
|
|
3123
|
+
this._workerImpl = new Worker(new URL("worker.js", import.meta.url), {
|
|
1131
3124
|
type: "module",
|
|
1132
3125
|
name: "cartowidgettileset"
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
3126
|
+
});
|
|
3127
|
+
this._workerImpl.postMessage({
|
|
3128
|
+
method: "init" /* INIT */,
|
|
3129
|
+
params: [this.props]
|
|
3130
|
+
});
|
|
3131
|
+
return this._workerImpl;
|
|
3132
|
+
} catch {
|
|
3133
|
+
this._workerEnabled = false;
|
|
3134
|
+
this._localImpl = new WidgetTilesetSourceImpl(this.props);
|
|
3135
|
+
return null;
|
|
3136
|
+
}
|
|
1140
3137
|
}
|
|
1141
3138
|
/** Executes a given method on the worker. */
|
|
1142
3139
|
_executeWorkerMethod(method, params, signal) {
|
|
1143
3140
|
const worker = this._getWorker();
|
|
3141
|
+
if (!worker) {
|
|
3142
|
+
return this._localImpl[method](...params);
|
|
3143
|
+
}
|
|
1144
3144
|
const requestId = this._workerNextRequestId++;
|
|
1145
3145
|
const options = params[0];
|
|
1146
3146
|
if (options?.spatialIndexReferenceViewState) {
|
|
@@ -1187,20 +3187,28 @@ var WidgetTilesetWorkerSource = class extends WidgetSource {
|
|
|
1187
3187
|
* After tiles are loaded, {@link extractTileFeatures} must be called
|
|
1188
3188
|
* before computing statistics on the tiles.
|
|
1189
3189
|
*/
|
|
1190
|
-
loadTiles(
|
|
1191
|
-
|
|
3190
|
+
loadTiles(tiles2) {
|
|
3191
|
+
const worker = this._getWorker();
|
|
3192
|
+
if (!worker) {
|
|
3193
|
+
return this._localImpl.loadTiles(tiles2);
|
|
3194
|
+
}
|
|
3195
|
+
tiles2 = tiles2.map(({ id, bbox, data }) => ({
|
|
1192
3196
|
id,
|
|
1193
3197
|
bbox,
|
|
1194
3198
|
data
|
|
1195
3199
|
}));
|
|
1196
|
-
|
|
3200
|
+
worker.postMessage({
|
|
1197
3201
|
method: "loadTiles" /* LOAD_TILES */,
|
|
1198
|
-
params: [
|
|
3202
|
+
params: [tiles2]
|
|
1199
3203
|
});
|
|
1200
3204
|
}
|
|
1201
3205
|
/** Configures options used to extract features from tiles. */
|
|
1202
3206
|
setTileFeatureExtractOptions(options) {
|
|
1203
|
-
this._getWorker()
|
|
3207
|
+
const worker = this._getWorker();
|
|
3208
|
+
if (!worker) {
|
|
3209
|
+
return this._localImpl?.setTileFeatureExtractOptions(options);
|
|
3210
|
+
}
|
|
3211
|
+
worker.postMessage({
|
|
1204
3212
|
type: "setTileFeatureExtractOptions" /* SET_TILE_FEATURE_EXTRACT_OPTIONS */,
|
|
1205
3213
|
params: [options]
|
|
1206
3214
|
});
|
|
@@ -1214,7 +3222,11 @@ var WidgetTilesetWorkerSource = class extends WidgetSource {
|
|
|
1214
3222
|
geojson,
|
|
1215
3223
|
spatialFilter
|
|
1216
3224
|
}) {
|
|
1217
|
-
this._getWorker()
|
|
3225
|
+
const worker = this._getWorker();
|
|
3226
|
+
if (!worker) {
|
|
3227
|
+
return this._localImpl.loadGeoJSON({ geojson, spatialFilter });
|
|
3228
|
+
}
|
|
3229
|
+
worker.postMessage({
|
|
1218
3230
|
method: "loadGeoJSON" /* LOAD_GEOJSON */,
|
|
1219
3231
|
params: [{ geojson, spatialFilter }]
|
|
1220
3232
|
});
|
|
@@ -1226,74 +3238,46 @@ var WidgetTilesetWorkerSource = class extends WidgetSource {
|
|
|
1226
3238
|
throw new Error("getFeatures not supported for tilesets");
|
|
1227
3239
|
}
|
|
1228
3240
|
async getFormula({
|
|
1229
|
-
|
|
3241
|
+
signal,
|
|
1230
3242
|
...options
|
|
1231
3243
|
}) {
|
|
1232
|
-
return this._executeWorkerMethod(
|
|
1233
|
-
"getFormula" /* GET_FORMULA */,
|
|
1234
|
-
[options],
|
|
1235
|
-
abortController?.signal
|
|
1236
|
-
);
|
|
3244
|
+
return this._executeWorkerMethod("getFormula" /* GET_FORMULA */, [options], signal);
|
|
1237
3245
|
}
|
|
1238
3246
|
async getHistogram({
|
|
1239
|
-
|
|
3247
|
+
signal,
|
|
1240
3248
|
...options
|
|
1241
3249
|
}) {
|
|
1242
|
-
return this._executeWorkerMethod(
|
|
1243
|
-
"getHistogram" /* GET_HISTOGRAM */,
|
|
1244
|
-
[options],
|
|
1245
|
-
abortController?.signal
|
|
1246
|
-
);
|
|
3250
|
+
return this._executeWorkerMethod("getHistogram" /* GET_HISTOGRAM */, [options], signal);
|
|
1247
3251
|
}
|
|
1248
3252
|
async getCategories({
|
|
1249
|
-
|
|
3253
|
+
signal,
|
|
1250
3254
|
...options
|
|
1251
3255
|
}) {
|
|
1252
|
-
return this._executeWorkerMethod(
|
|
1253
|
-
"getCategories" /* GET_CATEGORIES */,
|
|
1254
|
-
[options],
|
|
1255
|
-
abortController?.signal
|
|
1256
|
-
);
|
|
3256
|
+
return this._executeWorkerMethod("getCategories" /* GET_CATEGORIES */, [options], signal);
|
|
1257
3257
|
}
|
|
1258
3258
|
async getScatter({
|
|
1259
|
-
|
|
3259
|
+
signal,
|
|
1260
3260
|
...options
|
|
1261
3261
|
}) {
|
|
1262
|
-
return this._executeWorkerMethod(
|
|
1263
|
-
"getScatter" /* GET_SCATTER */,
|
|
1264
|
-
[options],
|
|
1265
|
-
abortController?.signal
|
|
1266
|
-
);
|
|
3262
|
+
return this._executeWorkerMethod("getScatter" /* GET_SCATTER */, [options], signal);
|
|
1267
3263
|
}
|
|
1268
3264
|
async getTable({
|
|
1269
|
-
|
|
3265
|
+
signal,
|
|
1270
3266
|
...options
|
|
1271
3267
|
}) {
|
|
1272
|
-
return this._executeWorkerMethod(
|
|
1273
|
-
"getTable" /* GET_TABLE */,
|
|
1274
|
-
[options],
|
|
1275
|
-
abortController?.signal
|
|
1276
|
-
);
|
|
3268
|
+
return this._executeWorkerMethod("getTable" /* GET_TABLE */, [options], signal);
|
|
1277
3269
|
}
|
|
1278
3270
|
async getTimeSeries({
|
|
1279
|
-
|
|
3271
|
+
signal,
|
|
1280
3272
|
...options
|
|
1281
3273
|
}) {
|
|
1282
|
-
return this._executeWorkerMethod(
|
|
1283
|
-
"getTimeSeries" /* GET_TIME_SERIES */,
|
|
1284
|
-
[options],
|
|
1285
|
-
abortController?.signal
|
|
1286
|
-
);
|
|
3274
|
+
return this._executeWorkerMethod("getTimeSeries" /* GET_TIME_SERIES */, [options], signal);
|
|
1287
3275
|
}
|
|
1288
3276
|
async getRange({
|
|
1289
|
-
|
|
3277
|
+
signal,
|
|
1290
3278
|
...options
|
|
1291
3279
|
}) {
|
|
1292
|
-
return this._executeWorkerMethod(
|
|
1293
|
-
"getRange" /* GET_RANGE */,
|
|
1294
|
-
[options],
|
|
1295
|
-
abortController?.signal
|
|
1296
|
-
);
|
|
3280
|
+
return this._executeWorkerMethod("getRange" /* GET_RANGE */, [options], signal);
|
|
1297
3281
|
}
|
|
1298
3282
|
};
|
|
1299
3283
|
|
|
@@ -1377,35 +3361,14 @@ function getTileFormat(tilejson) {
|
|
|
1377
3361
|
return tileParams.get("formatTiles") === "mvt" ? "mvt" /* MVT */ : "binary" /* BINARY */;
|
|
1378
3362
|
}
|
|
1379
3363
|
|
|
1380
|
-
// src/workers/utils.ts
|
|
1381
|
-
var _isModuleWorkerSupported = false ? false : null;
|
|
1382
|
-
function isModuleWorkerSupported() {
|
|
1383
|
-
if (_isModuleWorkerSupported !== null) {
|
|
1384
|
-
return _isModuleWorkerSupported;
|
|
1385
|
-
}
|
|
1386
|
-
try {
|
|
1387
|
-
new Worker("blob://", {
|
|
1388
|
-
get type() {
|
|
1389
|
-
_isModuleWorkerSupported = true;
|
|
1390
|
-
return "module";
|
|
1391
|
-
}
|
|
1392
|
-
});
|
|
1393
|
-
} catch {
|
|
1394
|
-
} finally {
|
|
1395
|
-
_isModuleWorkerSupported || (_isModuleWorkerSupported = false);
|
|
1396
|
-
}
|
|
1397
|
-
return _isModuleWorkerSupported;
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
3364
|
// src/sources/h3-tileset-source.ts
|
|
1401
3365
|
var h3TilesetSource = async function(options) {
|
|
1402
3366
|
const { tableName, spatialDataColumn = "h3" } = options;
|
|
1403
3367
|
const urlParameters = { name: tableName };
|
|
1404
|
-
const WidgetSourceClass = options.widgetSourceWorker !== false && isModuleWorkerSupported() ? WidgetTilesetWorkerSource : WidgetTilesetSource;
|
|
1405
3368
|
return baseSource("tileset", options, urlParameters).then(
|
|
1406
3369
|
(result) => ({
|
|
1407
3370
|
...result,
|
|
1408
|
-
widgetSource: new
|
|
3371
|
+
widgetSource: new WidgetTilesetSource({
|
|
1409
3372
|
...options,
|
|
1410
3373
|
tileFormat: getTileFormat(result),
|
|
1411
3374
|
spatialDataColumn,
|
|
@@ -1507,11 +3470,10 @@ var quadbinTableSource = async function(options) {
|
|
|
1507
3470
|
var quadbinTilesetSource = async function(options) {
|
|
1508
3471
|
const { tableName, spatialDataColumn = "quadbin" } = options;
|
|
1509
3472
|
const urlParameters = { name: tableName };
|
|
1510
|
-
const WidgetSourceClass = options.widgetSourceWorker !== false && isModuleWorkerSupported() ? WidgetTilesetWorkerSource : WidgetTilesetSource;
|
|
1511
3473
|
return baseSource("tileset", options, urlParameters).then(
|
|
1512
3474
|
(result) => ({
|
|
1513
3475
|
...result,
|
|
1514
|
-
widgetSource: new
|
|
3476
|
+
widgetSource: new WidgetTilesetSource({
|
|
1515
3477
|
...options,
|
|
1516
3478
|
tileFormat: getTileFormat(result),
|
|
1517
3479
|
spatialDataColumn,
|
|
@@ -1609,11 +3571,10 @@ var vectorTableSource = async function(options) {
|
|
|
1609
3571
|
var vectorTilesetSource = async function(options) {
|
|
1610
3572
|
const { tableName, spatialDataColumn = DEFAULT_GEO_COLUMN } = options;
|
|
1611
3573
|
const urlParameters = { name: tableName };
|
|
1612
|
-
const WidgetSourceClass = options.widgetSourceWorker !== false && isModuleWorkerSupported() ? WidgetTilesetWorkerSource : WidgetTilesetSource;
|
|
1613
3574
|
return baseSource("tileset", options, urlParameters).then(
|
|
1614
3575
|
(result) => ({
|
|
1615
3576
|
...result,
|
|
1616
|
-
widgetSource: new
|
|
3577
|
+
widgetSource: new WidgetTilesetSource({
|
|
1617
3578
|
...options,
|
|
1618
3579
|
tileFormat: getTileFormat(result),
|
|
1619
3580
|
spatialDataColumn,
|
|
@@ -1674,7 +3635,6 @@ export {
|
|
|
1674
3635
|
WidgetSource,
|
|
1675
3636
|
WidgetTableSource,
|
|
1676
3637
|
WidgetTilesetSource,
|
|
1677
|
-
WidgetTilesetWorkerSource,
|
|
1678
3638
|
_buildFeatureFilter,
|
|
1679
3639
|
_getHexagonResolution,
|
|
1680
3640
|
addFilter,
|