@carto/api-client 0.5.14 → 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.
@@ -8335,6 +8335,250 @@ var basemap_styles_default = {
8335
8335
  DARK_MATTER_NOLABELS: getStyleUrl("dark-matter-nolabels")
8336
8336
  };
8337
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
+
8338
8582
  // node_modules/d3-array/src/ascending.js
8339
8583
  function ascending(a, b) {
8340
8584
  return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
@@ -8962,6 +9206,12 @@ var sharedPropMap = {
8962
9206
  wireframe: "wireframe"
8963
9207
  }
8964
9208
  };
9209
+ var rasterPropsMap = {
9210
+ isVisible: "visible",
9211
+ visConfig: {
9212
+ opacity: "opacity"
9213
+ }
9214
+ };
8965
9215
  var customMarkersPropsMap = {
8966
9216
  color: "getIconColor",
8967
9217
  visConfig: {
@@ -9005,6 +9255,12 @@ function getLayerProps(type, config2, dataset) {
9005
9255
  `Outdated layer type: ${type}. Please open map in CARTO Builder to automatically migrate.`
9006
9256
  );
9007
9257
  }
9258
+ if (type === "raster") {
9259
+ return {
9260
+ propMap: rasterPropsMap,
9261
+ defaultProps: {}
9262
+ };
9263
+ }
9008
9264
  let basePropMap = sharedPropMap;
9009
9265
  if (config2.visConfig?.customMarkers) {
9010
9266
  basePropMap = mergePropMaps(basePropMap, customMarkersPropsMap);
@@ -9025,6 +9281,9 @@ function getLayerProps(type, config2, dataset) {
9025
9281
  }
9026
9282
  function domainFromAttribute(attribute, scaleType, scaleLength) {
9027
9283
  if (scaleType === "ordinal" || scaleType === "point") {
9284
+ if (!attribute.categories) {
9285
+ return [0, 1];
9286
+ }
9028
9287
  return attribute.categories.map((c) => c.category).filter((c) => c !== void 0 && c !== null);
9029
9288
  }
9030
9289
  if (scaleType === "quantile" && attribute.quantiles) {
@@ -9060,7 +9319,7 @@ function calculateDomain(data, name, scaleType, scaleLength) {
9060
9319
  return [0, 1];
9061
9320
  }
9062
9321
  function normalizeAccessor(accessor, data) {
9063
- if (data.features || data.tilestats) {
9322
+ if (data.features || data.tilestats || data.raster_metadata) {
9064
9323
  return (object, info) => {
9065
9324
  if (object) {
9066
9325
  return accessor(object.properties || object.__source.object.properties);
@@ -9112,7 +9371,6 @@ function getColorAccessor({ name, colorColumn }, scaleType, { aggregation, range
9112
9371
  return { accessor: normalizeAccessor(accessor, data), scale: scale2 };
9113
9372
  }
9114
9373
  function calculateLayerScale(name, scaleType, range, data) {
9115
- const scale2 = SCALE_FUNCS[scaleType]();
9116
9374
  let domain = [];
9117
9375
  let scaleColor = [];
9118
9376
  if (scaleType !== "identity") {
@@ -9130,9 +9388,13 @@ function calculateLayerScale(name, scaleType, range, data) {
9130
9388
  domain = domain.slice(0, scaleColor.length);
9131
9389
  }
9132
9390
  }
9391
+ return createColorScale(scaleType, domain, scaleColor, UNKNOWN_COLOR);
9392
+ }
9393
+ function createColorScale(scaleType, domain, range, unknown) {
9394
+ const scale2 = SCALE_FUNCS[scaleType]();
9133
9395
  scale2.domain(domain);
9134
- scale2.range(scaleColor);
9135
- scale2.unknown(UNKNOWN_COLOR);
9396
+ scale2.range(range);
9397
+ scale2.unknown(unknown);
9136
9398
  return scale2;
9137
9399
  }
9138
9400
  var FALLBACK_ICON = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iNTAiLz4NCjwvc3ZnPg==";
@@ -9247,13 +9509,419 @@ function calculateClusterTextFontSize(radius) {
9247
9509
  return 11;
9248
9510
  }
9249
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
+
9250
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
+ }
9251
9918
  function parseMap(json) {
9252
9919
  const { keplerMapConfig, datasets, token } = json;
9253
9920
  assert2(keplerMapConfig.version === "v1", "Only support Kepler v1");
9254
- const config2 = keplerMapConfig.config;
9255
- const { filters, mapState, mapStyle, popupSettings, legendSettings } = config2;
9256
- 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();
9257
9925
  return {
9258
9926
  id: json.id,
9259
9927
  title: json.title,
@@ -9266,45 +9934,19 @@ function parseMap(json) {
9266
9934
  popupSettings,
9267
9935
  legendSettings,
9268
9936
  token,
9269
- layers: layers.reverse().map(({ id, type, config: config3, visualChannels }) => {
9937
+ layers: layersReverse.map((layer) => {
9270
9938
  try {
9271
- const { dataId } = config3;
9939
+ const { dataId } = layer.config;
9272
9940
  const dataset = datasets.find(
9273
9941
  (d) => d.id === dataId
9274
9942
  );
9275
9943
  assert2(dataset, `No dataset matching dataId: ${dataId}`);
9276
- const { data } = dataset;
9277
- assert2(data, `No data loaded for dataId: ${dataId}`);
9278
- const { propMap, defaultProps: defaultProps2 } = getLayerProps(type, config3, dataset);
9279
- const styleProps = createStyleProps(config3, propMap);
9280
- const { channelProps, scales } = createChannelProps(
9281
- id,
9282
- type,
9283
- config3,
9284
- visualChannels,
9285
- data,
9944
+ const layerDescriptor = getLayerDescriptor({
9945
+ mapConfig,
9946
+ layer,
9286
9947
  dataset
9287
- );
9288
- const layer = {
9289
- type,
9290
- filters: isEmptyObject(filters) || isRemoteCalculationSupported(dataset) ? void 0 : filters[dataId],
9291
- props: {
9292
- id,
9293
- data,
9294
- ...defaultProps2,
9295
- ...createInteractionProps(interactionConfig),
9296
- ...styleProps,
9297
- ...channelProps,
9298
- ...createParametersProp(
9299
- layerBlending,
9300
- styleProps.parameters || {}
9301
- ),
9302
- // Must come after style
9303
- ...createLoadOptions(token)
9304
- },
9305
- scales
9306
- };
9307
- return layer;
9948
+ });
9949
+ return layerDescriptor;
9308
9950
  } catch (e) {
9309
9951
  console.error(e.message);
9310
9952
  return void 0;
@@ -9385,9 +10027,41 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9385
10027
  strokeColorScale,
9386
10028
  weightField
9387
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
+ }
9388
10061
  const { heightField, heightScale } = visualChannels;
9389
10062
  const { textLabel, visConfig } = config2;
9390
10063
  const result = {};
10064
+ const updateTriggers = {};
9391
10065
  const scales = {};
9392
10066
  if (colorField) {
9393
10067
  const { colorAggregation: aggregation, colorRange: range } = visConfig;
@@ -9399,7 +10073,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9399
10073
  data
9400
10074
  );
9401
10075
  result.getFillColor = accessor;
9402
- scales.fillColor = {
10076
+ scales.fillColor = updateTriggers.getFillColor = {
9403
10077
  field: colorField,
9404
10078
  type: colorScale,
9405
10079
  ...domainAndRangeFromScale(scale2)
@@ -9418,6 +10092,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9418
10092
  result.getWeight = (d) => {
9419
10093
  return d.properties[aggregationExpAlias];
9420
10094
  };
10095
+ updateTriggers.getWeight = aggregationExpAlias;
9421
10096
  result.getPointRadius = (d, info) => {
9422
10097
  return calculateClusterRadius(
9423
10098
  d.properties,
@@ -9426,11 +10101,16 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9426
10101
  aggregationExpAlias
9427
10102
  );
9428
10103
  };
10104
+ updateTriggers.getPointRadius = {
10105
+ aggregationExpAlias,
10106
+ radiusRange: visConfig.radiusRange
10107
+ };
9429
10108
  result.textCharacterSet = "auto";
9430
10109
  result.textFontFamily = "Inter, sans";
9431
10110
  result.textFontSettings = { sdf: true };
9432
10111
  result.textFontWeight = 600;
9433
10112
  result.getText = (d) => TEXT_NUMBER_FORMATTER.format(d.properties[aggregationExpAlias]);
10113
+ updateTriggers.getText = aggregationExpAlias;
9434
10114
  result.getTextColor = config2.textLabel[TEXT_LABEL_INDEX].color;
9435
10115
  result.textOutlineColor = [
9436
10116
  ...config2.textLabel[TEXT_LABEL_INDEX].outlineColor,
@@ -9447,6 +10127,10 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9447
10127
  );
9448
10128
  return calculateClusterTextFontSize(radius);
9449
10129
  };
10130
+ updateTriggers.getTextSize = {
10131
+ aggregationExpAlias,
10132
+ radiusRange: visConfig.radiusRange
10133
+ };
9450
10134
  }
9451
10135
  if (radiusField) {
9452
10136
  const { accessor, scale: scale2 } = getSizeAccessor(
@@ -9457,7 +10141,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9457
10141
  data
9458
10142
  );
9459
10143
  result.getPointRadius = accessor;
9460
- scales.pointRadius = {
10144
+ scales.pointRadius = updateTriggers.getPointRadius = {
9461
10145
  field: radiusField,
9462
10146
  type: radiusScale || "identity",
9463
10147
  ...domainAndRangeFromScale(scale2)
@@ -9474,7 +10158,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9474
10158
  data
9475
10159
  );
9476
10160
  result.getLineColor = accessor;
9477
- scales.lineColor = {
10161
+ scales.lineColor = updateTriggers.getLineColor = {
9478
10162
  field: strokeColorField,
9479
10163
  type: strokeColorScale,
9480
10164
  ...domainAndRangeFromScale(scale2)
@@ -9489,7 +10173,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9489
10173
  data
9490
10174
  );
9491
10175
  result.getElevation = accessor;
9492
- scales.elevation = {
10176
+ scales.elevation = updateTriggers.getElevation = {
9493
10177
  field: heightField,
9494
10178
  type: heightScale || "identity",
9495
10179
  ...domainAndRangeFromScale(scale2)
@@ -9504,7 +10188,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9504
10188
  data
9505
10189
  );
9506
10190
  result.getWeight = accessor;
9507
- scales.weight = {
10191
+ scales.weight = updateTriggers.getWeight = {
9508
10192
  field: weightField,
9509
10193
  type: "identity",
9510
10194
  ...domainAndRangeFromScale(scale2)
@@ -9525,6 +10209,12 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9525
10209
  { fallbackUrl: customMarkersUrl, maxIconSize, useMaskedIcons },
9526
10210
  data
9527
10211
  );
10212
+ updateTriggers.getIcon = {
10213
+ customMarkersUrl,
10214
+ customMarkersRange,
10215
+ maxIconSize,
10216
+ useMaskedIcons
10217
+ };
9528
10218
  result._subLayerProps = {
9529
10219
  "points-icon": {
9530
10220
  loadOptions: {
@@ -9541,9 +10231,11 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9541
10231
  };
9542
10232
  if (getFillColor && useMaskedIcons) {
9543
10233
  result.getIconColor = getFillColor;
10234
+ updateTriggers.getIconColor = updateTriggers.getFillColor;
9544
10235
  }
9545
10236
  if (getPointRadius) {
9546
10237
  result.getIconSize = getPointRadius;
10238
+ updateTriggers.getIconSize = updateTriggers.getPointRadius;
9547
10239
  }
9548
10240
  if (visualChannels.rotationField) {
9549
10241
  const { accessor } = getSizeAccessor(
@@ -9554,6 +10246,7 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9554
10246
  data
9555
10247
  );
9556
10248
  result.getIconAngle = negateAccessor(accessor);
10249
+ updateTriggers.getIconAngle = updateTriggers.getRotationField;
9557
10250
  }
9558
10251
  } else if (layerType === "tileset") {
9559
10252
  result.pointType = "circle";
@@ -9598,7 +10291,13 @@ function createChannelProps(id, layerType, config2, visualChannels, data, datase
9598
10291
  }
9599
10292
  };
9600
10293
  }
9601
- return { channelProps: result, scales };
10294
+ return {
10295
+ channelProps: {
10296
+ ...result,
10297
+ updateTriggers
10298
+ },
10299
+ scales
10300
+ };
9602
10301
  }
9603
10302
  function createLoadOptions(accessToken) {
9604
10303
  return {
@@ -10245,9 +10944,14 @@ export {
10245
10944
  WidgetSource,
10246
10945
  WidgetTableSource,
10247
10946
  WidgetTilesetSource,
10947
+ ErrorCode as _ErrorCode,
10248
10948
  _buildFeatureFilter,
10949
+ createVecExprEvaluator as _createVecExprEvaluator,
10249
10950
  domainFromValues as _domainFromValues,
10951
+ evaluateVecExpr as _evaluateVecExpr,
10250
10952
  _getHexagonResolution,
10953
+ getRasterTileLayerStyleProps as _getRasterTileLayerStyleProps,
10954
+ validateVecExprSyntax as _validateVecExprSyntax,
10251
10955
  addFilter,
10252
10956
  aggregate,
10253
10957
  aggregationFunctions,
@@ -10260,9 +10964,11 @@ export {
10260
10964
  buildStatsUrl,
10261
10965
  calculateClusterRadius,
10262
10966
  calculateClusterTextFontSize,
10967
+ calculateLayerScale,
10263
10968
  clearDefaultRequestCache,
10264
10969
  clearFilters,
10265
10970
  configureSource,
10971
+ createColorScale,
10266
10972
  createPolygonSpatialFilter,
10267
10973
  createViewportSpatialFilter,
10268
10974
  fetchBasemapProps,
@@ -10277,6 +10983,7 @@ export {
10277
10983
  getDefaultAggregationExpColumnAliasForLayerType,
10278
10984
  getFilter,
10279
10985
  getIconUrlAccessor,
10986
+ getLayerDescriptor,
10280
10987
  getLayerProps,
10281
10988
  getMaxMarkerSize,
10282
10989
  getSizeAccessor,