@mapbox/mapbox-gl-style-spec 14.2.0 → 14.3.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.
package/dist/index.cjs CHANGED
@@ -871,6 +871,17 @@
871
871
  type: "*",
872
872
  doc: "Contains the description of the raster data layers and the bands contained within the tiles."
873
873
  },
874
+ volatile: {
875
+ type: "boolean",
876
+ "default": false,
877
+ doc: "A setting to determine whether a source's tiles are cached locally.",
878
+ "sdk-support": {
879
+ "basic functionality": {
880
+ android: "9.3.0",
881
+ ios: "5.10.0"
882
+ }
883
+ }
884
+ },
874
885
  "*": {
875
886
  type: "*",
876
887
  doc: "Other keys to configure the data source."
@@ -1122,6 +1133,17 @@
1122
1133
  }
1123
1134
  }
1124
1135
  },
1136
+ "raster-particle": {
1137
+ doc: "Particle animation driven by textures such as wind maps.",
1138
+ "sdk-support": {
1139
+ "basic functionality": {
1140
+ js: "0.10.0",
1141
+ android: "2.0.1",
1142
+ ios: "2.0.0",
1143
+ macos: "0.1.0"
1144
+ }
1145
+ }
1146
+ },
1125
1147
  hillshade: {
1126
1148
  doc: "Client-side hillshading visualization based on DEM data. Currently, the implementation only supports Mapbox Terrain RGB and Mapzen Terrarium tiles.",
1127
1149
  "sdk-support": {
@@ -1232,6 +1254,7 @@
1232
1254
  "layout_fill-extrusion",
1233
1255
  "layout_symbol",
1234
1256
  "layout_raster",
1257
+ "layout_raster-particle",
1235
1258
  "layout_hillshade",
1236
1259
  "layout_background",
1237
1260
  "layout_sky",
@@ -3588,7 +3611,7 @@
3588
3611
  }
3589
3612
  },
3590
3613
  image: {
3591
- doc: "Returns a [`ResolvedImage`](/mapbox-gl-js/style-spec/types/#resolvedimage) for use in [`icon-image`](/mapbox-gl-js/style-spec/layers/#layout-symbol-icon-image), `*-pattern` entries, and as a section in the [`'format'`](#types-format) expression. A [`'coalesce'`](#coalesce) expression containing `image` expressions will evaluate to the first listed image that is currently in the style. This validation process is synchronous and requires the image to have been added to the style before requesting it in the `'image'` argument.",
3614
+ doc: "Returns a [`ResolvedImage`](/mapbox-gl-js/style-spec/types/#resolvedimage) for use in [`icon-image`](/mapbox-gl-js/style-spec/layers/#layout-symbol-icon-image), `*-pattern` entries, and as a section in the [`'format'`](#types-format) expression. A [`'coalesce'`](#coalesce) expression containing `image` expressions will evaluate to the first listed image that is currently in the style. This validation process is synchronous and requires the image to have been added to the style before requesting it in the `'image'` argument. To implement crossfading between two images within a symbol layer using the [`icon-image-cross-fade`](/mapbox-gl-js/style-spec/layers/#paint-symbol-icon-image-cross-fade) attribute, include a second image as the second argument in the `'image'` expression.",
3592
3615
  group: "Types",
3593
3616
  "sdk-support": {
3594
3617
  "basic functionality": {
@@ -4332,6 +4355,17 @@
4332
4355
  }
4333
4356
  }
4334
4357
  },
4358
+ "raster-particle-speed": {
4359
+ doc: "Returns the length of the particle velocity vector. Can only be used in the `raster-particle-color` property.",
4360
+ group: "Raster Particle Animation",
4361
+ "sdk-support": {
4362
+ "basic functionality": {
4363
+ js: "3.3.0",
4364
+ android: "",
4365
+ ios: ""
4366
+ }
4367
+ }
4368
+ },
4335
4369
  random: {
4336
4370
  doc: "Returns a random value in the specified range (first two input numbers) based on a supplied seed (third input). The seed can be an expression or a constant number or string value.",
4337
4371
  group: "Math",
@@ -6331,6 +6365,9 @@
6331
6365
  "measure-light"
6332
6366
  ]
