maplibre-gl 2.3.0 → 2.4.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.
Files changed (79) hide show
  1. package/build/generate-query-test-fixtures.ts +3 -2
  2. package/build/generate-struct-arrays.ts +0 -2
  3. package/build/generate-style-spec.ts +12 -17
  4. package/build/rollup_plugins.ts +0 -4
  5. package/dist/maplibre-gl-csp-worker.js +1 -1
  6. package/dist/maplibre-gl-csp.js +1 -1
  7. package/dist/maplibre-gl-dev.js +179 -1369
  8. package/dist/maplibre-gl.d.ts +15 -16
  9. package/dist/maplibre-gl.js +4 -4
  10. package/dist/style-spec/index.d.ts +3 -16
  11. package/package.json +20 -21
  12. package/src/data/array_types.g.ts +0 -5
  13. package/src/data/bucket/fill_bucket.ts +0 -2
  14. package/src/data/bucket/fill_extrusion_bucket.ts +0 -2
  15. package/src/data/feature_position_map.ts +1 -2
  16. package/src/gl/framebuffer.ts +3 -2
  17. package/src/gl/index_buffer.ts +1 -2
  18. package/src/gl/vertex_buffer.ts +1 -2
  19. package/src/index.ts +1 -3
  20. package/src/render/draw_debug.ts +1 -1
  21. package/src/render/draw_fill.ts +9 -1
  22. package/src/render/draw_fill_extrusion.ts +8 -1
  23. package/src/render/draw_heatmap.ts +5 -3
  24. package/src/render/draw_hillshade.ts +17 -2
  25. package/src/render/image_manager.ts +5 -7
  26. package/src/render/program/line_program.ts +1 -1
  27. package/src/render/program/pattern.ts +0 -2
  28. package/src/render/program.ts +12 -9
  29. package/src/render/vertex_array_object.ts +1 -3
  30. package/src/source/geojson_worker_source.ts +0 -4
  31. package/src/source/query_features.ts +0 -3
  32. package/src/source/rtl_text_plugin.ts +3 -4
  33. package/src/source/source_cache.ts +0 -2
  34. package/src/source/tile_id.ts +8 -8
  35. package/src/source/worker.ts +0 -7
  36. package/src/source/worker_tile.ts +3 -2
  37. package/src/style/format_section_override.ts +1 -2
  38. package/src/style/properties.ts +1 -3
  39. package/src/style/style.ts +6 -5
  40. package/src/style/style_layer/custom_style_layer.ts +1 -2
  41. package/src/style/style_layer/symbol_style_layer.ts +5 -8
  42. package/src/style-spec/CHANGELOG.md +2 -2
  43. package/src/style-spec/expression/compound_expression.ts +0 -4
  44. package/src/style-spec/expression/definitions/assertion.ts +2 -4
  45. package/src/style-spec/expression/definitions/case.ts +1 -2
  46. package/src/style-spec/expression/definitions/coalesce.ts +1 -3
  47. package/src/style-spec/expression/definitions/coercion.ts +2 -4
  48. package/src/style-spec/expression/definitions/match.ts +0 -3
  49. package/src/style-spec/expression/index.ts +0 -2
  50. package/src/style-spec/expression/values.ts +0 -2
  51. package/src/style-spec/feature_filter/feature_filter.test.ts +39 -2
  52. package/src/style-spec/function/convert.ts +1 -3
  53. package/src/style-spec/types.g.ts +12 -17
  54. package/src/symbol/collision_index.ts +0 -3
  55. package/src/symbol/path_interpolator.ts +0 -2
  56. package/src/symbol/placement.ts +14 -9
  57. package/src/symbol/shaping.ts +0 -4
  58. package/src/ui/camera.test.ts +64 -1
  59. package/src/ui/camera.ts +36 -10
  60. package/src/ui/control/attribution_control.test.ts +62 -0
  61. package/src/ui/control/attribution_control.ts +4 -2
  62. package/src/ui/control/geolocate_control.ts +4 -6
  63. package/src/ui/control/terrain_control.test.ts +60 -0
  64. package/src/ui/handler/handler_util.ts +1 -2
  65. package/src/ui/handler/map_event.test.ts +65 -1
  66. package/src/ui/handler/map_event.ts +4 -1
  67. package/src/ui/handler/scroll_zoom.ts +0 -2
  68. package/src/ui/handler_manager.ts +0 -2
  69. package/src/ui/map.test.ts +105 -0
  70. package/src/ui/map.ts +8 -1
  71. package/src/util/ajax.ts +1 -2
  72. package/src/util/color_ramp.ts +1 -2
  73. package/src/util/dictionary_coder.ts +1 -3
  74. package/src/util/dispatcher.ts +1 -4
  75. package/src/util/dom.ts +0 -3
  76. package/src/util/image.ts +1 -3
  77. package/src/util/struct_array.ts +0 -5
  78. package/src/util/task_queue.ts +1 -3
  79. package/src/util/web_worker_transfer.ts +5 -6
