@deck.gl/carto 9.2.0-beta.1 → 9.2.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dist.dev.js CHANGED
@@ -394,6 +394,13 @@ var __exports__ = (() => {
394
394
  }
395
395
  });
396
396
 
397
+ // external-global-plugin:h3-js
398
+ var require_h3_js = __commonJS({
399
+ "external-global-plugin:h3-js"(exports, module) {
400
+ module.exports = globalThis.h3 || {};
401
+ }
402
+ });
403
+
397
404
  // ../../node_modules/pako/lib/utils/common.js
398
405
  var require_common = __commonJS({
399
406
  "../../node_modules/pako/lib/utils/common.js"(exports) {
@@ -5342,13 +5349,6 @@ var __exports__ = (() => {
5342
5349
  }
5343
5350
  });
5344
5351
 
5345
- // external-global-plugin:h3-js
5346
- var require_h3_js = __commonJS({
5347
- "external-global-plugin:h3-js"(exports, module) {
5348
- module.exports = globalThis.h3 || {};
5349
- }
5350
- });
5351
-
5352
5352
  // ../../node_modules/earcut/src/earcut.js
5353
5353
  var require_earcut = __commonJS({
5354
5354
  "../../node_modules/earcut/src/earcut.js"(exports, module) {
@@ -5858,7 +5858,7 @@ var __exports__ = (() => {
5858
5858
 
5859
5859
  // src/layers/cluster-tile-layer.ts
5860
5860
  var import_layers = __toESM(require_layers(), 1);
5861
- var import_geo_layers2 = __toESM(require_geo_layers(), 1);
5861
+ var import_geo_layers3 = __toESM(require_geo_layers(), 1);
5862
5862
  var import_core5 = __toESM(require_core(), 1);
5863
5863
 
5864
5864
  // ../../node_modules/@loaders.gl/gis/dist/lib/binary-features/binary-to-geojson.js
@@ -6105,6 +6105,7 @@ var __exports__ = (() => {
6105
6105
  }
6106
6106
 
6107
6107
  // src/layers/cluster-utils.ts
6108
+ var import_h3_js = __toESM(require_h3_js(), 1);
6108
6109
  var import_core2 = __toESM(require_core2(), 1);
6109
6110
 
6110
6111
  // src/utils.ts
@@ -6189,7 +6190,7 @@ var __exports__ = (() => {
6189
6190
  }
6190
6191
 
6191
6192
  // src/layers/cluster-utils.ts
6192
- function aggregateTile(tile, tileAggregationCache, aggregationLevels, properties = [], getPosition, getWeight) {
6193
+ function aggregateTile(tile, tileAggregationCache, aggregationLevels, properties = [], getPosition, getWeight, scheme = "quadbin") {
6193
6194
  if (!tile.content)
6194
6195
  return false;
6195
6196
  if (!tile.userData)
@@ -6206,9 +6207,14 @@ var __exports__ = (() => {
6206
6207
  let id5 = cell.id;
6207
6208
  const position = typeof getPosition === "function" ? getPosition(cell, {}) : getPosition;
6208
6209
  for (let i = 0; i < aggregationLevels - 1; i++) {
6209
- id5 = cellToParent(id5);
6210
+ if (scheme === "h3") {
6211
+ const currentResolution = (0, import_h3_js.getResolution)(id5);
6212
+ id5 = (0, import_h3_js.cellToParent)(id5, Math.max(0, currentResolution - 1));
6213
+ } else {
6214
+ id5 = cellToParent(id5);
6215
+ }
6210
6216
  }
6211
- const parentId = Number(id5);
6217
+ const parentId = String(id5);
6212
6218
  if (!(parentId in out)) {
6213
6219
  out[parentId] = { id: id5, count: 0, position: [0, 0] };
6214
6220
  for (const { name, aggregation } of properties) {
@@ -6309,6 +6315,118 @@ var __exports__ = (() => {
6309
6315
  }
6310
6316
  };
6311
6317
 
6318
+ // src/layers/h3-tileset-2d.ts
6319
+ var import_geo_layers2 = __toESM(require_geo_layers(), 1);
6320
+ var import_h3_js2 = __toESM(require_h3_js(), 1);
6321
+ var MAX_LATITUDE2 = 85.051128;
6322
+ function padBoundingBox({ west, north, east, south }, resolution, scale = 1) {
6323
+ const corners = [
6324
+ [north, east],
6325
+ [south, east],
6326
+ [south, west],
6327
+ [north, west]
6328
+ ];
6329
+ const cornerCells = corners.map((c) => (0, import_h3_js2.latLngToCell)(c[0], c[1], resolution));
6330
+ const cornerEdgeLengths = cornerCells.map(
6331
+ (c) => Math.max(...(0, import_h3_js2.originToDirectedEdges)(c).map((e) => (0, import_h3_js2.edgeLength)(e, import_h3_js2.UNITS.rads))) * 180 / Math.PI
6332
+ );
6333
+ const bufferLat = Math.max(...cornerEdgeLengths) * scale;
6334
+ const bufferLon = Math.min(180, bufferLat / Math.cos((north + south) / 2 * Math.PI / 180));
6335
+ return {
6336
+ north: Math.min(north + bufferLat, MAX_LATITUDE2),
6337
+ east: east + bufferLon,
6338
+ south: Math.max(south - bufferLat, -MAX_LATITUDE2),
6339
+ west: west - bufferLon
6340
+ };
6341
+ }
6342
+ function getHexagonsInBoundingBox({ west, north, east, south }, resolution) {
6343
+ const longitudeSpan = Math.abs(east - west);
6344
+ if (longitudeSpan > 180) {
6345
+ const nSegments = Math.ceil(longitudeSpan / 180);
6346
+ let h3Indices = [];
6347
+ for (let s = 0; s < nSegments; s++) {
6348
+ const segmentWest = west + s * 180;
6349
+ const segmentEast = Math.min(segmentWest + 179.9999999, east);
6350
+ h3Indices = h3Indices.concat(
6351
+ getHexagonsInBoundingBox({ west: segmentWest, north, east: segmentEast, south }, resolution)
6352
+ );
6353
+ }
6354
+ return [...new Set(h3Indices)];
6355
+ }
6356
+ const polygon2 = [
6357
+ [north, east],
6358
+ [south, east],
6359
+ [south, west],
6360
+ [north, west],
6361
+ [north, east]
6362
+ ];
6363
+ return (0, import_h3_js2.polygonToCells)(polygon2, resolution);
6364
+ }
6365
+ function tileToBoundingBox(index2) {
6366
+ const coordinates = (0, import_h3_js2.cellToBoundary)(index2);
6367
+ const latitudes = coordinates.map((c) => c[0]);
6368
+ const longitudes = coordinates.map((c) => c[1]);
6369
+ const west = Math.min(...longitudes);
6370
+ const south = Math.min(...latitudes);
6371
+ const east = Math.max(...longitudes);
6372
+ const north = Math.max(...latitudes);
6373
+ const bbox2 = { west, south, east, north };
6374
+ return padBoundingBox(bbox2, (0, import_h3_js2.getResolution)(index2), 0.12);
6375
+ }
6376
+ var BIAS = 2;
6377
+ function getHexagonResolution(viewport, tileSize) {
6378
+ const zoomOffset = Math.log2(tileSize / 512);
6379
+ const hexagonScaleFactor = 2 / 3 * (viewport.zoom - zoomOffset);
6380
+ const latitudeScaleFactor = Math.log(1 / Math.cos(Math.PI * viewport.latitude / 180));
6381
+ return Math.max(0, Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS));
6382
+ }
6383
+ var H3Tileset2D = class extends import_geo_layers2._Tileset2D {
6384
+ /**
6385
+ * Returns all tile indices in the current viewport. If the current zoom level is smaller
6386
+ * than minZoom, return an empty array. If the current zoom level is greater than maxZoom,
6387
+ * return tiles that are on maxZoom.
6388
+ */
6389
+ // @ts-expect-error Tileset2D should be generic over TileIndex
6390
+ getTileIndices({ viewport, minZoom, maxZoom }) {
6391
+ if (viewport.latitude === void 0)
6392
+ return [];
6393
+ const [west, south, east, north] = viewport.getBounds();
6394
+ const { tileSize } = this.opts;
6395
+ let z = getHexagonResolution(viewport, tileSize);
6396
+ let indices;
6397
+ if (typeof minZoom === "number" && Number.isFinite(minZoom) && z < minZoom) {
6398
+ return [];
6399
+ }
6400
+ if (typeof maxZoom === "number" && Number.isFinite(maxZoom) && z > maxZoom) {
6401
+ z = maxZoom;
6402
+ const center = (0, import_h3_js2.latLngToCell)(viewport.latitude, viewport.longitude, maxZoom);
6403
+ indices = (0, import_h3_js2.gridDisk)(center, 1);
6404
+ } else {
6405
+ const paddedBounds = padBoundingBox({ west, north, east, south }, z);
6406
+ indices = getHexagonsInBoundingBox(paddedBounds, z);
6407
+ }
6408
+ return indices.map((i) => ({ i }));
6409
+ }
6410
+ // @ts-expect-error Tileset2D should be generic over TileIndex
6411
+ getTileId({ i }) {
6412
+ return i;
6413
+ }
6414
+ // @ts-expect-error Tileset2D should be generic over TileIndex
6415
+ getTileMetadata({ i }) {
6416
+ return { bbox: tileToBoundingBox(i) };
6417
+ }
6418
+ // @ts-expect-error Tileset2D should be generic over TileIndex
6419
+ getTileZoom({ i }) {
6420
+ return (0, import_h3_js2.getResolution)(i);
6421
+ }
6422
+ // @ts-expect-error Tileset2D should be generic over TileIndex
6423
+ getParentIndex(index2) {
6424
+ const resolution = (0, import_h3_js2.getResolution)(index2.i);
6425
+ const i = (0, import_h3_js2.cellToParent)(index2.i, resolution - 1);
6426
+ return { i };
6427
+ }
6428
+ };
6429
+
6312
6430
  // src/layers/quadbin-utils.ts
6313
6431
  var TILE_SIZE2 = 512;
6314
6432
  function quadbinToOffset(quadbin) {
@@ -6330,6 +6448,9 @@ var __exports__ = (() => {
6330
6448
  return [e, n, e, s, w, s, w, n, e, n];
6331
6449
  }
6332
6450
 
6451
+ // src/layers/cluster-tile-layer.ts
6452
+ var import_h3_js3 = __toESM(require_h3_js(), 1);
6453
+
6333
6454
  // node_modules/@loaders.gl/compression/node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/globals.js
6334
6455
  var globals = {
6335
6456
  self: typeof self !== "undefined" && self,
@@ -6987,40 +7108,62 @@ var __exports__ = (() => {
6987
7108
 
6988
7109
  // src/layers/cluster-tile-layer.ts
6989
7110
  (0, import_core5.registerLoaders)([carto_spatial_tile_loader_default]);
7111
+ function getScheme(tilesetClass) {
7112
+ if (tilesetClass === H3Tileset2D)
7113
+ return "h3";
7114
+ if (tilesetClass === QuadbinTileset2D)
7115
+ return "quadbin";
7116
+ throw new Error("Invalid tileset class");
7117
+ }
6990
7118
  var defaultProps = {
6991
7119
  data: TilejsonPropType,
6992
7120
  clusterLevel: { type: "number", value: 5, min: 1 },
6993
7121
  getPosition: {
6994
7122
  type: "accessor",
6995
- value: ({ id: id5 }) => getQuadbinPolygon(id5, 0.5).slice(2, 4)
7123
+ value: ({ id: id5 }) => {
7124
+ if (typeof id5 === "string") {
7125
+ const [lat, lng] = (0, import_h3_js3.cellToLatLng)(id5);
7126
+ return [lng, lat];
7127
+ }
7128
+ return getQuadbinPolygon(id5, 0.5).slice(2, 4);
7129
+ }
6996
7130
  },
6997
7131
  getWeight: { type: "accessor", value: 1 },
6998
7132
  refinementStrategy: "no-overlap",
6999
7133
  tileSize: DEFAULT_TILE_SIZE
7000
7134
  };
7001
- var ClusterGeoJsonLayer = class extends import_geo_layers2.TileLayer {
7135
+ var ClusterGeoJsonLayer = class extends import_geo_layers3.TileLayer {
7002
7136
  initializeState() {
7003
7137
  super.initializeState();
7004
7138
  this.state.aggregationCache = /* @__PURE__ */ new WeakMap();
7139
+ this.state.scheme = getScheme(this.props.TilesetClass);
7140
+ }
7141
+ updateState(opts) {
7142
+ const { props } = opts;
7143
+ const scheme = getScheme(props.TilesetClass);
7144
+ if (this.state.scheme !== scheme) {
7145
+ this.setState({ scheme, tileset: null });
7146
+ this.state.aggregationCache = /* @__PURE__ */ new WeakMap();
7147
+ }
7148
+ super.updateState(opts);
7005
7149
  }
7006
7150
  // eslint-disable-next-line max-statements
7007
7151
  renderLayers() {
7008
7152
  const visibleTiles = this.state.tileset?.tiles.filter((tile) => {
7009
7153
  return tile.isLoaded && tile.content && this.state.tileset.isTileVisible(tile);
7010
7154
  });
7011
- if (!visibleTiles?.length) {
7155
+ if (!visibleTiles?.length || !this.state.tileset) {
7012
7156
  return null;
7013
7157
  }
7014
7158
  visibleTiles.sort((a, b) => b.zoom - a.zoom);
7015
- const { zoom } = this.context.viewport;
7016
- const { clusterLevel, getPosition, getWeight } = this.props;
7017
- const { aggregationCache } = this.state;
7159
+ const { getPosition, getWeight } = this.props;
7160
+ const { aggregationCache, scheme } = this.state;
7161
+ const isH3 = scheme === "h3";
7018
7162
  const properties = extractAggregationProperties(visibleTiles[0]);
7019
7163
  const data = [];
7020
7164
  let needsUpdate = false;
7165
+ const aggregationLevels = this._getAggregationLevels(visibleTiles);
7021
7166
  for (const tile of visibleTiles) {
7022
- const overZoom = Math.round(zoom - tile.zoom);
7023
- const aggregationLevels = Math.round(clusterLevel) - overZoom;
7024
7167
  let tileAggregationCache = aggregationCache.get(tile.content);
7025
7168
  if (!tileAggregationCache) {
7026
7169
  tileAggregationCache = /* @__PURE__ */ new Map();
@@ -7032,7 +7175,8 @@ var __exports__ = (() => {
7032
7175
  aggregationLevels,
7033
7176
  properties,
7034
7177
  getPosition,
7035
- getWeight
7178
+ getWeight,
7179
+ isH3 ? "h3" : "quadbin"
7036
7180
  );
7037
7181
  needsUpdate ||= didAggregate;
7038
7182
  data.push(...tileAggregationCache.get(aggregationLevels));
@@ -7077,15 +7221,35 @@ var __exports__ = (() => {
7077
7221
  filterSubLayer() {
7078
7222
  return true;
7079
7223
  }
7224
+ _getAggregationLevels(visibleTiles) {
7225
+ const isH3 = this.state.scheme === "h3";
7226
+ const firstTile = visibleTiles[0];
7227
+ let tileResolution;
7228
+ let viewportResolution;
7229
+ if (isH3) {
7230
+ tileResolution = (0, import_h3_js3.getResolution)(firstTile.id);
7231
+ viewportResolution = getHexagonResolution(
7232
+ this.context.viewport,
7233
+ this.state.tileset.opts.tileSize
7234
+ );
7235
+ } else {
7236
+ tileResolution = firstTile.zoom;
7237
+ viewportResolution = this.context.viewport.zoom;
7238
+ }
7239
+ const resolutionDiff = Math.round(viewportResolution - tileResolution);
7240
+ const aggregationLevels = Math.round(this.props.clusterLevel) - resolutionDiff;
7241
+ return aggregationLevels;
7242
+ }
7080
7243
  };
7081
7244
  ClusterGeoJsonLayer.layerName = "ClusterGeoJsonLayer";
7082
7245
  ClusterGeoJsonLayer.defaultProps = defaultProps;
7083
7246
  var ClusterTileLayer = class extends import_core6.CompositeLayer {
7084
7247
  getLoadOptions() {
7085
7248
  const tileJSON = this.props.data;
7249
+ const scheme = tileJSON && "scheme" in tileJSON ? tileJSON.scheme : "quadbin";
7086
7250
  return mergeLoadOptions(super.getLoadOptions(), {
7087
7251
  fetch: { headers: { Authorization: `Bearer ${tileJSON.accessToken}` } },
7088
- cartoSpatialTile: { scheme: "quadbin" }
7252
+ cartoSpatialTile: { scheme }
7089
7253
  });
7090
7254
  }
7091
7255
  renderLayers() {
@@ -7093,13 +7257,15 @@ var __exports__ = (() => {
7093
7257
  if (!tileJSON)
7094
7258
  return null;
7095
7259
  const { tiles: data, maxresolution: maxZoom } = tileJSON;
7260
+ const isH3 = tileJSON && "scheme" in tileJSON && tileJSON.scheme === "h3";
7261
+ const TilesetClass = isH3 ? H3Tileset2D : QuadbinTileset2D;
7096
7262
  return [
7097
7263
  // @ts-ignore
7098
7264
  new ClusterGeoJsonLayer(this.props, {
7099
7265
  id: `cluster-geojson-layer-${this.props.id}`,
7100
7266
  data,
7101
7267
  // TODO: Tileset2D should be generic over TileIndex type
7102
- TilesetClass: QuadbinTileset2D,
7268
+ TilesetClass,
7103
7269
  maxZoom,
7104
7270
  loadOptions: this.getLoadOptions()
7105
7271
  })
@@ -7113,118 +7279,6 @@ var __exports__ = (() => {
7113
7279
  var import_core8 = __toESM(require_core2(), 1);
7114
7280
  var import_geo_layers5 = __toESM(require_geo_layers(), 1);
7115
7281
 
7116
- // src/layers/h3-tileset-2d.ts
7117
- var import_geo_layers3 = __toESM(require_geo_layers(), 1);
7118
- var import_h3_js = __toESM(require_h3_js(), 1);
7119
- var MAX_LATITUDE2 = 85.051128;
7120
- function padBoundingBox({ west, north, east, south }, resolution, scale = 1) {
7121
- const corners = [
7122
- [north, east],
7123
- [south, east],
7124
- [south, west],
7125
- [north, west]
7126
- ];
7127
- const cornerCells = corners.map((c) => (0, import_h3_js.latLngToCell)(c[0], c[1], resolution));
7128
- const cornerEdgeLengths = cornerCells.map(
7129
- (c) => Math.max(...(0, import_h3_js.originToDirectedEdges)(c).map((e) => (0, import_h3_js.edgeLength)(e, import_h3_js.UNITS.rads))) * 180 / Math.PI
7130
- );
7131
- const bufferLat = Math.max(...cornerEdgeLengths) * scale;
7132
- const bufferLon = Math.min(180, bufferLat / Math.cos((north + south) / 2 * Math.PI / 180));
7133
- return {
7134
- north: Math.min(north + bufferLat, MAX_LATITUDE2),
7135
- east: east + bufferLon,
7136
- south: Math.max(south - bufferLat, -MAX_LATITUDE2),
7137
- west: west - bufferLon
7138
- };
7139
- }
7140
- function getHexagonsInBoundingBox({ west, north, east, south }, resolution) {
7141
- const longitudeSpan = Math.abs(east - west);
7142
- if (longitudeSpan > 180) {
7143
- const nSegments = Math.ceil(longitudeSpan / 180);
7144
- let h3Indices = [];
7145
- for (let s = 0; s < nSegments; s++) {
7146
- const segmentWest = west + s * 180;
7147
- const segmentEast = Math.min(segmentWest + 179.9999999, east);
7148
- h3Indices = h3Indices.concat(
7149
- getHexagonsInBoundingBox({ west: segmentWest, north, east: segmentEast, south }, resolution)
7150
- );
7151
- }
7152
- return [...new Set(h3Indices)];
7153
- }
7154
- const polygon2 = [
7155
- [north, east],
7156
- [south, east],
7157
- [south, west],
7158
- [north, west],
7159
- [north, east]
7160
- ];
7161
- return (0, import_h3_js.polygonToCells)(polygon2, resolution);
7162
- }
7163
- function tileToBoundingBox(index2) {
7164
- const coordinates = (0, import_h3_js.cellToBoundary)(index2);
7165
- const latitudes = coordinates.map((c) => c[0]);
7166
- const longitudes = coordinates.map((c) => c[1]);
7167
- const west = Math.min(...longitudes);
7168
- const south = Math.min(...latitudes);
7169
- const east = Math.max(...longitudes);
7170
- const north = Math.max(...latitudes);
7171
- const bbox2 = { west, south, east, north };
7172
- return padBoundingBox(bbox2, (0, import_h3_js.getResolution)(index2), 0.12);
7173
- }
7174
- var BIAS = 2;
7175
- function getHexagonResolution(viewport, tileSize) {
7176
- const zoomOffset = Math.log2(tileSize / 512);
7177
- const hexagonScaleFactor = 2 / 3 * (viewport.zoom - zoomOffset);
7178
- const latitudeScaleFactor = Math.log(1 / Math.cos(Math.PI * viewport.latitude / 180));
7179
- return Math.max(0, Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS));
7180
- }
7181
- var H3Tileset2D = class extends import_geo_layers3._Tileset2D {
7182
- /**
7183
- * Returns all tile indices in the current viewport. If the current zoom level is smaller
7184
- * than minZoom, return an empty array. If the current zoom level is greater than maxZoom,
7185
- * return tiles that are on maxZoom.
7186
- */
7187
- // @ts-expect-error Tileset2D should be generic over TileIndex
7188
- getTileIndices({ viewport, minZoom, maxZoom }) {
7189
- if (viewport.latitude === void 0)
7190
- return [];
7191
- const [west, south, east, north] = viewport.getBounds();
7192
- const { tileSize } = this.opts;
7193
- let z = getHexagonResolution(viewport, tileSize);
7194
- let indices;
7195
- if (typeof minZoom === "number" && Number.isFinite(minZoom) && z < minZoom) {
7196
- return [];
7197
- }
7198
- if (typeof maxZoom === "number" && Number.isFinite(maxZoom) && z > maxZoom) {
7199
- z = maxZoom;
7200
- const center = (0, import_h3_js.latLngToCell)(viewport.latitude, viewport.longitude, maxZoom);
7201
- indices = (0, import_h3_js.gridDisk)(center, 1);
7202
- } else {
7203
- const paddedBounds = padBoundingBox({ west, north, east, south }, z);
7204
- indices = getHexagonsInBoundingBox(paddedBounds, z);
7205
- }
7206
- return indices.map((i) => ({ i }));
7207
- }
7208
- // @ts-expect-error Tileset2D should be generic over TileIndex
7209
- getTileId({ i }) {
7210
- return i;
7211
- }
7212
- // @ts-expect-error Tileset2D should be generic over TileIndex
7213
- getTileMetadata({ i }) {
7214
- return { bbox: tileToBoundingBox(i) };
7215
- }
7216
- // @ts-expect-error Tileset2D should be generic over TileIndex
7217
- getTileZoom({ i }) {
7218
- return (0, import_h3_js.getResolution)(i);
7219
- }
7220
- // @ts-expect-error Tileset2D should be generic over TileIndex
7221
- getParentIndex(index2) {
7222
- const resolution = (0, import_h3_js.getResolution)(index2.i);
7223
- const i = (0, import_h3_js.cellToParent)(index2.i, resolution - 1);
7224
- return { i };
7225
- }
7226
- };
7227
-
7228
7282
  // src/layers/spatial-index-tile-layer.ts
7229
7283
  var import_core7 = __toESM(require_core(), 1);
7230
7284
  var import_geo_layers4 = __toESM(require_geo_layers(), 1);
@@ -7349,7 +7403,7 @@ var __exports__ = (() => {
7349
7403
  H3TileLayer.defaultProps = defaultProps3;
7350
7404
 
7351
7405
  // src/layers/heatmap-tile-layer.ts
7352
- var import_h3_js2 = __toESM(require_h3_js(), 1);
7406
+ var import_h3_js4 = __toESM(require_h3_js(), 1);
7353
7407
  var import_core11 = __toESM(require_core2(), 1);
7354
7408
  var import_layers2 = __toESM(require_layers(), 1);
7355
7409
 
@@ -7713,8 +7767,8 @@ vec4 heatmap_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {
7713
7767
  return Math.pow(4, cellResolution);
7714
7768
  }
7715
7769
  function unitDensityForH3Cell(cellId) {
7716
- const cellResolution = Number((0, import_h3_js2.getResolution)(cellId));
7717
- return (0, import_h3_js2.getNumCells)(cellResolution);
7770
+ const cellResolution = Number((0, import_h3_js4.getResolution)(cellId));
7771
+ return (0, import_h3_js4.getNumCells)(cellResolution);
7718
7772
  }
7719
7773
  function colorRangeToFlatArray(colorRange) {
7720
7774
  const flatArray = new Uint8Array(colorRange.length * 4);
@@ -9315,6 +9369,26 @@ void main(void) {
9315
9369
  }
9316
9370
  var B2 = [0x5555555555555555n, 0x3333333333333333n, 0x0f0f0f0f0f0f0f0fn, 0x00ff00ff00ff00ffn, 0x0000ffff0000ffffn, 0x00000000ffffffffn];
9317
9371
  var S2 = [0n, 1n, 2n, 4n, 8n, 16n];
9372
+ var TILE_SIZE3 = 512;
9373
+ function cellToOffset(quadbin) {
9374
+ const {
9375
+ x,
9376
+ y,
9377
+ z
9378
+ } = cellToTile2(quadbin);
9379
+ const scale = TILE_SIZE3 / (1 << z);
9380
+ return [x * scale, TILE_SIZE3 - y * scale, scale];
9381
+ }
9382
+ function cellToWorldBounds(quadbin, coverage) {
9383
+ const [xOffset, yOffset, scale] = cellToOffset(quadbin);
9384
+ return [[xOffset, yOffset], [xOffset + coverage * scale, yOffset - coverage * scale]];
9385
+ }
9386
+ function getCellPolygon(quadbin, coverage = 1) {
9387
+ const [topLeft, bottomRight] = cellToWorldBounds(quadbin, coverage);
9388
+ const [w, n] = worldToLngLat(topLeft);
9389
+ const [e, s] = worldToLngLat(bottomRight);
9390
+ return [e, n, e, s, w, s, w, n, e, n];
9391
+ }
9318
9392
  function tileToCell2(tile) {
9319
9393
  if (tile.z < 0 || tile.z > 26) {
9320
9394
  throw new Error("Wrong zoom");
@@ -9356,26 +9430,9 @@ void main(void) {
9356
9430
  y: Number(y)
9357
9431
  };
9358
9432
  }
9359
- function getResolution3(quadbin) {
9433
+ function getResolution4(quadbin) {
9360
9434
  return quadbin >> 52n & 0x1fn;
9361
9435
  }
9362
- function cellToChildren(quadbin, resolution) {
9363
- if (resolution < 0 || resolution > 26 || resolution < getResolution3(quadbin)) {
9364
- throw new Error("Invalid resolution");
9365
- }
9366
- const zoomLevelMask = ~(0x1fn << 52n);
9367
- const blockRange = 1n << (resolution - (quadbin >> 52n & 0x1fn) << 1n);
9368
- const sqrtBlockRange = 1n << resolution - (quadbin >> 52n & 0x1fn);
9369
- const blockShift = 52n - (resolution << 1n);
9370
- const childBase = (quadbin & zoomLevelMask | resolution << 52n) & ~(blockRange - 1n << blockShift);
9371
- const children = [];
9372
- for (let blockRow = 0n; blockRow < sqrtBlockRange; blockRow++) {
9373
- for (let blockColumn = 0n; blockColumn < sqrtBlockRange; blockColumn++) {
9374
- children.push(childBase | blockRow * sqrtBlockRange + blockColumn << blockShift);
9375
- }
9376
- }
9377
- return children;
9378
- }
9379
9436
  function geometryToCells(geometry, resolution) {
9380
9437
  const zoom = Number(resolution);
9381
9438
  return tiles2(geometry, {
@@ -9387,9 +9444,962 @@ void main(void) {
9387
9444
  z
9388
9445
  }));
9389
9446
  }
9390
-
9447
+ function cellToBoundary2(cell) {
9448
+ const bbox2 = getCellPolygon(cell);
9449
+ const boundary = [[bbox2[0], bbox2[1]], [bbox2[2], bbox2[3]], [bbox2[4], bbox2[5]], [bbox2[6], bbox2[7]], [bbox2[0], bbox2[1]]];
9450
+ return {
9451
+ type: "Polygon",
9452
+ coordinates: [boundary]
9453
+ };
9454
+ }
9455
+
9391
9456
  // ../../node_modules/@carto/api-client/build/api-client.js
9392
- var import_h3_js3 = __toESM(require_h3_js(), 1);
9457
+ var import_h3_js5 = __toESM(require_h3_js(), 1);
9458
+ var import_h3_js6 = __toESM(require_h3_js(), 1);
9459
+
9460
+ // ../../node_modules/@carto/api-client/node_modules/jsep/dist/jsep.js
9461
+ var Hooks = class {
9462
+ /**
9463
+ * @callback HookCallback
9464
+ * @this {*|Jsep} this
9465
+ * @param {Jsep} env
9466
+ * @returns: void
9467
+ */
9468
+ /**
9469
+ * Adds the given callback to the list of callbacks for the given hook.
9470
+ *
9471
+ * The callback will be invoked when the hook it is registered for is run.
9472
+ *
9473
+ * One callback function can be registered to multiple hooks and the same hook multiple times.
9474
+ *
9475
+ * @param {string|object} name The name of the hook, or an object of callbacks keyed by name
9476
+ * @param {HookCallback|boolean} callback The callback function which is given environment variables.
9477
+ * @param {?boolean} [first=false] Will add the hook to the top of the list (defaults to the bottom)
9478
+ * @public
9479
+ */
9480
+ add(name, callback, first) {
9481
+ if (typeof arguments[0] != "string") {
9482
+ for (let name2 in arguments[0]) {
9483
+ this.add(name2, arguments[0][name2], arguments[1]);
9484
+ }
9485
+ } else {
9486
+ (Array.isArray(name) ? name : [name]).forEach(function(name2) {
9487
+ this[name2] = this[name2] || [];
9488
+ if (callback) {
9489
+ this[name2][first ? "unshift" : "push"](callback);
9490
+ }
9491
+ }, this);
9492
+ }
9493
+ }
9494
+ /**
9495
+ * Runs a hook invoking all registered callbacks with the given environment variables.
9496
+ *
9497
+ * Callbacks will be invoked synchronously and in the order in which they were registered.
9498
+ *
9499
+ * @param {string} name The name of the hook.
9500
+ * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
9501
+ * @public
9502
+ */
9503
+ run(name, env) {
9504
+ this[name] = this[name] || [];
9505
+ this[name].forEach(function(callback) {
9506
+ callback.call(env && env.context ? env.context : env, env);
9507
+ });
9508
+ }
9509
+ };
9510
+ var Plugins = class {
9511
+ constructor(jsep2) {
9512
+ this.jsep = jsep2;
9513
+ this.registered = {};
9514
+ }
9515
+ /**
9516
+ * @callback PluginSetup
9517
+ * @this {Jsep} jsep
9518
+ * @returns: void
9519
+ */
9520
+ /**
9521
+ * Adds the given plugin(s) to the registry
9522
+ *
9523
+ * @param {object} plugins
9524
+ * @param {string} plugins.name The name of the plugin
9525
+ * @param {PluginSetup} plugins.init The init function
9526
+ * @public
9527
+ */
9528
+ register(...plugins) {
9529
+ plugins.forEach((plugin) => {
9530
+ if (typeof plugin !== "object" || !plugin.name || !plugin.init) {
9531
+ throw new Error("Invalid JSEP plugin format");
9532
+ }
9533
+ if (this.registered[plugin.name]) {
9534
+ return;
9535
+ }
9536
+ plugin.init(this.jsep);
9537
+ this.registered[plugin.name] = plugin;
9538
+ });
9539
+ }
9540
+ };
9541
+ var Jsep = class {
9542
+ /**
9543
+ * @returns {string}
9544
+ */
9545
+ static get version() {
9546
+ return "1.4.0";
9547
+ }
9548
+ /**
9549
+ * @returns {string}
9550
+ */
9551
+ static toString() {
9552
+ return "JavaScript Expression Parser (JSEP) v" + Jsep.version;
9553
+ }
9554
+ // ==================== CONFIG ================================
9555
+ /**
9556
+ * @method addUnaryOp
9557
+ * @param {string} op_name The name of the unary op to add
9558
+ * @returns {Jsep}
9559
+ */
9560
+ static addUnaryOp(op_name) {
9561
+ Jsep.max_unop_len = Math.max(op_name.length, Jsep.max_unop_len);
9562
+ Jsep.unary_ops[op_name] = 1;
9563
+ return Jsep;
9564
+ }
9565
+ /**
9566
+ * @method jsep.addBinaryOp
9567
+ * @param {string} op_name The name of the binary op to add
9568
+ * @param {number} precedence The precedence of the binary op (can be a float). Higher number = higher precedence
9569
+ * @param {boolean} [isRightAssociative=false] whether operator is right-associative
9570
+ * @returns {Jsep}
9571
+ */
9572
+ static addBinaryOp(op_name, precedence, isRightAssociative) {
9573
+ Jsep.max_binop_len = Math.max(op_name.length, Jsep.max_binop_len);
9574
+ Jsep.binary_ops[op_name] = precedence;
9575
+ if (isRightAssociative) {
9576
+ Jsep.right_associative.add(op_name);
9577
+ } else {
9578
+ Jsep.right_associative.delete(op_name);
9579
+ }
9580
+ return Jsep;
9581
+ }
9582
+ /**
9583
+ * @method addIdentifierChar
9584
+ * @param {string} char The additional character to treat as a valid part of an identifier
9585
+ * @returns {Jsep}
9586
+ */
9587
+ static addIdentifierChar(char) {
9588
+ Jsep.additional_identifier_chars.add(char);
9589
+ return Jsep;
9590
+ }
9591
+ /**
9592
+ * @method addLiteral
9593
+ * @param {string} literal_name The name of the literal to add
9594
+ * @param {*} literal_value The value of the literal
9595
+ * @returns {Jsep}
9596
+ */
9597
+ static addLiteral(literal_name, literal_value) {
9598
+ Jsep.literals[literal_name] = literal_value;
9599
+ return Jsep;
9600
+ }
9601
+ /**
9602
+ * @method removeUnaryOp
9603
+ * @param {string} op_name The name of the unary op to remove
9604
+ * @returns {Jsep}
9605
+ */
9606
+ static removeUnaryOp(op_name) {
9607
+ delete Jsep.unary_ops[op_name];
9608
+ if (op_name.length === Jsep.max_unop_len) {
9609
+ Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);
9610
+ }
9611
+ return Jsep;
9612
+ }
9613
+ /**
9614
+ * @method removeAllUnaryOps
9615
+ * @returns {Jsep}
9616
+ */
9617
+ static removeAllUnaryOps() {
9618
+ Jsep.unary_ops = {};
9619
+ Jsep.max_unop_len = 0;
9620
+ return Jsep;
9621
+ }
9622
+ /**
9623
+ * @method removeIdentifierChar
9624
+ * @param {string} char The additional character to stop treating as a valid part of an identifier
9625
+ * @returns {Jsep}
9626
+ */
9627
+ static removeIdentifierChar(char) {
9628
+ Jsep.additional_identifier_chars.delete(char);
9629
+ return Jsep;
9630
+ }
9631
+ /**
9632
+ * @method removeBinaryOp
9633
+ * @param {string} op_name The name of the binary op to remove
9634
+ * @returns {Jsep}
9635
+ */
9636
+ static removeBinaryOp(op_name) {
9637
+ delete Jsep.binary_ops[op_name];
9638
+ if (op_name.length === Jsep.max_binop_len) {
9639
+ Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);
9640
+ }
9641
+ Jsep.right_associative.delete(op_name);
9642
+ return Jsep;
9643
+ }
9644
+ /**
9645
+ * @method removeAllBinaryOps
9646
+ * @returns {Jsep}
9647
+ */
9648
+ static removeAllBinaryOps() {
9649
+ Jsep.binary_ops = {};
9650
+ Jsep.max_binop_len = 0;
9651
+ return Jsep;
9652
+ }
9653
+ /**
9654
+ * @method removeLiteral
9655
+ * @param {string} literal_name The name of the literal to remove
9656
+ * @returns {Jsep}
9657
+ */
9658
+ static removeLiteral(literal_name) {
9659
+ delete Jsep.literals[literal_name];
9660
+ return Jsep;
9661
+ }
9662
+ /**
9663
+ * @method removeAllLiterals
9664
+ * @returns {Jsep}
9665
+ */
9666
+ static removeAllLiterals() {
9667
+ Jsep.literals = {};
9668
+ return Jsep;
9669
+ }
9670
+ // ==================== END CONFIG ============================
9671
+ /**
9672
+ * @returns {string}
9673
+ */
9674
+ get char() {
9675
+ return this.expr.charAt(this.index);
9676
+ }
9677
+ /**
9678
+ * @returns {number}
9679
+ */
9680
+ get code() {
9681
+ return this.expr.charCodeAt(this.index);
9682
+ }
9683
+ /**
9684
+ * @param {string} expr a string with the passed in express
9685
+ * @returns Jsep
9686
+ */
9687
+ constructor(expr) {
9688
+ this.expr = expr;
9689
+ this.index = 0;
9690
+ }
9691
+ /**
9692
+ * static top-level parser
9693
+ * @returns {jsep.Expression}
9694
+ */
9695
+ static parse(expr) {
9696
+ return new Jsep(expr).parse();
9697
+ }
9698
+ /**
9699
+ * Get the longest key length of any object
9700
+ * @param {object} obj
9701
+ * @returns {number}
9702
+ */
9703
+ static getMaxKeyLen(obj) {
9704
+ return Math.max(0, ...Object.keys(obj).map((k) => k.length));
9705
+ }
9706
+ /**
9707
+ * `ch` is a character code in the next three functions
9708
+ * @param {number} ch
9709
+ * @returns {boolean}
9710
+ */
9711
+ static isDecimalDigit(ch) {
9712
+ return ch >= 48 && ch <= 57;
9713
+ }
9714
+ /**
9715
+ * Returns the precedence of a binary operator or `0` if it isn't a binary operator. Can be float.
9716
+ * @param {string} op_val
9717
+ * @returns {number}
9718
+ */
9719
+ static binaryPrecedence(op_val) {
9720
+ return Jsep.binary_ops[op_val] || 0;
9721
+ }
9722
+ /**
9723
+ * Looks for start of identifier
9724
+ * @param {number} ch
9725
+ * @returns {boolean}
9726
+ */
9727
+ static isIdentifierStart(ch) {
9728
+ return ch >= 65 && ch <= 90 || // A...Z
9729
+ ch >= 97 && ch <= 122 || // a...z
9730
+ ch >= 128 && !Jsep.binary_ops[String.fromCharCode(ch)] || // any non-ASCII that is not an operator
9731
+ Jsep.additional_identifier_chars.has(String.fromCharCode(ch));
9732
+ }
9733
+ /**
9734
+ * @param {number} ch
9735
+ * @returns {boolean}
9736
+ */
9737
+ static isIdentifierPart(ch) {
9738
+ return Jsep.isIdentifierStart(ch) || Jsep.isDecimalDigit(ch);
9739
+ }
9740
+ /**
9741
+ * throw error at index of the expression
9742
+ * @param {string} message
9743
+ * @throws
9744
+ */
9745
+ throwError(message) {
9746
+ const error = new Error(message + " at character " + this.index);
9747
+ error.index = this.index;
9748
+ error.description = message;
9749
+ throw error;
9750
+ }
9751
+ /**
9752
+ * Run a given hook
9753
+ * @param {string} name
9754
+ * @param {jsep.Expression|false} [node]
9755
+ * @returns {?jsep.Expression}
9756
+ */
9757
+ runHook(name, node) {
9758
+ if (Jsep.hooks[name]) {
9759
+ const env = { context: this, node };
9760
+ Jsep.hooks.run(name, env);
9761
+ return env.node;
9762
+ }
9763
+ return node;
9764
+ }
9765
+ /**
9766
+ * Runs a given hook until one returns a node
9767
+ * @param {string} name
9768
+ * @returns {?jsep.Expression}
9769
+ */
9770
+ searchHook(name) {
9771
+ if (Jsep.hooks[name]) {
9772
+ const env = { context: this };
9773
+ Jsep.hooks[name].find(function(callback) {
9774
+ callback.call(env.context, env);
9775
+ return env.node;
9776
+ });
9777
+ return env.node;
9778
+ }
9779
+ }
9780
+ /**
9781
+ * Push `index` up to the next non-space character
9782
+ */
9783
+ gobbleSpaces() {
9784
+ let ch = this.code;
9785
+ while (ch === Jsep.SPACE_CODE || ch === Jsep.TAB_CODE || ch === Jsep.LF_CODE || ch === Jsep.CR_CODE) {
9786
+ ch = this.expr.charCodeAt(++this.index);
9787
+ }
9788
+ this.runHook("gobble-spaces");
9789
+ }
9790
+ /**
9791
+ * Top-level method to parse all expressions and returns compound or single node
9792
+ * @returns {jsep.Expression}
9793
+ */
9794
+ parse() {
9795
+ this.runHook("before-all");
9796
+ const nodes = this.gobbleExpressions();
9797
+ const node = nodes.length === 1 ? nodes[0] : {
9798
+ type: Jsep.COMPOUND,
9799
+ body: nodes
9800
+ };
9801
+ return this.runHook("after-all", node);
9802
+ }
9803
+ /**
9804
+ * top-level parser (but can be reused within as well)
9805
+ * @param {number} [untilICode]
9806
+ * @returns {jsep.Expression[]}
9807
+ */
9808
+ gobbleExpressions(untilICode) {
9809
+ let nodes = [], ch_i, node;
9810
+ while (this.index < this.expr.length) {
9811
+ ch_i = this.code;
9812
+ if (ch_i === Jsep.SEMCOL_CODE || ch_i === Jsep.COMMA_CODE) {
9813
+ this.index++;
9814
+ } else {
9815
+ if (node = this.gobbleExpression()) {
9816
+ nodes.push(node);
9817
+ } else if (this.index < this.expr.length) {
9818
+ if (ch_i === untilICode) {
9819
+ break;
9820
+ }
9821
+ this.throwError('Unexpected "' + this.char + '"');
9822
+ }
9823
+ }
9824
+ }
9825
+ return nodes;
9826
+ }
9827
+ /**
9828
+ * The main parsing function.
9829
+ * @returns {?jsep.Expression}
9830
+ */
9831
+ gobbleExpression() {
9832
+ const node = this.searchHook("gobble-expression") || this.gobbleBinaryExpression();
9833
+ this.gobbleSpaces();
9834
+ return this.runHook("after-expression", node);
9835
+ }
9836
+ /**
9837
+ * Search for the operation portion of the string (e.g. `+`, `===`)
9838
+ * Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`)
9839
+ * and move down from 3 to 2 to 1 character until a matching binary operation is found
9840
+ * then, return that binary operation
9841
+ * @returns {string|boolean}
9842
+ */
9843
+ gobbleBinaryOp() {
9844
+ this.gobbleSpaces();
9845
+ let to_check = this.expr.substr(this.index, Jsep.max_binop_len);
9846
+ let tc_len = to_check.length;
9847
+ while (tc_len > 0) {
9848
+ if (Jsep.binary_ops.hasOwnProperty(to_check) && (!Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) {
9849
+ this.index += tc_len;
9850
+ return to_check;
9851
+ }
9852
+ to_check = to_check.substr(0, --tc_len);
9853
+ }
9854
+ return false;
9855
+ }
9856
+ /**
9857
+ * This function is responsible for gobbling an individual expression,
9858
+ * e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)`
9859
+ * @returns {?jsep.BinaryExpression}
9860
+ */
9861
+ gobbleBinaryExpression() {
9862
+ let node, biop, prec, stack, biop_info, left, right, i, cur_biop;
9863
+ left = this.gobbleToken();
9864
+ if (!left) {
9865
+ return left;
9866
+ }
9867
+ biop = this.gobbleBinaryOp();
9868
+ if (!biop) {
9869
+ return left;
9870
+ }
9871
+ biop_info = { value: biop, prec: Jsep.binaryPrecedence(biop), right_a: Jsep.right_associative.has(biop) };
9872
+ right = this.gobbleToken();
9873
+ if (!right) {
9874
+ this.throwError("Expected expression after " + biop);
9875
+ }
9876
+ stack = [left, biop_info, right];
9877
+ while (biop = this.gobbleBinaryOp()) {
9878
+ prec = Jsep.binaryPrecedence(biop);
9879
+ if (prec === 0) {
9880
+ this.index -= biop.length;
9881
+ break;
9882
+ }
9883
+ biop_info = { value: biop, prec, right_a: Jsep.right_associative.has(biop) };
9884
+ cur_biop = biop;
9885
+ const comparePrev = (prev) => biop_info.right_a && prev.right_a ? prec > prev.prec : prec <= prev.prec;
9886
+ while (stack.length > 2 && comparePrev(stack[stack.length - 2])) {
9887
+ right = stack.pop();
9888
+ biop = stack.pop().value;
9889
+ left = stack.pop();
9890
+ node = {
9891
+ type: Jsep.BINARY_EXP,
9892
+ operator: biop,
9893
+ left,
9894
+ right
9895
+ };
9896
+ stack.push(node);
9897
+ }
9898
+ node = this.gobbleToken();
9899
+ if (!node) {
9900
+ this.throwError("Expected expression after " + cur_biop);
9901
+ }
9902
+ stack.push(biop_info, node);
9903
+ }
9904
+ i = stack.length - 1;
9905
+ node = stack[i];
9906
+ while (i > 1) {
9907
+ node = {
9908
+ type: Jsep.BINARY_EXP,
9909
+ operator: stack[i - 1].value,
9910
+ left: stack[i - 2],
9911
+ right: node
9912
+ };
9913
+ i -= 2;
9914
+ }
9915
+ return node;
9916
+ }
9917
+ /**
9918
+ * An individual part of a binary expression:
9919
+ * e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis)
9920
+ * @returns {boolean|jsep.Expression}
9921
+ */
9922
+ gobbleToken() {
9923
+ let ch, to_check, tc_len, node;
9924
+ this.gobbleSpaces();
9925
+ node = this.searchHook("gobble-token");
9926
+ if (node) {
9927
+ return this.runHook("after-token", node);
9928
+ }
9929
+ ch = this.code;
9930
+ if (Jsep.isDecimalDigit(ch) || ch === Jsep.PERIOD_CODE) {
9931
+ return this.gobbleNumericLiteral();
9932
+ }
9933
+ if (ch === Jsep.SQUOTE_CODE || ch === Jsep.DQUOTE_CODE) {
9934
+ node = this.gobbleStringLiteral();
9935
+ } else if (ch === Jsep.OBRACK_CODE) {
9936
+ node = this.gobbleArray();
9937
+ } else {
9938
+ to_check = this.expr.substr(this.index, Jsep.max_unop_len);
9939
+ tc_len = to_check.length;
9940
+ while (tc_len > 0) {
9941
+ if (Jsep.unary_ops.hasOwnProperty(to_check) && (!Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) {
9942
+ this.index += tc_len;
9943
+ const argument = this.gobbleToken();
9944
+ if (!argument) {
9945
+ this.throwError("missing unaryOp argument");
9946
+ }
9947
+ return this.runHook("after-token", {
9948
+ type: Jsep.UNARY_EXP,
9949
+ operator: to_check,
9950
+ argument,
9951
+ prefix: true
9952
+ });
9953
+ }
9954
+ to_check = to_check.substr(0, --tc_len);
9955
+ }
9956
+ if (Jsep.isIdentifierStart(ch)) {
9957
+ node = this.gobbleIdentifier();
9958
+ if (Jsep.literals.hasOwnProperty(node.name)) {
9959
+ node = {
9960
+ type: Jsep.LITERAL,
9961
+ value: Jsep.literals[node.name],
9962
+ raw: node.name
9963
+ };
9964
+ } else if (node.name === Jsep.this_str) {
9965
+ node = { type: Jsep.THIS_EXP };
9966
+ }
9967
+ } else if (ch === Jsep.OPAREN_CODE) {
9968
+ node = this.gobbleGroup();
9969
+ }
9970
+ }
9971
+ if (!node) {
9972
+ return this.runHook("after-token", false);
9973
+ }
9974
+ node = this.gobbleTokenProperty(node);
9975
+ return this.runHook("after-token", node);
9976
+ }
9977
+ /**
9978
+ * Gobble properties of of identifiers/strings/arrays/groups.
9979
+ * e.g. `foo`, `bar.baz`, `foo['bar'].baz`
9980
+ * It also gobbles function calls:
9981
+ * e.g. `Math.acos(obj.angle)`
9982
+ * @param {jsep.Expression} node
9983
+ * @returns {jsep.Expression}
9984
+ */
9985
+ gobbleTokenProperty(node) {
9986
+ this.gobbleSpaces();
9987
+ let ch = this.code;
9988
+ while (ch === Jsep.PERIOD_CODE || ch === Jsep.OBRACK_CODE || ch === Jsep.OPAREN_CODE || ch === Jsep.QUMARK_CODE) {
9989
+ let optional;
9990
+ if (ch === Jsep.QUMARK_CODE) {
9991
+ if (this.expr.charCodeAt(this.index + 1) !== Jsep.PERIOD_CODE) {
9992
+ break;
9993
+ }
9994
+ optional = true;
9995
+ this.index += 2;
9996
+ this.gobbleSpaces();
9997
+ ch = this.code;
9998
+ }
9999
+ this.index++;
10000
+ if (ch === Jsep.OBRACK_CODE) {
10001
+ node = {
10002
+ type: Jsep.MEMBER_EXP,
10003
+ computed: true,
10004
+ object: node,
10005
+ property: this.gobbleExpression()
10006
+ };
10007
+ if (!node.property) {
10008
+ this.throwError('Unexpected "' + this.char + '"');
10009
+ }
10010
+ this.gobbleSpaces();
10011
+ ch = this.code;
10012
+ if (ch !== Jsep.CBRACK_CODE) {
10013
+ this.throwError("Unclosed [");
10014
+ }
10015
+ this.index++;
10016
+ } else if (ch === Jsep.OPAREN_CODE) {
10017
+ node = {
10018
+ type: Jsep.CALL_EXP,
10019
+ "arguments": this.gobbleArguments(Jsep.CPAREN_CODE),
10020
+ callee: node
10021
+ };
10022
+ } else if (ch === Jsep.PERIOD_CODE || optional) {
10023
+ if (optional) {
10024
+ this.index--;
10025
+ }
10026
+ this.gobbleSpaces();
10027
+ node = {
10028
+ type: Jsep.MEMBER_EXP,
10029
+ computed: false,
10030
+ object: node,
10031
+ property: this.gobbleIdentifier()
10032
+ };
10033
+ }
10034
+ if (optional) {
10035
+ node.optional = true;
10036
+ }
10037
+ this.gobbleSpaces();
10038
+ ch = this.code;
10039
+ }
10040
+ return node;
10041
+ }
10042
+ /**
10043
+ * Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to
10044
+ * keep track of everything in the numeric literal and then calling `parseFloat` on that string
10045
+ * @returns {jsep.Literal}
10046
+ */
10047
+ gobbleNumericLiteral() {
10048
+ let number3 = "", ch, chCode;
10049
+ while (Jsep.isDecimalDigit(this.code)) {
10050
+ number3 += this.expr.charAt(this.index++);
10051
+ }
10052
+ if (this.code === Jsep.PERIOD_CODE) {
10053
+ number3 += this.expr.charAt(this.index++);
10054
+ while (Jsep.isDecimalDigit(this.code)) {
10055
+ number3 += this.expr.charAt(this.index++);
10056
+ }
10057
+ }
10058
+ ch = this.char;
10059
+ if (ch === "e" || ch === "E") {
10060
+ number3 += this.expr.charAt(this.index++);
10061
+ ch = this.char;
10062
+ if (ch === "+" || ch === "-") {
10063
+ number3 += this.expr.charAt(this.index++);
10064
+ }
10065
+ while (Jsep.isDecimalDigit(this.code)) {
10066
+ number3 += this.expr.charAt(this.index++);
10067
+ }
10068
+ if (!Jsep.isDecimalDigit(this.expr.charCodeAt(this.index - 1))) {
10069
+ this.throwError("Expected exponent (" + number3 + this.char + ")");
10070
+ }
10071
+ }
10072
+ chCode = this.code;
10073
+ if (Jsep.isIdentifierStart(chCode)) {
10074
+ this.throwError("Variable names cannot start with a number (" + number3 + this.char + ")");
10075
+ } else if (chCode === Jsep.PERIOD_CODE || number3.length === 1 && number3.charCodeAt(0) === Jsep.PERIOD_CODE) {
10076
+ this.throwError("Unexpected period");
10077
+ }
10078
+ return {
10079
+ type: Jsep.LITERAL,
10080
+ value: parseFloat(number3),
10081
+ raw: number3
10082
+ };
10083
+ }
10084
+ /**
10085
+ * Parses a string literal, staring with single or double quotes with basic support for escape codes
10086
+ * e.g. `"hello world"`, `'this is\nJSEP'`
10087
+ * @returns {jsep.Literal}
10088
+ */
10089
+ gobbleStringLiteral() {
10090
+ let str = "";
10091
+ const startIndex = this.index;
10092
+ const quote = this.expr.charAt(this.index++);
10093
+ let closed = false;
10094
+ while (this.index < this.expr.length) {
10095
+ let ch = this.expr.charAt(this.index++);
10096
+ if (ch === quote) {
10097
+ closed = true;
10098
+ break;
10099
+ } else if (ch === "\\") {
10100
+ ch = this.expr.charAt(this.index++);
10101
+ switch (ch) {
10102
+ case "n":
10103
+ str += "\n";
10104
+ break;
10105
+ case "r":
10106
+ str += "\r";
10107
+ break;
10108
+ case "t":
10109
+ str += " ";
10110
+ break;
10111
+ case "b":
10112
+ str += "\b";
10113
+ break;
10114
+ case "f":
10115
+ str += "\f";
10116
+ break;
10117
+ case "v":
10118
+ str += "\v";
10119
+ break;
10120
+ default:
10121
+ str += ch;
10122
+ }
10123
+ } else {
10124
+ str += ch;
10125
+ }
10126
+ }
10127
+ if (!closed) {
10128
+ this.throwError('Unclosed quote after "' + str + '"');
10129
+ }
10130
+ return {
10131
+ type: Jsep.LITERAL,
10132
+ value: str,
10133
+ raw: this.expr.substring(startIndex, this.index)
10134
+ };
10135
+ }
10136
+ /**
10137
+ * Gobbles only identifiers
10138
+ * e.g.: `foo`, `_value`, `$x1`
10139
+ * Also, this function checks if that identifier is a literal:
10140
+ * (e.g. `true`, `false`, `null`) or `this`
10141
+ * @returns {jsep.Identifier}
10142
+ */
10143
+ gobbleIdentifier() {
10144
+ let ch = this.code, start = this.index;
10145
+ if (Jsep.isIdentifierStart(ch)) {
10146
+ this.index++;
10147
+ } else {
10148
+ this.throwError("Unexpected " + this.char);
10149
+ }
10150
+ while (this.index < this.expr.length) {
10151
+ ch = this.code;
10152
+ if (Jsep.isIdentifierPart(ch)) {
10153
+ this.index++;
10154
+ } else {
10155
+ break;
10156
+ }
10157
+ }
10158
+ return {
10159
+ type: Jsep.IDENTIFIER,
10160
+ name: this.expr.slice(start, this.index)
10161
+ };
10162
+ }
10163
+ /**
10164
+ * Gobbles a list of arguments within the context of a function call
10165
+ * or array literal. This function also assumes that the opening character
10166
+ * `(` or `[` has already been gobbled, and gobbles expressions and commas
10167
+ * until the terminator character `)` or `]` is encountered.
10168
+ * e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]`
10169
+ * @param {number} termination
10170
+ * @returns {jsep.Expression[]}
10171
+ */
10172
+ gobbleArguments(termination) {
10173
+ const args = [];
10174
+ let closed = false;
10175
+ let separator_count = 0;
10176
+ while (this.index < this.expr.length) {
10177
+ this.gobbleSpaces();
10178
+ let ch_i = this.code;
10179
+ if (ch_i === termination) {
10180
+ closed = true;
10181
+ this.index++;
10182
+ if (termination === Jsep.CPAREN_CODE && separator_count && separator_count >= args.length) {
10183
+ this.throwError("Unexpected token " + String.fromCharCode(termination));
10184
+ }
10185
+ break;
10186
+ } else if (ch_i === Jsep.COMMA_CODE) {
10187
+ this.index++;
10188
+ separator_count++;
10189
+ if (separator_count !== args.length) {
10190
+ if (termination === Jsep.CPAREN_CODE) {
10191
+ this.throwError("Unexpected token ,");
10192
+ } else if (termination === Jsep.CBRACK_CODE) {
10193
+ for (let arg = args.length; arg < separator_count; arg++) {
10194
+ args.push(null);
10195
+ }
10196
+ }
10197
+ }
10198
+ } else if (args.length !== separator_count && separator_count !== 0) {
10199
+ this.throwError("Expected comma");
10200
+ } else {
10201
+ const node = this.gobbleExpression();
10202
+ if (!node || node.type === Jsep.COMPOUND) {
10203
+ this.throwError("Expected comma");
10204
+ }
10205
+ args.push(node);
10206
+ }
10207
+ }
10208
+ if (!closed) {
10209
+ this.throwError("Expected " + String.fromCharCode(termination));
10210
+ }
10211
+ return args;
10212
+ }
10213
+ /**
10214
+ * Responsible for parsing a group of things within parentheses `()`
10215
+ * that have no identifier in front (so not a function call)
10216
+ * This function assumes that it needs to gobble the opening parenthesis
10217
+ * and then tries to gobble everything within that parenthesis, assuming
10218
+ * that the next thing it should see is the close parenthesis. If not,
10219
+ * then the expression probably doesn't have a `)`
10220
+ * @returns {boolean|jsep.Expression}
10221
+ */
10222
+ gobbleGroup() {
10223
+ this.index++;
10224
+ let nodes = this.gobbleExpressions(Jsep.CPAREN_CODE);
10225
+ if (this.code === Jsep.CPAREN_CODE) {
10226
+ this.index++;
10227
+ if (nodes.length === 1) {
10228
+ return nodes[0];
10229
+ } else if (!nodes.length) {
10230
+ return false;
10231
+ } else {
10232
+ return {
10233
+ type: Jsep.SEQUENCE_EXP,
10234
+ expressions: nodes
10235
+ };
10236
+ }
10237
+ } else {
10238
+ this.throwError("Unclosed (");
10239
+ }
10240
+ }
10241
+ /**
10242
+ * Responsible for parsing Array literals `[1, 2, 3]`
10243
+ * This function assumes that it needs to gobble the opening bracket
10244
+ * and then tries to gobble the expressions as arguments.
10245
+ * @returns {jsep.ArrayExpression}
10246
+ */
10247
+ gobbleArray() {
10248
+ this.index++;
10249
+ return {
10250
+ type: Jsep.ARRAY_EXP,
10251
+ elements: this.gobbleArguments(Jsep.CBRACK_CODE)
10252
+ };
10253
+ }
10254
+ };
10255
+ var hooks = new Hooks();
10256
+ Object.assign(Jsep, {
10257
+ hooks,
10258
+ plugins: new Plugins(Jsep),
10259
+ // Node Types
10260
+ // ----------
10261
+ // This is the full set of types that any JSEP node can be.
10262
+ // Store them here to save space when minified
10263
+ COMPOUND: "Compound",
10264
+ SEQUENCE_EXP: "SequenceExpression",
10265
+ IDENTIFIER: "Identifier",
10266
+ MEMBER_EXP: "MemberExpression",
10267
+ LITERAL: "Literal",
10268
+ THIS_EXP: "ThisExpression",
10269
+ CALL_EXP: "CallExpression",
10270
+ UNARY_EXP: "UnaryExpression",
10271
+ BINARY_EXP: "BinaryExpression",
10272
+ ARRAY_EXP: "ArrayExpression",
10273
+ TAB_CODE: 9,
10274
+ LF_CODE: 10,
10275
+ CR_CODE: 13,
10276
+ SPACE_CODE: 32,
10277
+ PERIOD_CODE: 46,
10278
+ // '.'
10279
+ COMMA_CODE: 44,
10280
+ // ','
10281
+ SQUOTE_CODE: 39,
10282
+ // single quote
10283
+ DQUOTE_CODE: 34,
10284
+ // double quotes
10285
+ OPAREN_CODE: 40,
10286
+ // (
10287
+ CPAREN_CODE: 41,
10288
+ // )
10289
+ OBRACK_CODE: 91,
10290
+ // [
10291
+ CBRACK_CODE: 93,
10292
+ // ]
10293
+ QUMARK_CODE: 63,
10294
+ // ?
10295
+ SEMCOL_CODE: 59,
10296
+ // ;
10297
+ COLON_CODE: 58,
10298
+ // :
10299
+ // Operations
10300
+ // ----------
10301
+ // Use a quickly-accessible map to store all of the unary operators
10302
+ // Values are set to `1` (it really doesn't matter)
10303
+ unary_ops: {
10304
+ "-": 1,
10305
+ "!": 1,
10306
+ "~": 1,
10307
+ "+": 1
10308
+ },
10309
+ // Also use a map for the binary operations but set their values to their
10310
+ // binary precedence for quick reference (higher number = higher precedence)
10311
+ // see [Order of operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)
10312
+ binary_ops: {
10313
+ "||": 1,
10314
+ "??": 1,
10315
+ "&&": 2,
10316
+ "|": 3,
10317
+ "^": 4,
10318
+ "&": 5,
10319
+ "==": 6,
10320
+ "!=": 6,
10321
+ "===": 6,
10322
+ "!==": 6,
10323
+ "<": 7,
10324
+ ">": 7,
10325
+ "<=": 7,
10326
+ ">=": 7,
10327
+ "<<": 8,
10328
+ ">>": 8,
10329
+ ">>>": 8,
10330
+ "+": 9,
10331
+ "-": 9,
10332
+ "*": 10,
10333
+ "/": 10,
10334
+ "%": 10,
10335
+ "**": 11
10336
+ },
10337
+ // sets specific binary_ops as right-associative
10338
+ right_associative: /* @__PURE__ */ new Set(["**"]),
10339
+ // Additional valid identifier chars, apart from a-z, A-Z and 0-9 (except on the starting char)
10340
+ additional_identifier_chars: /* @__PURE__ */ new Set(["$", "_"]),
10341
+ // Literals
10342
+ // ----------
10343
+ // Store the values to return for the various literals we may encounter
10344
+ literals: {
10345
+ "true": true,
10346
+ "false": false,
10347
+ "null": null
10348
+ },
10349
+ // Except for `this`, which is special. This could be changed to something like `'self'` as well
10350
+ this_str: "this"
10351
+ });
10352
+ Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);
10353
+ Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);
10354
+ var jsep = (expr) => new Jsep(expr).parse();
10355
+ var stdClassProps = Object.getOwnPropertyNames(class Test {
10356
+ });
10357
+ Object.getOwnPropertyNames(Jsep).filter((prop) => !stdClassProps.includes(prop) && jsep[prop] === void 0).forEach((m) => {
10358
+ jsep[m] = Jsep[m];
10359
+ });
10360
+ jsep.Jsep = Jsep;
10361
+ var CONDITIONAL_EXP = "ConditionalExpression";
10362
+ var ternary = {
10363
+ name: "ternary",
10364
+ init(jsep2) {
10365
+ jsep2.hooks.add("after-expression", function gobbleTernary(env) {
10366
+ if (env.node && this.code === jsep2.QUMARK_CODE) {
10367
+ this.index++;
10368
+ const test = env.node;
10369
+ const consequent = this.gobbleExpression();
10370
+ if (!consequent) {
10371
+ this.throwError("Expected expression");
10372
+ }
10373
+ this.gobbleSpaces();
10374
+ if (this.code === jsep2.COLON_CODE) {
10375
+ this.index++;
10376
+ const alternate = this.gobbleExpression();
10377
+ if (!alternate) {
10378
+ this.throwError("Expected expression");
10379
+ }
10380
+ env.node = {
10381
+ type: CONDITIONAL_EXP,
10382
+ test,
10383
+ consequent,
10384
+ alternate
10385
+ };
10386
+ if (test.operator && jsep2.binary_ops[test.operator] <= 0.9) {
10387
+ let newTest = test;
10388
+ while (newTest.right.operator && jsep2.binary_ops[newTest.right.operator] <= 0.9) {
10389
+ newTest = newTest.right;
10390
+ }
10391
+ env.node.test = newTest.right;
10392
+ newTest.right = env.node;
10393
+ env.node = test;
10394
+ }
10395
+ } else {
10396
+ this.throwError("Expected :");
10397
+ }
10398
+ }
10399
+ });
10400
+ }
10401
+ };
10402
+ jsep.plugins.register(ternary);
9393
10403
 
9394
10404
  // ../../node_modules/d3-array/src/ascending.js
9395
10405
  function ascending(a, b) {
@@ -11103,11 +12113,11 @@ void main(void) {
11103
12113
  FilterType2["STRING_SEARCH"] = "stringSearch";
11104
12114
  return FilterType2;
11105
12115
  })(FilterType || {});
11106
- var ApiVersion = /* @__PURE__ */ ((ApiVersion3) => {
11107
- ApiVersion3["V1"] = "v1";
11108
- ApiVersion3["V2"] = "v2";
11109
- ApiVersion3["V3"] = "v3";
11110
- return ApiVersion3;
12116
+ var ApiVersion = /* @__PURE__ */ ((ApiVersion2) => {
12117
+ ApiVersion2["V1"] = "v1";
12118
+ ApiVersion2["V2"] = "v2";
12119
+ ApiVersion2["V3"] = "v3";
12120
+ return ApiVersion2;
11111
12121
  })(ApiVersion || {});
11112
12122
  var DEFAULT_API_BASE_URL = "https://gcp-us-east1.api.carto.com";
11113
12123
  var SpatialIndex = /* @__PURE__ */ ((SpatialIndex2) => {
@@ -12520,6 +13530,100 @@ void main(void) {
12520
13530
  }
12521
13531
  return Array.from(map2.values());
12522
13532
  }
13533
+ var RADIANS_TO_DEGREES2 = 1 / Math.PI * 180;
13534
+ var DEGREES_TO_RADIANS3 = 1 / 180 * Math.PI;
13535
+ var DEFAULT_CONFIG = {
13536
+ EPSILON: 1e-12,
13537
+ debug: false,
13538
+ precision: 4,
13539
+ printTypes: false,
13540
+ printDegrees: false,
13541
+ printRowMajor: true,
13542
+ _cartographicRadians: false
13543
+ };
13544
+ globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
13545
+ var config = globalThis.mathgl.config;
13546
+ function isArray(value) {
13547
+ return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
13548
+ }
13549
+ function lerp2(a, b, t) {
13550
+ if (isArray(a)) {
13551
+ return a.map((ai, i) => lerp2(ai, b[i], t));
13552
+ }
13553
+ return t * b + (1 - t) * a;
13554
+ }
13555
+ function assert3(condition, message) {
13556
+ if (!condition) {
13557
+ throw new Error(message || "@math.gl/web-mercator: assertion failed.");
13558
+ }
13559
+ }
13560
+ var PI2 = Math.PI;
13561
+ var PI_42 = PI2 / 4;
13562
+ var DEGREES_TO_RADIANS22 = PI2 / 180;
13563
+ var RADIANS_TO_DEGREES22 = 180 / PI2;
13564
+ var TILE_SIZE4 = 512;
13565
+ function lngLatToWorld2(lngLat) {
13566
+ const [lng, lat] = lngLat;
13567
+ assert3(Number.isFinite(lng));
13568
+ assert3(Number.isFinite(lat) && lat >= -90 && lat <= 90, "invalid latitude");
13569
+ const lambda2 = lng * DEGREES_TO_RADIANS22;
13570
+ const phi2 = lat * DEGREES_TO_RADIANS22;
13571
+ const x = TILE_SIZE4 * (lambda2 + PI2) / (2 * PI2);
13572
+ const y = TILE_SIZE4 * (PI2 + Math.log(Math.tan(PI_42 + phi2 * 0.5))) / (2 * PI2);
13573
+ return [x, y];
13574
+ }
13575
+ function worldToLngLat2(xy) {
13576
+ const [x, y] = xy;
13577
+ const lambda2 = x / TILE_SIZE4 * (2 * PI2) - PI2;
13578
+ const phi2 = 2 * (Math.atan(Math.exp(y / TILE_SIZE4 * (2 * PI2) - PI2)) - PI_42);
13579
+ return [lambda2 * RADIANS_TO_DEGREES22, phi2 * RADIANS_TO_DEGREES22];
13580
+ }
13581
+ var DEGREES_TO_RADIANS32 = Math.PI / 180;
13582
+ var TRANSFORM_FN = {
13583
+ Point: transformPoint,
13584
+ MultiPoint: transformMultiPoint,
13585
+ LineString: transformLineString,
13586
+ MultiLineString: transformMultiLineString,
13587
+ Polygon: transformPolygon,
13588
+ MultiPolygon: transformMultiPolygon
13589
+ };
13590
+ function transformTileCoordsToWGS84(geometry, bbox2) {
13591
+ const [west, south, east, north] = bbox2;
13592
+ const nw = lngLatToWorld2([west, north]);
13593
+ const se = lngLatToWorld2([east, south]);
13594
+ const projectedBbox = [nw, se];
13595
+ if (geometry.type === "GeometryCollection") {
13596
+ throw new Error("Unsupported geometry type GeometryCollection");
13597
+ }
13598
+ const transformFn = TRANSFORM_FN[geometry.type];
13599
+ const coordinates = transformFn(geometry.coordinates, projectedBbox);
13600
+ return { ...geometry, coordinates };
13601
+ }
13602
+ function transformPoint([pointX, pointY], [nw, se]) {
13603
+ const x = lerp2(nw[0], se[0], pointX);
13604
+ const y = lerp2(nw[1], se[1], pointY);
13605
+ return worldToLngLat2([x, y]);
13606
+ }
13607
+ function getPoints(geometry, bbox2) {
13608
+ return geometry.map((g) => transformPoint(g, bbox2));
13609
+ }
13610
+ function transformMultiPoint(multiPoint, bbox2) {
13611
+ return getPoints(multiPoint, bbox2);
13612
+ }
13613
+ function transformLineString(line, bbox2) {
13614
+ return getPoints(line, bbox2);
13615
+ }
13616
+ function transformMultiLineString(multiLineString2, bbox2) {
13617
+ return multiLineString2.map(
13618
+ (lineString2) => transformLineString(lineString2, bbox2)
13619
+ );
13620
+ }
13621
+ function transformPolygon(polygon2, bbox2) {
13622
+ return polygon2.map((polygonRing) => getPoints(polygonRing, bbox2));
13623
+ }
13624
+ function transformMultiPolygon(multiPolygon2, bbox2) {
13625
+ return multiPolygon2.map((polygon2) => transformPolygon(polygon2, bbox2));
13626
+ }
12523
13627
  function bboxPolygon(bbox2, options = {}) {
12524
13628
  const west = Number(bbox2[0]);
12525
13629
  const south = Number(bbox2[1]);
@@ -12833,7 +13937,7 @@ void main(void) {
12833
13937
  var POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13];
12834
13938
  var SQRT_BASE = 1e7;
12835
13939
  var MAX = 1e9;
12836
- function clone(configObject) {
13940
+ function clone2(configObject) {
12837
13941
  var div, convertBase, parseNumeric, P = BigNumber2.prototype = { constructor: BigNumber2, toString: null, valueOf: null }, ONE = new BigNumber2(1), DECIMAL_PLACES = 20, ROUNDING_MODE = 4, TO_EXP_NEG = -7, TO_EXP_POS = 21, MIN_EXP = -1e7, MAX_EXP = 1e7, CRYPTO = false, MODULO_MODE = 1, POW_PRECISION = 0, FORMAT = {
12838
13942
  prefix: "",
12839
13943
  groupSize: 3,
@@ -12972,7 +14076,7 @@ void main(void) {
12972
14076
  x.c = [x.e = 0];
12973
14077
  }
12974
14078
  }
12975
- BigNumber2.clone = clone;
14079
+ BigNumber2.clone = clone2;
12976
14080
  BigNumber2.ROUND_UP = 0;
12977
14081
  BigNumber2.ROUND_DOWN = 1;
12978
14082
  BigNumber2.ROUND_CEIL = 2;
@@ -14292,7 +15396,7 @@ void main(void) {
14292
15396
  }
14293
15397
  return str;
14294
15398
  }
14295
- var BigNumber = clone();
15399
+ var BigNumber = clone2();
14296
15400
  var bignumber_default = BigNumber;
14297
15401
  var SplayTreeNode = class {
14298
15402
  constructor(key) {
@@ -16011,62 +17115,13 @@ void main(void) {
16011
17115
  return multiPolygon(intersection22, options.properties);
16012
17116
  }
16013
17117
  var turf_intersect_default = intersect;
16014
- var RADIANS_TO_DEGREES2 = 1 / Math.PI * 180;
16015
- var DEGREES_TO_RADIANS3 = 1 / 180 * Math.PI;
16016
- var DEFAULT_CONFIG = {
16017
- EPSILON: 1e-12,
16018
- debug: false,
16019
- precision: 4,
16020
- printTypes: false,
16021
- printDegrees: false,
16022
- printRowMajor: true,
16023
- _cartographicRadians: false
16024
- };
16025
- globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
16026
- var config = globalThis.mathgl.config;
16027
- function isArray(value) {
16028
- return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
16029
- }
16030
- function lerp2(a, b, t) {
16031
- if (isArray(a)) {
16032
- return a.map((ai, i) => lerp2(ai, b[i], t));
16033
- }
16034
- return t * b + (1 - t) * a;
16035
- }
16036
- function assert3(condition, message) {
16037
- if (!condition) {
16038
- throw new Error(message || "@math.gl/web-mercator: assertion failed.");
16039
- }
16040
- }
16041
- var PI2 = Math.PI;
16042
- var PI_42 = PI2 / 4;
16043
- var DEGREES_TO_RADIANS22 = PI2 / 180;
16044
- var RADIANS_TO_DEGREES22 = 180 / PI2;
16045
- var TILE_SIZE3 = 512;
16046
- function lngLatToWorld2(lngLat) {
16047
- const [lng, lat] = lngLat;
16048
- assert3(Number.isFinite(lng));
16049
- assert3(Number.isFinite(lat) && lat >= -90 && lat <= 90, "invalid latitude");
16050
- const lambda2 = lng * DEGREES_TO_RADIANS22;
16051
- const phi2 = lat * DEGREES_TO_RADIANS22;
16052
- const x = TILE_SIZE3 * (lambda2 + PI2) / (2 * PI2);
16053
- const y = TILE_SIZE3 * (PI2 + Math.log(Math.tan(PI_42 + phi2 * 0.5))) / (2 * PI2);
16054
- return [x, y];
16055
- }
16056
- function worldToLngLat2(xy) {
16057
- const [x, y] = xy;
16058
- const lambda2 = x / TILE_SIZE3 * (2 * PI2) - PI2;
16059
- const phi2 = 2 * (Math.atan(Math.exp(y / TILE_SIZE3 * (2 * PI2) - PI2)) - PI_42);
16060
- return [lambda2 * RADIANS_TO_DEGREES22, phi2 * RADIANS_TO_DEGREES22];
16061
- }
16062
- var DEGREES_TO_RADIANS32 = Math.PI / 180;
16063
- var TRANSFORM_FN = {
16064
- Point: transformPoint,
16065
- MultiPoint: transformMultiPoint,
16066
- LineString: transformLineString,
16067
- MultiLineString: transformMultiLineString,
16068
- Polygon: transformPolygon,
16069
- MultiPolygon: transformMultiPolygon
17118
+ var TRANSFORM_FN2 = {
17119
+ Point: transformPoint2,
17120
+ MultiPoint: transformMultiPoint2,
17121
+ LineString: transformLineString2,
17122
+ MultiLineString: transformMultiLineString2,
17123
+ Polygon: transformPolygon2,
17124
+ MultiPolygon: transformMultiPolygon2
16070
17125
  };
16071
17126
  function transformToTileCoords(geometry, bbox2) {
16072
17127
  const [west, south, east, north] = bbox2;
@@ -16076,34 +17131,34 @@ void main(void) {
16076
17131
  if (geometry.type === "GeometryCollection") {
16077
17132
  throw new Error("Unsupported geometry type GeometryCollection");
16078
17133
  }
16079
- const transformFn = TRANSFORM_FN[geometry.type];
17134
+ const transformFn = TRANSFORM_FN2[geometry.type];
16080
17135
  const coordinates = transformFn(geometry.coordinates, projectedBbox);
16081
17136
  return { ...geometry, coordinates };
16082
17137
  }
16083
- function transformPoint([pointX, pointY], [nw, se]) {
17138
+ function transformPoint2([pointX, pointY], [nw, se]) {
16084
17139
  const x = inverseLerp(nw[0], se[0], pointX);
16085
17140
  const y = inverseLerp(nw[1], se[1], pointY);
16086
17141
  return [x, y];
16087
17142
  }
16088
- function getPoints(geometry, bbox2) {
16089
- return geometry.map((g) => transformPoint(projectFlat(g), bbox2));
17143
+ function getPoints2(geometry, bbox2) {
17144
+ return geometry.map((g) => transformPoint2(projectFlat(g), bbox2));
16090
17145
  }
16091
- function transformMultiPoint(multiPoint, bbox2) {
16092
- return getPoints(multiPoint, bbox2);
17146
+ function transformMultiPoint2(multiPoint, bbox2) {
17147
+ return getPoints2(multiPoint, bbox2);
16093
17148
  }
16094
- function transformLineString(line, bbox2) {
16095
- return getPoints(line, bbox2);
17149
+ function transformLineString2(line, bbox2) {
17150
+ return getPoints2(line, bbox2);
16096
17151
  }
16097
- function transformMultiLineString(multiLineString2, bbox2) {
17152
+ function transformMultiLineString2(multiLineString2, bbox2) {
16098
17153
  return multiLineString2.map(
16099
- (lineString2) => transformLineString(lineString2, bbox2)
17154
+ (lineString2) => transformLineString2(lineString2, bbox2)
16100
17155
  );
16101
17156
  }
16102
- function transformPolygon(polygon2, bbox2) {
16103
- return polygon2.map((polygonRing) => getPoints(polygonRing, bbox2));
17157
+ function transformPolygon2(polygon2, bbox2) {
17158
+ return polygon2.map((polygonRing) => getPoints2(polygonRing, bbox2));
16104
17159
  }
16105
- function transformMultiPolygon(multiPolygon2, bbox2) {
16106
- return multiPolygon2.map((polygon2) => transformPolygon(polygon2, bbox2));
17160
+ function transformMultiPolygon2(multiPolygon2, bbox2) {
17161
+ return multiPolygon2.map((polygon2) => transformPolygon2(polygon2, bbox2));
16107
17162
  }
16108
17163
  function projectFlat(xyz) {
16109
17164
  return lngLatToWorld2(xyz);
@@ -16111,50 +17166,182 @@ void main(void) {
16111
17166
  function inverseLerp(a, b, x) {
16112
17167
  return (x - a) / (b - a);
16113
17168
  }
16114
- var TRANSFORM_FN2 = {
16115
- Point: transformPoint2,
16116
- MultiPoint: transformMultiPoint2,
16117
- LineString: transformLineString2,
16118
- MultiLineString: transformMultiLineString2,
16119
- Polygon: transformPolygon2,
16120
- MultiPolygon: transformMultiPolygon2
16121
- };
16122
- function transformTileCoordsToWGS84(geometry, bbox2) {
16123
- const [west, south, east, north] = bbox2;
16124
- const nw = lngLatToWorld2([west, north]);
16125
- const se = lngLatToWorld2([east, south]);
16126
- const projectedBbox = [nw, se];
16127
- if (geometry.type === "GeometryCollection") {
16128
- throw new Error("Unsupported geometry type GeometryCollection");
17169
+ function lineclip(points, bbox2, result) {
17170
+ var len = points.length, codeA = bitCode(points[0], bbox2), part = [], i, codeB, lastCode;
17171
+ let a;
17172
+ let b;
17173
+ if (!result)
17174
+ result = [];
17175
+ for (i = 1; i < len; i++) {
17176
+ a = points[i - 1];
17177
+ b = points[i];
17178
+ codeB = lastCode = bitCode(b, bbox2);
17179
+ while (true) {
17180
+ if (!(codeA | codeB)) {
17181
+ part.push(a);
17182
+ if (codeB !== lastCode) {
17183
+ part.push(b);
17184
+ if (i < len - 1) {
17185
+ result.push(part);
17186
+ part = [];
17187
+ }
17188
+ } else if (i === len - 1) {
17189
+ part.push(b);
17190
+ }
17191
+ break;
17192
+ } else if (codeA & codeB) {
17193
+ break;
17194
+ } else if (codeA) {
17195
+ a = intersect2(a, b, codeA, bbox2);
17196
+ codeA = bitCode(a, bbox2);
17197
+ } else {
17198
+ b = intersect2(a, b, codeB, bbox2);
17199
+ codeB = bitCode(b, bbox2);
17200
+ }
17201
+ }
17202
+ codeA = lastCode;
17203
+ }
17204
+ if (part.length)
17205
+ result.push(part);
17206
+ return result;
17207
+ }
17208
+ function polygonclip(points, bbox2) {
17209
+ var result, edge, prev, prevInside, i, p, inside;
17210
+ for (edge = 1; edge <= 8; edge *= 2) {
17211
+ result = [];
17212
+ prev = points[points.length - 1];
17213
+ prevInside = !(bitCode(prev, bbox2) & edge);
17214
+ for (i = 0; i < points.length; i++) {
17215
+ p = points[i];
17216
+ inside = !(bitCode(p, bbox2) & edge);
17217
+ if (inside !== prevInside)
17218
+ result.push(intersect2(prev, p, edge, bbox2));
17219
+ if (inside)
17220
+ result.push(p);
17221
+ prev = p;
17222
+ prevInside = inside;
17223
+ }
17224
+ points = result;
17225
+ if (!points.length)
17226
+ break;
16129
17227
  }
16130
- const transformFn = TRANSFORM_FN2[geometry.type];
16131
- const coordinates = transformFn(geometry.coordinates, projectedBbox);
16132
- return { ...geometry, coordinates };
17228
+ return result;
16133
17229
  }
16134
- function transformPoint2([pointX, pointY], [nw, se]) {
16135
- const x = lerp2(nw[0], se[0], pointX);
16136
- const y = lerp2(nw[1], se[1], pointY);
16137
- return worldToLngLat2([x, y]);
17230
+ function intersect2(a, b, edge, bbox2) {
17231
+ return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox2[3] - a[1]) / (b[1] - a[1]), bbox2[3]] : edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox2[1] - a[1]) / (b[1] - a[1]), bbox2[1]] : edge & 2 ? [bbox2[2], a[1] + (b[1] - a[1]) * (bbox2[2] - a[0]) / (b[0] - a[0])] : edge & 1 ? [bbox2[0], a[1] + (b[1] - a[1]) * (bbox2[0] - a[0]) / (b[0] - a[0])] : null;
16138
17232
  }
16139
- function getPoints2(geometry, bbox2) {
16140
- return geometry.map((g) => transformPoint2(g, bbox2));
17233
+ function bitCode(p, bbox2) {
17234
+ var code = 0;
17235
+ if (p[0] < bbox2[0])
17236
+ code |= 1;
17237
+ else if (p[0] > bbox2[2])
17238
+ code |= 2;
17239
+ if (p[1] < bbox2[1])
17240
+ code |= 4;
17241
+ else if (p[1] > bbox2[3])
17242
+ code |= 8;
17243
+ return code;
16141
17244
  }
16142
- function transformMultiPoint2(multiPoint, bbox2) {
16143
- return getPoints2(multiPoint, bbox2);
17245
+ function bboxClip(feature2, bbox2) {
17246
+ const geom = getGeom(feature2);
17247
+ const type = geom.type;
17248
+ const properties = feature2.type === "Feature" ? feature2.properties : {};
17249
+ let coords = geom.coordinates;
17250
+ switch (type) {
17251
+ case "LineString":
17252
+ case "MultiLineString": {
17253
+ const lines = [];
17254
+ if (type === "LineString") {
17255
+ coords = [coords];
17256
+ }
17257
+ coords.forEach((line) => {
17258
+ lineclip(line, bbox2, lines);
17259
+ });
17260
+ if (lines.length === 1) {
17261
+ return lineString(lines[0], properties);
17262
+ }
17263
+ return multiLineString(lines, properties);
17264
+ }
17265
+ case "Polygon":
17266
+ return polygon(clipPolygon(coords, bbox2), properties);
17267
+ case "MultiPolygon":
17268
+ return multiPolygon(
17269
+ coords.map((poly) => {
17270
+ return clipPolygon(poly, bbox2);
17271
+ }),
17272
+ properties
17273
+ );
17274
+ default:
17275
+ throw new Error("geometry " + type + " not supported");
17276
+ }
16144
17277
  }
16145
- function transformLineString2(line, bbox2) {
16146
- return getPoints2(line, bbox2);
17278
+ function clipPolygon(rings, bbox2) {
17279
+ const outRings = [];
17280
+ for (const ring of rings) {
17281
+ const clipped = polygonclip(ring, bbox2);
17282
+ if (clipped.length > 0) {
17283
+ if (clipped[0][0] !== clipped[clipped.length - 1][0] || clipped[0][1] !== clipped[clipped.length - 1][1]) {
17284
+ clipped.push(clipped[0]);
17285
+ }
17286
+ if (clipped.length >= 4) {
17287
+ outRings.push(clipped);
17288
+ }
17289
+ }
17290
+ }
17291
+ return outRings;
16147
17292
  }
16148
- function transformMultiLineString2(multiLineString2, bbox2) {
16149
- return multiLineString2.map(
16150
- (lineString2) => transformLineString2(lineString2, bbox2)
17293
+ var turf_bbox_clip_default = bboxClip;
17294
+ function intersectTileGeometry(tileBbox, tileFormat, spatialFilter) {
17295
+ const tilePolygon = turf_bbox_polygon_default(tileBbox);
17296
+ if (!spatialFilter || turf_boolean_within_default(tilePolygon, spatialFilter)) {
17297
+ return true;
17298
+ }
17299
+ const clippedSpatialFilter = turf_intersect_default(
17300
+ featureCollection([tilePolygon, feature(spatialFilter)])
16151
17301
  );
17302
+ if (!clippedSpatialFilter) {
17303
+ return false;
17304
+ }
17305
+ return tileFormat === "mvt" ? transformToTileCoords(clippedSpatialFilter.geometry, tileBbox) : clippedSpatialFilter.geometry;
16152
17306
  }
16153
- function transformPolygon2(polygon2, bbox2) {
16154
- return polygon2.map((polygonRing) => getPoints2(polygonRing, bbox2));
17307
+ function intersectTileRaster(parent, cellResolution, spatialFilter) {
17308
+ return intersectTileQuadbin(parent, cellResolution, spatialFilter);
16155
17309
  }
16156
- function transformMultiPolygon2(multiPolygon2, bbox2) {
16157
- return multiPolygon2.map((polygon2) => transformPolygon2(polygon2, bbox2));
17310
+ function intersectTileQuadbin(parent, cellResolution, spatialFilter) {
17311
+ const tilePolygon = cellToBoundary2(parent);
17312
+ if (!spatialFilter || turf_boolean_within_default(tilePolygon, spatialFilter)) {
17313
+ return true;
17314
+ }
17315
+ const clippedSpatialFilter = turf_intersect_default(
17316
+ featureCollection([feature(tilePolygon), feature(spatialFilter)])
17317
+ );
17318
+ if (!clippedSpatialFilter) {
17319
+ return false;
17320
+ }
17321
+ const cells = geometryToCells(
17322
+ clippedSpatialFilter.geometry,
17323
+ cellResolution
17324
+ );
17325
+ return new Set(cells);
17326
+ }
17327
+ var BBOX_WEST = [-180, -90, 0, 90];
17328
+ var BBOX_EAST = [0, -90, 180, 90];
17329
+ function intersectTileH3(cellResolution, spatialFilter) {
17330
+ if (!spatialFilter) {
17331
+ return true;
17332
+ }
17333
+ const spatialFilterFeature = feature(spatialFilter);
17334
+ const cellsWest = (0, import_h3_js5.polygonToCells)(
17335
+ turf_bbox_clip_default(spatialFilterFeature, BBOX_WEST).geometry.coordinates,
17336
+ cellResolution,
17337
+ true
17338
+ );
17339
+ const cellsEast = (0, import_h3_js5.polygonToCells)(
17340
+ turf_bbox_clip_default(spatialFilterFeature, BBOX_EAST).geometry.coordinates,
17341
+ cellResolution,
17342
+ true
17343
+ );
17344
+ return new Set(cellsWest.concat(cellsEast));
16158
17345
  }
16159
17346
  var FEATURE_GEOM_PROPERTY = "__geomValue";
16160
17347
  function tileFeaturesGeometries({
@@ -16169,55 +17356,46 @@ void main(void) {
16169
17356
  if (tile.isVisible === false || !tile.data) {
16170
17357
  continue;
16171
17358
  }
16172
- const bbox2 = [
17359
+ const tileBbox = [
16173
17360
  tile.bbox.west,
16174
17361
  tile.bbox.south,
16175
17362
  tile.bbox.east,
16176
17363
  tile.bbox.north
16177
17364
  ];
16178
- const bboxToGeom = turf_bbox_polygon_default(bbox2);
16179
- const tileIsFullyVisible = turf_boolean_within_default(bboxToGeom, spatialFilter);
16180
- const spatialFilterFeature = {
16181
- type: "Feature",
16182
- geometry: spatialFilter,
16183
- properties: {}
16184
- };
16185
- const clippedGeometryToIntersect = turf_intersect_default(
16186
- featureCollection([bboxToGeom, spatialFilterFeature])
17365
+ const intersection3 = intersectTileGeometry(
17366
+ tileBbox,
17367
+ tileFormat,
17368
+ spatialFilter
16187
17369
  );
16188
- if (!clippedGeometryToIntersect) {
17370
+ if (intersection3 === false)
16189
17371
  continue;
16190
- }
16191
- const transformedGeometryToIntersect = tileFormat === "mvt" ? transformToTileCoords(clippedGeometryToIntersect.geometry, bbox2) : clippedGeometryToIntersect.geometry;
17372
+ const transformedSpatialFilter = intersection3 === true ? void 0 : intersection3;
16192
17373
  calculateFeatures({
16193
17374
  map: map2,
16194
- tileIsFullyVisible,
16195
- geometryIntersection: transformedGeometryToIntersect,
17375
+ spatialFilter: transformedSpatialFilter,
16196
17376
  data: tile.data.points,
16197
17377
  type: "Point",
16198
- bbox: bbox2,
17378
+ bbox: tileBbox,
16199
17379
  tileFormat,
16200
17380
  uniqueIdProperty,
16201
17381
  options
16202
17382
  });
16203
17383
  calculateFeatures({
16204
17384
  map: map2,
16205
- tileIsFullyVisible,
16206
- geometryIntersection: transformedGeometryToIntersect,
17385
+ spatialFilter: transformedSpatialFilter,
16207
17386
  data: tile.data.lines,
16208
17387
  type: "LineString",
16209
- bbox: bbox2,
17388
+ bbox: tileBbox,
16210
17389
  tileFormat,
16211
17390
  uniqueIdProperty,
16212
17391
  options
16213
17392
  });
16214
17393
  calculateFeatures({
16215
17394
  map: map2,
16216
- tileIsFullyVisible,
16217
- geometryIntersection: transformedGeometryToIntersect,
17395
+ spatialFilter: transformedSpatialFilter,
16218
17396
  data: tile.data.polygons,
16219
17397
  type: "Polygon",
16220
- bbox: bbox2,
17398
+ bbox: tileBbox,
16221
17399
  tileFormat,
16222
17400
  uniqueIdProperty,
16223
17401
  options
@@ -16235,7 +17413,7 @@ void main(void) {
16235
17413
  tileFormat,
16236
17414
  uniqueIdProperty,
16237
17415
  storeGeometry,
16238
- geometryIntersection
17416
+ spatialFilter
16239
17417
  }) {
16240
17418
  const tileProps = getPropertiesFromTile(data, startIndex);
16241
17419
  const uniquePropertyValue = getUniquePropertyValue(
@@ -16247,7 +17425,7 @@ void main(void) {
16247
17425
  return;
16248
17426
  }
16249
17427
  let geometry = null;
16250
- if (storeGeometry || geometryIntersection) {
17428
+ if (storeGeometry || spatialFilter) {
16251
17429
  const { positions } = data;
16252
17430
  const ringCoordinates = getRingCoordinatesFor(
16253
17431
  startIndex,
@@ -16256,7 +17434,7 @@ void main(void) {
16256
17434
  );
16257
17435
  geometry = getFeatureByType(ringCoordinates, type);
16258
17436
  }
16259
- if (geometry && geometryIntersection && !turf_boolean_intersects_default(geometry, geometryIntersection)) {
17437
+ if (geometry && spatialFilter && !turf_boolean_intersects_default(geometry, spatialFilter)) {
16260
17438
  return;
16261
17439
  }
16262
17440
  const properties = parseProperties2(tileProps);
@@ -16268,7 +17446,7 @@ void main(void) {
16268
17446
  function addIntersectedFeaturesInTile({
16269
17447
  map: map2,
16270
17448
  data,
16271
- geometryIntersection,
17449
+ spatialFilter,
16272
17450
  type,
16273
17451
  bbox: bbox2,
16274
17452
  tileFormat,
@@ -16290,7 +17468,7 @@ void main(void) {
16290
17468
  tileFormat,
16291
17469
  uniqueIdProperty,
16292
17470
  storeGeometry,
16293
- geometryIntersection
17471
+ spatialFilter
16294
17472
  });
16295
17473
  }
16296
17474
  }
@@ -16372,8 +17550,7 @@ void main(void) {
16372
17550
  }
16373
17551
  function calculateFeatures({
16374
17552
  map: map2,
16375
- tileIsFullyVisible,
16376
- geometryIntersection,
17553
+ spatialFilter,
16377
17554
  data,
16378
17555
  type,
16379
17556
  bbox: bbox2,
@@ -16384,7 +17561,7 @@ void main(void) {
16384
17561
  if (!data?.properties.length) {
16385
17562
  return;
16386
17563
  }
16387
- if (tileIsFullyVisible) {
17564
+ if (!spatialFilter) {
16388
17565
  addAllFeaturesInTile({
16389
17566
  map: map2,
16390
17567
  data,
@@ -16398,7 +17575,7 @@ void main(void) {
16398
17575
  addIntersectedFeaturesInTile({
16399
17576
  map: map2,
16400
17577
  data,
16401
- geometryIntersection,
17578
+ spatialFilter,
16402
17579
  type,
16403
17580
  bbox: bbox2,
16404
17581
  tileFormat,
@@ -16407,170 +17584,45 @@ void main(void) {
16407
17584
  });
16408
17585
  }
16409
17586
  }
16410
- function addAllFeaturesInTile({
16411
- map: map2,
16412
- data,
16413
- type,
16414
- bbox: bbox2,
16415
- tileFormat,
16416
- uniqueIdProperty,
16417
- options
16418
- }) {
16419
- const indices = getIndices(data, type);
16420
- const storeGeometry = options?.storeGeometry || false;
16421
- for (let i = 0; i < indices.length - 1; i++) {
16422
- const startIndex = indices[i];
16423
- const endIndex = indices[i + 1];
16424
- processTileFeatureProperties({
16425
- map: map2,
16426
- data,
16427
- startIndex,
16428
- endIndex,
16429
- type,
16430
- bbox: bbox2,
16431
- tileFormat,
16432
- uniqueIdProperty,
16433
- storeGeometry
16434
- });
16435
- }
16436
- }
16437
- function createIndicesForPoints(data) {
16438
- const featureIds = data.featureIds.value;
16439
- const lastFeatureId = featureIds[featureIds.length - 1];
16440
- const PointIndicesArray = featureIds.constructor;
16441
- const pointIndices = {
16442
- value: new PointIndicesArray(featureIds.length + 1),
16443
- size: 1
16444
- };
16445
- pointIndices.value.set(featureIds);
16446
- pointIndices.value.set([lastFeatureId + 1], featureIds.length);
16447
- return pointIndices;
16448
- }
16449
- function lineclip(points, bbox2, result) {
16450
- var len = points.length, codeA = bitCode(points[0], bbox2), part = [], i, codeB, lastCode;
16451
- let a;
16452
- let b;
16453
- if (!result)
16454
- result = [];
16455
- for (i = 1; i < len; i++) {
16456
- a = points[i - 1];
16457
- b = points[i];
16458
- codeB = lastCode = bitCode(b, bbox2);
16459
- while (true) {
16460
- if (!(codeA | codeB)) {
16461
- part.push(a);
16462
- if (codeB !== lastCode) {
16463
- part.push(b);
16464
- if (i < len - 1) {
16465
- result.push(part);
16466
- part = [];
16467
- }
16468
- } else if (i === len - 1) {
16469
- part.push(b);
16470
- }
16471
- break;
16472
- } else if (codeA & codeB) {
16473
- break;
16474
- } else if (codeA) {
16475
- a = intersect2(a, b, codeA, bbox2);
16476
- codeA = bitCode(a, bbox2);
16477
- } else {
16478
- b = intersect2(a, b, codeB, bbox2);
16479
- codeB = bitCode(b, bbox2);
16480
- }
16481
- }
16482
- codeA = lastCode;
16483
- }
16484
- if (part.length)
16485
- result.push(part);
16486
- return result;
16487
- }
16488
- function polygonclip(points, bbox2) {
16489
- var result, edge, prev, prevInside, i, p, inside;
16490
- for (edge = 1; edge <= 8; edge *= 2) {
16491
- result = [];
16492
- prev = points[points.length - 1];
16493
- prevInside = !(bitCode(prev, bbox2) & edge);
16494
- for (i = 0; i < points.length; i++) {
16495
- p = points[i];
16496
- inside = !(bitCode(p, bbox2) & edge);
16497
- if (inside !== prevInside)
16498
- result.push(intersect2(prev, p, edge, bbox2));
16499
- if (inside)
16500
- result.push(p);
16501
- prev = p;
16502
- prevInside = inside;
16503
- }
16504
- points = result;
16505
- if (!points.length)
16506
- break;
16507
- }
16508
- return result;
16509
- }
16510
- function intersect2(a, b, edge, bbox2) {
16511
- return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox2[3] - a[1]) / (b[1] - a[1]), bbox2[3]] : edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox2[1] - a[1]) / (b[1] - a[1]), bbox2[1]] : edge & 2 ? [bbox2[2], a[1] + (b[1] - a[1]) * (bbox2[2] - a[0]) / (b[0] - a[0])] : edge & 1 ? [bbox2[0], a[1] + (b[1] - a[1]) * (bbox2[0] - a[0]) / (b[0] - a[0])] : null;
16512
- }
16513
- function bitCode(p, bbox2) {
16514
- var code = 0;
16515
- if (p[0] < bbox2[0])
16516
- code |= 1;
16517
- else if (p[0] > bbox2[2])
16518
- code |= 2;
16519
- if (p[1] < bbox2[1])
16520
- code |= 4;
16521
- else if (p[1] > bbox2[3])
16522
- code |= 8;
16523
- return code;
16524
- }
16525
- function bboxClip(feature2, bbox2) {
16526
- const geom = getGeom(feature2);
16527
- const type = geom.type;
16528
- const properties = feature2.type === "Feature" ? feature2.properties : {};
16529
- let coords = geom.coordinates;
16530
- switch (type) {
16531
- case "LineString":
16532
- case "MultiLineString": {
16533
- const lines = [];
16534
- if (type === "LineString") {
16535
- coords = [coords];
16536
- }
16537
- coords.forEach((line) => {
16538
- lineclip(line, bbox2, lines);
16539
- });
16540
- if (lines.length === 1) {
16541
- return lineString(lines[0], properties);
16542
- }
16543
- return multiLineString(lines, properties);
16544
- }
16545
- case "Polygon":
16546
- return polygon(clipPolygon(coords, bbox2), properties);
16547
- case "MultiPolygon":
16548
- return multiPolygon(
16549
- coords.map((poly) => {
16550
- return clipPolygon(poly, bbox2);
16551
- }),
16552
- properties
16553
- );
16554
- default:
16555
- throw new Error("geometry " + type + " not supported");
16556
- }
16557
- }
16558
- function clipPolygon(rings, bbox2) {
16559
- const outRings = [];
16560
- for (const ring of rings) {
16561
- const clipped = polygonclip(ring, bbox2);
16562
- if (clipped.length > 0) {
16563
- if (clipped[0][0] !== clipped[clipped.length - 1][0] || clipped[0][1] !== clipped[clipped.length - 1][1]) {
16564
- clipped.push(clipped[0]);
16565
- }
16566
- if (clipped.length >= 4) {
16567
- outRings.push(clipped);
16568
- }
16569
- }
17587
+ function addAllFeaturesInTile({
17588
+ map: map2,
17589
+ data,
17590
+ type,
17591
+ bbox: bbox2,
17592
+ tileFormat,
17593
+ uniqueIdProperty,
17594
+ options
17595
+ }) {
17596
+ const indices = getIndices(data, type);
17597
+ const storeGeometry = options?.storeGeometry || false;
17598
+ for (let i = 0; i < indices.length - 1; i++) {
17599
+ const startIndex = indices[i];
17600
+ const endIndex = indices[i + 1];
17601
+ processTileFeatureProperties({
17602
+ map: map2,
17603
+ data,
17604
+ startIndex,
17605
+ endIndex,
17606
+ type,
17607
+ bbox: bbox2,
17608
+ tileFormat,
17609
+ uniqueIdProperty,
17610
+ storeGeometry
17611
+ });
16570
17612
  }
16571
- return outRings;
16572
17613
  }
16573
- var turf_bbox_clip_default = bboxClip;
17614
+ function createIndicesForPoints(data) {
17615
+ const featureIds = data.featureIds.value;
17616
+ const lastFeatureId = featureIds[featureIds.length - 1];
17617
+ const PointIndicesArray = featureIds.constructor;
17618
+ const pointIndices = {
17619
+ value: new PointIndicesArray(featureIds.length + 1),
17620
+ size: 1
17621
+ };
17622
+ pointIndices.value.set(featureIds);
17623
+ pointIndices.value.set([lastFeatureId + 1], featureIds.length);
17624
+ return pointIndices;
17625
+ }
16574
17626
  function tileFeaturesSpatialIndex({
16575
17627
  tiles: tiles3,
16576
17628
  spatialFilter,
@@ -16579,58 +17631,53 @@ void main(void) {
16579
17631
  }) {
16580
17632
  const map2 = /* @__PURE__ */ new Map();
16581
17633
  const spatialIndex = getSpatialIndex(spatialDataType);
16582
- const resolution = getResolution4(tiles3, spatialIndex);
17634
+ const cellResolution = getResolution5(tiles3, spatialIndex);
16583
17635
  const spatialIndexIDName = spatialDataColumn ? spatialDataColumn : spatialIndex;
16584
- if (!resolution) {
17636
+ if (!cellResolution) {
16585
17637
  return [];
16586
17638
  }
16587
- const cells = getCellsCoverGeometry(spatialFilter, spatialIndex, resolution);
16588
- if (!cells?.length) {
16589
- return [];
17639
+ let intersection3;
17640
+ if (spatialIndex === "h3") {
17641
+ intersection3 = intersectTileH3(cellResolution, spatialFilter);
16590
17642
  }
16591
- const cellsSet = new Set(cells);
16592
17643
  for (const tile of tiles3) {
16593
17644
  if (tile.isVisible === false || !tile.data) {
16594
17645
  continue;
16595
17646
  }
17647
+ if (spatialIndex === "quadbin") {
17648
+ const parent = getTileIndex(tile, spatialIndex);
17649
+ intersection3 = intersectTileQuadbin(
17650
+ parent,
17651
+ cellResolution,
17652
+ spatialFilter
17653
+ );
17654
+ }
17655
+ if (!intersection3)
17656
+ continue;
16596
17657
  tile.data.forEach((d) => {
16597
- if (cellsSet.has(d.id)) {
17658
+ if (intersection3 === true || intersection3.has(d.id)) {
16598
17659
  map2.set(d.id, { ...d.properties, [spatialIndexIDName]: d.id });
16599
17660
  }
16600
17661
  });
16601
17662
  }
16602
17663
  return Array.from(map2.values());
16603
17664
  }
16604
- function getResolution4(tiles3, spatialIndex) {
17665
+ function getTileIndex(tile, spatialIndex) {
17666
+ if (spatialIndex === "quadbin") {
17667
+ return tile.index.q;
17668
+ }
17669
+ return tile.id;
17670
+ }
17671
+ function getResolution5(tiles3, spatialIndex) {
16605
17672
  const data = tiles3.find((tile) => tile.data?.length)?.data;
16606
17673
  if (!data) {
16607
17674
  return;
16608
17675
  }
16609
17676
  if (spatialIndex === "quadbin") {
16610
- return Number(getResolution3(data[0].id));
16611
- }
16612
- if (spatialIndex === "h3") {
16613
- return (0, import_h3_js3.getResolution)(data[0].id);
16614
- }
16615
- }
16616
- var bboxWest = [-180, -90, 0, 90];
16617
- var bboxEast = [0, -90, 180, 90];
16618
- function getCellsCoverGeometry(geometry, spatialIndex, resolution) {
16619
- if (spatialIndex === "quadbin") {
16620
- return geometryToCells(geometry, resolution);
17677
+ return Number(getResolution4(data[0].id));
16621
17678
  }
16622
17679
  if (spatialIndex === "h3") {
16623
- return (0, import_h3_js3.polygonToCells)(
16624
- turf_bbox_clip_default(geometry, bboxWest).geometry.coordinates,
16625
- resolution,
16626
- true
16627
- ).concat(
16628
- (0, import_h3_js3.polygonToCells)(
16629
- turf_bbox_clip_default(geometry, bboxEast).geometry.coordinates,
16630
- resolution,
16631
- true
16632
- )
16633
- );
17680
+ return (0, import_h3_js6.getResolution)(data[0].id);
16634
17681
  }
16635
17682
  }
16636
17683
  function getSpatialIndex(spatialDataType) {
@@ -16663,19 +17710,24 @@ void main(void) {
16663
17710
  tiles3 = tiles3.filter(isRasterTileVisible);
16664
17711
  if (tiles3.length === 0)
16665
17712
  return [];
16666
- const tileResolution = getResolution3(tiles3[0].index.q);
17713
+ const tileResolution = getResolution4(tiles3[0].index.q);
16667
17714
  const tileBlockSize = tiles3[0].data.blockSize;
16668
17715
  const cellResolution = tileResolution + BigInt(Math.log2(tileBlockSize));
16669
- const spatialFilterCells = new Set(
16670
- geometryToCells(options.spatialFilter, cellResolution)
16671
- );
16672
17716
  const data = /* @__PURE__ */ new Map();
16673
17717
  for (const tile of tiles3) {
16674
17718
  const parent = tile.index.q;
16675
- const children = cellToChildrenSorted(parent, cellResolution);
16676
- for (let i = 0; i < children.length; i++) {
16677
- if (!spatialFilterCells.has(children[i]))
17719
+ const intersection3 = intersectTileRaster(
17720
+ parent,
17721
+ cellResolution,
17722
+ options.spatialFilter
17723
+ );
17724
+ if (intersection3 === false)
17725
+ continue;
17726
+ const tileSortedCells = cellToChildrenRaster(parent, cellResolution);
17727
+ for (let i = 0; i < tileSortedCells.length; i++) {
17728
+ if (intersection3 !== true && !intersection3.has(tileSortedCells[i])) {
16678
17729
  continue;
17730
+ }
16679
17731
  const cellData = {};
16680
17732
  let cellDataExists = false;
16681
17733
  for (const band2 in tile.data.cells.numericProps) {
@@ -16687,7 +17739,7 @@ void main(void) {
16687
17739
  }
16688
17740
  }
16689
17741
  if (cellDataExists) {
16690
- data.set(children[i], cellData);
17742
+ data.set(tileSortedCells[i], cellData);
16691
17743
  }
16692
17744
  }
16693
17745
  }
@@ -16699,17 +17751,19 @@ void main(void) {
16699
17751
  function isRasterTileVisible(tile) {
16700
17752
  return !!(tile.isVisible && tile.data?.cells?.numericProps);
16701
17753
  }
16702
- function cellToChildrenSorted(parent, resolution) {
16703
- return cellToChildren(parent, resolution).sort(
16704
- (cellA, cellB) => {
16705
- const tileA = cellToTile2(cellA);
16706
- const tileB = cellToTile2(cellB);
16707
- if (tileA.y !== tileB.y) {
16708
- return tileA.y > tileB.y ? 1 : -1;
16709
- }
16710
- return tileA.x > tileB.x ? 1 : -1;
16711
- }
16712
- );
17754
+ function cellToChildrenRaster(parent, resolution) {
17755
+ const parentTile = cellToTile2(parent);
17756
+ const childZ = Number(resolution);
17757
+ const blockSize = 2 ** (childZ - parentTile.z);
17758
+ const childBaseX = parentTile.x * blockSize;
17759
+ const childBaseY = parentTile.y * blockSize;
17760
+ const cells = [];
17761
+ for (let i = 0, il = blockSize ** 2; i < il; i++) {
17762
+ const x = childBaseX + i % blockSize;
17763
+ const y = childBaseY + Math.floor(i / blockSize);
17764
+ cells.push(tileToCell2({ x, y, z: childZ }));
17765
+ }
17766
+ return cells;
16713
17767
  }
16714
17768
  function isValidBandValue(value, nodata) {
16715
17769
  return Number.isNaN(value) ? false : nodata !== value;
@@ -16897,7 +17951,8 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
16897
17951
  headers: customHeaders = {},
16898
17952
  errorContext,
16899
17953
  maxLengthURL = DEFAULT_MAX_LENGTH_URL,
16900
- localCache
17954
+ localCache,
17955
+ signal
16901
17956
  }) {
16902
17957
  parameters = {
16903
17958
  v: V3_MINOR_VERSION,
@@ -16920,8 +17975,9 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
16920
17975
  const fetchPromise = url.length > maxLengthURL ? fetch(baseUrl, {
16921
17976
  method: "POST",
16922
17977
  body: JSON.stringify(parameters),
16923
- headers
16924
- }) : fetch(url, { headers });
17978
+ headers,
17979
+ signal
17980
+ }) : fetch(url, { headers, signal });
16925
17981
  let response;
16926
17982
  let responseJson;
16927
17983
  const jsonPromise = fetchPromise.then((_response) => {
@@ -16973,10 +18029,12 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
16973
18029
  if (isPureObject(value) || Array.isArray(value)) {
16974
18030
  baseUrl.searchParams.set(key, JSON.stringify(value));
16975
18031
  } else {
16976
- baseUrl.searchParams.set(
16977
- key,
16978
- value.toString()
16979
- );
18032
+ if (value !== null && value !== void 0) {
18033
+ baseUrl.searchParams.set(
18034
+ key,
18035
+ value.toString()
18036
+ );
18037
+ }
16980
18038
  }
16981
18039
  }
16982
18040
  return baseUrl.toString();
@@ -17015,7 +18073,7 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17015
18073
  Authorization: `Bearer ${options.accessToken}`,
17016
18074
  ...options.headers
17017
18075
  };
17018
- const parameters = { client: clientId, ...urlParameters };
18076
+ const parameters = { client: clientId, ...options.tags, ...urlParameters };
17019
18077
  const errorContext = {
17020
18078
  requestType: "Map instantiation",
17021
18079
  connection: options.connectionName,
@@ -17144,7 +18202,8 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17144
18202
  "timeseries",
17145
18203
  "range",
17146
18204
  "scatterplot",
17147
- "table"
18205
+ "table",
18206
+ "aggregations"
17148
18207
  ];
17149
18208
  var { V3 } = ApiVersion;
17150
18209
  var REQUEST_GET_MAX_URL_LENGTH = 2048;
@@ -17171,7 +18230,8 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17171
18230
  filtersLogicalOperator = "and",
17172
18231
  spatialDataType = "geo",
17173
18232
  spatialDataColumn = DEFAULT_GEO_COLUMN,
17174
- spatialFiltersMode = "intersects"
18233
+ spatialFiltersMode = "intersects",
18234
+ tags
17175
18235
  } = source;
17176
18236
  const queryParams = {
17177
18237
  type,
@@ -17180,7 +18240,8 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17180
18240
  params,
17181
18241
  queryParameters: source.queryParameters || "",
17182
18242
  filters,
17183
- filtersLogicalOperator
18243
+ filtersLogicalOperator,
18244
+ ...tags ?? {}
17184
18245
  };
17185
18246
  queryParams.spatialDataType = spatialDataType;
17186
18247
  queryParams.spatialDataColumn = spatialDataColumn;
@@ -17240,6 +18301,7 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17240
18301
  }
17241
18302
  return applicableFilters;
17242
18303
  }
18304
+ var OTHERS_CATEGORY_NAME = "_carto_others";
17243
18305
  var WidgetRemoteSource = class extends WidgetSource {
17244
18306
  _getModelSource(filters, filterOwner) {
17245
18307
  const props = this.props;
@@ -17252,7 +18314,8 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17252
18314
  filters: getApplicableFilters(filterOwner, filters || props.filters),
17253
18315
  filtersLogicalOperator: props.filtersLogicalOperator,
17254
18316
  spatialDataType: props.spatialDataType,
17255
- spatialDataColumn: props.spatialDataColumn
18317
+ spatialDataColumn: props.spatialDataColumn,
18318
+ tags: props.tags
17256
18319
  };
17257
18320
  }
17258
18321
  async getCategories(options) {
@@ -17262,13 +18325,21 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17262
18325
  filterOwner,
17263
18326
  spatialFilter,
17264
18327
  spatialFiltersMode,
18328
+ rawResult,
17265
18329
  ...params
17266
18330
  } = options;
17267
- const { column, operation: operation2, operationColumn, operationExp } = params;
18331
+ const {
18332
+ column,
18333
+ operation: operation2,
18334
+ operationColumn,
18335
+ operationExp,
18336
+ othersThreshold,
18337
+ orderBy
18338
+ } = params;
17268
18339
  if (operation2 === AggregationTypes.Custom) {
17269
18340
  assert22(operationExp, "operationExp is required for custom operation");
17270
18341
  }
17271
- return executeModel({
18342
+ const result = await executeModel({
17272
18343
  model: "category",
17273
18344
  source: {
17274
18345
  ...this.getModelSource(filters, filterOwner),
@@ -17279,10 +18350,23 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17279
18350
  column,
17280
18351
  operation: operation2,
17281
18352
  operationExp,
17282
- operationColumn: operationColumn || column
18353
+ operationColumn: operationColumn || column,
18354
+ othersThreshold,
18355
+ orderBy
17283
18356
  },
17284
18357
  opts: { signal, headers: this.props.headers }
17285
- }).then((res) => normalizeObjectKeys(res.rows));
18358
+ });
18359
+ const normalizedRows = normalizeObjectKeys(result.rows || []);
18360
+ if (rawResult) {
18361
+ return result;
18362
+ }
18363
+ if (!othersThreshold) {
18364
+ return normalizedRows;
18365
+ }
18366
+ return [
18367
+ ...normalizedRows,
18368
+ { name: OTHERS_CATEGORY_NAME, value: result?.metadata?.others }
18369
+ ];
17286
18370
  }
17287
18371
  async getFeatures(options) {
17288
18372
  const {
@@ -17500,6 +18584,72 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17500
18584
  categories: res.metadata?.categories
17501
18585
  }));
17502
18586
  }
18587
+ async getAggregations(options) {
18588
+ const {
18589
+ signal,
18590
+ filters = this.props.filters,
18591
+ filterOwner,
18592
+ spatialFilter,
18593
+ spatialFiltersMode,
18594
+ aggregations
18595
+ } = options;
18596
+ return executeModel({
18597
+ model: "aggregations",
18598
+ source: {
18599
+ ...this.getModelSource(filters, filterOwner),
18600
+ spatialFiltersMode,
18601
+ spatialFilter
18602
+ },
18603
+ params: {
18604
+ aggregations
18605
+ },
18606
+ opts: { signal, headers: this.props.headers }
18607
+ }).then((res) => ({
18608
+ rows: res.rows.map((row) => normalizeObjectKeys(row))
18609
+ }));
18610
+ }
18611
+ /** @experimental */
18612
+ async getExtent(options = {}) {
18613
+ const { signal, filters = this.props.filters, filterOwner } = options;
18614
+ const {
18615
+ type,
18616
+ data,
18617
+ apiBaseUrl,
18618
+ apiVersion,
18619
+ connectionName,
18620
+ spatialDataColumn,
18621
+ spatialDataType,
18622
+ queryParameters
18623
+ } = this.getModelSource(filters, filterOwner);
18624
+ assert22(apiVersion === "v3", "Stats API requires CARTO 3+");
18625
+ let url;
18626
+ const parameters = { filters, spatialDataType };
18627
+ if (type === "query") {
18628
+ url = `${apiBaseUrl}/${apiVersion}/stats/${connectionName}/${spatialDataColumn}`;
18629
+ parameters.q = data;
18630
+ parameters.queryParameters = queryParameters;
18631
+ } else {
18632
+ url = `${apiBaseUrl}/${apiVersion}/stats/${connectionName}/${data}/${spatialDataColumn}`;
18633
+ }
18634
+ const headers = {
18635
+ Authorization: `Bearer ${this.props.accessToken}`,
18636
+ ...this.props.headers
18637
+ };
18638
+ const errorContext = {
18639
+ requestType: "Tile stats",
18640
+ connection: connectionName,
18641
+ type
18642
+ };
18643
+ return requestWithParameters({
18644
+ baseUrl: url,
18645
+ headers,
18646
+ signal,
18647
+ errorContext,
18648
+ parameters
18649
+ }).then(({ extent: { xmin, ymin, xmax, ymax } }) => ({
18650
+ bbox: [xmin, ymin, xmax, ymax]
18651
+ }));
18652
+ }
17503
18653
  };
17504
18654
  var WidgetQuerySource = class extends WidgetRemoteSource {
17505
18655
  getModelSource(filters, filterOwner) {
@@ -17667,10 +18817,12 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17667
18817
  valuesColumns,
17668
18818
  joinOperation,
17669
18819
  keysColumn,
17670
- operation: operation2
18820
+ operation: operation2,
18821
+ othersThreshold,
18822
+ orderBy = "frequency_desc"
17671
18823
  }) {
17672
18824
  if (Array.isArray(data) && data.length === 0) {
17673
- return null;
18825
+ return { rows: null };
17674
18826
  }
17675
18827
  const groups = data.reduce((accumulator, item) => {
17676
18828
  const group2 = item[keysColumn];
@@ -17685,13 +18837,43 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
17685
18837
  return accumulator;
17686
18838
  }, /* @__PURE__ */ new Map());
17687
18839
  const targetOperation = aggregationFunctions[operation2];
17688
- if (targetOperation) {
17689
- return Array.from(groups).map(([name, value]) => ({
17690
- name,
17691
- value: targetOperation(value)
17692
- }));
18840
+ if (!targetOperation) {
18841
+ return { rows: [] };
18842
+ }
18843
+ const allCategories = Array.from(groups).map(([name, value]) => ({
18844
+ name,
18845
+ value: targetOperation(value)
18846
+ })).sort(getSorter(orderBy));
18847
+ if (othersThreshold && allCategories.length > othersThreshold) {
18848
+ const otherValue = allCategories.slice(othersThreshold).flatMap(({ name }) => groups.get(name));
18849
+ return {
18850
+ rows: allCategories,
18851
+ metadata: {
18852
+ others: targetOperation(otherValue)
18853
+ }
18854
+ };
18855
+ }
18856
+ return {
18857
+ rows: allCategories
18858
+ };
18859
+ }
18860
+ function getSorter(orderBy) {
18861
+ switch (orderBy) {
18862
+ case "frequency_asc":
18863
+ return (a, b) => a.value - b.value || nameCompare(a.name, b.name);
18864
+ case "frequency_desc":
18865
+ return (a, b) => b.value - a.value || nameCompare(a.name, b.name);
18866
+ case "alphabetical_asc":
18867
+ return (a, b) => nameCompare(a.name, b.name) || b.value - a.value;
18868
+ case "alphabetical_desc":
18869
+ return (a, b) => nameCompare(b.name, a.name) || b.value - a.value;
18870
+ }
18871
+ }
18872
+ function nameCompare(a, b) {
18873
+ if (typeof a === "number" && typeof b === "number") {
18874
+ return a - b;
17693
18875
  }
17694
- return [];
18876
+ return String(a ?? "null").localeCompare(String(b ?? "null"));
17695
18877
  }
17696
18878
  function getUTCMonday(date) {
17697
18879
  const dateCp = new Date(date);
@@ -18155,7 +19337,7 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18155
19337
  }
18156
19338
  _extractTileFeatures(spatialFilter) {
18157
19339
  const prevInputs = this._tileFeatureExtractPreviousInputs;
18158
- if (this._features.length && prevInputs.spatialFilter && booleanEqual(prevInputs.spatialFilter, spatialFilter)) {
19340
+ if (this._features.length && spatialFilterEquals(prevInputs.spatialFilter, spatialFilter)) {
18159
19341
  return;
18160
19342
  }
18161
19343
  this._features = tileFeatures({
@@ -18207,6 +19389,7 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18207
19389
  assertColumn(this._features, column);
18208
19390
  }
18209
19391
  const targetOperation = aggregationFunctions[operation2];
19392
+ assert22(targetOperation, `Unsupported aggregation operation: ${operation2}`);
18210
19393
  return {
18211
19394
  value: targetOperation(filteredFeatures, column, joinOperation)
18212
19395
  };
@@ -18244,7 +19427,10 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18244
19427
  joinOperation,
18245
19428
  filters,
18246
19429
  filterOwner,
18247
- spatialFilter
19430
+ spatialFilter,
19431
+ othersThreshold,
19432
+ orderBy = "frequency_desc",
19433
+ rawResult
18248
19434
  }) {
18249
19435
  const filteredFeatures = this._getFilteredFeatures(
18250
19436
  spatialFilter,
@@ -18255,14 +19441,25 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18255
19441
  return [];
18256
19442
  }
18257
19443
  assertColumn(this._features, column, operationColumn);
18258
- const groups = groupValuesByColumn({
19444
+ const result = groupValuesByColumn({
18259
19445
  data: filteredFeatures,
18260
19446
  valuesColumns: normalizeColumns(operationColumn || column),
18261
19447
  joinOperation,
18262
19448
  keysColumn: column,
18263
- operation: operation2
19449
+ operation: operation2,
19450
+ othersThreshold,
19451
+ orderBy
18264
19452
  });
18265
- return groups || [];
19453
+ if (rawResult) {
19454
+ return result;
19455
+ }
19456
+ if (!othersThreshold) {
19457
+ return result?.rows || [];
19458
+ }
19459
+ return [
19460
+ ...result?.rows || [],
19461
+ { name: OTHERS_CATEGORY_NAME, value: result?.metadata?.others }
19462
+ ];
18266
19463
  }
18267
19464
  async getScatter({
18268
19465
  xAxisColumn,
@@ -18391,11 +19588,47 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18391
19588
  max: aggregationFunctions.max(filteredFeatures, column)
18392
19589
  };
18393
19590
  }
19591
+ async getAggregations({
19592
+ aggregations,
19593
+ filters,
19594
+ filterOwner,
19595
+ spatialFilter
19596
+ }) {
19597
+ const filteredFeatures = this._getFilteredFeatures(
19598
+ spatialFilter,
19599
+ filters,
19600
+ filterOwner
19601
+ );
19602
+ if (!this._features.length) {
19603
+ return { rows: [] };
19604
+ }
19605
+ assert22(
19606
+ typeof aggregations !== "string",
19607
+ "Unsupported tileset SQL aggregation"
19608
+ );
19609
+ const result = {};
19610
+ const usedAliases = /* @__PURE__ */ new Set();
19611
+ for (const { column, operation: operation2, alias } of aggregations) {
19612
+ if (column && column !== "*" || operation2 !== AggregationTypes.Count) {
19613
+ assertColumn(this._features, column);
19614
+ }
19615
+ const aliasKey = alias.toLowerCase();
19616
+ assert22(!usedAliases.has(aliasKey), `Duplicate alias: ${aliasKey}`);
19617
+ usedAliases.add(aliasKey);
19618
+ const targetOperation = aggregationFunctions[operation2];
19619
+ assert22(targetOperation, `Unsupported operation: ${operation2}`);
19620
+ result[alias] = targetOperation(filteredFeatures, column);
19621
+ }
19622
+ return { rows: [result] };
19623
+ }
19624
+ /** @experimental */
19625
+ async getExtent() {
19626
+ return Promise.reject(new Error("not implemented"));
19627
+ }
18394
19628
  /****************************************************************************
18395
19629
  * INTERNAL
18396
19630
  */
18397
19631
  _getFilteredFeatures(spatialFilter, filters, filterOwner) {
18398
- assert22(spatialFilter, "spatialFilter required for tilesets");
18399
19632
  this._extractTileFeatures(spatialFilter);
18400
19633
  return applyFilters(
18401
19634
  this._features,
@@ -18419,6 +19652,13 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18419
19652
  function normalizeColumns(columns) {
18420
19653
  return Array.isArray(columns) ? columns : typeof columns === "string" ? [columns] : [];
18421
19654
  }
19655
+ function spatialFilterEquals(a, b) {
19656
+ if (a === b)
19657
+ return true;
19658
+ if (!a || !b)
19659
+ return false;
19660
+ return booleanEqual(a, b);
19661
+ }
18422
19662
  var WidgetTilesetSource = class extends WidgetSource {
18423
19663
  constructor(props) {
18424
19664
  super(props);
@@ -18617,6 +19857,22 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18617
19857
  }) {
18618
19858
  return this._executeWorkerMethod("getRange", [options], signal);
18619
19859
  }
19860
+ async getAggregations({
19861
+ signal,
19862
+ ...options
19863
+ }) {
19864
+ return this._executeWorkerMethod(
19865
+ "getAggregations",
19866
+ [options],
19867
+ signal
19868
+ );
19869
+ }
19870
+ /** @experimental */
19871
+ async getExtent() {
19872
+ return Promise.resolve({
19873
+ bbox: this.props.spatialDataBounds
19874
+ });
19875
+ }
18620
19876
  };
18621
19877
  var WidgetRasterSource = class extends WidgetTilesetSource {
18622
19878
  };
@@ -18711,25 +19967,6 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18711
19967
  const tileParams = new URL(tilejson.tiles[0]).searchParams;
18712
19968
  return tileParams.get("formatTiles") === "mvt" ? "mvt" : "binary";
18713
19969
  }
18714
- var rasterSource = async function(options) {
18715
- const { tableName, filters } = options;
18716
- const urlParameters = { name: tableName };
18717
- if (filters) {
18718
- urlParameters.filters = filters;
18719
- }
18720
- return baseSource("raster", options, urlParameters).then(
18721
- (result) => ({
18722
- ...result,
18723
- widgetSource: new WidgetRasterSource({
18724
- ...options,
18725
- tileFormat: getTileFormat(result),
18726
- spatialDataColumn: "quadbin",
18727
- spatialDataType: "quadbin",
18728
- rasterMetadata: result.raster_metadata
18729
- })
18730
- })
18731
- );
18732
- };
18733
19970
  var quadbinQuerySource = async function(options) {
18734
19971
  const {
18735
19972
  aggregationExp,
@@ -18808,6 +20045,26 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18808
20045
  })
18809
20046
  );
18810
20047
  };
20048
+ var rasterSource = async function(options) {
20049
+ const { tableName, filters } = options;
20050
+ const urlParameters = { name: tableName };
20051
+ if (filters) {
20052
+ urlParameters.filters = filters;
20053
+ }
20054
+ return baseSource("raster", options, urlParameters).then(
20055
+ (result) => ({
20056
+ ...result,
20057
+ widgetSource: new WidgetRasterSource({
20058
+ ...options,
20059
+ tileFormat: getTileFormat(result),
20060
+ spatialDataColumn: "quadbin",
20061
+ spatialDataType: "quadbin",
20062
+ spatialDataBounds: result.bounds,
20063
+ rasterMetadata: result.raster_metadata
20064
+ })
20065
+ })
20066
+ );
20067
+ };
18811
20068
  var vectorQuerySource = async function(options) {
18812
20069
  const {
18813
20070
  columns,
@@ -18898,7 +20155,8 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
18898
20155
  ...options,
18899
20156
  tileFormat: getTileFormat(result),
18900
20157
  spatialDataColumn,
18901
- spatialDataType: "geo"
20158
+ spatialDataType: "geo",
20159
+ spatialDataBounds: result.bounds
18902
20160
  })
18903
20161
  })
18904
20162
  );
@@ -19007,14 +20265,188 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19007
20265
  );
19008
20266
  });
19009
20267
  }
19010
- var basemap_styles_default = {
19011
- VOYAGER: getStyleUrl("voyager"),
19012
- POSITRON: getStyleUrl("positron"),
19013
- DARK_MATTER: getStyleUrl("dark-matter"),
19014
- VOYAGER_NOLABELS: getStyleUrl("voyager-nolabels"),
19015
- POSITRON_NOLABELS: getStyleUrl("positron-nolabels"),
19016
- DARK_MATTER_NOLABELS: getStyleUrl("dark-matter-nolabels")
19017
- };
20268
+ var basemap_styles_default = {
20269
+ VOYAGER: getStyleUrl("voyager"),
20270
+ POSITRON: getStyleUrl("positron"),
20271
+ DARK_MATTER: getStyleUrl("dark-matter"),
20272
+ VOYAGER_NOLABELS: getStyleUrl("voyager-nolabels"),
20273
+ POSITRON_NOLABELS: getStyleUrl("positron-nolabels"),
20274
+ DARK_MATTER_NOLABELS: getStyleUrl("dark-matter-nolabels")
20275
+ };
20276
+ function createVecExprEvaluator(expression) {
20277
+ try {
20278
+ const parsed = compile(expression);
20279
+ const evalFun = (context) => evaluate(parsed, context);
20280
+ evalFun.symbols = getSymbols(parsed);
20281
+ return evalFun;
20282
+ } catch {
20283
+ return null;
20284
+ }
20285
+ }
20286
+ function createResultArray(typeTemplate, length2 = typeTemplate.length) {
20287
+ return new Array(length2);
20288
+ }
20289
+ function isVecLike(a) {
20290
+ return Array.isArray(a) || ArrayBuffer.isView(a);
20291
+ }
20292
+ var createBinopVec = (scalarBinOp) => (left, right) => {
20293
+ const length2 = Math.min(left.length, right.length);
20294
+ const r = createResultArray(left, length2);
20295
+ for (let i = 0; i < length2; i++) {
20296
+ r[i] = scalarBinOp(left[i], right[i]);
20297
+ }
20298
+ return r;
20299
+ };
20300
+ var createBinopVecNum = (scalarBinOp) => (left, right) => {
20301
+ const length2 = left.length;
20302
+ const r = createResultArray(left, length2);
20303
+ for (let i = 0; i < length2; i++) {
20304
+ r[i] = scalarBinOp(left[i], right);
20305
+ }
20306
+ return r;
20307
+ };
20308
+ var createBinopNumVec = (scalarBinOp) => (left, right) => {
20309
+ const length2 = right.length;
20310
+ const r = createResultArray(right, length2);
20311
+ for (let i = 0; i < length2; i++) {
20312
+ r[i] = scalarBinOp(left, right[i]);
20313
+ }
20314
+ return r;
20315
+ };
20316
+ var createUnopVec = (scalarUnop) => (a) => {
20317
+ const length2 = a.length;
20318
+ const r = createResultArray(a, length2);
20319
+ for (let i = 0; i < length2; i++) {
20320
+ r[i] = scalarUnop(a[i]);
20321
+ }
20322
+ return r;
20323
+ };
20324
+ function mapDictValues(dict, fun) {
20325
+ return Object.keys(dict).reduce(
20326
+ (acc, key) => {
20327
+ acc[key] = fun(dict[key]);
20328
+ return acc;
20329
+ },
20330
+ {}
20331
+ );
20332
+ }
20333
+ var binopsNum = {
20334
+ "||": (a, b) => a || b,
20335
+ "&&": (a, b) => a && b,
20336
+ "|": (a, b) => a | b,
20337
+ "^": (a, b) => a ^ b,
20338
+ "&": (a, b) => a & b,
20339
+ "==": (a, b) => Number(a == b),
20340
+ "!=": (a, b) => Number(a != b),
20341
+ "===": (a, b) => Number(a === b),
20342
+ "!==": (a, b) => Number(a !== b),
20343
+ "<": (a, b) => Number(a < b),
20344
+ ">": (a, b) => Number(a > b),
20345
+ "<=": (a, b) => Number(a <= b),
20346
+ ">=": (a, b) => Number(a >= b),
20347
+ "<<": (a, b) => a << b,
20348
+ ">>": (a, b) => a >> b,
20349
+ ">>>": (a, b) => a >>> b,
20350
+ "+": (a, b) => a + b,
20351
+ "-": (a, b) => a - b,
20352
+ "*": (a, b) => a * b,
20353
+ "/": (a, b) => a / b,
20354
+ "%": (a, b) => a % b
20355
+ };
20356
+ var unopsNum = {
20357
+ "-": (a) => -a,
20358
+ "+": (a) => +a,
20359
+ "~": (a) => ~a,
20360
+ "!": (a) => Number(!a)
20361
+ };
20362
+ var binopsVector = mapDictValues(binopsNum, createBinopVec);
20363
+ var binopsNumVec = mapDictValues(binopsNum, createBinopNumVec);
20364
+ var binopsVecNum = mapDictValues(binopsNum, createBinopVecNum);
20365
+ var unopsVector = mapDictValues(unopsNum, createUnopVec);
20366
+ function getBinop(operator, left, right) {
20367
+ const isLeftVec = isVecLike(left);
20368
+ const isRightVec = isVecLike(right);
20369
+ if (isLeftVec && isRightVec) {
20370
+ return binopsVector[operator];
20371
+ } else if (isLeftVec) {
20372
+ return binopsVecNum[operator];
20373
+ } else if (isRightVec) {
20374
+ return binopsNumVec[operator];
20375
+ } else {
20376
+ return binopsNum[operator];
20377
+ }
20378
+ }
20379
+ function evaluate(_node, context) {
20380
+ const node = _node;
20381
+ switch (node.type) {
20382
+ case "BinaryExpression": {
20383
+ const left = evaluate(node.left, context);
20384
+ const right = evaluate(node.right, context);
20385
+ const binopFun = getBinop(node.operator, left, right);
20386
+ return binopFun(left, right);
20387
+ }
20388
+ case "ConditionalExpression": {
20389
+ const val = evaluate(node.test, context);
20390
+ if (isVecLike(val)) {
20391
+ const length2 = val.length;
20392
+ const consequentVal = evaluate(node.consequent, context);
20393
+ const alternateVal = evaluate(node.alternate, context);
20394
+ const r = createResultArray(val);
20395
+ for (let i = 0; i < length2; i++) {
20396
+ const entryVal = val[i] ? consequentVal : alternateVal;
20397
+ r[i] = isVecLike(entryVal) ? entryVal[i] ?? NaN : entryVal;
20398
+ }
20399
+ return r;
20400
+ } else {
20401
+ return val ? evaluate(node.consequent, context) : evaluate(node.alternate, context);
20402
+ }
20403
+ }
20404
+ case "Identifier":
20405
+ return context[node.name];
20406
+ case "Literal":
20407
+ return node.value;
20408
+ case "UnaryExpression": {
20409
+ const val = evaluate(node.argument, context);
20410
+ const unopFun = isVecLike(val) ? unopsVector[node.operator] : unopsNum[node.operator];
20411
+ return unopFun(val);
20412
+ }
20413
+ default:
20414
+ return void 0;
20415
+ }
20416
+ }
20417
+ function visit(_node, visitor) {
20418
+ const node = _node;
20419
+ visitor(node);
20420
+ switch (node.type) {
20421
+ case "BinaryExpression": {
20422
+ visit(node.left, visitor);
20423
+ visit(node.right, visitor);
20424
+ break;
20425
+ }
20426
+ case "ConditionalExpression": {
20427
+ visit(node.test, visitor);
20428
+ visit(node.consequent, visitor);
20429
+ visit(node.alternate, visitor);
20430
+ break;
20431
+ }
20432
+ case "UnaryExpression": {
20433
+ visit(node.argument, visitor);
20434
+ break;
20435
+ }
20436
+ }
20437
+ }
20438
+ function getSymbols(node) {
20439
+ const symbols = /* @__PURE__ */ new Set();
20440
+ visit(node, (node2) => {
20441
+ if (node2.type === "Identifier") {
20442
+ symbols.add(node2.name);
20443
+ }
20444
+ });
20445
+ return Array.from(symbols);
20446
+ }
20447
+ function compile(expression) {
20448
+ return jsep(expression);
20449
+ }
19018
20450
  function define_default2(constructor, factory, prototype) {
19019
20451
  constructor.prototype = factory.prototype = prototype;
19020
20452
  prototype.constructor = constructor;
@@ -19434,6 +20866,37 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19434
20866
  function formatTimestamp(value) {
19435
20867
  return String(Math.floor(new Date(value).getTime() / 1e3));
19436
20868
  }
20869
+ function roundedPow10(exp) {
20870
+ const raw = Math.pow(10, exp);
20871
+ if (exp < 0) {
20872
+ const shift = Math.pow(10, -exp);
20873
+ return Math.round(raw * shift) / shift;
20874
+ }
20875
+ return raw;
20876
+ }
20877
+ function getLog10ScaleSteps({
20878
+ min: min2,
20879
+ max: max2,
20880
+ steps
20881
+ }) {
20882
+ if (min2 === 0) {
20883
+ if (max2 === Infinity) {
20884
+ return [...Array(steps - 1)].map((_v, i) => roundedPow10(i + 1));
20885
+ }
20886
+ const maxLog = Math.log10(max2);
20887
+ const endExponent = Math.ceil(maxLog);
20888
+ const startExponent = endExponent - steps + 1;
20889
+ return [...Array(steps - 1)].map(
20890
+ (_v, i) => roundedPow10(startExponent + i)
20891
+ );
20892
+ } else {
20893
+ const minLog = Math.log10(min2);
20894
+ const startExponent = Math.ceil(minLog) === minLog ? minLog + 1 : Math.ceil(minLog);
20895
+ return [...Array(steps - 1)].map(
20896
+ (_v, i) => roundedPow10(startExponent + i)
20897
+ );
20898
+ }
20899
+ }
19437
20900
  var SCALE_FUNCS = {
19438
20901
  linear: linear2,
19439
20902
  ordinal,
@@ -19448,7 +20911,19 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19448
20911
  function identity2(v2) {
19449
20912
  return v2;
19450
20913
  }
20914
+ var hexToRGB = (c) => {
20915
+ const { r, g, b } = rgb2(c);
20916
+ return [r, g, b];
20917
+ };
20918
+ var rgbToHex = (c) => {
20919
+ const [r, g, b] = c;
20920
+ const rStr = r.toString(16).padStart(2, "0");
20921
+ const gStr = g.toString(16).padStart(2, "0");
20922
+ const bStr = b.toString(16).padStart(2, "0");
20923
+ return `#${rStr}${gStr}${bStr}`.toUpperCase();
20924
+ };
19451
20925
  var UNKNOWN_COLOR = "#868d91";
20926
+ var UNKNOWN_COLOR_RGB = hexToRGB(UNKNOWN_COLOR);
19452
20927
  var OPACITY_MAP = {
19453
20928
  getFillColor: "opacity",
19454
20929
  getLineColor: "strokeOpacity",
@@ -19481,6 +20956,12 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19481
20956
  wireframe: "wireframe"
19482
20957
  }
19483
20958
  };
20959
+ var rasterPropsMap = {
20960
+ isVisible: "visible",
20961
+ visConfig: {
20962
+ opacity: "opacity"
20963
+ }
20964
+ };
19484
20965
  var customMarkersPropsMap = {
19485
20966
  color: "getIconColor",
19486
20967
  visConfig: {
@@ -19524,6 +21005,12 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19524
21005
  `Outdated layer type: ${type}. Please open map in CARTO Builder to automatically migrate.`
19525
21006
  );
19526
21007
  }
21008
+ if (type === "raster") {
21009
+ return {
21010
+ propMap: rasterPropsMap,
21011
+ defaultProps: {}
21012
+ };
21013
+ }
19527
21014
  let basePropMap = sharedPropMap;
19528
21015
  if (config2.visConfig?.customMarkers) {
19529
21016
  basePropMap = mergePropMaps(basePropMap, customMarkersPropsMap);
@@ -19544,27 +21031,32 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19544
21031
  }
19545
21032
  function domainFromAttribute(attribute, scaleType, scaleLength) {
19546
21033
  if (scaleType === "ordinal" || scaleType === "point") {
21034
+ if (!attribute.categories) {
21035
+ return [0, 1];
21036
+ }
19547
21037
  return attribute.categories.map((c) => c.category).filter((c) => c !== void 0 && c !== null);
19548
21038
  }
19549
21039
  if (scaleType === "quantile" && attribute.quantiles) {
19550
- return attribute.quantiles.global ? attribute.quantiles.global[scaleLength] : attribute.quantiles[scaleLength];
21040
+ return "global" in attribute.quantiles ? attribute.quantiles.global[scaleLength] : attribute.quantiles[scaleLength];
19551
21041
  }
19552
21042
  let { min: min2 } = attribute;
19553
21043
  if (scaleType === "log" && min2 === 0) {
19554
21044
  min2 = 1e-5;
19555
21045
  }
19556
- return [min2, attribute.max];
21046
+ return [min2 ?? 0, attribute.max ?? 1];
19557
21047
  }
19558
21048
  function calculateDomain(data, name, scaleType, scaleLength) {
19559
21049
  if (data.tilestats) {
19560
21050
  const { attributes } = data.tilestats.layers[0];
19561
21051
  const attribute = attributes.find((a) => a.attribute === name);
19562
- return domainFromAttribute(attribute, scaleType, scaleLength);
21052
+ if (attribute) {
21053
+ return domainFromAttribute(attribute, scaleType, scaleLength);
21054
+ }
19563
21055
  }
19564
21056
  return [0, 1];
19565
21057
  }
19566
21058
  function normalizeAccessor(accessor, data) {
19567
- if (data.features || data.tilestats) {
21059
+ if (data.features || data.tilestats || data.raster_metadata) {
19568
21060
  return (object, info) => {
19569
21061
  if (object) {
19570
21062
  return accessor(object.properties || object.__source.object.properties);
@@ -19597,46 +21089,72 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19597
21089
  return keys;
19598
21090
  }
19599
21091
  function getColorAccessor({ name, colorColumn }, scaleType, { aggregation, range: range2 }, opacity, data) {
19600
- const scale2 = calculateLayerScale(
21092
+ const { scale: scale2, domain } = calculateLayerScale(
19601
21093
  colorColumn || name,
19602
- scaleType,
21094
+ colorColumn ? "identity" : scaleType,
19603
21095
  range2,
19604
21096
  data
19605
21097
  );
19606
21098
  const alpha = opacityToAlpha(opacity);
19607
- let accessorKeys = getAccessorKeys(name, aggregation);
21099
+ let accessorKeys = getAccessorKeys(colorColumn || name, aggregation);
19608
21100
  const accessor = (properties) => {
19609
21101
  if (!(accessorKeys[0] in properties)) {
19610
21102
  accessorKeys = findAccessorKey(accessorKeys, properties);
19611
21103
  }
19612
21104
  const propertyValue = properties[accessorKeys[0]];
19613
- const { r, g, b } = rgb2(scale2(propertyValue));
19614
- return [r, g, b, propertyValue === null ? 0 : alpha];
21105
+ const scaled = scale2(propertyValue);
21106
+ const rgb22 = typeof scaled === "string" ? hexToRGB(scaled) : scaled;
21107
+ return [...rgb22, propertyValue === null ? 0 : alpha];
21108
+ };
21109
+ return {
21110
+ accessor: normalizeAccessor(accessor, data),
21111
+ scaleDomain: scale2.domain(),
21112
+ domain,
21113
+ range: (scale2.range() || []).map(rgbToHex)
19615
21114
  };
19616
- return { accessor: normalizeAccessor(accessor, data), scale: scale2 };
19617
21115
  }
19618
21116
  function calculateLayerScale(name, scaleType, range2, data) {
19619
- const scale2 = SCALE_FUNCS[scaleType]();
19620
- let domain = [];
19621
- let scaleColor = [];
21117
+ let scaleDomain;
21118
+ let scaleColors = [];
21119
+ const { colors } = range2;
21120
+ const domain = calculateDomain(data, name, scaleType, colors.length);
19622
21121
  if (scaleType !== "identity") {
19623
- const { colorMap, colors } = range2;
19624
- if (Array.isArray(colorMap)) {
21122
+ if (range2.colorMap) {
21123
+ const { colorMap } = range2;
21124
+ scaleDomain = [];
19625
21125
  colorMap.forEach(([value, color22]) => {
19626
- domain.push(value);
19627
- scaleColor.push(color22);
21126
+ scaleDomain.push(value);
21127
+ scaleColors.push(color22);
19628
21128
  });
19629
21129
  } else {
19630
- domain = calculateDomain(data, name, scaleType, colors.length);
19631
- scaleColor = colors;
19632
- }
19633
- if (scaleType === "ordinal") {
19634
- domain = domain.slice(0, scaleColor.length);
21130
+ if (scaleType === "custom" && range2.uiCustomScaleType === "logarithmic") {
21131
+ const [min2, max2] = domain;
21132
+ scaleDomain = getLog10ScaleSteps({
21133
+ min: min2,
21134
+ max: max2,
21135
+ steps: colors.length
21136
+ });
21137
+ scaleColors = colors;
21138
+ } else {
21139
+ scaleColors = colors;
21140
+ }
19635
21141
  }
19636
21142
  }
21143
+ return {
21144
+ scale: createColorScale(
21145
+ scaleType,
21146
+ scaleDomain || domain,
21147
+ scaleColors.map(hexToRGB),
21148
+ UNKNOWN_COLOR_RGB
21149
+ ),
21150
+ domain
21151
+ };
21152
+ }
21153
+ function createColorScale(scaleType, domain, range2, unknown) {
21154
+ const scale2 = SCALE_FUNCS[scaleType]();
19637
21155
  scale2.domain(domain);
19638
- scale2.range(scaleColor);
19639
- scale2.unknown(UNKNOWN_COLOR);
21156
+ scale2.range(range2);
21157
+ scale2.unknown(unknown);
19640
21158
  return scale2;
19641
21159
  }
19642
21160
  var FALLBACK_ICON = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNTAiLz4NCjwvc3ZnPg==";
@@ -19686,9 +21204,13 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19686
21204
  }
19687
21205
  function getSizeAccessor({ name }, scaleType, aggregation, range2, data) {
19688
21206
  const scale2 = scaleType ? SCALE_FUNCS[scaleType]() : identity2;
19689
- if (scaleType) {
21207
+ let domain = [];
21208
+ if (scaleType && range2) {
19690
21209
  if (aggregation !== AggregationTypes.Count) {
19691
- scale2.domain(calculateDomain(data, name, scaleType));
21210
+ domain = calculateDomain(data, name, scaleType);
21211
+ scale2.domain(domain);
21212
+ } else {
21213
+ domain = scale2.domain();
19692
21214
  }
19693
21215
  scale2.range(range2);
19694
21216
  }
@@ -19700,7 +21222,12 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19700
21222
  const propertyValue = properties[accessorKeys[0]];
19701
21223
  return scale2(propertyValue);
19702
21224
  };
19703
- return { accessor: normalizeAccessor(accessor, data), scale: scale2 };
21225
+ return {
21226
+ accessor: normalizeAccessor(accessor, data),
21227
+ domain,
21228
+ scaleDomain: domain,
21229
+ range: range2
21230
+ };
19704
21231
  }
19705
21232
  var FORMATS = {
19706
21233
  date: formatDate,
@@ -19757,12 +21284,399 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19757
21284
  return 11;
19758
21285
  return 11;
19759
21286
  }
21287
+ var UNKNOWN_COLOR2 = [134, 141, 145];
21288
+ var RASTER_COLOR_BANDS = ["red", "green", "blue"];
21289
+ function getHasDataPredicate(noData) {
21290
+ if (noData === "nan") {
21291
+ return (v2) => !isNaN(v2);
21292
+ }
21293
+ if (typeof noData === "string") {
21294
+ noData = parseFloat(noData);
21295
+ }
21296
+ if (typeof noData === "number") {
21297
+ return (v2) => v2 !== noData && !isNaN(v2);
21298
+ }
21299
+ return () => true;
21300
+ }
21301
+ function createRasterColumnLayerDataTransform(transform) {
21302
+ return (data) => {
21303
+ if (!data || !("data" in data) || !data?.data?.cells?.numericProps) {
21304
+ return data;
21305
+ }
21306
+ return transform(data);
21307
+ };
21308
+ }
21309
+ function createEvaluationContext(numericProps, noData) {
21310
+ const hasData = getHasDataPredicate(noData);
21311
+ const bands = Object.entries(numericProps).map(([bandName, { value }]) => ({
21312
+ bandName,
21313
+ values: value,
21314
+ copied: false
21315
+ }));
21316
+ const length2 = bands[0].values.length;
21317
+ for (let i = 0; i < length2; i++) {
21318
+ let hasSomeData = false;
21319
+ for (let j = 0; j < bands.length; j++) {
21320
+ hasSomeData = hasSomeData || hasData(bands[j].values[i]);
21321
+ }
21322
+ if (!hasSomeData) {
21323
+ for (let j = 0; j < bands.length; j++) {
21324
+ if (!bands[j].copied) {
21325
+ bands[j].copied = true;
21326
+ bands[j].values = Array.from(bands[j].values);
21327
+ }
21328
+ bands[j].values[i] = NaN;
21329
+ }
21330
+ }
21331
+ }
21332
+ const context = bands.reduce(
21333
+ (agg, { bandName, values }) => {
21334
+ agg[bandName] = values;
21335
+ return agg;
21336
+ },
21337
+ {}
21338
+ );
21339
+ return context;
21340
+ }
21341
+ function createExprDataTransform({
21342
+ colorBand,
21343
+ rasterMetadata,
21344
+ usedSymbols
21345
+ }) {
21346
+ if (!colorBand || !colorBand.type || colorBand.type === "none") {
21347
+ return void 0;
21348
+ }
21349
+ const expr = colorBand?.type === "expression" ? colorBand.value : void 0;
21350
+ const vecExprEvaluator = expr ? createVecExprEvaluator(expr) : void 0;
21351
+ const dataTransform = createRasterColumnLayerDataTransform(
21352
+ (dataWrapped) => {
21353
+ const data = dataWrapped.data;
21354
+ if (expr) {
21355
+ const cachedResult = dataWrapped.customExpressionResults?.[expr];
21356
+ if (cachedResult) {
21357
+ return dataWrapped;
21358
+ }
21359
+ }
21360
+ let context = dataWrapped.expressionEvalContext;
21361
+ if (!context) {
21362
+ const usedNumericProps = usedSymbols.reduce(
21363
+ (acc, symbol) => {
21364
+ acc[symbol] = data.cells.numericProps[symbol];
21365
+ return acc;
21366
+ },
21367
+ {}
21368
+ );
21369
+ context = createEvaluationContext(
21370
+ usedNumericProps,
21371
+ rasterMetadata.nodata
21372
+ );
21373
+ dataWrapped = {
21374
+ ...dataWrapped,
21375
+ expressionEvalContext: context
21376
+ };
21377
+ }
21378
+ if (!vecExprEvaluator || !expr)
21379
+ return dataWrapped;
21380
+ const evalResult = vecExprEvaluator(context);
21381
+ return {
21382
+ ...dataWrapped,
21383
+ customExpressionResults: {
21384
+ ...dataWrapped.customExpressionResults,
21385
+ [expr]: evalResult
21386
+ }
21387
+ };
21388
+ }
21389
+ );
21390
+ return dataTransform;
21391
+ }
21392
+ function combineDataTransforms(dataTransforms) {
21393
+ const actualTransforms = dataTransforms.filter((v2) => v2);
21394
+ if (actualTransforms.length === 0)
21395
+ return void 0;
21396
+ if (actualTransforms.length === 1)
21397
+ return actualTransforms[0];
21398
+ return (data) => actualTransforms.reduce(
21399
+ (aggData, transformFun) => transformFun(aggData),
21400
+ data
21401
+ );
21402
+ }
21403
+ function createRgbToColorBufferDataTransform({
21404
+ bandDefs,
21405
+ attribute
21406
+ }) {
21407
+ return createRasterColumnLayerDataTransform(
21408
+ (dataWrapped) => {
21409
+ const length2 = dataWrapped.length;
21410
+ const getBandBufferOrValue = (colorBand) => {
21411
+ if (colorBand?.type === "expression") {
21412
+ return dataWrapped.customExpressionResults?.[colorBand.value];
21413
+ }
21414
+ if (colorBand?.type === "band") {
21415
+ return dataWrapped.expressionEvalContext?.[colorBand.value];
21416
+ }
21417
+ return 0;
21418
+ };
21419
+ const red = getBandBufferOrValue(bandDefs.red);
21420
+ const green = getBandBufferOrValue(bandDefs.green);
21421
+ const blue = getBandBufferOrValue(bandDefs.blue);
21422
+ const colorBuffer = new Uint8Array(length2 * 4);
21423
+ for (let inputIndex = 0, outputIndex = 0; inputIndex < length2; inputIndex++, outputIndex += 4) {
21424
+ const redRaw = typeof red === "number" ? red : red ? red[inputIndex] : NaN;
21425
+ const greenRaw = typeof green === "number" ? green : green ? green[inputIndex] : NaN;
21426
+ const blueRaw = typeof blue === "number" ? blue : blue ? blue[inputIndex] : NaN;
21427
+ if (isNaN(redRaw) && isNaN(greenRaw) && isNaN(blueRaw)) {
21428
+ bufferSetRgba(colorBuffer, outputIndex, 0, 0, 0, 0);
21429
+ } else {
21430
+ bufferSetRgba(
21431
+ colorBuffer,
21432
+ outputIndex,
21433
+ redRaw,
21434
+ greenRaw,
21435
+ blueRaw,
21436
+ 255
21437
+ );
21438
+ }
21439
+ }
21440
+ dataWrapped.customExpressionResults = void 0;
21441
+ dataWrapped.expressionEvalContext = void 0;
21442
+ return {
21443
+ ...dataWrapped,
21444
+ attributes: {
21445
+ [attribute]: colorBuffer
21446
+ }
21447
+ };
21448
+ }
21449
+ );
21450
+ }
21451
+ function getUsedSymbols(colorBands) {
21452
+ return Array.from(
21453
+ colorBands.reduce((symbols, band2) => {
21454
+ if (band2.type === "expression") {
21455
+ const expressionSymbols = createVecExprEvaluator(band2.value)?.symbols || [];
21456
+ expressionSymbols.forEach((symbol) => symbols.add(symbol));
21457
+ }
21458
+ if (band2.type === "band") {
21459
+ symbols.add(band2.value);
21460
+ }
21461
+ return symbols;
21462
+ }, /* @__PURE__ */ new Set())
21463
+ );
21464
+ }
21465
+ function getRasterTileLayerStylePropsRgb({
21466
+ layerConfig,
21467
+ rasterMetadata,
21468
+ visualChannels
21469
+ }) {
21470
+ const { visConfig } = layerConfig;
21471
+ const { colorBands } = visConfig;
21472
+ const bandDefs = {
21473
+ red: colorBands?.find((band2) => band2.band === "red"),
21474
+ green: colorBands?.find((band2) => band2.band === "green"),
21475
+ blue: colorBands?.find((band2) => band2.band === "blue")
21476
+ };
21477
+ const rgbToInstanceFillColorsDataTransform = createRgbToColorBufferDataTransform({
21478
+ bandDefs,
21479
+ attribute: "instanceFillColors"
21480
+ });
21481
+ const usedSymbols = colorBands ? getUsedSymbols(colorBands) : [];
21482
+ const bandTransforms = RASTER_COLOR_BANDS.map(
21483
+ (band2) => createExprDataTransform({
21484
+ colorBand: bandDefs[band2],
21485
+ rasterMetadata,
21486
+ usedSymbols
21487
+ })
21488
+ );
21489
+ const combinedDataTransform = combineDataTransforms([
21490
+ ...bandTransforms,
21491
+ rgbToInstanceFillColorsDataTransform
21492
+ ]);
21493
+ return {
21494
+ dataTransform: combinedDataTransform,
21495
+ updateTriggers: getRasterTileLayerUpdateTriggers({
21496
+ layerConfig,
21497
+ visualChannels
21498
+ })
21499
+ };
21500
+ }
21501
+ function createBandColorScaleDataTransform({
21502
+ bandName,
21503
+ scaleFun,
21504
+ nodata,
21505
+ attribute
21506
+ }) {
21507
+ const hasData = getHasDataPredicate(nodata);
21508
+ return createRasterColumnLayerDataTransform(
21509
+ (dataWrapped) => {
21510
+ const length2 = dataWrapped.length;
21511
+ const bandBuffer = dataWrapped.data.cells.numericProps[bandName].value;
21512
+ const colorBuffer = new Uint8Array(length2 * 4);
21513
+ for (let i = 0; i < length2; i++) {
21514
+ const rawValue = bandBuffer[i];
21515
+ if (!hasData(rawValue)) {
21516
+ bufferSetRgba(colorBuffer, i * 4, 0, 0, 0, 0);
21517
+ } else {
21518
+ const colorRgb = scaleFun(rawValue);
21519
+ bufferSetRgba(
21520
+ colorBuffer,
21521
+ i * 4,
21522
+ colorRgb[0],
21523
+ colorRgb[1],
21524
+ colorRgb[2],
21525
+ 255
21526
+ );
21527
+ }
21528
+ }
21529
+ return {
21530
+ ...dataWrapped,
21531
+ attributes: {
21532
+ [attribute]: colorBuffer
21533
+ }
21534
+ };
21535
+ }
21536
+ );
21537
+ }
21538
+ function domainFromRasterMetadataBand(band2, scaleType, colorRange) {
21539
+ if (scaleType === "ordinal") {
21540
+ return colorRange.colorMap?.map(([value]) => value) || [];
21541
+ }
21542
+ if (scaleType === "custom") {
21543
+ if (colorRange.uiCustomScaleType === "logarithmic") {
21544
+ return getLog10ScaleSteps({
21545
+ min: band2.stats.min,
21546
+ max: band2.stats.max,
21547
+ steps: colorRange.colors.length
21548
+ });
21549
+ } else {
21550
+ return colorRange.colorMap?.map(([value]) => value) || [];
21551
+ }
21552
+ }
21553
+ const scaleLength = colorRange.colors.length;
21554
+ if (scaleType === "quantile") {
21555
+ const quantiles = band2.stats.quantiles?.[scaleLength];
21556
+ if (!quantiles) {
21557
+ return [0, 1];
21558
+ }
21559
+ return [band2.stats.min, ...quantiles, band2.stats.max];
21560
+ }
21561
+ return [band2.stats.min, band2.stats.max];
21562
+ }
21563
+ function getRasterTileLayerStylePropsScaledBand({
21564
+ layerConfig,
21565
+ rasterMetadata,
21566
+ visualChannels
21567
+ }) {
21568
+ const { visConfig } = layerConfig;
21569
+ const { colorField } = visualChannels;
21570
+ const { rasterStyleType } = visConfig;
21571
+ const colorRange = rasterStyleType === "ColorRange" ? visConfig.colorRange : visConfig.uniqueValuesColorRange;
21572
+ const scaleType = rasterStyleType === "ColorRange" ? visualChannels.colorScale : "ordinal";
21573
+ const bandInfo = rasterMetadata.bands.find(
21574
+ (band2) => band2.name === colorField?.name
21575
+ );
21576
+ if (!colorField?.name || !scaleType || !colorRange || !bandInfo) {
21577
+ return {};
21578
+ }
21579
+ const domain = domainFromRasterMetadataBand(bandInfo, scaleType, colorRange);
21580
+ const scaleFun = createColorScale(
21581
+ scaleType,
21582
+ domain,
21583
+ colorRange.colors.map(hexToRGB2),
21584
+ UNKNOWN_COLOR2
21585
+ );
21586
+ const bandColorScaleDataTransform = createBandColorScaleDataTransform({
21587
+ bandName: bandInfo.name,
21588
+ scaleFun,
21589
+ nodata: bandInfo?.nodata ?? rasterMetadata.nodata,
21590
+ attribute: "instanceFillColors"
21591
+ });
21592
+ return {
21593
+ dataTransform: bandColorScaleDataTransform,
21594
+ updateTriggers: getRasterTileLayerUpdateTriggers({
21595
+ layerConfig,
21596
+ visualChannels
21597
+ })
21598
+ };
21599
+ }
21600
+ function getRasterTileLayerUpdateTriggers({
21601
+ layerConfig,
21602
+ visualChannels
21603
+ }) {
21604
+ const { visConfig } = layerConfig;
21605
+ const { rasterStyleType } = visConfig;
21606
+ const getFillColorUpdateTriggers = {
21607
+ rasterStyleType
21608
+ };
21609
+ if (rasterStyleType === "ColorRange") {
21610
+ getFillColorUpdateTriggers.colorRange = visConfig.colorRange?.colors;
21611
+ getFillColorUpdateTriggers.colorMap = visConfig.colorRange?.colorMap;
21612
+ getFillColorUpdateTriggers.colorScale = visualChannels.colorScale;
21613
+ getFillColorUpdateTriggers.colorFieldId = visualChannels.colorField?.name;
21614
+ } else if (rasterStyleType === "UniqueValues") {
21615
+ getFillColorUpdateTriggers.colorMap = visConfig.uniqueValuesColorRange?.colorMap;
21616
+ getFillColorUpdateTriggers.colorFieldId = visualChannels.colorField?.name;
21617
+ } else if (rasterStyleType === "Rgb") {
21618
+ getFillColorUpdateTriggers.colorBands = visConfig.colorBands;
21619
+ }
21620
+ return {
21621
+ getFillColor: getFillColorUpdateTriggers
21622
+ };
21623
+ }
21624
+ function bufferSetRgba(target, index2, r, g, b, a) {
21625
+ target[index2 + 0] = r;
21626
+ target[index2 + 1] = g;
21627
+ target[index2 + 2] = b;
21628
+ target[index2 + 3] = a;
21629
+ }
21630
+ function hexToRGB2(hexColor) {
21631
+ const r = parseInt(hexColor.slice(1, 3), 16);
21632
+ const g = parseInt(hexColor.slice(3, 5), 16);
21633
+ const b = parseInt(hexColor.slice(5, 7), 16);
21634
+ return [r, g, b];
21635
+ }
21636
+ function getLayerDescriptor({
21637
+ mapConfig,
21638
+ layer,
21639
+ dataset
21640
+ }) {
21641
+ const { filters, visState } = mapConfig;
21642
+ const { layerBlending, interactionConfig } = visState;
21643
+ const { id: id5, type, config: config2, visualChannels } = layer;
21644
+ const { data, id: datasetId } = dataset;
21645
+ const { propMap, defaultProps: defaultProps22 } = getLayerProps(type, config2, dataset);
21646
+ const styleProps = createStyleProps(config2, propMap);
21647
+ const { channelProps, scales } = createChannelProps(
21648
+ id5,
21649
+ type,
21650
+ config2,
21651
+ visualChannels,
21652
+ data,
21653
+ dataset
21654
+ );
21655
+ const layerDescriptor = {
21656
+ type,
21657
+ filters: isEmptyObject(filters) || isRemoteCalculationSupported(dataset) ? void 0 : filters[datasetId],
21658
+ props: {
21659
+ id: id5,
21660
+ data,
21661
+ ...defaultProps22,
21662
+ ...createInteractionProps(interactionConfig),
21663
+ ...styleProps,
21664
+ ...channelProps,
21665
+ ...createParametersProp(layerBlending, styleProps.parameters || {}),
21666
+ // Must come after style
21667
+ ...createLoadOptions(data.accessToken)
21668
+ },
21669
+ scales
21670
+ };
21671
+ return layerDescriptor;
21672
+ }
19760
21673
  function parseMap(json) {
19761
21674
  const { keplerMapConfig, datasets, token } = json;
19762
21675
  assert22(keplerMapConfig.version === "v1", "Only support Kepler v1");
19763
- const config2 = keplerMapConfig.config;
19764
- const { filters, mapState, mapStyle, popupSettings, legendSettings } = config2;
19765
- const { layers, layerBlending, interactionConfig } = config2.visState;
21676
+ const mapConfig = keplerMapConfig.config;
21677
+ const { mapState, mapStyle, popupSettings, legendSettings, visState } = mapConfig;
21678
+ const { layers } = visState;
21679
+ const layersReverse = [...layers].reverse();
19766
21680
  return {
19767
21681
  id: json.id,
19768
21682
  title: json.title,
@@ -19775,45 +21689,19 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19775
21689
  popupSettings,
19776
21690
  legendSettings,
19777
21691
  token,
19778
- layers: layers.reverse().map(({ id: id5, type, config: config3, visualChannels }) => {
21692
+ layers: layersReverse.map((layer) => {
19779
21693
  try {
19780
- const { dataId } = config3;
21694
+ const { dataId } = layer.config;
19781
21695
  const dataset = datasets.find(
19782
21696
  (d) => d.id === dataId
19783
21697
  );
19784
21698
  assert22(dataset, `No dataset matching dataId: ${dataId}`);
19785
- const { data } = dataset;
19786
- assert22(data, `No data loaded for dataId: ${dataId}`);
19787
- const { propMap, defaultProps: defaultProps22 } = getLayerProps(type, config3, dataset);
19788
- const styleProps = createStyleProps(config3, propMap);
19789
- const { channelProps, scales } = createChannelProps(
19790
- id5,
19791
- type,
19792
- config3,
19793
- visualChannels,
19794
- data,
21699
+ const layerDescriptor = getLayerDescriptor({
21700
+ mapConfig,
21701
+ layer,
19795
21702
  dataset
19796
- );
19797
- const layer = {
19798
- type,
19799
- filters: isEmptyObject(filters) || isRemoteCalculationSupported(dataset) ? void 0 : filters[dataId],
19800
- props: {
19801
- id: id5,
19802
- data,
19803
- ...defaultProps22,
19804
- ...createInteractionProps(interactionConfig),
19805
- ...styleProps,
19806
- ...channelProps,
19807
- ...createParametersProp(
19808
- layerBlending,
19809
- styleProps.parameters || {}
19810
- ),
19811
- // Must come after style
19812
- ...createLoadOptions(token)
19813
- },
19814
- scales
19815
- };
19816
- return layer;
21703
+ });
21704
+ return layerDescriptor;
19817
21705
  } catch (e) {
19818
21706
  console.error(e.message);
19819
21707
  return void 0;
@@ -19878,43 +21766,63 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19878
21766
  result.highlightColor = config2.visConfig.enable3d ? [255, 255, 255, 60] : [252, 242, 26, 255];
19879
21767
  return result;
19880
21768
  }
19881
- function domainAndRangeFromScale(scale2) {
19882
- return {
19883
- domain: scale2.domain(),
19884
- range: scale2.range()
19885
- };
19886
- }
19887
21769
  function createChannelProps(id5, layerType, config2, visualChannels, data, dataset) {
19888
- const {
19889
- colorField,
19890
- colorScale,
19891
- radiusField,
19892
- radiusScale,
19893
- strokeColorField,
19894
- strokeColorScale,
19895
- weightField
19896
- } = visualChannels;
19897
- const { heightField, heightScale } = visualChannels;
21770
+ if (layerType === "raster") {
21771
+ const rasterMetadata = data.raster_metadata;
21772
+ if (!rasterMetadata) {
21773
+ return {
21774
+ channelProps: {},
21775
+ scales: {}
21776
+ };
21777
+ }
21778
+ const rasterStyleType = config2.visConfig.rasterStyleType;
21779
+ if (rasterStyleType === "Rgb") {
21780
+ return {
21781
+ channelProps: getRasterTileLayerStylePropsRgb({
21782
+ layerConfig: config2,
21783
+ rasterMetadata,
21784
+ visualChannels
21785
+ }),
21786
+ scales: {}
21787
+ // TODO
21788
+ };
21789
+ } else {
21790
+ return {
21791
+ channelProps: getRasterTileLayerStylePropsScaledBand({
21792
+ layerConfig: config2,
21793
+ visualChannels,
21794
+ rasterMetadata
21795
+ }),
21796
+ scales: {
21797
+ // TODO
21798
+ }
21799
+ };
21800
+ }
21801
+ }
19898
21802
  const { textLabel, visConfig } = config2;
19899
21803
  const result = {};
21804
+ const updateTriggers = {};
19900
21805
  const scales = {};
19901
- if (colorField) {
19902
- const { colorAggregation: aggregation, colorRange: range2 } = visConfig;
19903
- const { accessor, scale: scale2 } = getColorAccessor(
19904
- colorField,
19905
- colorScale,
19906
- { aggregation, range: range2 },
19907
- visConfig.opacity,
19908
- data
19909
- );
19910
- result.getFillColor = accessor;
19911
- scales.fillColor = {
19912
- field: colorField,
19913
- type: colorScale,
19914
- ...domainAndRangeFromScale(scale2)
19915
- };
19916
- } else if (visConfig.filled) {
19917
- scales.fillColor = {};
21806
+ {
21807
+ const { colorField, colorScale } = visualChannels;
21808
+ const { colorRange, colorAggregation } = visConfig;
21809
+ if (colorField && colorScale && colorRange) {
21810
+ const { accessor, ...scaleProps } = getColorAccessor(
21811
+ colorField,
21812
+ colorScale,
21813
+ { aggregation: colorAggregation, range: colorRange },
21814
+ visConfig.opacity,
21815
+ data
21816
+ );
21817
+ result.getFillColor = accessor;
21818
+ scales.fillColor = updateTriggers.getFillColor = {
21819
+ field: colorField,
21820
+ type: colorScale,
21821
+ ...scaleProps
21822
+ };
21823
+ } else {
21824
+ scales.fillColor = {};
21825
+ }
19918
21826
  }
19919
21827
  if (layerType === "clusterTile") {
19920
21828
  const aggregationExpAlias = getDefaultAggregationExpColumnAliasForLayerType(
@@ -19927,6 +21835,7 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19927
21835
  result.getWeight = (d) => {
19928
21836
  return d.properties[aggregationExpAlias];
19929
21837
  };
21838
+ updateTriggers.getWeight = aggregationExpAlias;
19930
21839
  result.getPointRadius = (d, info) => {
19931
21840
  return calculateClusterRadius(
19932
21841
  d.properties,
@@ -19935,11 +21844,16 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19935
21844
  aggregationExpAlias
19936
21845
  );
19937
21846
  };
21847
+ updateTriggers.getPointRadius = {
21848
+ aggregationExpAlias,
21849
+ radiusRange: visConfig.radiusRange
21850
+ };
19938
21851
  result.textCharacterSet = "auto";
19939
21852
  result.textFontFamily = "Inter, sans";
19940
21853
  result.textFontSettings = { sdf: true };
19941
21854
  result.textFontWeight = 600;
19942
21855
  result.getText = (d) => TEXT_NUMBER_FORMATTER.format(d.properties[aggregationExpAlias]);
21856
+ updateTriggers.getText = aggregationExpAlias;
19943
21857
  result.getTextColor = config2.textLabel[TEXT_LABEL_INDEX].color;
19944
21858
  result.textOutlineColor = [
19945
21859
  ...config2.textLabel[TEXT_LABEL_INDEX].outlineColor,
@@ -19956,68 +21870,107 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
19956
21870
  );
19957
21871
  return calculateClusterTextFontSize(radius);
19958
21872
  };
19959
- }
19960
- if (radiusField) {
19961
- const { accessor, scale: scale2 } = getSizeAccessor(
19962
- radiusField,
19963
- radiusScale,
19964
- visConfig.sizeAggregation,
19965
- visConfig.radiusRange || visConfig.sizeRange,
19966
- data
19967
- );
19968
- result.getPointRadius = accessor;
19969
- scales.pointRadius = {
19970
- field: radiusField,
19971
- type: radiusScale || "identity",
19972
- ...domainAndRangeFromScale(scale2)
21873
+ updateTriggers.getTextSize = {
21874
+ aggregationExpAlias,
21875
+ radiusRange: visConfig.radiusRange
19973
21876
  };
19974
21877
  }
19975
- if (strokeColorField) {
19976
- const opacity = visConfig.strokeOpacity !== void 0 ? visConfig.strokeOpacity : 1;
19977
- const { strokeColorAggregation: aggregation, strokeColorRange: range2 } = visConfig;
19978
- const { accessor, scale: scale2 } = getColorAccessor(
19979
- strokeColorField,
19980
- strokeColorScale,
19981
- { aggregation, range: range2 },
19982
- opacity,
19983
- data
19984
- );
19985
- result.getLineColor = accessor;
19986
- scales.lineColor = {
19987
- field: strokeColorField,
19988
- type: strokeColorScale,
19989
- ...domainAndRangeFromScale(scale2)
19990
- };
21878
+ {
21879
+ const radiusRange = visConfig.radiusRange;
21880
+ const { radiusField, radiusScale } = visualChannels;
21881
+ if (radiusField && radiusRange && radiusScale) {
21882
+ const { accessor, ...scaleProps } = getSizeAccessor(
21883
+ radiusField,
21884
+ radiusScale,
21885
+ visConfig.radiusAggregation,
21886
+ radiusRange,
21887
+ data
21888
+ );
21889
+ result.getPointRadius = accessor;
21890
+ scales.pointRadius = updateTriggers.getPointRadius = {
21891
+ field: radiusField,
21892
+ type: radiusScale,
21893
+ ...scaleProps
21894
+ };
21895
+ }
19991
21896
  }
19992
- if (heightField && visConfig.enable3d) {
19993
- const { accessor, scale: scale2 } = getSizeAccessor(
19994
- heightField,
19995
- heightScale,
19996
- visConfig.heightAggregation,
19997
- visConfig.heightRange || visConfig.sizeRange,
19998
- data
19999
- );
20000
- result.getElevation = accessor;
20001
- scales.elevation = {
20002
- field: heightField,
20003
- type: heightScale || "identity",
20004
- ...domainAndRangeFromScale(scale2)
20005
- };
21897
+ {
21898
+ const strokeColorRange = visConfig.strokeColorRange;
21899
+ const { strokeColorScale, strokeColorField } = visualChannels;
21900
+ if (strokeColorField && strokeColorRange && strokeColorScale) {
21901
+ const { strokeColorAggregation: aggregation } = visConfig;
21902
+ const opacity = visConfig.strokeOpacity !== void 0 ? visConfig.strokeOpacity : 1;
21903
+ const { accessor, ...scaleProps } = getColorAccessor(
21904
+ strokeColorField,
21905
+ strokeColorScale,
21906
+ { aggregation, range: strokeColorRange },
21907
+ opacity,
21908
+ data
21909
+ );
21910
+ result.getLineColor = accessor;
21911
+ scales.lineColor = updateTriggers.getLineColor = {
21912
+ field: strokeColorField,
21913
+ type: strokeColorScale,
21914
+ ...scaleProps
21915
+ };
21916
+ }
20006
21917
  }
20007
- if (weightField) {
20008
- const { accessor, scale: scale2 } = getSizeAccessor(
20009
- weightField,
20010
- void 0,
20011
- visConfig.weightAggregation,
20012
- void 0,
20013
- data
20014
- );
20015
- result.getWeight = accessor;
20016
- scales.weight = {
20017
- field: weightField,
20018
- type: "identity",
20019
- ...domainAndRangeFromScale(scale2)
20020
- };
21918
+ {
21919
+ const { sizeField: strokeWidthField, sizeScale: strokeWidthScale } = visualChannels;
21920
+ const { sizeRange, sizeAggregation } = visConfig;
21921
+ if (strokeWidthField && sizeRange) {
21922
+ const { accessor, ...scaleProps } = getSizeAccessor(
21923
+ strokeWidthField,
21924
+ strokeWidthScale,
21925
+ sizeAggregation,
21926
+ sizeRange,
21927
+ data
21928
+ );
21929
+ result.getLineWidth = accessor;
21930
+ scales.lineWidth = updateTriggers.getLineWidth = {
21931
+ field: strokeWidthField,
21932
+ type: strokeWidthScale || "identity",
21933
+ ...scaleProps
21934
+ };
21935
+ }
21936
+ }
21937
+ {
21938
+ const { enable3d, heightRange } = visConfig;
21939
+ const { heightField, heightScale } = visualChannels;
21940
+ if (heightField && heightRange && enable3d) {
21941
+ const { accessor, ...scaleProps } = getSizeAccessor(
21942
+ heightField,
21943
+ heightScale,
21944
+ visConfig.heightAggregation,
21945
+ heightRange,
21946
+ data
21947
+ );
21948
+ result.getElevation = accessor;
21949
+ scales.elevation = updateTriggers.getElevation = {
21950
+ field: heightField,
21951
+ type: heightScale || "identity",
21952
+ ...scaleProps
21953
+ };
21954
+ }
21955
+ }
21956
+ {
21957
+ const { weightField } = visualChannels;
21958
+ const { weightAggregation } = visConfig;
21959
+ if (weightField && weightAggregation) {
21960
+ const { accessor, ...scaleProps } = getSizeAccessor(
21961
+ weightField,
21962
+ void 0,
21963
+ weightAggregation,
21964
+ void 0,
21965
+ data
21966
+ );
21967
+ result.getWeight = accessor;
21968
+ scales.weight = updateTriggers.getWeight = {
21969
+ field: weightField,
21970
+ type: "identity",
21971
+ ...scaleProps
21972
+ };
21973
+ }
20021
21974
  }
20022
21975
  if (visConfig.customMarkers) {
20023
21976
  const maxIconSize = getMaxMarkerSize(visConfig, visualChannels);
@@ -20034,6 +21987,12 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
20034
21987
  { fallbackUrl: customMarkersUrl, maxIconSize, useMaskedIcons },
20035
21988
  data
20036
21989
  );
21990
+ updateTriggers.getIcon = {
21991
+ customMarkersUrl,
21992
+ customMarkersRange,
21993
+ maxIconSize,
21994
+ useMaskedIcons
21995
+ };
20037
21996
  result._subLayerProps = {
20038
21997
  "points-icon": {
20039
21998
  loadOptions: {
@@ -20050,9 +22009,11 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
20050
22009
  };
20051
22010
  if (getFillColor && useMaskedIcons) {
20052
22011
  result.getIconColor = getFillColor;
22012
+ updateTriggers.getIconColor = updateTriggers.getFillColor;
20053
22013
  }
20054
22014
  if (getPointRadius) {
20055
22015
  result.getIconSize = getPointRadius;
22016
+ updateTriggers.getIconSize = updateTriggers.getPointRadius;
20056
22017
  }
20057
22018
  if (visualChannels.rotationField) {
20058
22019
  const { accessor } = getSizeAccessor(
@@ -20063,6 +22024,7 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
20063
22024
  data
20064
22025
  );
20065
22026
  result.getIconAngle = negateAccessor(accessor);
22027
+ updateTriggers.getIconAngle = updateTriggers.getRotationField;
20066
22028
  }
20067
22029
  } else if (layerType === "tileset") {
20068
22030
  result.pointType = "circle";
@@ -20107,7 +22069,13 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
20107
22069
  }
20108
22070
  };
20109
22071
  }
20110
- return { channelProps: result, scales };
22072
+ return {
22073
+ channelProps: {
22074
+ ...result,
22075
+ updateTriggers
22076
+ },
22077
+ scales
22078
+ };
20111
22079
  }
20112
22080
  function createLoadOptions(accessToken) {
20113
22081
  return {
@@ -20530,6 +22498,7 @@ ${formatErrorKey(key)}: ${errorContext[key]}`;
20530
22498
  }
20531
22499
  return out;
20532
22500
  }
22501
+ var EMPTY_U32 = 2 ** 32 - 1;
20533
22502
 
20534
22503
  // src/basemap.ts
20535
22504
  var cartoStyleUrlTemplate2 = "https://basemaps.cartocdn.com/gl/{basemap}-gl-style/style.json";