6333
6367
  },
6368
+ requires: [
6369
+ "icon-image"
6370
+ ],
6334
6371
  "sdk-support": {
6335
6372
  "basic functionality": {
6336
6373
  js: "3.0.0",
@@ -6671,10 +6708,6 @@
6671
6708
  },
6672
6709
  "raster-color-range": {
6673
6710
  type: "array",
6674
- "default": [
6675
- 0,
6676
- 1
6677
- ],
6678
6711
  length: 2,
6679
6712
  value: "number",
6680
6713
  "property-type": "data-constant",
@@ -6688,7 +6721,7 @@
6688
6721
  "zoom"
6689
6722
  ]
6690
6723
  },
6691
- doc: "When `raster-color` is active, specifies the range over which `raster-color` is tabulated. Units correspond to the computed raster value via `raster-color-mix`.",
6724
+ doc: "When `raster-color` is active, specifies the range over which `raster-color` is tabulated. Units correspond to the computed raster value via `raster-color-mix`. For `rasterarray` sources, if `raster-color-range` is unspecified, the source's stated data range is used.",
6692
6725
  example: [
6693
6726
  0.5,
6694
6727
  10
@@ -6908,7 +6941,7 @@
6908
6941
  },
6909
6942
  "raster-elevation": {
6910
6943
  type: "number",
6911
- doc: "Specifies an uniform elevation from the ground, in meters. Only supported with image sources.",
6944
+ doc: "Specifies an uniform elevation from the ground, in meters.",
6912
6945
  "default": 0,
6913
6946
  minimum: 0,
6914
6947
  transition: true,
@@ -7982,6 +8015,37 @@
7982
8015
  layout_line: layout_line,
7983
8016
  layout_symbol: layout_symbol,
7984
8017
  layout_raster: layout_raster,
8018
+ "layout_raster-particle": {
8019
+ visibility: {
8020
+ type: "enum",
8021
+ values: {
8022
+ visible: {
8023
+ doc: "The layer is shown."
8024
+ },
8025
+ none: {
8026
+ doc: "The layer is not shown."
8027
+ }
8028
+ },
8029
+ "default": "visible",
8030
+ doc: "Whether this layer is displayed.",
8031
+ "sdk-support": {
8032
+ "basic functionality": {
8033
+ js: "0.10.0",
8034
+ android: "2.0.1",
8035
+ ios: "2.0.0"
8036
+ },
8037
+ "expressions support": {
8038
+ js: "3.0.0",
8039
+ android: "11.0.0",
8040
+ ios: "11.0.0"
8041
+ }
8042
+ },
8043
+ expression: {
8044
+ interpolated: false
8045
+ },
8046
+ "property-type": "constant"
8047
+ }
8048
+ },
7985
8049
  layout_hillshade: layout_hillshade,
7986
8050
  filter: filter,
7987
8051
  filter_symbol: filter_symbol,
@@ -8648,6 +8712,134 @@
8648
8712
  paint_heatmap: paint_heatmap,
8649
8713
  paint_symbol: paint_symbol,
8650
8714
  paint_raster: paint_raster,
8715
+ "paint_raster-particle": {
8716
+ "raster-particle-array-band": {
8717
+ type: "string",
8718
+ required: false,
8719
+ "property-type": "data-constant",
8720
+ transition: false,
8721
+ doc: "Displayed band of raster array source layer",
8722
+ example: "band-name",
8723
+ "sdk-support": {
8724
+ "basic functionality": {
8725
+ js: "",
8726
+ android: "",
8727
+ ios: ""
8728
+ }
8729
+ }
8730
+ },
8731
+ "raster-particle-count": {
8732
+ type: "number",
8733
+ doc: "Defines the amount of particles per tile.",
8734
+ "default": 512,
8735
+ minimum: 1,
8736
+ transition: false,
8737
+ "sdk-support": {
8738
+ "basic functionality": {
8739
+ js: "",
8740
+ android: "",
8741
+ ios: ""
8742
+ }
8743
+ },
8744
+ "property-type": "data-constant"
8745
+ },
8746
+ "raster-particle-color": {
8747
+ type: "color",
8748
+ doc: "Defines a color map by which to colorize a raster particle layer, parameterized by the `[\"raster-particle-speed\"]` expression and evaluated at 256 uniformly spaced steps over the range specified by `raster-particle-max-speed`.",
8749
+ transition: false,
8750
+ "sdk-support": {
8751
+ "basic functionality": {
8752
+ js: "",
8753
+ android: "",
8754
+ ios: ""
8755
+ },
8756
+ "data-driven styling": {
8757
+ }
8758
+ },
8759
+ expression: {
8760
+ interpolated: true,
8761
+ parameters: [
8762
+ "raster-particle-speed"
8763
+ ]
8764
+ },
8765
+ "property-type": "color-ramp"
8766
+ },
8767
+ "raster-particle-max-speed": {
8768
+ type: "number",
8769
+ doc: "Defines the maximum speed for particles. Velocities with magnitudes equal to or exceeding this value are clamped to the max value.",
8770
+ "default": 1,
8771
+ minimum: 1,
8772
+ transition: false,
8773
+ "sdk-support": {
8774
+ "basic functionality": {
8775
+ js: "",
8776
+ android: "",
8777
+ ios: ""
8778
+ }
8779
+ },
8780
+ "property-type": "data-constant"
8781
+ },
8782
+ "raster-particle-speed-factor": {
8783
+ type: "number",
8784
+ doc: "Defines a coefficient for the speed of particles’ motion.",
8785
+ "default": 0.2,
8786
+ minimum: 0,
8787
+ maximum: 1,
8788
+ transition: true,
8789
+ "sdk-support": {
8790
+ "basic functionality": {
8791
+ js: "",
8792
+ android: "",
8793
+ ios: ""
8794
+ }
8795
+ },
8796
+ expression: {
8797
+ interpolated: true,
8798
+ parameters: [
8799
+ "zoom"
8800
+ ]
8801
+ },
8802
+ "property-type": "data-constant"
8803
+ },
8804
+ "raster-particle-fade-opacity-factor": {
8805
+ type: "number",
8806
+ doc: "Defines defines the opacity coefficient applied to the faded particles in each frame. In practice, this property controls the length of the particle tail.",
8807
+ "default": 0.98,
8808
+ minimum: 0,
8809
+ maximum: 1,
8810
+ transition: true,
8811
+ "sdk-support": {
8812
+ "basic functionality": {
8813
+ js: "",
8814
+ android: "",
8815
+ ios: ""
8816
+ }
8817
+ },
8818
+ expression: {
8819
+ interpolated: true,
8820
+ parameters: [
8821
+ "zoom"
8822
+ ]
8823
+ },
8824
+ "property-type": "data-constant"
8825
+ },
8826
+ "raster-particle-reset-rate-factor": {
8827
+ type: "number",
8828
+ doc: "Defines a coefficient for a time period at which particles will restart at a random position, to avoid degeneration (empty areas without particles).",
8829
+ "default": 0.8,
8830
+ minimum: 0,
8831
+ maximum: 1,
8832
+ transition: false,
8833
+ "sdk-support": {
8834
+ "basic functionality": {
8835
+ js: "",
8836
+ android: "",
8837
+ ios: ""
8838
+ }
8839
+ },
8840
+ "property-type": "data-constant"
8841
+ }
8842
+ },
8651
8843
  paint_hillshade: paint_hillshade,
8652
8844
  paint_background: paint_background,
8653
8845
  paint_sky: paint_sky,
@@ -13245,6 +13437,125 @@
13245
13437
  }