@@ -1,7 +1,6 @@
1
1
  import {Event, Evented} from '../util/evented';
2
2
  import {getArrayBuffer} from '../util/ajax';
3
3
  import browser from '../util/browser';
4
- import assert from 'assert';
5
4
  import {isWorker} from '../util/util';
6
5
 
7
6
  const status = {
@@ -113,20 +112,20 @@ export const plugin: {
113
112
  return pluginStatus === status.loading;
114
113
  },
115
114
  setState(state: PluginState) { // Worker thread only: this tells the worker threads that the plugin is available on the Main thread
116
- assert(isWorker(), 'Cannot set the state of the rtl-text-plugin when not in the web-worker context');
115
+ if (!isWorker()) throw new Error('Cannot set the state of the rtl-text-plugin when not in the web-worker context');
117
116
 
118
117
  pluginStatus = state.pluginStatus;
119
118
  pluginURL = state.pluginURL;
120
119
  },
121
120
  isParsed(): boolean {
122
- assert(isWorker(), 'rtl-text-plugin is only parsed on the worker-threads');
121
+ if (!isWorker()) throw new Error('rtl-text-plugin is only parsed on the worker-threads');
123
122
 
124
123
  return plugin.applyArabicShaping != null &&
125
124
  plugin.processBidirectionalText != null &&
126
125
  plugin.processStyledBidirectionalText != null;
127
126
  },
128
127
  getPluginURL(): string {
129
- assert(isWorker(), 'rtl-text-plugin url can only be queried from the worker threads');
128
+ if (!isWorker()) throw new Error('rtl-text-plugin url can only be queried from the worker threads');
130
129
  return pluginURL;
131
130
  }
132
131
  };
@@ -10,7 +10,6 @@ import Context from '../gl/context';
10
10
  import Point from '@mapbox/point-geometry';
11
11
  import browser from '../util/browser';
12
12
  import {OverscaledTileID} from './tile_id';
13
- import assert from 'assert';
14
13
  import SourceFeatureState from './source_state';
15
14
 
16
15
  import type {Source} from './source';
