@carto/api-client 0.5.13 → 0.5.15-alpha.raster-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -94,11 +94,11 @@ var FilterType = /* @__PURE__ */ ((FilterType2) => {
94
94
  FilterType2["STRING_SEARCH"] = "stringSearch";
95
95
  return FilterType2;
96
96
  })(FilterType || {});
97
- var ApiVersion = /* @__PURE__ */ ((ApiVersion3) => {
98
- ApiVersion3["V1"] = "v1";
99
- ApiVersion3["V2"] = "v2";
100
- ApiVersion3["V3"] = "v3";
101
- return ApiVersion3;
97
+ var ApiVersion = /* @__PURE__ */ ((ApiVersion2) => {
98
+ ApiVersion2["V1"] = "v1";
99
+ ApiVersion2["V2"] = "v2";
100
+ ApiVersion2["V3"] = "v3";
101
+ return ApiVersion2;
102
102
  })(ApiVersion || {});
103
103
  var DEFAULT_API_BASE_URL = "https://gcp-us-east1.api.carto.com";
104
104
  var TileFormat = /* @__PURE__ */ ((TileFormat2) => {
@@ -6593,6 +6593,48 @@ var WidgetRemoteSource = class extends WidgetSource {
6593
6593
  categories: res.metadata?.categories
6594
6594
  }));
6595
6595
  }
6596
+ /** @experimental */
6597
+ async getExtent(options = {}) {
6598
+ const { signal, filters = this.props.filters, filterOwner } = options;
6599
+ const {
6600
+ type,
6601
+ data,
6602
+ apiBaseUrl,
6603
+ apiVersion,
6604
+ connectionName,
6605
+ spatialDataColumn,
6606
+ spatialDataType,
6607
+ queryParameters
6608
+ } = this.getModelSource(filters, filterOwner);
6609
+ assert2(apiVersion === "v3" /* V3 */, "Stats API requires CARTO 3+");
6610
+ let url;
6611
+ const parameters = { filters, spatialDataType };
6612
+ if (type === "query") {
6613
+ url = `${apiBaseUrl}/${apiVersion}/stats/${connectionName}/${spatialDataColumn}`;
6614
+ parameters.q = data;
6615
+ parameters.queryParameters = queryParameters;
6616
+ } else {
6617
+ url = `${apiBaseUrl}/${apiVersion}/stats/${connectionName}/${data}/${spatialDataColumn}`;
6618
+ }
6619
+ const headers = {
6620
+ Authorization: `Bearer ${this.props.accessToken}`,
6621
+ ...this.props.headers
6622
+ };
6623
+ const errorContext = {
6624
+ requestType: "Tile stats",
6625
+ connection: connectionName,
6626
+ type
6627
+ };
6628
+ return requestWithParameters({
6629
+ baseUrl: url,
6630
+ headers,
6631
+ signal,
6632
+ errorContext,
6633
+ parameters
6634
+ }).then(({ extent: { xmin, ymin, xmax, ymax } }) => ({
6635
+ bbox: [xmin, ymin, xmax, ymax]
6636
+ }));
6637
+ }
6596
6638
  };
6597
6639
 
6598
6640
  // src/widget-sources/widget-query-source.ts
@@ -7548,6 +7590,10 @@ var WidgetTilesetSourceImpl = class extends WidgetSource {
7548
7590
  max: aggregationFunctions.max(filteredFeatures, column)
7549
7591
  };
7550
7592
  }
7593
+ /** @experimental */
7594
+ async getExtent() {
7595
+ return Promise.reject(new Error("not implemented"));
7596
+ }
7551
7597
  /****************************************************************************
7552
7598
  * INTERNAL
7553
7599
  */
@@ -7778,6 +7824,12 @@ var WidgetTilesetSource = class extends WidgetSource {
7778
7824
  }) {
7779
7825
  return this._executeWorkerMethod("getRange" /* GET_RANGE */, [options], signal);
7780
7826
  }
7827
+ /** @experimental */
7828
+ async getExtent() {
7829
+ return Promise.resolve({
7830
+ bbox: this.props.spatialDataBounds
7831
+ });
7832
+ }
7781
7833
  };
7782
7834
 
7783
7835
  // src/widget-sources/widget-raster-source.ts
@@ -7894,7 +7946,8 @@ var h3TilesetSource = async function(options) {
7894
7946
  ...options,
7895
7947
  tileFormat: getTileFormat(result),
7896
7948
  spatialDataColumn,
7897
- spatialDataType: "h3"
7949
+ spatialDataType: "h3",
7950
+ spatialDataBounds: result.bounds
7898
7951
  })
7899
7952
  })
7900
7953
  );
@@ -7915,6 +7968,7 @@ var rasterSource = async function(options) {
7915
7968
  tileFormat: getTileFormat(result),
7916
7969
  spatialDataColumn: "quadbin",
7917
7970
  spatialDataType: "quadbin",
7971
+ spatialDataBounds: result.bounds,
7918
7972
  rasterMetadata: result.raster_metadata
7919
7973
  })
7920
7974
  })
@@ -8014,7 +8068,8 @@ var quadbinTilesetSource = async function(options) {
8014
8068
  ...options,
8015
8069
  tileFormat: getTileFormat(result),
8016
8070
  spatialDataColumn,
8017
- spatialDataType: "quadbin"
8071
+ spatialDataType: "quadbin",
8072
+ spatialDataBounds: result.bounds
8018
8073
  })
8019
8074
  })
8020
8075
  );
@@ -8115,7 +8170,8 @@ var vectorTilesetSource = async function(options) {
8115
8170
  ...options,
8116
8171
  tileFormat: getTileFormat(result),
8117
8172
  spatialDataColumn,
8118
- spatialDataType: "geo"
8173
+ spatialDataType: "geo",
8174
+ spatialDataBounds: result.bounds
8119
8175
  })
8120
8176
  })
8121
8177
  );
@@ -8279,6 +8335,250 @@ var basemap_styles_default = {
8279
8335
  DARK_MATTER_NOLABELS: getStyleUrl("dark-matter-nolabels")
8280
8336
  };
8281
8337
 