13246
13438
  var Distance$1 = Distance;
13247
13439
 
13440
+ //
13441
+ function coerceValue(type, value) {
13442
+ switch (type) {
13443
+ case 'string':
13444
+ return toString(value);
13445
+ case 'number':
13446
+ return +value;
13447
+ case 'boolean':
13448
+ return !!value;
13449
+ case 'color':
13450
+ return Color$1.parse(value);
13451
+ case 'formatted': {
13452
+ return Formatted.fromString(toString(value));
13453
+ }
13454
+ case 'resolvedImage': {
13455
+ return ResolvedImage.fromString(toString(value));
13456
+ }
13457
+ }
13458
+ return value;
13459
+ }
13460
+ function clampToAllowedNumber(value, min, max, step) {
13461
+ if (step !== undefined) {
13462
+ value = step * Math.round(value / step);
13463
+ }
13464
+ if (min !== undefined && value < min) {
13465
+ value = min;
13466
+ }
13467
+ if (max !== undefined && value > max) {
13468
+ value = max;
13469
+ }
13470
+ return value;
13471
+ }
13472
+ class Config {
13473
+ constructor(type, key, scope) {
13474
+ this.type = type;
13475
+ this.key = key;
13476
+ this.scope = scope;
13477
+ }
13478
+ static parse(args, context) {
13479
+ let type = context.expectedType;
13480
+ if (type === null || type === undefined) {
13481
+ type = ValueType;
13482
+ }
13483
+ if (args.length < 2 || args.length > 3) {
13484
+ return context.error(`Invalid number of arguments for 'config' expression.`);
13485
+ }
13486
+ const configKey = context.parse(args[1], 1);
13487
+ if (!(configKey instanceof Literal$1)) {
13488
+ return context.error(`Key name of 'config' expression must be a string literal.`);
13489
+ }
13490
+ if (args.length >= 3) {
13491
+ const configScope = context.parse(args[2], 2);
13492
+ if (!(configScope instanceof Literal$1)) {
13493
+ return context.error(`Scope of 'config' expression must be a string literal.`);
13494
+ }
13495
+ return new Config(type, toString(configKey.value), toString(configScope.value));
13496
+ }
13497
+ return new Config(type, toString(configKey.value));
13498
+ }
13499
+ evaluate(ctx) {
13500
+ const FQIDSeparator = '\x1F';
13501
+ const configKey = [
13502
+ this.key,
13503
+ this.scope,
13504
+ ctx.scope
13505
+ ].filter(Boolean).join(FQIDSeparator);
13506
+ const config = ctx.getConfig(configKey);
13507
+ if (!config)
13508
+ return null;
13509
+ const {type, value, values, minValue, maxValue, stepValue} = config;
13510
+ const defaultValue = config.default.evaluate(ctx);
13511
+ let result = defaultValue;
13512
+ if (value) {
13513
+ // temporarily override scope to parent to evaluate config expressions passed from the parent
13514
+ const originalScope = ctx.scope;
13515
+ ctx.scope = (originalScope || '').split(FQIDSeparator).slice(1).join(FQIDSeparator);
13516
+ result = value.evaluate(ctx);
13517
+ ctx.scope = originalScope;
13518
+ }
13519
+ if (type) {
13520
+ result = coerceValue(type, result);
13521
+ }
13522
+ if (result !== undefined && (minValue !== undefined || maxValue !== undefined || stepValue !== undefined)) {
13523
+ if (typeof result === 'number') {
13524
+ result = clampToAllowedNumber(result, minValue, maxValue, stepValue);
13525
+ } else if (Array.isArray(result)) {
13526
+ result = result.map(item => typeof item === 'number' ? clampToAllowedNumber(item, minValue, maxValue, stepValue) : item);
13527
+ }
13528
+ }
13529
+ if (value !== undefined && result !== undefined && values && !values.includes(result)) {
13530
+ // The result is not among the allowed values. Instead, use the default value from the option.
13531
+ result = defaultValue;
13532
+ if (type) {
13533
+ result = coerceValue(type, result);
13534
+ }
13535
+ }
13536
+ if (type && type !== this.type || result !== undefined && typeOf(result) !== this.type) {
13537
+ result = coerceValue(this.type.kind, result);
13538
+ }
13539
+ return result;
13540
+ }
13541
+ eachChild() {
13542
+ }
13543
+ outputDefined() {
13544
+ return false;
13545
+ }
13546
+ serialize() {
13547
+ const res = [
13548
+ 'config',
13549
+ this.key
13550
+ ];
13551
+ if (this.scope) {
13552
+ res.concat(this.key);
13553
+ }
13554
+ return res;
13555
+ }
13556
+ }
13557
+ var Config$1 = Config;
13558
+
13248
13559
  //