@@ -556,7 +555,6 @@ class SourceCache extends Evented {
556
555
  const ids = Object.keys(retain);
557
556
  for (const id of ids) {
558
557
  const tileID = retain[id];
559
- assert(tileID.key === id);
560
558
 
561
559
  const tile = this._tiles[id];
562
560
  if (!tile || tile.fadeEndTime && tile.fadeEndTime <= browser.now()) continue;
@@ -2,8 +2,6 @@ import {getTileBBox} from '@mapbox/whoots-js';
2
2
  import EXTENT from '../data/extent';
3
3
  import Point from '@mapbox/point-geometry';
4
4
  import MercatorCoordinate from '../geo/mercator_coordinate';
5
-
6
- import assert from 'assert';
7
5
  import {register} from '../util/web_worker_transfer';
8
6
  import {mat4} from 'gl-matrix';
9
7
 
@@ -14,9 +12,11 @@ export class CanonicalTileID {
14
12
  key: string;
15
13
 
16
14
  constructor(z: number, x: number, y: number) {
17
- assert(z >= 0 && z <= 25);
18
- assert(x >= 0 && x < Math.pow(2, z));
19
- assert(y >= 0 && y < Math.pow(2, z));
15
+
16
+ if (z < 0 || z > 25 || y < 0 || y >= Math.pow(2, z) || x < 0 || x >= Math.pow(2, z)) {
17
+ throw new Error(`x=${x}, y=${y}, z=${z} outside of bounds. 0<=x<${Math.pow(2, z)}, 0<=y<${Math.pow(2, z)} 0<=z<=25 `);
18
+ }
19
+
20
20
  this.z = z;
21
21
  this.x = x;
22
22
  this.y = y;
@@ -79,7 +79,7 @@ export class OverscaledTileID {
79
79
  posMatrix: mat4;
80
80
 
81
81
  constructor(overscaledZ: number, wrap: number, z: number, x: number, y: number) {
82
- assert(overscaledZ >= z);
82
+ if (overscaledZ < z) throw new Error(`overscaledZ should be >= z; overscaledZ = ${overscaledZ}; z = ${z}`);
83
83
  this.overscaledZ = overscaledZ;
84
84
  this.wrap = wrap;
85
85
  this.canonical = new CanonicalTileID(z, +x, +y);
@@ -95,7 +95,7 @@ export class OverscaledTileID {
95
95
  }
96
96
 
97
97
  scaledTo(targetZ: number) {
98
- assert(targetZ <= this.overscaledZ);
98
+ if (targetZ > this.overscaledZ) throw new Error(`targetZ > this.overscaledZ; targetZ = ${targetZ}; overscaledZ = ${this.overscaledZ}`);
99
99
  const zDifference = this.canonical.z - targetZ;
100
100
  if (targetZ > this.canonical.z) {
101
101
  return new OverscaledTileID(targetZ, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y);
@@ -110,7 +110,7 @@ export class OverscaledTileID {
110
110
  * when withWrap == false, implements the same as this.scaledTo(z).wrapped().key.
111
111
  */
112
112
  calculateScaledKey(targetZ: number, withWrap: boolean): string {
113
- assert(targetZ <= this.overscaledZ);
113
+ if (targetZ > this.overscaledZ) throw new Error(`targetZ > this.overscaledZ; targetZ = ${targetZ}; overscaledZ = ${this.overscaledZ}`);
114
114
  const zDifference = this.canonical.z - targetZ;
115
115
  if (targetZ > this.canonical.z) {
116
116
  return calculateKey(this.wrap * +withWrap, targetZ, this.canonical.z, this.canonical.x, this.canonical.y);
@@ -4,7 +4,6 @@ import StyleLayerIndex from '../style/style_layer_index';
4
4
  import VectorTileWorkerSource from './vector_tile_worker_source';
5
5
  import RasterDEMTileWorkerSource from './raster_dem_tile_worker_source';
6
6
  import GeoJSONWorkerSource from './geojson_worker_source';
7
- import assert from 'assert';
8
7
  import {plugin as globalRTLTextPlugin} from './rtl_text_plugin';
9
8
  import {enforceCacheSizeLimit} from '../util/tile_request_cache';
10
9
  import {isWorker} from '../util/util';
@@ -121,7 +120,6 @@ export default class Worker {
121
120
  loadTile(mapId: string, params: WorkerTileParameters & {
122
121
  type: string;
123
122
  }, callback: WorkerTileCallback) {
124
- assert(params.type);
125
123
  this.getWorkerSource(mapId, params.type, params.source).loadTile(params, callback);
126
124
  }
127
125
 
@@ -132,21 +130,18 @@ export default class Worker {
132
130
  reloadTile(mapId: string, params: WorkerTileParameters & {
133
131
  type: string;
134
132
  }, callback: WorkerTileCallback) {
135
- assert(params.type);
136
133
  this.getWorkerSource(mapId, params.type, params.source).reloadTile(params, callback);
137
134
  }
138
135
 
139
136
  abortTile(mapId: string, params: TileParameters & {
140
137
  type: string;
141
138
  }, callback: WorkerTileCallback) {
142
- assert(params.type);
143
139
  this.getWorkerSource(mapId, params.type, params.source).abortTile(params, callback);
144
140
  }
145
141
 
146
142
  removeTile(mapId: string, params: TileParameters & {
147
143
  type: string;
148
144
  }, callback: WorkerTileCallback) {
149
- assert(params.type);
150
145
  this.getWorkerSource(mapId, params.type, params.source).removeTile(params, callback);
151
146
  }
152
147
 
@@ -159,8 +154,6 @@ export default class Worker {
159
154
  } & {
160
155
  type: string;
161
156
  }, callback: WorkerTileCallback) {
162
- assert(params.type);
163
- assert(params.source);
164
157
 
165
158
  if (!this.workerSources[mapId] ||
166
159
  !this.workerSources[mapId][params.type] ||
@@ -8,7 +8,6 @@ import LineBucket from '../data/bucket/line_bucket';
8
8
  import FillBucket from '../data/bucket/fill_bucket';
9
9
  import FillExtrusionBucket from '../data/bucket/fill_extrusion_bucket';
10
10
  import {warnOnce, mapObject} from '../util/util';
11
- import assert from 'assert';
12
11
  import ImageAtlas from '../render/image_atlas';
13
12
  import GlyphAtlas from '../render/glyph_atlas';
14
13
  import EvaluationParameters from '../style/evaluation_parameters';
@@ -105,7 +104,9 @@ class WorkerTile {
105
104
  for (const family of layerFamilies[sourceLayerId]) {
106
105
  const layer = family[0];
107
106
 
108
- assert(layer.source === this.source);
107
+ if (layer.source !== this.source) {
108
+ warnOnce(`layer.source = ${layer.source} does not equal this.source = ${this.source}`);
109
+ }
109
110
  if (layer.minzoom && this.zoom < Math.floor(layer.minzoom)) continue;
110
111
  if (layer.maxzoom && this.zoom >= layer.maxzoom) continue;
111
112
  if (layer.visibility === 'none') continue;
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
  import type {Expression} from '../style-spec/expression/expression';
3
2
  import type EvaluationContext from '../style-spec/expression/evaluation_context';
4
3
  import type {Type} from '../style-spec/expression/types';
@@ -14,7 +13,7 @@ export default class FormatSectionOverride<T> implements Expression {
14
13
  defaultValue: PossiblyEvaluatedPropertyValue<T>;
15
14
 
16
15
  constructor(defaultValue: PossiblyEvaluatedPropertyValue<T>) {
17
- assert(defaultValue.property.overrides !== undefined);
16
+ if (defaultValue.property.overrides === undefined) throw new Error('overrides must be provided to instantiate FormatSectionOverride class');
18
17
  this.type = defaultValue.property.overrides ? defaultValue.property.overrides.runtimeType : NullType;
19
18
  this.defaultValue = defaultValue;
20
19
  }
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
  import {clone, extend, easeCubicInOut} from '../util/util';
3
2
  import * as interpolate from '../style-spec/util/interpolate';
4
3
  import Color from '../style-spec/util/color';
@@ -488,7 +487,7 @@ export class DataConstantProperty<T> implements Property<T, T> {
488
487
  }
489
488
 
490
489
  possiblyEvaluate(value: PropertyValue<T, T>, parameters: EvaluationParameters): T {
491
- assert(!value.isDataDriven());
490
+ if (value.isDataDriven()) throw new Error('Value should not be data driven');
492
491
  return value.expression.evaluate(parameters);
493
492
  }
494
493
 
@@ -668,7 +667,6 @@ export class CrossFadedProperty<T> implements Property<T, CrossFaded<T>> {
668
667
  const constant = value.expression.evaluate(parameters, null, {}, canonical, availableImages);
669
668
  return this._calculate(constant, constant, constant, parameters);
670
669
  } else {
671
- assert(!value.isDataDriven());
672
670
  return this._calculate(
673
671
  value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom - 1.0), parameters)),
674
672
  value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom), parameters)),
@@ -1,5 +1,3 @@
1
- import assert from 'assert';
2
-
3
1
  import {Event, ErrorEvent, Evented} from '../util/evented';
4
2
  import StyleLayer from './style_layer';
5
3
  import createStyleLayer from './create_style_layer';
@@ -402,11 +400,13 @@ class Style extends Evented {
402
400
  }
403
401
  for (const id in this._updatedSources) {
404
402
  const action = this._updatedSources[id];
405
- assert(action === 'reload' || action === 'clear');
403
+
406
404
  if (action === 'reload') {
407
405
  this._reloadSource(id);
408
406
  } else if (action === 'clear') {
409
407
  this._clearSource(id);
408
+ } else {
409
+ throw new Error(`Invalid action ${action}`);
410
410
  }
411
411
  }
412
412
 
@@ -499,6 +499,7 @@ class Style extends Evented {
499
499
 
500
500
  // remove terrain
501
501
  if (!options) {
502
+ if (this.terrain) this.terrain.sourceCache.destruct();
502
503
  this.terrain = null;
503
504
  this.map.transform.updateElevation(this.terrain);
504
505
 
@@ -677,9 +678,9 @@ class Style extends Evented {
677
678
  setGeoJSONSourceData(id: string, data: GeoJSON.GeoJSON | string) {
678
679
  this._checkLoaded();
679
680
 
680
- assert(this.sourceCaches[id] !== undefined, 'There is no source with this ID');
681
+ if (this.sourceCaches[id] === undefined) throw new Error(`There is no source with this ID=${id}`);
681
682
  const geojsonSource: GeoJSONSource = (this.sourceCaches[id].getSource() as any);
682
- assert(geojsonSource.type === 'geojson');
683
+ if (geojsonSource.type !== 'geojson') throw new Error(`geojsonSource.type is ${geojsonSource.type}, which is !== 'geojson`);
683
684
 
684
685
  geojsonSource.setData(data);
685
686
  this._changed = true;
@@ -1,6 +1,5 @@
1
1
  import StyleLayer from '../style_layer';
2
2
  import type Map from '../../ui/map';
3
- import assert from 'assert';
4
3
  import {mat4} from 'gl-matrix';
5
4
  import {LayerSpecification} from '../../style-spec/types.g';
6
5
 
@@ -206,7 +205,7 @@ class CustomStyleLayer extends StyleLayer {
206
205
  hasTransition() { return false; }
207
206
 
208
207
  serialize(): LayerSpecification {
209
- assert(false, 'Custom layers cannot be serialized');
208
+ throw new Error('Custom layers cannot be serialized');
210
209
  }
211
210
 
212
211
  onAdd = (map: Map) => {
@@ -1,6 +1,5 @@
1
1
  import StyleLayer from '../style_layer';
2
2
 
3
- import assert from 'assert';
4
3
  import SymbolBucket, {SymbolFeature} from '../../data/bucket/symbol_bucket';
5
4
  import resolveTokens from '../../util/resolve_tokens';
6
5
  import properties, {SymbolLayoutPropsPossiblyEvaluated, SymbolPaintPropsPossiblyEvaluated} from './symbol_style_layer_properties.g';
@@ -25,7 +24,7 @@ import type {BucketParameters} from '../../data/bucket';
25
24
  import type {SymbolLayoutProps, SymbolPaintProps} from './symbol_style_layer_properties.g';
26
25
  import type EvaluationParameters from '../evaluation_parameters';
27
26
  import type {LayerSpecification} from '../../style-spec/types.g';
28
- import type {Feature, SourceExpression, CompositeExpression} from '../../style-spec/expression';
27
+ import type {Feature, SourceExpression} from '../../style-spec/expression';
29
28
  import type {Expression} from '../../style-spec/expression/expression';
30
29
  import type {CanonicalTileID} from '../../source/tile_id';
31
30
  import {FormattedType} from '../../style-spec/expression/types';
@@ -110,8 +109,7 @@ class SymbolStyleLayer extends StyleLayer {
110
109
  }
111
110
 
112
111
  queryIntersectsFeature(): boolean {
113
- assert(false); // Should take a different path in FeatureIndex
114
- return false;
112
+ throw new Error('Should take a different path in FeatureIndex');
115
113
  }
116
114
 
117
115
  _setPaintOverrides() {
@@ -124,12 +122,11 @@ class SymbolStyleLayer extends StyleLayer {
124
122
  const styleExpression = new StyleExpression(override, overriden.property.specification);
125
123
  let expression = null;
126
124
  if (overriden.value.kind === 'constant' || overriden.value.kind === 'source') {
127
- expression = (new ZoomConstantExpression('source', styleExpression) as SourceExpression);
125
+ expression = new ZoomConstantExpression('source', styleExpression) as SourceExpression;
128
126
  } else {
129
- expression = (new ZoomDependentExpression('composite',
127
+ expression = new ZoomDependentExpression('composite',
130
128
  styleExpression,
131
- overriden.value.zoomStops,
132
- (overriden.value as any)._interpolationType) as CompositeExpression);
129
+ overriden.value.zoomStops);
133
130
  }
134
131
  this.paint._values[overridable] = new PossiblyEvaluatedPropertyValue(overriden.property,
135
132
  expression,
@@ -6,7 +6,7 @@
6
6
 
7
7
  ### Breaking changes
8
8
 
9
- * Renamed `ParsingError` to `ExpressionParsingError` as there were two with the same name and added typescript typings [1468](https://github.com/maplibre/maplibre-gl-js/pull/1468)
9
+ * Renamed `ParsingError` to `ExpressionParsingError` as there were two with the same name and added typescript typings [#1468](https://github.com/maplibre/maplibre-gl-js/pull/1468)
10
10
 
11
11
  ## 16.1.0
12
12
 
@@ -55,7 +55,7 @@
55
55
  ## 13.16.0
56
56
 
57
57
  ### ✨ Features and improvements
58
- * Added `volatile` source property to control storing the tiles in local storage. ([9702](https://github.com/mapbox/mapbox-gl-js/pull/9702))
58
+ * Added `volatile` source property to control storing the tiles in local storage. ([#9702](https://github.com/mapbox/mapbox-gl-js/pull/9702))
59
59
 
60
60
  * Added `clusterMinPoints` option for clustered GeoJSON sources that defines the minimum number of points to form a cluster. ([#9748](https://github.com/mapbox/mapbox-gl-js/pull/9748))
61
61
 
@@ -2,7 +2,6 @@ import {toString} from './types';
2
2
 
3
3
  import ParsingContext from './parsing_context';
4
4
  import EvaluationContext from './evaluation_context';
5
- import assert from 'assert';
6
5
 
7
6
  import type {Expression, ExpressionRegistry} from './expression';
8
7
  import type {Type} from './types';
@@ -114,8 +113,6 @@ class CompoundExpression implements Expression {
114
113
  }
115
114
  }
116
115
 
117
- assert(!signatureContext || signatureContext.errors.length > 0);
118
-
119
116
  if (overloads.length === 1) {
120
117
  context.errors.push(...signatureContext.errors);
121
118
  } else {
@@ -142,7 +139,6 @@ class CompoundExpression implements Expression {
142
139
  registry: ExpressionRegistry,
143
140
  definitions: {[_: string]: Definition}
144
141
  ) {
145
- assert(!CompoundExpression.definitions);
146
142
  CompoundExpression.definitions = definitions;
147
143
  for (const name in definitions) {
148
144
  registry[name] = CompoundExpression;
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
 
3
2
  import {
4
3
  ObjectType,
@@ -69,7 +68,7 @@ class Assertion implements Expression {
69
68
 
70
69
  type = array(itemType, N);
71
70
  } else {
72
- assert(types[name], name);
71
+ if (!types[name]) throw new Error(`Types doesn't contain name = ${name}`);
73
72
  type = types[name];
74
73
  }
75
74
 
@@ -94,8 +93,7 @@ class Assertion implements Expression {
94
93
  }
95
94
  }
96
95
 
97
- assert(false);
98
- return null;
96
+ throw new Error();
99
97
  }
100
98
 
101
99
  eachChild(fn: (_: Expression) => void) {
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
 
3
2
  import {BooleanType} from '../types';
4
3
 
@@ -48,7 +47,7 @@ class Case implements Expression {
48
47
  const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);
49
48
  if (!otherwise) return null;
50
49
 
51
- assert(outputType);
50
+ if (!outputType) throw new Error('Can\'t infer output type');
52
51
  return new Case((outputType as any), branches, otherwise);
53
52
  }
54
53
 
@@ -1,5 +1,3 @@
1
- import assert from 'assert';
2
-
3
1
  import {checkSubtype, ValueType} from '../types';
4
2
  import ResolvedImage from '../types/resolved_image';
5
3
 
@@ -34,7 +32,7 @@ class Coalesce implements Expression {
34
32
  outputType = outputType || parsed.type;
35
33
  parsedArgs.push(parsed);
36
34
  }
37
- assert(outputType);
35
+ if (!outputType) throw new Error('No output type');
38
36
 
39
37
  // Above, we parse arguments without inferred type annotation so that
40
38
  // they don't produce a runtime error for `null` input, which would
@@ -1,5 +1,3 @@
1
- import assert from 'assert';
2
-
3
1
  import {BooleanType, ColorType, NumberType, StringType, ValueType} from '../types';
4
2
  import {Color, Padding, toString as valueToString, validateRGBA} from '../values';
5
3
  import RuntimeError from '../runtime_error';
@@ -32,6 +30,7 @@ class Coercion implements Expression {
32
30
  constructor(type: Type, args: Array<Expression>) {
33
31
  this.type = type;
34
32
  this.args = args;
33
+
35
34
  }
36
35
 
37
36
  static parse(args: ReadonlyArray<unknown>, context: ParsingContext): Expression {
@@ -39,8 +38,7 @@ class Coercion implements Expression {
39
38
  return context.error('Expected at least one argument.') as null;
40
39
 
41
40
  const name: string = (args[0] as any);
42
- assert(types[name], name);
43
-
41
+ if (!types[name]) throw new Error(`Can't parse ${name} as it is not part of the known types`);
44
42
  if ((name === 'to-boolean' || name === 'to-string') && args.length !== 2)
45
43
  return context.error('Expected one argument.') as null;
46
44
 
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
 
3
2
  import {typeOf} from '../values';
4
3
  import {ValueType} from '../types';
@@ -92,8 +91,6 @@ class Match implements Expression {
92
91
  const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);
93
92
  if (!otherwise) return null;
94
93
 
95
- assert(inputType && outputType);
96
-
97
94
  if (input.type.kind !== 'value' && context.concat(1).checkSubtype(((inputType as any)), input.type)) {
98
95
  return null;
99
96
  }
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
 
3
2
  import extend from '../util/extend';
4
3
  import ExpressionParsingError from './parsing_error';
@@ -143,7 +142,6 @@ export function createExpression(expression: unknown, propertySpec?: StyleProper
143
142
  propertySpec && propertySpec.type === 'string' ? {typeAnnotation: 'coerce'} : undefined);
144
143
 
145
144
  if (!parsed) {
146
- assert(parser.errors.length > 0);
147
145
  return error(parser.errors);
148
146
  }
149
147
 
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
 
3
2
  import Color from '../util/color';
4
3
  import Collator from './types/collator';
@@ -107,7 +106,6 @@ export function typeOf(value: Value): Type {
107
106
 
108
107
  return array(itemType || ValueType, length);
109
108
  } else {
110
- assert(typeof value === 'object');
111
109
  return ObjectType;
112
110
  }
113
111
  }
@@ -5,11 +5,11 @@ import Point from '@mapbox/point-geometry';
5
5
  import MercatorCoordinate from '../../geo/mercator_coordinate';
6
6
  import EXTENT from '../../data/extent';
7
7
  import {CanonicalTileID} from '../../source/tile_id';
8
- import {ExpressionFilterSpecification, FilterSpecification} from '../types.g';
8
+ import {ExpressionFilterSpecification, ExpressionInputType, ExpressionSpecification, FilterSpecification} from '../types.g';
9
9
  import {Feature} from '../expression';
10
10
 
11
11
  describe('filter', () => {
12
- test('exprssions transpilation test', () => {
12
+ test('expressions transpilation test', () => {
13
13
  function compileTimeCheck(_: ExpressionFilterSpecification) {
14
14
  expect(true).toBeTruthy();
15
15
  }
@@ -36,6 +36,43 @@ describe('filter', () => {
36
36
  compileTimeCheck(['match', ['get', 'TYPE'], ['TARGETPOINT:HOSPITAL'], true, false]);
37
37
  compileTimeCheck(['match', ['get', 'TYPE'], ['ADIZ', 'AMA', 'AWY', 'CLASS', 'NO-FIR', 'OCA', 'OTA', 'P', 'RAS', 'RCA', 'UTA', 'UTA-P'], true, false]);
38
38
  compileTimeCheck(['==', ['get', 'MILITARYAIRPORT'], 1]);
39
+ compileTimeCheck(['interpolate', ['linear'], ['line-progress'], 0, 10, 0.5, 100, 1, 1000]); // number output
40
+ compileTimeCheck(['interpolate', ['linear'], ['line-progress'], 0, 'red', 0.5, 'green', 1, 'blue']); // color output
41
+ compileTimeCheck(['interpolate', ['linear'], ['line-progress'], 0, [10, 20, 30], 0.5, [20, 30, 40], 1, [30, 40, 80]]); // number array output!
42
+ compileTimeCheck(['interpolate-hcl', ['linear'], ['line-progress'], 0, 'red', 0.5, 'green', 1, 'blue']);
43
+ compileTimeCheck(['interpolate-lab', ['linear'], ['line-progress'], 0, 'red', 0.5, 'green', 1, 'blue']);
44
+ compileTimeCheck(['step', ['get', 'point_count'], '#df2d43', 50, '#df2d43', 200, '#df2d43']);
45
+ compileTimeCheck(['step', ['get', 'point_count'], 20, 50, 30, 200, 40]);
46
+ compileTimeCheck(['step', ['get', 'point_count'], 0.6, 50, 0.7, 200, 0.8]);
47
+
48
+ // checks, where parts of the expression are injected from constants
49
+ // as in most cases the styling is read from JSON, these are rather optional tests.
50
+ // due to typescript inferring rather broad types, this is only possible in few places without specifying a type for the constant.
51
+ const colorStops = [0, 'red', 0.5, 'green', 1, 'blue'];
52
+ compileTimeCheck([
53
+ 'interpolate',
54
+ ['linear'],
55
+ ['line-progress'],
56
+ ...colorStops
57
+ ]);
58
+ compileTimeCheck([
59
+ 'interpolate-hcl',
60
+ ['linear'],
61
+ ['line-progress'],
62
+ ...colorStops
63
+ ]);
64
+ compileTimeCheck([
65
+ 'interpolate-lab',
66
+ ['linear'],
67
+ ['line-progress'],
68
+ ...colorStops
69
+ ]);
70
+ const [firstOutput, ...steps] = ['#df2d43', 50, '#df2d43', 200, '#df2d43'];
71
+ compileTimeCheck(['step', ['get', 'point_count'], firstOutput, ...steps]);
72
+ const strings = ['first', 'second', 'third'];
73
+ compileTimeCheck(['concat', ...strings]);
74
+ const values: (ExpressionInputType | ExpressionSpecification)[] = [['get', 'name'], ['get', 'code'], 'NONE']; // type is necessary!
75
+ compileTimeCheck(['coalesce', ...values]);
39
76
  });
40
77
 
41
78
  test('expression, zoom', () => {
@@ -1,4 +1,4 @@
1
- import assert from 'assert';
1
+
2
2
  import type {StylePropertySpecification} from '../style-spec';
3
3
 
4
4
  export default convertFunction;
@@ -138,7 +138,6 @@ function convertPropertyFunction(parameters, propertySpec, stops) {
138
138
  const type = getFunctionType(parameters, propertySpec);
139
139
  const get = ['get', parameters.property];
140
140
  if (type === 'categorical' && typeof stops[0][0] === 'boolean') {
141
- assert(parameters.stops.length > 0 && parameters.stops.length <= 2);
142
141
  const expression: any = ['case'];
143
142
  for (const stop of stops) {
144
143
  expression.push(['==', get, stop[0]], stop[1]);
@@ -236,7 +235,6 @@ function getFunctionType(parameters, propertySpec) {
236
235
  if (parameters.type) {
237
236
  return parameters.type;
238
237
  } else {
239
- assert(propertySpec.expression);
240
238
  return (propertySpec.expression as any).interpolated ? 'exponential' : 'interval';
241
239
  }
242
240
  }
@@ -24,7 +24,7 @@ export type InterpolationSpecification =
24
24
  | ['linear']
25
25
  | ['exponential', number | ExpressionSpecification]
26
26
  | ['cubic-bezier', number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification]
27
-
27
+
28
28
  export type ExpressionSpecification =
29
29
  // types
30
30
  | ['array', unknown | ExpressionSpecification] // array
@@ -70,31 +70,26 @@ export type ExpressionSpecification =
70
70
  | ['any', ...(boolean | ExpressionSpecification)[]] // boolean
71
71
  | ['case', boolean | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
72
72
  ...(boolean | ExpressionInputType | ExpressionSpecification)[], ExpressionInputType | ExpressionSpecification]
73
- | ['coalesce', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
74
- ...(ExpressionInputType | ExpressionSpecification)[]]
73
+ | ['coalesce', ...(ExpressionInputType | ExpressionSpecification)[]] // at least two inputs required
75
74
  | ['match', ExpressionInputType | ExpressionSpecification,
76
75
  ExpressionInputType | ExpressionInputType[], ExpressionInputType | ExpressionSpecification,
77
76
  ...(ExpressionInputType | ExpressionInputType[] | ExpressionSpecification)[], // repeated as above
78
77
  ExpressionInputType]
79
78
  | ['within', unknown | ExpressionSpecification]
80
79
  // Ramps, scales, curves
81
- | ['interpolate', InterpolationSpecification,
82
- number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
83
- ...(number | ExpressionInputType | ExpressionSpecification)[]]
84
- | ['interpolate-hcl', InterpolationSpecification,
85
- number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
86
- ...(number | ColorSpecification | ExpressionSpecification)[]]
87
- | ['interpolate-lab', InterpolationSpecification,
88
- number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
89
- ...(number | ColorSpecification | ExpressionSpecification)[]]
90
- | ['step', number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
91
- ...(number | ExpressionInputType | ExpressionSpecification)[]]
80
+ | ['interpolate', InterpolationSpecification, number | ExpressionSpecification,
81
+ ...(number | number[] | ColorSpecification)[]] // alternating number and number | number[] | ColorSpecification
82
+ | ['interpolate-hcl', InterpolationSpecification, number | ExpressionSpecification,
83
+ ...(number | ColorSpecification)[]] // alternating number and ColorSpecificaton
84
+ | ['interpolate-lab', InterpolationSpecification, number | ExpressionSpecification,
85
+ ...(number | ColorSpecification)[]] // alternating number and ColorSpecification
86
+ | ['step', number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
87
+ ...(number | ExpressionInputType | ExpressionSpecification)[]] // alternating number and ExpressionInputType | ExpressionSpecification
92
88
  // Variable binding
93
89
  | ['let', string, ExpressionInputType | ExpressionSpecification, ...(string | ExpressionInputType | ExpressionSpecification)[]]
94
90
  | ['var', string]
95
91
  // String
96
- | ['concat', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
97
- ...(ExpressionInputType | ExpressionSpecification)[]] // string
92
+ | ['concat', ...(ExpressionInputType | ExpressionSpecification)[]] // at least two inputs required -> string
98
93
  | ['downcase', string | ExpressionSpecification] // string
99
94
  | ['is-supported-script', string | ExpressionSpecification] // boolean
100
95
  | ['resolved-locale', CollatorExpressionSpecification] // string
@@ -109,7 +104,7 @@ export type ExpressionSpecification =
109
104
  | ['/', number | ExpressionSpecification, number | ExpressionSpecification] // number
110
105
  | ['%', number | ExpressionSpecification, number | ExpressionSpecification] // number
111
106
  | ['^', number | ExpressionSpecification, number | ExpressionSpecification] // number
112
- | ['+', number | ExpressionSpecification, number | ExpressionSpecification, ...(number | ExpressionSpecification)[]] // number
107
+ | ['+', ...(number | ExpressionSpecification)[]] // at least two inputs required -> number
113
108
  | ['abs', number | ExpressionSpecification] // number
114
109
  | ['acos', number | ExpressionSpecification] // number
115
110
  | ['asin', number | ExpressionSpecification] // number
@@ -6,7 +6,6 @@ import * as intersectionTests from '../util/intersection_tests';
6
6
  import GridIndex from './grid_index';
7
7
  import {mat4, vec4} from 'gl-matrix';
8
8
  import ONE_EM from '../symbol/one_em';
9
- import assert from 'assert';
10
9
 
11
10
  import * as projection from '../symbol/projection';
12
11
 
@@ -181,7 +180,6 @@ class CollisionIndex {
181
180
  for (let i = 1; i < last.path.length; i++) {
182
181
  projectedPath.push(last.path[i]);
183
182
  }
184
- assert(projectedPath.length >= 2);
185
183
 
186
184
  // Tolerate a slightly longer distance than one diameter between two adjacent circles
187
185
  const circleDist = radius * 2.5;
@@ -229,7 +227,6 @@ class CollisionIndex {
229
227
 
230
228
  for (const seg of segments) {
231
229
  // interpolate positions for collision circles. Add a small padding to both ends of the segment
232
- assert(seg.length > 0);
233
230
  interpolator.reset(seg, radius * 0.25);
234
231
 
235
232
  let numCircles = 0;