8338
+ // src/fetch-map/vec-expr-evaluator.ts
8339
+ import jsep from "jsep";
8340
+ function createVecExprEvaluator(expression) {
8341
+ try {
8342
+ const parsed = compile(expression);
8343
+ const evalFun = (context) => evaluate(parsed, context);
8344
+ evalFun.symbols = getSymbols(parsed);
8345
+ return evalFun;
8346
+ } catch {
8347
+ return null;
8348
+ }
8349
+ }
8350
+ function evaluateVecExpr(expression, context) {
8351
+ try {
8352
+ return createVecExprEvaluator(expression)?.(context);
8353
+ } catch {
8354
+ return null;
8355
+ }
8356
+ }
8357
+ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
8358
+ ErrorCode2[ErrorCode2["InvalidSyntax"] = 0] = "InvalidSyntax";
8359
+ ErrorCode2[ErrorCode2["UnknownIdentifier"] = 1] = "UnknownIdentifier";
8360
+ return ErrorCode2;
8361
+ })(ErrorCode || {});
8362
+ function validateVecExprSyntax(expression, context) {
8363
+ let parsed;
8364
+ try {
8365
+ parsed = compile(expression);
8366
+ } catch (e) {
8367
+ return {
8368
+ valid: false,
8369
+ errorCode: 0 /* InvalidSyntax */,
8370
+ errorMessage: e && "message" in e ? String(e.message) : String(e)
8371
+ };
8372
+ }
8373
+ return validate(parsed, context);
8374
+ }
8375
+ function createResultArray(typeTemplate, length2 = typeTemplate.length) {
8376
+ return new Array(length2);
8377
+ }
8378
+ function isVecLike(a) {
8379
+ return Array.isArray(a) || ArrayBuffer.isView(a);
8380
+ }
8381
+ var createBinopVec = (scalarBinOp) => (left, right) => {
8382
+ const length2 = Math.min(left.length, right.length);
8383
+ const r = createResultArray(left, length2);
8384
+ for (let i = 0; i < length2; i++) {
8385
+ r[i] = scalarBinOp(left[i], right[i]);
8386
+ }
8387
+ return r;
8388
+ };
8389
+ var createBinopVecNum = (scalarBinOp) => (left, right) => {
8390
+ const length2 = left.length;
8391
+ const r = createResultArray(left, length2);
8392
+ for (let i = 0; i < length2; i++) {
8393
+ r[i] = scalarBinOp(left[i], right);
8394
+ }
8395
+ return r;
8396
+ };
8397
+ var createBinopNumVec = (scalarBinOp) => (left, right) => {
8398
+ const length2 = right.length;
8399
+ const r = createResultArray(right, length2);
8400
+ for (let i = 0; i < length2; i++) {
8401
+ r[i] = scalarBinOp(left, right[i]);
8402
+ }
8403
+ return r;
8404
+ };
8405
+ var createUnopVec = (scalarUnop) => (a) => {
8406
+ const length2 = a.length;
8407
+ const r = createResultArray(a, length2);
8408
+ for (let i = 0; i < length2; i++) {
8409
+ r[i] = scalarUnop(a[i]);
8410
+ }
8411
+ return r;
8412
+ };
8413
+ function mapDictValues(dict, fun) {
8414
+ return Object.keys(dict).reduce(
8415
+ (acc, key) => {
8416
+ acc[key] = fun(dict[key]);
8417
+ return acc;
8418
+ },
8419
+ {}
8420
+ );
8421
+ }
8422
+ var binopsNum = {
8423
+ "||": (a, b) => a || b,
8424
+ "&&": (a, b) => a && b,
8425
+ "|": (a, b) => a | b,
8426
+ "^": (a, b) => a ^ b,
8427
+ "&": (a, b) => a & b,
8428
+ "==": (a, b) => Number(a == b),
8429
+ "!=": (a, b) => Number(a != b),
8430
+ "===": (a, b) => Number(a === b),
8431
+ "!==": (a, b) => Number(a !== b),
8432
+ "<": (a, b) => Number(a < b),
8433
+ ">": (a, b) => Number(a > b),
8434
+ "<=": (a, b) => Number(a <= b),
8435
+ ">=": (a, b) => Number(a >= b),
8436
+ "<<": (a, b) => a << b,
8437
+ ">>": (a, b) => a >> b,
8438
+ ">>>": (a, b) => a >>> b,
8439
+ "+": (a, b) => a + b,
8440
+ "-": (a, b) => a - b,
8441
+ "*": (a, b) => a * b,
8442
+ "/": (a, b) => a / b,
8443
+ "%": (a, b) => a % b
8444
+ };
8445
+ var unopsNum = {
8446
+ "-": (a) => -a,
8447
+ "+": (a) => +a,
8448
+ "~": (a) => ~a,
8449
+ "!": (a) => Number(!a)
8450
+ };
8451
+ var binopsVector = mapDictValues(binopsNum, createBinopVec);
8452
+ var binopsNumVec = mapDictValues(binopsNum, createBinopNumVec);
8453
+ var binopsVecNum = mapDictValues(binopsNum, createBinopVecNum);
8454
+ var unopsVector = mapDictValues(unopsNum, createUnopVec);
8455
+ function getBinop(operator, left, right) {
8456
+ const isLeftVec = isVecLike(left);
8457
+ const isRightVec = isVecLike(right);
8458
+ if (isLeftVec && isRightVec) {
8459
+ return binopsVector[operator];
8460
+ } else if (isLeftVec) {
8461
+ return binopsVecNum[operator];
8462
+ } else if (isRightVec) {
8463
+ return binopsNumVec[operator];
8464
+ } else {
8465
+ return binopsNum[operator];
8466
+ }
8467
+ }
8468
+ function evaluate(_node, context) {
8469
+ const node = _node;
8470
+ switch (node.type) {
8471
+ case "BinaryExpression": {
8472
+ const left = evaluate(node.left, context);
8473
+ const right = evaluate(node.right, context);
8474
+ const binopFun = getBinop(node.operator, left, right);
8475
+ return binopFun(left, right);
8476
+ }
8477
+ case "ConditionalExpression": {
8478
+ const val = evaluate(node.test, context);
8479
+ if (isVecLike(val)) {
8480
+ const length2 = val.length;
8481
+ const consequentVal = evaluate(node.consequent, context);
8482
+ const alternateVal = evaluate(node.alternate, context);
8483
+ const r = createResultArray(val);
8484
+ for (let i = 0; i < length2; i++) {
8485
+ const entryVal = val[i] ? consequentVal : alternateVal;
8486
+ r[i] = isVecLike(entryVal) ? entryVal[i] ?? NaN : entryVal;
8487
+ }
8488
+ return r;
8489
+ } else {
8490
+ return val ? evaluate(node.consequent, context) : evaluate(node.alternate, context);
8491
+ }
8492
+ }
8493
+ case "Identifier":
8494
+ return context[node.name];
8495
+ case "Literal":
8496
+ return node.value;
8497
+ case "UnaryExpression": {
8498
+ const val = evaluate(node.argument, context);
8499
+ const unopFun = isVecLike(val) ? unopsVector[node.operator] : unopsNum[node.operator];
8500
+ return unopFun(val);
8501
+ }
8502
+ default:
8503
+ return void 0;
8504
+ }
8505
+ }
8506
+ var validResult = { valid: true };
8507
+ function visit(_node, visitor) {
8508
+ const node = _node;
8509
+ visitor(node);
8510
+ switch (node.type) {
8511
+ case "BinaryExpression": {
8512
+ visit(node.left, visitor);
8513
+ visit(node.right, visitor);
8514
+ break;
8515
+ }
8516
+ case "ConditionalExpression": {
8517
+ visit(node.test, visitor);
8518
+ visit(node.consequent, visitor);
8519
+ visit(node.alternate, visitor);
8520
+ break;
8521
+ }
8522
+ case "UnaryExpression": {
8523
+ visit(node.argument, visitor);
8524
+ break;
8525
+ }
8526
+ }
8527
+ }
8528
+ var supportedExpressionTypes = [
8529
+ "BinaryExpression",
8530
+ "UnaryExpression",
8531
+ "ConditionalExpression",
8532
+ "LogicalExpression",
8533
+ "Identifier",
8534
+ "Literal"
8535
+ ];
8536
+ function validate(_node, context) {
8537
+ const node = _node;
8538
+ const errors = [];
8539
+ visit(node, (node2) => {
8540
+ if (!supportedExpressionTypes.includes(node2.type)) {
8541
+ errors.push({
8542
+ valid: false,
8543
+ errorCode: 0 /* InvalidSyntax */,
8544
+ errorMessage: `Not allowed`
8545
+ });
8546
+ return;
8547
+ }
8548
+ if (node2.type === "Identifier") {
8549
+ if (!Object.prototype.hasOwnProperty.call(context, node2.name)) {
8550
+ return errors.push({
8551
+ valid: false,
8552
+ errorCode: 1 /* UnknownIdentifier */,
8553
+ errorMessage: `"${node2.name}" not found`
8554
+ });
8555
+ }
8556
+ }
8557
+ if (node2.type === "Literal") {
8558
+ if (typeof node2.value !== "number") {
8559
+ return errors.push({
8560
+ valid: false,
8561
+ errorCode: 0 /* InvalidSyntax */,
8562
+ errorMessage: `Only number literals are supported`
8563
+ });
8564
+ }
8565
+ }
8566
+ });
8567
+ return errors.length ? errors[0] : validResult;
8568
+ }
8569
+ function getSymbols(node) {
8570
+ const symbols = /* @__PURE__ */ new Set();
8571
+ visit(node, (node2) => {
8572
+ if (node2.type === "Identifier") {
8573
+ symbols.add(node2.name);
8574
+ }
8575
+ });
8576
+ return Array.from(symbols);
8577
+ }
8578
+ function compile(expression) {
8579
+ return jsep(expression);
8580
+ }
8581
+
8282
8582
  // node_modules/d3-array/src/ascending.js