13249
13560
  function isFeatureConstant(e) {
13250
13561
  if (e instanceof CompoundExpression$1) {
@@ -13289,10 +13600,8 @@
13289
13600
  return result;
13290
13601
  }
13291
13602
  function isConfigConstant(e) {
13292
- if (e instanceof CompoundExpression$1) {
13293
- if (e.name === 'config') {
13294
- return false;
13295
- }
13603
+ if (e instanceof Config$1) {
13604
+ return false;
13296
13605
  }
13297
13606
  let result = true;
13298
13607
  e.eachChild(arg => {
@@ -13494,8 +13803,6 @@
13494
13803
  return isConstant(expression.boundExpression);
13495
13804
  } else if (expression instanceof CompoundExpression$1 && expression.name === 'error') {
13496
13805
  return false;
13497
- } else if (expression instanceof CompoundExpression$1 && expression.name === 'config') {
13498
- return false;
13499
13806
  } else if (expression instanceof CollatorExpression) {
13500
13807
  // Although the results of a Collator expression with fixed arguments
13501
13808
  // generally shouldn't change between executions, we can't serialize them
@@ -13505,6 +13812,8 @@
13505
13812
  return false;
13506
13813
  } else if (expression instanceof Distance$1) {
13507
13814
  return false;
13815
+ } else if (expression instanceof Config$1) {
13816
+ return false;
13508
13817
  }
13509
13818
  const isTypeAnnotation = expression instanceof Coercion$1 || expression instanceof Assertion$1;
13510
13819
  let childrenConstant = true;
@@ -13534,7 +13843,8 @@
13534
13843
  'is-supported-script',
13535
13844
  'pitch',
13536
13845
  'distance-from-center',
13537
- 'measure-light'
13846
+ 'measure-light',
13847
+ 'raster-particle-speed'
13538
13848
  ]);
13539
13849
  }
13540
13850
 
@@ -15018,7 +15328,9 @@
15018
15328
  // $FlowFixMe[method-unbinding]
15019
15329
  'within': Within$1,
15020
15330
  // $FlowFixMe[method-unbinding]
15021
- 'distance': Distance$1
15331
+ 'distance': Distance$1,
15332
+ // $FlowFixMe[method-unbinding]
15333
+ 'config': Config$1
15022
15334
  };
15023
15335
  function rgba(ctx, [r, g, b, a]) {
15024
15336
  r = r.evaluate(ctx);
@@ -15051,69 +15363,6 @@
15051
15363
  const v = obj[key];
15052
15364
  return typeof v === 'undefined' ? null : v;
15053
15365
  }
15054
- function coerceValue(type, value) {
15055
- switch (type) {
15056
- case 'string':
15057
- return String(value);
15058
- case 'number':
15059
- return +value;
15060
- case 'boolean':
15061
- return !!value;
15062
- case 'color':
15063
- return Color$1.parse(value);
15064
- }
15065
- return value;
15066
- }
15067
- function clampToAllowedNumber(value, min, max, step) {
15068
- if (step !== undefined) {
15069
- value = step * Math.round(value / step);
15070
- }
15071
- if (min !== undefined && value < min) {
15072
- value = min;
15073
- }
15074
- if (max !== undefined && value > max) {
15075
- value = max;
15076
- }
15077
- return value;
15078
- }
15079
- const FQIDSeparator = '\x1F';
15080
- function getConfig(ctx, key, scope) {
15081
- // Create a fully qualified key from the requested scope
15082
- // and the scope from the current evaluation context
15083
- key = [
15084
- key,
15085
- scope,
15086
- ctx.scope
15087
- ].filter(Boolean).join(FQIDSeparator);
15088
- const config = ctx.getConfig(key);
15089
- if (!config)
15090
- return null;
15091
- const {type, value, values, minValue, maxValue, stepValue} = config;
15092
- const defaultValue = config.default.evaluate(ctx);
15093
- let result = defaultValue;
15094
- if (value) {
15095
- // temporarily override scope to parent to evaluate config expressions passed from the parent
15096
- const originalScope = ctx.scope;
15097
- ctx.scope = (originalScope || '').split(FQIDSeparator).slice(1).join(FQIDSeparator);
15098
- result = value.evaluate(ctx);
15099
- ctx.scope = originalScope;
15100
- }
15101
- if (type)
15102
- result = coerceValue(type, result);
15103
- if (value !== undefined && result !== undefined && values && !values.includes(result)) {
15104
- result = defaultValue;
15105
- if (type)
15106
- result = coerceValue(type, result);
15107
- }
15108
- if (result !== undefined && (minValue !== undefined || maxValue !== undefined || stepValue !== undefined)) {
15109
- if (typeof result === 'number') {
15110
- result = clampToAllowedNumber(result, minValue, maxValue, stepValue);
15111
- } else if (Array.isArray(result)) {
15112
- result = result.map(item => typeof item === 'number' ? clampToAllowedNumber(item, minValue, maxValue, stepValue) : item);
15113
- }
15114
- }
15115
- return result;
15116
- }
15117
15366
  function binarySearch(v, a, i, j) {
15118
15367
  while (i <= j) {
15119
15368
  const m = i + j >> 1;
@@ -15231,22 +15480,6 @@
15231
15480
  ]
15232
15481
  ]