8283
8583
  function ascending(a, b) {
8284
8584
  return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
@@ -8906,6 +9206,12 @@ var sharedPropMap = {
8906
9206
  wireframe: "wireframe"
8907
9207
  }
8908
9208
  };
9209
+ var rasterPropsMap = {
9210
+ isVisible: "visible",
9211
+ visConfig: {
9212
+ opacity: "opacity"
9213
+ }
9214
+ };
8909
9215
  var customMarkersPropsMap = {
8910
9216
  color: "getIconColor",
8911
9217
  visConfig: {
@@ -8949,6 +9255,12 @@ function getLayerProps(type, config2, dataset) {
8949
9255
  `Outdated layer type: ${type}. Please open map in CARTO Builder to automatically migrate.`
8950
9256
  );
8951
9257
  }
9258
+ if (type === "raster") {
9259
+ return {
9260
+ propMap: rasterPropsMap,
9261
+ defaultProps: {}
9262
+ };
9263
+ }
8952
9264
  let basePropMap = sharedPropMap;
8953
9265
  if (config2.visConfig?.customMarkers) {
8954
9266
  basePropMap = mergePropMaps(basePropMap, customMarkersPropsMap);
@@ -8969,6 +9281,9 @@ function getLayerProps(type, config2, dataset) {
8969
9281
  }
8970
9282
  function domainFromAttribute(attribute, scaleType, scaleLength) {
8971
9283
  if (scaleType === "ordinal" || scaleType === "point") {
9284
+ if (!attribute.categories) {
9285
+ return [0, 1];
9286
+ }
8972
9287
  return attribute.categories.map((c) => c.category).filter((c) => c !== void 0 && c !== null);
8973
9288
  }
8974
9289
  if (scaleType === "quantile" && attribute.quantiles) {
@@ -9004,7 +9319,7 @@ function calculateDomain(data, name, scaleType, scaleLength) {
9004
9319
  return [0, 1];
9005
9320
  }
9006
9321
  function normalizeAccessor(accessor, data) {
9007
- if (data.features || data.tilestats) {
9322
+ if (data.features || data.tilestats || data.raster_metadata) {
9008
9323
  return (object, info) => {
9009
9324
  if (object) {
9010
9325
  return accessor(object.properties || object.__source.object.properties);
@@ -9056,7 +9371,6 @@ function getColorAccessor({ name, colorColumn }, scaleType, { aggregation, range
9056
9371
  return { accessor: normalizeAccessor(accessor, data), scale: scale2 };
9057
9372
  }
9058
9373
  function calculateLayerScale(name, scaleType, range, data) {
9059
- const scale2 = SCALE_FUNCS[scaleType]();
9060
9374
  let domain = [];
9061
9375
  let scaleColor = [];
9062
9376
  if (scaleType !== "identity") {
@@ -9074,9 +9388,13 @@ function calculateLayerScale(name, scaleType, range, data) {
9074
9388
  domain = domain.slice(0, scaleColor.length);
9075
9389
  }
9076
9390
  }
9391
+ return createColorScale(scaleType, domain, scaleColor, UNKNOWN_COLOR);
9392
+ }
9393
+ function createColorScale(scaleType, domain, range, unknown) {
9394
+ const scale2 = SCALE_FUNCS[scaleType]();
9077
9395
  scale2.domain(domain);
9078
- scale2.range(scaleColor);
9079
- scale2.unknown(UNKNOWN_COLOR);
9396
+ scale2.range(range);
9397
+ scale2.unknown(unknown);
9080
9398
  return scale2;
9081
9399
  }
9082
9400
  var FALLBACK_ICON = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNTAiLz4NCjwvc3ZnPg==";
@@ -9191,13 +9509,419 @@ function calculateClusterTextFontSize(radius) {
9191
9509
  return 11;
9192
9510
  }
9193
9511
 
9512
+ // src/fetch-map/raster-layer.ts
9513
+ var UNKNOWN_COLOR2 = [134, 141, 145];
9514
+ var RASTER_COLOR_BANDS = ["red", "green", "blue"];
9515
+ function getHasDataPredicate(noData) {
9516
+ if (noData === "nan") {
9517
+ return (v2) => !isNaN(v2);
9518
+ }
9519
+ if (typeof noData === "string") {
9520
+ noData = parseFloat(noData);
9521
+ }
9522
+ if (typeof noData === "number") {
9523
+ return (v2) => v2 !== noData && !isNaN(v2);
9524
+ }
9525
+ return () => true;
9526
+ }
9527
+ function createRasterColumnLayerDataTransform(transform) {
9528
+ return (data) => {
9529
+ if (!data || !("data" in data) || !data?.data?.cells?.numericProps) {
9530
+ return data;
9531
+ }
9532
+ return transform(data);
9533
+ };
9534
+ }
9535
+ function createEvaluationContext(numericProps, noData) {
9536
+ const hasData = getHasDataPredicate(noData);
9537
+ const bands = Object.entries(numericProps).map(([bandName, { value }]) => ({
9538
+ bandName,
9539
+ values: value,
9540
+ copied: false
9541
+ }));
9542
+ const length2 = bands[0].values.length;
9543
+ for (let i = 0; i < length2; i++) {
9544
+ let hasSomeData = false;
9545
+ for (let j = 0; j < bands.length; j++) {
9546
+ hasSomeData = hasSomeData || hasData(bands[j].values[i]);
9547
+ }
9548
+ if (!hasSomeData) {
9549
+ for (let j = 0; j < bands.length; j++) {
9550
+ if (!bands[j].copied) {
9551
+ bands[j].copied = true;
9552
+ bands[j].values = Array.from(bands[j].values);
9553
+ }
9554
+ bands[j].values[i] = NaN;
9555
+ }
9556
+ }
9557
+ }
9558
+ const context = bands.reduce(
9559
+ (agg, { bandName, values }) => {
9560
+ agg[bandName] = values;
9561
+ return agg;
9562
+ },
9563
+ {}
9564
+ );
9565
+ return context;
9566
+ }
9567
+ function createExprDataTransform({
9568
+ colorBand,
9569
+ rasterMetadata,
9570
+ usedSymbols
9571
+ }) {
9572
+ if (!colorBand || !colorBand.type || colorBand.type === "none") {
9573
+ return void 0;
9574
+ }
9575
+ const expr = colorBand?.type === "expression" ? colorBand.value : void 0;
9576
+ const vecExprEvaluator = expr ? createVecExprEvaluator(expr) : void 0;
9577
+ const dataTransform = createRasterColumnLayerDataTransform(
9578
+ (dataWrapped) => {
9579
+ const data = dataWrapped.data;
9580
+ if (expr) {
9581
+ const cachedResult = dataWrapped.customExpressionResults?.[expr];
9582
+ if (cachedResult) {
9583
+ return dataWrapped;
9584
+ }
9585
+ }
9586
+ let context = dataWrapped.expressionEvalContext;
9587
+ if (!context) {
9588
+ const usedNumericProps = usedSymbols.reduce(
9589
+ (acc, symbol) => {
9590
+ acc[symbol] = data.cells.numericProps[symbol];
9591
+ return acc;
9592
+ },
9593
+ {}
9594
+ );
9595
+ context = createEvaluationContext(
9596
+ usedNumericProps,
9597
+ rasterMetadata.nodata
9598
+ );
9599
+ dataWrapped = {
9600
+ ...dataWrapped,
9601
+ expressionEvalContext: context
9602
+ };
9603
+ }
9604
+ if (!vecExprEvaluator || !expr) return dataWrapped;
9605
+ const evalResult = vecExprEvaluator(context);
9606
+ return {
9607
+ ...dataWrapped,
9608
+ customExpressionResults: {
9609
+ ...dataWrapped.customExpressionResults,
9610
+ [expr]: evalResult
9611
+ }
9612
+ };
9613
+ }
9614
+ );
9615
+ return dataTransform;
9616
+ }
9617
+ function combineDataTransforms(dataTransforms) {
9618
+ const actualTransforms = dataTransforms.filter((v2) => v2);
9619
+ if (actualTransforms.length === 0) return void 0;
9620
+ if (actualTransforms.length === 1) return actualTransforms[0];
9621
+ return (data) => actualTransforms.reduce(
9622
+ (aggData, transformFun) => transformFun(aggData),
9623
+ data
9624
+ );
9625
+ }
9626
+ function createRgbToColorBufferDataTransform({
9627
+ bandDefs,
9628
+ attribute
9629
+ }) {
9630
+ return createRasterColumnLayerDataTransform(
9631
+ (dataWrapped) => {
9632
+ const length2 = dataWrapped.length;
9633
+ const getBandBufferOrValue = (colorBand) => {
9634
+ if (colorBand?.type === "expression") {
9635
+ return dataWrapped.customExpressionResults?.[colorBand.value];
9636
+ }
9637
+ if (colorBand?.type === "band") {
9638
+ return dataWrapped.expressionEvalContext?.[colorBand.value];
9639
+ }
9640
+ return 0;
9641
+ };
9642
+ const red = getBandBufferOrValue(bandDefs.red);
9643
+ const green = getBandBufferOrValue(bandDefs.green);
9644
+ const blue = getBandBufferOrValue(bandDefs.blue);
9645
+ const colorBuffer = new Uint8Array(length2 * 4);
9646
+ for (let inputIndex = 0, outputIndex = 0; inputIndex < length2; inputIndex++, outputIndex += 4) {
9647
+ const redRaw = typeof red === "number" ? red : red ? red[inputIndex] : NaN;
9648
+ const greenRaw = typeof green === "number" ? green : green ? green[inputIndex] : NaN;
9649
+ const blueRaw = typeof blue === "number" ? blue : blue ? blue[inputIndex] : NaN;
9650
+ if (isNaN(redRaw) && isNaN(greenRaw) && isNaN(blueRaw)) {
9651
+ bufferSetRgba(colorBuffer, outputIndex, 0, 0, 0, 0);
9652
+ } else {
9653
+ bufferSetRgba(
9654
+ colorBuffer,
9655
+ outputIndex,
9656
+ redRaw,
9657
+ greenRaw,
9658
+ blueRaw,
9659
+ 255
9660
+ );
9661
+ }
9662
+ }
9663
+ dataWrapped.customExpressionResults = void 0;
9664
+ dataWrapped.expressionEvalContext = void 0;
9665
+ return {
9666
+ ...dataWrapped,
9667
+ attributes: {
9668
+ [attribute]: colorBuffer
9669
+ }
9670
+ };
9671
+ }
9672
+ );
9673
+ }
9674
+ function getUsedSymbols(colorBands) {
9675
+ return Array.from(
9676
+ colorBands.reduce((symbols, band) => {
9677
+ if (band.type === "expression") {
9678
+ const expressionSymbols = createVecExprEvaluator(band.value)?.symbols || [];
9679
+ expressionSymbols.forEach((symbol) => symbols.add(symbol));
9680
+ }
9681
+ if (band.type === "band") {
9682
+ symbols.add(band.value);
9683
+ }
9684
+ return symbols;
9685
+ }, /* @__PURE__ */ new Set())
9686
+ );
9687
+ }
9688
+ function getRasterTileLayerStylePropsRgb({
9689
+ layerConfig,
9690
+ rasterMetadata,
9691
+ visualChannels
9692
+ }) {
9693
+ const { visConfig } = layerConfig;
9694
+ const { colorBands } = visConfig;
9695
+ const bandDefs = {
9696
+ red: colorBands?.find((band) => band.band === "red"),
9697
+ green: colorBands?.find((band) => band.band === "green"),
9698
+ blue: colorBands?.find((band) => band.band === "blue")
9699
+ };
9700
+ const rgbToInstanceFillColorsDataTransform = createRgbToColorBufferDataTransform({
9701
+ bandDefs,
9702
+ attribute: "instanceFillColors"
9703
+ });
9704
+ const usedSymbols = colorBands ? getUsedSymbols(colorBands) : [];
9705
+ const bandTransforms = RASTER_COLOR_BANDS.map(
9706
+ (band) => createExprDataTransform({
9707
+ colorBand: bandDefs[band],
9708
+ rasterMetadata,
9709
+ usedSymbols
9710
+ })
9711
+ );
9712
+ const combinedDataTransform = combineDataTransforms([
9713
+ ...bandTransforms,
9714
+ rgbToInstanceFillColorsDataTransform
9715
+ ]);
9716
+ return {
9717
+ dataTransform: combinedDataTransform,
9718
+ updateTriggers: getRasterTileLayerUpdateTriggers({
9719
+ layerConfig,
9720
+ visualChannels
9721
+ })
9722
+ };
9723
+ }
9724
+ function createBandColorScaleDataTransform({
9725
+ bandName,
9726
+ scaleFun,
9727
+ nodata,
9728
+ attribute
9729
+ }) {
9730
+ const hasData = getHasDataPredicate(nodata);
9731
+ return createRasterColumnLayerDataTransform(
9732
+ (dataWrapped) => {
9733
+ const length2 = dataWrapped.length;
9734
+ const bandBuffer = dataWrapped.data.cells.numericProps[bandName].value;
9735
+ const colorBuffer = new Uint8Array(length2 * 4);
9736
+ for (let i = 0; i < length2; i++) {
9737
+ const rawValue = bandBuffer[i];
9738
+ if (!hasData(rawValue)) {
9739
+ bufferSetRgba(colorBuffer, i * 4, 0, 0, 0, 0);
9740
+ } else {
9741
+ const colorRgb = scaleFun(rawValue);
9742
+ bufferSetRgba(
9743
+ colorBuffer,
9744
+ i * 4,
9745
+ colorRgb[0],
9746
+ colorRgb[1],
9747
+ colorRgb[2],
9748
+ 255
9749
+ );
9750
+ }
9751
+ }
9752
+ return {
9753
+ ...dataWrapped,
9754
+ attributes: {
9755
+ [attribute]: colorBuffer
9756
+ }
9757
+ };
9758
+ }
9759
+ );
9760
+ }
9761
+ function domainFromRasterMetadataBand(band, scaleType, colorRange) {
9762
+ if (scaleType === "ordinal") {
9763
+ return colorRange.colorMap?.map(([value]) => value) || [];
9764
+ }
9765
+ if (scaleType === "custom") {
9766
+ if (colorRange.uiCustomScaleType === "logarithmic") {
9767
+ if (colorRange.colorMap) {
9768
+ return colorRange.colorMap?.map(([value]) => value) || [];
9769
+ }
9770
+ return [band.stats.min, band.stats.max];
9771
+ } else {
9772
+ return colorRange.colorMap?.map(([value]) => value) || [];
9773
+ }
9774
+ }
9775
+ const scaleLength = colorRange.colors.length;
9776
+ if (scaleType === "quantile") {
9777
+ const quantiles = band.stats.quantiles?.[scaleLength];
9778
+ if (!quantiles) {
9779
+ return [0, 1];
9780
+ }
9781
+ return [band.stats.min, ...quantiles, band.stats.max];
9782
+ }
9783
+ return [band.stats.min, band.stats.max];
9784
+ }
9785
+ function getRasterTileLayerStylePropsScaledBand({
9786
+ layerConfig,
9787
+ rasterMetadata,
9788
+ visualChannels
9789
+ }) {
9790
+ const { visConfig } = layerConfig;
9791
+ const { colorField } = visualChannels;
9792
+ const { rasterStyleType } = visConfig;
9793
+ const colorRange = rasterStyleType === "ColorRange" ? visConfig.colorRange : visConfig.uniqueValuesColorRange;
9794
+ const scaleType = rasterStyleType === "ColorRange" ? visualChannels.colorScale : "ordinal";
9795
+ const bandInfo = rasterMetadata.bands.find(
9796
+ (band) => band.name === colorField?.name
9797
+ );
9798
+ if (!colorField?.name || !scaleType || !colorRange || !bandInfo) {
9799
+ return {};
9800
+ }
9801
+ const domain = domainFromRasterMetadataBand(bandInfo, scaleType, colorRange);
9802
+ const scaleFun = createColorScale(
9803
+ scaleType,
9804
+ domain,
9805
+ colorRange.colors.map(hexToRGB),
9806
+ UNKNOWN_COLOR2
9807
+ );
9808
+ const bandColorScaleDataTransform = createBandColorScaleDataTransform({
9809
+ bandName: bandInfo.name,
9810
+ scaleFun,
9811
+ nodata: bandInfo?.nodata ?? rasterMetadata.nodata,
9812
+ attribute: "instanceFillColors"
9813
+ });
9814
+ return {
9815
+ dataTransform: bandColorScaleDataTransform,
9816
+ updateTriggers: getRasterTileLayerUpdateTriggers({
9817
+ layerConfig,
9818
+ visualChannels
9819
+ })
9820
+ };
9821
+ }
9822
+ function getRasterTileLayerStyleProps({
9823
+ layerConfig,
9824
+ visualChannels,
9825
+ rasterMetadata
9826
+ }) {
9827
+ const { visConfig } = layerConfig;
9828
+ const { rasterStyleType } = visConfig;
9829
+ if (rasterStyleType === "Rgb") {
9830
+ return getRasterTileLayerStylePropsRgb({
9831
+ layerConfig,
9832
+ rasterMetadata,
9833
+ visualChannels
9834
+ });
9835
+ } else {
9836
+ return getRasterTileLayerStylePropsScaledBand({
9837
+ layerConfig,
9838
+ rasterMetadata,
9839
+ visualChannels
9840
+ });
9841
+ }
9842
+ }
9843
+ function getRasterTileLayerUpdateTriggers({
9844
+ layerConfig,
9845
+ visualChannels
9846
+ }) {
9847
+ const { visConfig } = layerConfig;
9848
+ const { rasterStyleType } = visConfig;
9849
+ const getFillColorUpdateTriggers = {
9850
+ rasterStyleType
9851
+ };
9852
+ if (rasterStyleType === "ColorRange") {
9853
+ getFillColorUpdateTriggers.colorRange = visConfig.colorRange?.colors;
9854
+ getFillColorUpdateTriggers.colorMap = visConfig.colorRange?.colorMap;
9855
+ getFillColorUpdateTriggers.colorScale = visualChannels.colorScale;
9856
+ getFillColorUpdateTriggers.colorFieldId = visualChannels.colorField?.name;
9857
+ } else if (rasterStyleType === "UniqueValues") {
9858
+ getFillColorUpdateTriggers.colorMap = visConfig.uniqueValuesColorRange?.colorMap;
9859
+ getFillColorUpdateTriggers.colorFieldId = visualChannels.colorField?.name;
9860
+ } else if (rasterStyleType === "Rgb") {
9861
+ getFillColorUpdateTriggers.colorBands = visConfig.colorBands;
9862
+ }
9863
+ return {
9864
+ getFillColor: getFillColorUpdateTriggers
9865
+ };
9866
+ }
9867
+ function bufferSetRgba(target, index, r, g, b, a) {
9868
+ target[index + 0] = r;
9869
+ target[index + 1] = g;
9870
+ target[index + 2] = b;
9871
+ target[index + 3] = a;
9872
+ }
9873
+ function hexToRGB(hexColor) {
9874
+ const r = parseInt(hexColor.slice(1, 3), 16);
9875
+ const g = parseInt(hexColor.slice(3, 5), 16);
9876
+ const b = parseInt(hexColor.slice(5, 7), 16);
9877
+ return [r, g, b];
9878
+ }
9879
+
9194
9880
  // src/fetch-map/parse-map.ts
9881
+ function getLayerDescriptor({
9882
+ mapConfig,
9883
+ layer,
9884
+ dataset
9885
+ }) {
9886
+ const { filters, visState } = mapConfig;
9887
+ const { layerBlending, interactionConfig } = visState;
9888
+ const { id, type, config: config2, visualChannels } = layer;
9889
+ const { data, id: datasetId } = dataset;
9890
+ const { propMap, defaultProps: defaultProps2 } = getLayerProps(type, config2, dataset);
9891
+ const styleProps = createStyleProps(config2, propMap);
9892
+ const { channelProps, scales } = createChannelProps(
9893
+ id,
9894
+ type,
9895
+ config2,
9896
+ visualChannels,
9897
+ data,
9898
+ dataset
9899
+ );
9900
+ const layerDescriptor = {
9901
+ type,
9902
+ filters: isEmptyObject(filters) || isRemoteCalculationSupported(dataset) ? void 0 : filters[datasetId],
9903
+ props: {
9904
+ id,
9905
+ data,
9906
+ ...defaultProps2,
9907
+ ...createInteractionProps(interactionConfig),
9908
+ ...styleProps,
9909
+ ...channelProps,
9910
+ ...createParametersProp(layerBlending, styleProps.parameters || {}),
9911
+ // Must come after style
9912
+ ...createLoadOptions(data.accessToken)
9913
+ },
9914
+ scales
9915
+ };
9916
+ return layerDescriptor;
9917
+ }
9195
9918
  function parseMap(json) {
9196
9919
  const { keplerMapConfig, datasets, token } = json;
9197
9920
  assert2(keplerMapConfig.version === "v1", "Only support Kepler v1");
9198
- const config2 = keplerMapConfig.config;
9199
- const { filters, mapState, mapStyle, popupSettings, legendSettings } = config2;
9200
- const { layers, layerBlending, interactionConfig } = config2.visState;
9921
+ const mapConfig = keplerMapConfig.config;
9922
+ const { mapState, mapStyle, popupSettings, legendSettings, visState } = mapConfig;
9923
+ const { layers } = visState;
9924
+ const layersReverse = [...layers].reverse();
9201
9925
  return {
9202
9926
  id: json.id,
9203
9927
  title: json.title,
@@ -9210,45 +9934,19 @@ function parseMap(json) {
9210
9934
  popupSettings,
9211
9935
  legendSettings,
9212
9936
  token,
9213
- layers: layers.reverse().map(({ id, type, config: config3, visualChannels }) => {
9937
+ layers: layersReverse.map((layer) => {
9214
9938
  try {
9215
- const { dataId } = config3;
9939
+ const { dataId } = layer.config;
9216
9940
  const dataset = datasets.find(
9217
9941
  (d) => d.id === dataId
9218
9942
  );
9219
9943
  assert2(dataset, `No dataset matching dataId: ${dataId}`);
9220
- const { data } = dataset;
9221
- assert2(data, `No data loaded for dataId: ${dataId}`);
9222
- const { propMap, defaultProps: defaultProps2 } = getLayerProps(type, config3, dataset);
9223
- const styleProps = createStyleProps(config3, propMap);
9224
- const { channelProps, scales } = createChannelProps(
9225
- id,
9226
- type,
9227
- config3,
9228
- visualChannels,
9229
- data,
9944
+ const layerDescriptor = getLayerDescriptor({
9945
+ mapConfig,
9946
+ layer,
9230
9947
  dataset
9231
- );
9232
- const layer = {
9233
- type,
9234
- filters: isEmptyObject(filters) || isRemoteCalculationSupported(dataset) ? void 0 : filters[dataId],
9235
- props: {
9236
- id,
9237
- data,
9238
- ...defaultProps2,
9239
- ...createInteractionProps(interactionConfig),
9240
- ...styleProps,
9241
- ...channelProps,
9242
- ...createParametersProp(
9243
- layerBlending,
9244
- styleProps.parameters || {}
9245
- ),
9246
- // Must come after style
9247
- ...createLoadOptions(token)
9248
- },
9249
- scales
9250
- };
9251
- return layer;
9948
+ });
9949
+ return layerDescriptor;
9252
9950
  } catch (e) {
9253
9951
  console.error(e.message);
9254
9952
  return void 0;
@@ -9329,9 +10027,41 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9329
10027
  strokeColorScale,
9330
10028
  weightField
9331
10029
  } = visualChannels;
10030
+ if (layerType === "raster") {
10031
+ const rasterStyleType = config2.visConfig.rasterStyleType;
10032
+ if (rasterStyleType === "Rgb") {
10033
+ return {
10034
+ channelProps: getRasterTileLayerStylePropsRgb({
10035
+ layerConfig: config2,
10036
+ rasterMetadata: data.raster_metadata,
10037
+ visualChannels
10038
+ }),
10039
+ scales: {}
10040
+ };
10041
+ } else {
10042
+ return {
10043
+ channelProps: getRasterTileLayerStylePropsScaledBand({
10044
+ layerConfig: config2,
10045
+ visualChannels,
10046
+ rasterMetadata: data.raster_metadata
10047
+ }),
10048
+ scales: {
10049
+ ...colorField && {
10050
+ fillColor: {
10051
+ field: colorField,
10052
+ type: "ordinal",
10053
+ domain: [],
10054
+ range: []
10055
+ }
10056
+ }
10057
+ }
10058
+ };
10059
+ }
10060
+ }
9332
10061
  const { heightField, heightScale } = visualChannels;
9333
10062
  const { textLabel, visConfig } = config2;
9334
10063
  const result = {};
10064
+ const updateTriggers = {};
9335
10065
  const scales = {};
9336
10066
  if (colorField) {
9337
10067
  const { colorAggregation: aggregation, colorRange: range } = visConfig;
@@ -9343,7 +10073,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9343
10073
  data
9344
10074
  );
9345
10075
  result.getFillColor = accessor;
9346
- scales.fillColor = {
10076
+ scales.fillColor = updateTriggers.getFillColor = {
9347
10077
  field: colorField,
9348
10078
  type: colorScale,
9349
10079
  ...domainAndRangeFromScale(scale2)
@@ -9362,6 +10092,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9362
10092
  result.getWeight = (d) => {
9363
10093
  return d.properties[aggregationExpAlias];
9364
10094
  };
10095
+ updateTriggers.getWeight = aggregationExpAlias;
9365
10096
  result.getPointRadius = (d, info) => {
9366
10097
  return calculateClusterRadius(
9367
10098
  d.properties,
@@ -9370,11 +10101,16 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9370
10101
  aggregationExpAlias
9371
10102
  );
9372
10103
  };
10104
+ updateTriggers.getPointRadius = {
10105
+ aggregationExpAlias,
10106
+ radiusRange: visConfig.radiusRange
10107
+ };
9373
10108
  result.textCharacterSet = "auto";
9374
10109
  result.textFontFamily = "Inter, sans";
9375
10110
  result.textFontSettings = { sdf: true };
9376
10111
  result.textFontWeight = 600;
9377
10112
  result.getText = (d) => TEXT_NUMBER_FORMATTER.format(d.properties[aggregationExpAlias]);
10113
+ updateTriggers.getText = aggregationExpAlias;
9378
10114
  result.getTextColor = config2.textLabel[TEXT_LABEL_INDEX].color;
9379
10115
  result.textOutlineColor = [
9380
10116
  ...config2.textLabel[TEXT_LABEL_INDEX].outlineColor,
@@ -9391,6 +10127,10 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9391
10127
  );
9392
10128
  return calculateClusterTextFontSize(radius);
9393
10129
  };
10130
+ updateTriggers.getTextSize = {
10131
+ aggregationExpAlias,
10132
+ radiusRange: visConfig.radiusRange
10133
+ };
9394
10134
  }
9395
10135
  if (radiusField) {
9396
10136
  const { accessor, scale: scale2 } = getSizeAccessor(
@@ -9401,7 +10141,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9401
10141
  data
9402
10142
  );
9403
10143
  result.getPointRadius = accessor;
9404
- scales.pointRadius = {
10144
+ scales.pointRadius = updateTriggers.getPointRadius = {
9405
10145
  field: radiusField,
9406
10146
  type: radiusScale || "identity",
9407
10147
  ...domainAndRangeFromScale(scale2)
@@ -9418,7 +10158,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9418
10158
  data
9419
10159
  );
9420
10160
  result.getLineColor = accessor;
9421
- scales.lineColor = {
10161
+ scales.lineColor = updateTriggers.getLineColor = {
9422
10162
  field: strokeColorField,
9423
10163
  type: strokeColorScale,
9424
10164
  ...domainAndRangeFromScale(scale2)
@@ -9433,7 +10173,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9433
10173
  data
9434
10174
  );
9435
10175
  result.getElevation = accessor;
9436
- scales.elevation = {
10176
+ scales.elevation = updateTriggers.getElevation = {
9437
10177
  field: heightField,
9438
10178
  type: heightScale || "identity",
9439
10179
  ...domainAndRangeFromScale(scale2)
@@ -9448,7 +10188,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9448
10188
  data
9449
10189
  );
9450
10190
  result.getWeight = accessor;
9451
- scales.weight = {
10191
+ scales.weight = updateTriggers.getWeight = {
9452
10192
  field: weightField,
9453
10193
  type: "identity",
9454
10194
  ...domainAndRangeFromScale(scale2)
@@ -9469,6 +10209,12 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9469
10209
  { fallbackUrl: customMarkersUrl, maxIconSize, useMaskedIcons },
9470
10210
  data
9471
10211
  );
10212
+ updateTriggers.getIcon = {
10213
+ customMarkersUrl,
10214
+ customMarkersRange,
10215
+ maxIconSize,
10216
+ useMaskedIcons
10217
+ };
9472
10218
  result._subLayerProps = {
9473
10219
  "points-icon": {
9474
10220
  loadOptions: {
@@ -9485,9 +10231,11 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9485
10231
  };
9486
10232
  if (getFillColor && useMaskedIcons) {
9487
10233
  result.getIconColor = getFillColor;
10234
+ updateTriggers.getIconColor = updateTriggers.getFillColor;
9488
10235
  }
9489
10236
  if (getPointRadius) {
9490
10237
  result.getIconSize = getPointRadius;
10238
+ updateTriggers.getIconSize = updateTriggers.getPointRadius;
9491
10239
  }
9492
10240
  if (visualChannels.rotationField) {
9493
10241
  const { accessor } = getSizeAccessor(
@@ -9498,6 +10246,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9498
10246
  data
9499
10247
  );
9500
10248
  result.getIconAngle = negateAccessor(accessor);
10249
+ updateTriggers.getIconAngle = updateTriggers.getRotationField;
9501
10250
  }
9502
10251
  } else if (layerType === "tileset") {
9503
10252
  result.pointType = "circle";
@@ -9542,7 +10291,13 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9542
10291
  }
9543
10292
  };
9544
10293
  }
9545
- return { channelProps: result, scales };
10294
+ return {
10295
+ channelProps: {
10296
+ ...result,
10297
+ updateTriggers
10298
+ },
10299
+ scales
10300
+ };
9546
10301
  }
9547
10302
  function createLoadOptions(accessToken) {
9548
10303
  return {
@@ -10189,9 +10944,14 @@ export {
10189
10944
  WidgetSource,
10190
10945
  WidgetTableSource,
10191
10946
  WidgetTilesetSource,
10947
+ ErrorCode as _ErrorCode,
10192
10948
  _buildFeatureFilter,
10949
+ createVecExprEvaluator as _createVecExprEvaluator,
10193
10950
  domainFromValues as _domainFromValues,
10951
+ evaluateVecExpr as _evaluateVecExpr,
10194
10952
  _getHexagonResolution,
10953
+ getRasterTileLayerStyleProps as _getRasterTileLayerStyleProps,
10954
+ validateVecExprSyntax as _validateVecExprSyntax,
10195
10955
  addFilter,
10196
10956
  aggregate,
10197
10957
  aggregationFunctions,
@@ -10204,9 +10964,11 @@ export {
10204
10964
  buildStatsUrl,
10205
10965
  calculateClusterRadius,
10206
10966
  calculateClusterTextFontSize,
10967
+ calculateLayerScale,
10207
10968
  clearDefaultRequestCache,
10208
10969
  clearFilters,
10209
10970
  configureSource,
10971
+ createColorScale,
10210
10972
  createPolygonSpatialFilter,
10211
10973
  createViewportSpatialFilter,
10212
10974
  fetchBasemapProps,
@@ -10221,6 +10983,7 @@ export {
10221
10983
  getDefaultAggregationExpColumnAliasForLayerType,
10222
10984
  getFilter,
10223
10985
  getIconUrlAccessor,
10986
+ getLayerDescriptor,
10224
10987
  getLayerProps,
10225
10988
  getMaxMarkerSize,
10226
10989
  getSizeAccessor,