15233
15482
  },
15234
- 'config': {
15235
- type: ValueType,
15236
- overloads: [
15237
- [
15238
- [StringType],
15239
- (ctx, [key]) => getConfig(ctx, key.evaluate(ctx))
15240
- ],
15241
- [
15242
- [
15243
- StringType,
15244
- StringType
15245
- ],
15246
- (ctx, [key, scope]) => getConfig(ctx, key.evaluate(ctx), scope.evaluate(ctx))
15247
- ]
15248
- ]
15249
- },
15250
15483
  'feature-state': [
15251
15484
  ValueType,
15252
15485
  [StringType],
@@ -15302,6 +15535,11 @@
15302
15535
  [],
15303
15536
  ctx => ctx.globals.rasterValue || 0
15304
15537
  ],
15538
+ 'raster-particle-speed': [
15539
+ NumberType,
15540
+ [],
15541
+ ctx => ctx.globals.rasterParticleSpeed || 0
15542
+ ],
15305
15543
  'sky-radial-progress': [
15306
15544
  NumberType,
15307
15545
  [],
@@ -17459,18 +17697,10 @@ ${ JSON.stringify(filterExp, null, 2) }
17459
17697
  * { command: 'removeImport', args: [importId] }
17460
17698
  */
17461
17699
  removeImport: 'removeImport',
17462
- /*
17463
- * { command: 'setImportUrl', args: [importId, styleUrl] }
17464
- */
17465
- setImportUrl: 'setImportUrl',
17466
- /*
17467
- * { command: 'setImportData', args: [importId, stylesheet] }
17468
- */
17469
- setImportData: 'setImportData',
17470
- /*
17471
- * { command: 'setImportConfig', args: [importId, config] }
17700
+ /**
17701
+ * { command: 'updateImport', args: [importId, importSpecification | styleUrl] }
17472
17702
  */
17473
- setImportConfig: 'setImportConfig'
17703
+ updateImport: 'updateImport'
17474
17704
  };
17475
17705
  function addSource(sourceId, after, commands) {
17476
17706
  commands.push({
@@ -17801,35 +18031,13 @@ ${ JSON.stringify(filterExp, null, 2) }
17801
18031
  const beforeImport = beforeIndex[afterImport.id];
17802
18032
  if (!beforeImport || deepEqual(beforeImport, afterImport))
17803
18033
  continue;
17804
- if (!deepEqual(beforeImport.config, afterImport.config)) {
17805
- commands.push({
17806
- command: operations.setImportConfig,
17807
- args: [
17808
- afterImport.id,
17809
- afterImport.config
17810
- ]
17811
- });
17812
- }
17813
- if (!deepEqual(beforeImport.url, afterImport.url)) {
17814
- commands.push({
17815
- command: operations.setImportUrl,
17816
- args: [
17817
- afterImport.id,
17818
- afterImport.url
17819
- ]
17820
- });
17821
- }
17822
- const beforeData = beforeImport && beforeImport.data;
17823
- const afterData = afterImport.data;
17824
- if (!deepEqual(beforeData, afterData)) {
17825
- commands.push({
17826
- command: operations.setImportData,
17827
- args: [
17828
- afterImport.id,
17829
- afterData
17830
- ]
17831
- });
17832
- }
18034
+ commands.push({
18035
+ command: operations.updateImport,
18036
+ args: [
18037
+ afterImport.id,
18038
+ afterImport
18039
+ ]
18040
+ });
17833
18041
  }
17834
18042
  }
17835
18043
  /**
@@ -18686,8 +18894,15 @@ ${ JSON.stringify(filterExp, null, 2) }
18686
18894
  errors.push(new ValidationError(key, layer, `layer "${ layer.id }" must specify a "source-layer"`));
18687
18895
  } else if (sourceType === 'raster-dem' && type !== 'hillshade') {
18688
18896
  errors.push(new ValidationError(key, layer.source, 'raster-dem source can only be used with layer type \'hillshade\'.'));
18897
+ } else if (sourceType === 'raster-array' && ![
18898
+ 'raster',
18899
+ 'raster-particle'
18900
+ ].includes(type)) {
18901
+ errors.push(new ValidationError(key, layer.source, `raster-array source can only be used with layer type \'raster\'.`));
18689
18902
  } else if (type === 'line' && layer.paint && (layer.paint['line-gradient'] || layer.paint['line-trim-offset']) && (sourceType !== 'geojson' || !source.lineMetrics)) {
18690
18903
  errors.push(new ValidationError(key, layer, `layer "${ layer.id }" specifies a line-gradient, which requires a GeoJSON source with \`lineMetrics\` enabled.`));
18904
+ } else if (type === 'raster-particle' && sourceType !== 'raster-array') {
18905
+ errors.push(new ValidationError(key, layer.source, `layer "${ layer.id }" requires a \'raster-array\' source.`));
18691
18906
  }
18692
18907
  }
18693
18908
  }
@@ -18781,7 +18996,8 @@ ${ JSON.stringify(filterExp, null, 2) }
18781
18996
  if ([
18782
18997
  'vector',
18783
18998
  'raster',
18784
- 'raster-dem'
18999
+ 'raster-dem',
19000
+ 'raster-array'
18785
19001
  ].includes(type)) {
18786
19002
  if (!value.url && !value.tiles) {
18787
19003
  errors.push(new ValidationWarning(key, value, 'Either "url" or "tiles" is required.'));
@@ -18791,6 +19007,7 @@ ${ JSON.stringify(filterExp, null, 2) }
18791
19007
  case 'vector':
18792
19008
  case 'raster':
18793
19009
  case 'raster-dem':
19010
+ case 'raster-array':
18794
19011
  errors = errors.concat(validateObject({
18795
19012
  key,
18796
19013
  value,
@@ -20419,6 +20636,7 @@ ${ JSON.stringify(filterExp, null, 2) }
20419
20636
  'vector',
20420
20637
  'raster',
20421
20638
  'raster-dem',
20639
+ 'raster-array',
20422
20640
  'model',
20423
20641
  'batched-model'
20424
20642
  ]);
@@ -20435,7 +20653,7 @@ ${ JSON.stringify(filterExp, null, 2) }
20435
20653
  ];
20436
20654
  errors.push(...getAllowedKeyErrors(source, sourceKeys, 'source'));
20437
20655
  /*
20438
- * "type" is required and must be one of "vector", "raster", "raster-dem"
20656
+ * "type" is required and must be one of "vector", "raster", "raster-dem", "raster-array"
20439
20657
  */
20440
20658
  if (!acceptedSourceTypes.has(String(source.type))) {
20441
20659
  errors.push(new ValidationError(`sources[${ i }].type`, source.type, `Expected one of [${ Array.from(acceptedSourceTypes).join(', ') }]`));