maplibre-gl 6.0.0 → 6.2.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 (181) hide show
  1. package/build/readme.md +0 -2
  2. package/dist/maplibre-gl-dev.mjs +433 -573
  3. package/dist/maplibre-gl-dev.mjs.map +1 -1
  4. package/dist/maplibre-gl-shared-dev.mjs +984 -850
  5. package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
  6. package/dist/maplibre-gl-shared.mjs +2 -2
  7. package/dist/maplibre-gl-shared.mjs.map +1 -1
  8. package/dist/maplibre-gl-worker-dev.mjs +14 -12
  9. package/dist/maplibre-gl-worker-dev.mjs.map +1 -1
  10. package/dist/maplibre-gl-worker.mjs +2 -2
  11. package/dist/maplibre-gl-worker.mjs.map +1 -1
  12. package/dist/maplibre-gl.css +1 -1
  13. package/dist/maplibre-gl.d.ts +119 -42
  14. package/dist/maplibre-gl.mjs +22 -22
  15. package/dist/maplibre-gl.mjs.map +1 -1
  16. package/package.json +20 -22
  17. package/src/css/maplibre-gl.css +4 -0
  18. package/src/data/bucket/circle_bucket.ts +3 -2
  19. package/src/data/bucket/fill_bucket.ts +3 -2
  20. package/src/data/bucket/fill_extrusion_bucket.test.ts +22 -0
  21. package/src/data/bucket/fill_extrusion_bucket.ts +17 -4
  22. package/src/data/bucket/line_bucket.test.ts +5 -5
  23. package/src/data/bucket/line_bucket.ts +3 -2
  24. package/src/data/bucket/round_polygon_corners.test.ts +159 -0
  25. package/src/data/bucket/round_polygon_corners.ts +121 -0
  26. package/src/data/bucket/symbol_bucket.test.ts +7 -7
  27. package/src/data/dem_data.test.ts +23 -23
  28. package/src/data/feature_position_map.test.ts +1 -1
  29. package/src/data/segment.test.ts +14 -14
  30. package/src/geo/bounds.test.ts +4 -4
  31. package/src/geo/lng_lat_bounds.test.ts +1 -1
  32. package/src/geo/projection/covering_tiles.bench.ts +39 -0
  33. package/src/geo/projection/covering_tiles.test.ts +3 -7
  34. package/src/geo/projection/covering_tiles.ts +37 -2
  35. package/src/geo/projection/globe_covering_tiles_details_provider.ts +4 -4
  36. package/src/geo/projection/globe_projection.test.ts +2 -2
  37. package/src/geo/projection/globe_projection.ts +6 -15
  38. package/src/geo/projection/globe_transform.test.ts +3 -6
  39. package/src/geo/projection/globe_transform.ts +4 -7
  40. package/src/geo/projection/mercator_covering_tiles_details_provider.ts +4 -4
  41. package/src/geo/projection/mercator_projection.ts +1 -13
  42. package/src/geo/projection/mercator_transform.test.ts +1 -1
  43. package/src/geo/projection/mercator_transform.ts +2 -1
  44. package/src/geo/projection/mercator_utils.test.ts +8 -8
  45. package/src/geo/projection/projection.ts +0 -27
  46. package/src/geo/projection/projection_data.ts +8 -0
  47. package/src/geo/projection/projection_factory.ts +3 -3
  48. package/src/geo/projection/vertical_perspective_projection.ts +3 -60
  49. package/src/geo/projection/vertical_perspective_transform.ts +16 -23
  50. package/src/geo/transform_interface.ts +1 -2
  51. package/src/index.test.ts +7 -12
  52. package/src/index.ts +4 -2
  53. package/src/render/glyph_manager.test.ts +7 -22
  54. package/src/render/painter.test.ts +2 -0
  55. package/src/render/painter.ts +8 -11
  56. package/src/render/subdivision.bench.ts +39 -0
  57. package/src/render/subdivision.test.ts +22 -23
  58. package/src/render/subdivision.ts +46 -0
  59. package/src/render/terrain.test.ts +68 -34
  60. package/src/render/terrain.ts +69 -26
  61. package/src/shaders/glsl/_projection_globe.fragment.glsl +12 -0
  62. package/src/shaders/glsl/_projection_globe.fragment.glsl.g.ts +2 -0
  63. package/src/shaders/glsl/_projection_globe.vertex.glsl +29 -10
  64. package/src/shaders/glsl/_projection_globe.vertex.glsl.g.ts +1 -1
  65. package/src/shaders/glsl/_projection_mercator.fragment.glsl +4 -0
  66. package/src/shaders/glsl/_projection_mercator.fragment.glsl.g.ts +2 -0
  67. package/src/shaders/glsl/line.fragment.glsl +2 -0
  68. package/src/shaders/glsl/line.fragment.glsl.g.ts +1 -1
  69. package/src/shaders/glsl/line_gradient.fragment.glsl +2 -0
  70. package/src/shaders/glsl/line_gradient.fragment.glsl.g.ts +1 -1
  71. package/src/shaders/glsl/line_gradient_sdf.fragment.glsl +2 -0
  72. package/src/shaders/glsl/line_gradient_sdf.fragment.glsl.g.ts +1 -1
  73. package/src/shaders/glsl/line_pattern.fragment.glsl +2 -0
  74. package/src/shaders/glsl/line_pattern.fragment.glsl.g.ts +1 -1
  75. package/src/shaders/glsl/line_sdf.fragment.glsl +2 -0
  76. package/src/shaders/glsl/line_sdf.fragment.glsl.g.ts +1 -1
  77. package/src/shaders/shaders.ts +4 -6
  78. package/src/source/canvas_source.test.ts +1 -1
  79. package/src/source/geojson_source.test.ts +32 -4
  80. package/src/source/geojson_source.ts +41 -0
  81. package/src/source/geojson_source_diff.test.ts +2 -2
  82. package/src/source/geojson_worker_source.test.ts +9 -5
  83. package/src/source/image_source.test.ts +137 -62
  84. package/src/source/image_source.ts +49 -12
  85. package/src/source/raster_dem_tile_source.test.ts +2 -2
  86. package/src/source/raster_tile_source.test.ts +64 -9
  87. package/src/source/raster_tile_source.ts +2 -1
  88. package/src/source/rtl_text_plugin_main_thread.test.ts +14 -14
  89. package/src/source/source.test.ts +8 -8
  90. package/src/source/vector_tile_source.test.ts +1 -1
  91. package/src/source/vector_tile_worker_source.test.ts +7 -5
  92. package/src/source/video_source.test.ts +1 -1
  93. package/src/source/worker.test.ts +1 -1
  94. package/src/source/worker_tile.test.ts +10 -8
  95. package/src/style/light.test.ts +9 -9
  96. package/src/style/light.ts +3 -3
  97. package/src/style/load_glyph_range.test.ts +8 -8
  98. package/src/style/load_sprite.test.ts +1 -1
  99. package/src/style/properties.test.ts +94 -2
  100. package/src/style/properties.ts +30 -1
  101. package/src/style/sky.test.ts +9 -9
  102. package/src/style/sky.ts +2 -2
  103. package/src/style/style.test.ts +38 -36
  104. package/src/style/style.ts +3 -3
  105. package/src/style/style_layer/color_relief_style_layer.test.ts +1 -1
  106. package/src/style/style_layer/fill_extrusion_style_layer.ts +6 -3
  107. package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +14 -1
  108. package/src/style/style_layer/raster_style_layer.test.ts +2 -2
  109. package/src/style/style_layer.test.ts +5 -51
  110. package/src/style/validate_style.test.ts +1 -1
  111. package/src/symbol/collision_index.test.ts +1 -1
  112. package/src/symbol/grid_index.test.ts +1 -1
  113. package/src/tile/terrain_tile_manager.test.ts +2 -2
  114. package/src/tile/tile_id.test.ts +5 -5
  115. package/src/tile/tile_manager.test.ts +113 -72
  116. package/src/tile/tile_manager.ts +2 -2
  117. package/src/tile/tile_manager_in_view_tiles.test.ts +2 -2
  118. package/src/ui/camera.test.ts +138 -135
  119. package/src/ui/control/geolocate_control.test.ts +7 -30
  120. package/src/ui/handler/dblclick_zoom.test.ts +2 -2
  121. package/src/ui/handler/mouse.ts +15 -7
  122. package/src/ui/handler/mouse_handler_interface.test.ts +21 -1
  123. package/src/ui/handler/scroll_zoom.test.ts +2 -0
  124. package/src/ui/handler_manager.test.ts +7 -7
  125. package/src/ui/hash.test.ts +1 -0
  126. package/src/ui/map.ts +45 -20
  127. package/src/ui/map_tests/map_basic.test.ts +11 -23
  128. package/src/ui/map_tests/map_calculate_camera_options.test.ts +6 -6
  129. package/src/ui/map_tests/map_events.test.ts +5 -7
  130. package/src/ui/map_tests/map_global_state.test.ts +3 -3
  131. package/src/ui/map_tests/map_images.test.ts +4 -3
  132. package/src/ui/map_tests/map_is_moving.test.ts +1 -1
  133. package/src/ui/map_tests/map_is_rotating.test.ts +1 -1
  134. package/src/ui/map_tests/map_layer.test.ts +2 -1
  135. package/src/ui/map_tests/map_options.test.ts +1 -5
  136. package/src/ui/map_tests/map_pitch.test.ts +6 -6
  137. package/src/ui/map_tests/map_refresh_tiles.test.ts +2 -2
  138. package/src/ui/map_tests/map_render.test.ts +1 -1
  139. package/src/ui/map_tests/map_set_lod_params.test.ts +1 -1
  140. package/src/ui/map_tests/map_style.test.ts +9 -1
  141. package/src/ui/map_tests/map_terrain.test.ts +41 -1
  142. package/src/ui/map_tests/map_zoom.test.ts +15 -15
  143. package/src/ui/marker.test.ts +71 -14
  144. package/src/ui/marker.ts +30 -6
  145. package/src/ui/popup.test.ts +3 -3
  146. package/src/util/actor.test.ts +6 -6
  147. package/src/util/ajax.test.ts +27 -39
  148. package/src/util/browser.test.ts +7 -9
  149. package/src/util/create_tile_mesh.test.ts +2 -2
  150. package/src/util/dispatcher.test.ts +1 -1
  151. package/src/util/evented.test.ts +4 -1
  152. package/src/util/fast_maths.test.ts +4 -4
  153. package/src/util/image_request.test.ts +6 -4
  154. package/src/util/primitives/bounding_volume_cache.ts +3 -1
  155. package/src/util/struct_array.test.ts +2 -2
  156. package/src/util/task_queue.test.ts +1 -1
  157. package/src/util/test/util.ts +1 -0
  158. package/src/util/time_control.test.ts +2 -2
  159. package/src/util/transferable_grid_index.test.ts +1 -1
  160. package/src/util/util.test.ts +27 -13
  161. package/src/util/verticalize_punctuation.test.ts +4 -4
  162. package/src/util/web_worker_transfer.test.ts +5 -5
  163. package/src/webgl/draw/draw_custom.test.ts +13 -13
  164. package/src/webgl/draw/draw_debug.test.ts +1 -1
  165. package/src/webgl/draw/draw_fill.test.ts +13 -12
  166. package/src/webgl/draw/draw_symbol.test.ts +17 -16
  167. package/src/webgl/program/program_uniforms.ts +0 -3
  168. package/src/webgl/program/projection_program.ts +12 -10
  169. package/src/webgl/program/terrain_program.test.ts +2 -2
  170. package/src/webgl/program.ts +6 -4
  171. package/src/webgl/render_to_texture.test.ts +5 -5
  172. package/src/webgl/state.test.ts +1 -1
  173. package/src/webgl/texture.test.ts +3 -3
  174. package/src/webgl/vertex_buffer.test.ts +1 -1
  175. package/build/rolldown_plugins.ts +0 -18
  176. package/src/geo/projection/globe_projection_error_measurement.ts +0 -229
  177. package/src/shaders/glsl/projection_error_measurement.fragment.glsl +0 -5
  178. package/src/shaders/glsl/projection_error_measurement.fragment.glsl.g.ts +0 -2
  179. package/src/shaders/glsl/projection_error_measurement.vertex.glsl +0 -22
  180. package/src/shaders/glsl/projection_error_measurement.vertex.glsl.g.ts +0 -2
  181. package/src/webgl/program/projection_error_measurement_program.ts +0 -23
@@ -4,6 +4,7 @@ import {TileManager} from '../tile/tile_manager.ts';
4
4
  import {StyleLayer} from './style_layer.ts';
5
5
  import {extend} from '../util/util.ts';
6
6
  import {Event} from '../util/evented.ts';
7
+ import {type AJAXError} from '../util/ajax.ts';
7
8
  import {RGBAImage} from '../util/image.ts';
8
9
  import {rtlMainThreadPluginFactory} from '../source/rtl_text_plugin_main_thread.ts';
9
10
  import {browser} from '../util/browser.ts';
@@ -71,7 +72,7 @@ let mockConsoleError: MockInstance;
71
72
  beforeEach(() => {
72
73
  global.fetch = null;
73
74
  server = fakeServer.create();
74
- mockConsoleError = vi.spyOn(console, 'error').mockImplementation(() => { });
75
+ mockConsoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
75
76
  });
76
77
 
77
78
  afterEach(() => {
@@ -206,7 +207,7 @@ describe('Style.loadURL', () => {
206
207
  const {error} = await promise;
207
208
 
208
209
  expect(error).toBeTruthy();
209
- expect(error.status).toBe(errorStatus);
210
+ expect((error as AJAXError).status).toBe(errorStatus);
210
211
  });
211
212
 
212
213
  test('does not throw if request is pending when removed', async () => {
@@ -442,9 +443,9 @@ describe('Style.loadJSON', () => {
442
443
  const event = await style.once('error');
443
444
  const err = event.error;
444
445
  expect(err).toBeTruthy();
445
- expect(err.toString().indexOf('-source-layer-') !== -1).toBeTruthy();
446
- expect(err.toString().indexOf('-source-id-') !== -1).toBeTruthy();
447
- expect(err.toString().indexOf('-layer-id-') !== -1).toBeTruthy();
446
+ expect(err.toString()).toContain('-source-layer-');
447
+ expect(err.toString()).toContain('-source-id-');
448
+ expect(err.toString()).toContain('-layer-id-');
448
449
  });
449
450
 
450
451
  test('sets up layer event forwarding', async () => {
@@ -597,7 +598,7 @@ describe('Style.loadJSON', () => {
597
598
  layer.recalculate({} as EvaluationParameters, []);
598
599
  const paint = layer.paint as PossiblyEvaluated<CirclePaintProps, CirclePaintPropsPossiblyEvaluated>;
599
600
  expect(paint.get('circle-color').evaluate({} as Feature, {})).toEqual(new Color(1, 0, 0, 1));
600
- expect(paint.get('circle-radius').evaluate({} as Feature, {})).toEqual(12);
601
+ expect(paint.get('circle-radius').evaluate({} as Feature, {})).toBe(12);
601
602
  });
602
603
 
603
604
  test('does not throw if request is pending when removed', async () => {
@@ -695,7 +696,7 @@ describe('Style._load', () => {
695
696
  type: 'custom'
696
697
  }]
697
698
  });
698
- const stub = vi.spyOn(console, 'error');
699
+ const stub = vi.spyOn(console, 'error').mockImplementation(() => {});
699
700
 
700
701
  style._load(styleSpec, {validate: true});
701
702
 
@@ -777,7 +778,7 @@ describe('Style.update', () => {
777
778
 
778
779
  await style.once('style.load');
779
780
 
780
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
781
+ const spy = vi.fn().mockResolvedValue({});
781
782
  style.dispatcher.broadcast = spy;
782
783
 
783
784
  // Add multiple images — should NOT broadcast setImages immediately
@@ -805,7 +806,7 @@ describe('Style.update', () => {
805
806
 
806
807
  await style.once('style.load');
807
808
 
808
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
809
+ const spy = vi.fn().mockResolvedValue({});
809
810
  style.dispatcher.broadcast = spy;
810
811
 
811
812
  // Trigger an update that changes layers but not images
@@ -825,7 +826,7 @@ describe('Style.update', () => {
825
826
 
826
827
  await style.once('style.load');
827
828
 
828
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
829
+ const spy = vi.fn().mockResolvedValue({});
829
830
  style.dispatcher.broadcast = spy;
830
831
 
831
832
  // Trigger both image and layer changes in the same frame
@@ -852,7 +853,7 @@ describe('Style.update', () => {
852
853
  style.addImage('img2', {data: new RGBAImage({width: 1, height: 1}, new Uint8Array(4)), pixelRatio: 1, sdf: false});
853
854
  style.update({} as EvaluationParameters);
854
855
 
855
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
856
+ const spy = vi.fn().mockResolvedValue({});
856
857
  style.dispatcher.broadcast = spy;
857
858
 
858
859
  style.removeImage('img1');
@@ -876,7 +877,7 @@ describe('Style.update', () => {
876
877
  style.addImage('img1', {data: new RGBAImage({width: 1, height: 1}, new Uint8Array(4)), pixelRatio: 1, sdf: false});
877
878
  style.update({} as EvaluationParameters);
878
879
 
879
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
880
+ const spy = vi.fn().mockResolvedValue({});
880
881
  style.dispatcher.broadcast = spy;
881
882
 
882
883
  style.updateImage('img1', {data: new RGBAImage({width: 1, height: 1}, new Uint8Array(4)), pixelRatio: 1, sdf: false});
@@ -1299,7 +1300,7 @@ describe('Style.addSource', () => {
1299
1300
  style.addSource('source-id', source);
1300
1301
  style.update({} as EvaluationParameters);
1301
1302
  });
1302
- await dataPromise;
1303
+ await expect(dataPromise).resolves.toBeDefined();
1303
1304
  });
1304
1305
 
1305
1306
  test('throws on duplicates', async () => {
@@ -1369,7 +1370,7 @@ describe('Style.removeSource', () => {
1369
1370
  style.removeSource('source-id');
1370
1371
  style.update({} as EvaluationParameters);
1371
1372
  });
1372
- await dataPromise;
1373
+ await expect(dataPromise).resolves.toBeDefined();
1373
1374
  });
1374
1375
 
1375
1376
  test('clears tiles', async () => {
@@ -1417,8 +1418,8 @@ describe('Style.removeSource', () => {
1417
1418
  const promise = style.once('error');
1418
1419
  style.removeSource('mapLibre-source');
1419
1420
  const event = await promise;
1420
- expect(event.error.message.includes('"mapLibre-source"')).toBeTruthy();
1421
- expect(event.error.message.includes('"mapLibre-layer"')).toBeTruthy();
1421
+ expect(event.error.message).toContain('"mapLibre-source"');
1422
+ expect(event.error.message).toContain('"mapLibre-layer"');
1422
1423
  });
1423
1424
 
1424
1425
  test('does not throw if source is not in use', async () => {
@@ -2327,9 +2328,9 @@ describe('Style.addLayer', () => {
2327
2328
  const err = event.error;
2328
2329
 
2329
2330
  expect(err).toBeTruthy();
2330
- expect(err.toString().indexOf('-source-layer-') !== -1).toBeTruthy();
2331
- expect(err.toString().indexOf('-source-id-') !== -1).toBeTruthy();
2332
- expect(err.toString().indexOf('-layer-id-') !== -1).toBeTruthy();
2331
+ expect(err.toString()).toContain('-source-layer-');
2332
+ expect(err.toString()).toContain('-source-id-');
2333
+ expect(err.toString()).toContain('-layer-id-');
2333
2334
  });
2334
2335
 
2335
2336
  test('emits error on invalid layer', async () => {
@@ -2473,7 +2474,7 @@ describe('Style.addLayer', () => {
2473
2474
  style.addLayer(layer);
2474
2475
  style.update({} as EvaluationParameters);
2475
2476
  });
2476
- await dataPromise;
2477
+ await expect(dataPromise).resolves.toBeDefined();
2477
2478
  });
2478
2479
 
2479
2480
  test('emits error on duplicates', async () => {
@@ -2591,7 +2592,7 @@ describe('Style.removeLayer', () => {
2591
2592
  style.update({} as EvaluationParameters);
2592
2593
  });
2593
2594
 
2594
- await dataPromise;
2595
+ await expect(dataPromise).resolves.toBeDefined();
2595
2596
  });
2596
2597
 
2597
2598
  test('tears down layer event forwarding', async () => {
@@ -2603,9 +2604,8 @@ describe('Style.removeLayer', () => {
2603
2604
  }]
2604
2605
  }));
2605
2606
 
2606
- style.on('error', () => {
2607
- throw new Error('test failed');
2608
- });
2607
+ const styleErrorListener = vi.fn();
2608
+ style.on('error', styleErrorListener);
2609
2609
 
2610
2610
  await style.once('style.load');
2611
2611
  const layer = style._layers.background;
@@ -2615,6 +2615,8 @@ describe('Style.removeLayer', () => {
2615
2615
  layer.on('error', () => {});
2616
2616
 
2617
2617
  layer.fire(new Event('error', {mapLibre: true}));
2618
+
2619
+ expect(styleErrorListener).not.toHaveBeenCalled();
2618
2620
  });
2619
2621
 
2620
2622
  test('fires an error on non-existence', async () => {
@@ -2681,7 +2683,7 @@ describe('Style.moveLayer', () => {
2681
2683
  style.moveLayer('background');
2682
2684
  style.update({} as EvaluationParameters);
2683
2685
  });
2684
- await dataPromise;
2686
+ await expect(dataPromise).resolves.toBeDefined();
2685
2687
  });
2686
2688
 
2687
2689
  test('fires an error on non-existence', async () => {
@@ -2983,7 +2985,7 @@ describe('Style.setFilter', () => {
2983
2985
  const style = createStyle();
2984
2986
 
2985
2987
  await style.once('style.load');
2986
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
2988
+ const spy = vi.fn().mockResolvedValue({});
2987
2989
  style.dispatcher.broadcast = spy;
2988
2990
 
2989
2991
  style.setFilter('symbol', ['==', 'id', 1]);
@@ -3017,7 +3019,7 @@ describe('Style.setFilter', () => {
3017
3019
  style.setFilter('symbol', filter);
3018
3020
  style.update({} as EvaluationParameters); // flush pending operations
3019
3021
 
3020
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
3022
+ const spy = vi.fn().mockResolvedValue({});
3021
3023
  style.dispatcher.broadcast = spy;
3022
3024
  filter[2] = 2;
3023
3025
  style.setFilter('symbol', filter);
@@ -3066,7 +3068,7 @@ describe('Style.setFilter', () => {
3066
3068
  const style = createStyle();
3067
3069
 
3068
3070
  await style.once('style.load');
3069
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
3071
+ const spy = vi.fn().mockResolvedValue({});
3070
3072
  style.dispatcher.broadcast = spy;
3071
3073
 
3072
3074
  style.setFilter('symbol', 'notafilter' as any as FilterSpecification, {validate: false});
@@ -3118,7 +3120,7 @@ describe('Style.setLayerZoomRange', () => {
3118
3120
  const style = createStyle();
3119
3121
 
3120
3122
  await style.once('style.load');
3121
- const spy = vi.fn().mockReturnValue(Promise.resolve({}));
3123
+ const spy = vi.fn().mockResolvedValue({});
3122
3124
  style.dispatcher.broadcast = spy;
3123
3125
  style.setLayerZoomRange('symbol', 5, 12);
3124
3126
  expect(style.getLayer('symbol').minzoom).toBe(5);
@@ -3473,7 +3475,7 @@ describe('Style.query*Features', () => {
3473
3475
  expect(onError.mock.calls[0][0].error.message).toMatch(/queryRenderedFeatures\.filter/);
3474
3476
  });
3475
3477
 
3476
- test('querySourceFeatures not raise validation errors if validation was disabled', () => {
3478
+ test('queryRenderedFeatures not raise validation errors if validation was disabled', () => {
3477
3479
  let errors = 0;
3478
3480
  vi.spyOn(style, 'fire').mockImplementation((event) => {
3479
3481
  if (event['error']) {
@@ -3780,12 +3782,12 @@ describe('Style.serialize', () => {
3780
3782
  expect(result['4,2,true']).toBeDefined();
3781
3783
 
3782
3784
  // Verify the entries have the expected atlas properties
3783
- expect(typeof result['2,1,false'].width).toBe('number');
3784
- expect(typeof result['2,1,false'].height).toBe('number');
3785
- expect(typeof result['2,1,false'].y).toBe('number');
3786
- expect(typeof result['4,2,true'].width).toBe('number');
3787
- expect(typeof result['4,2,true'].height).toBe('number');
3788
- expect(typeof result['4,2,true'].y).toBe('number');
3785
+ expect(result['2,1,false'].width).toBeTypeOf('number');
3786
+ expect(result['2,1,false'].height).toBeTypeOf('number');
3787
+ expect(result['2,1,false'].y).toBeTypeOf('number');
3788
+ expect(result['4,2,true'].width).toBeTypeOf('number');
3789
+ expect(result['4,2,true'].height).toBeTypeOf('number');
3790
+ expect(result['4,2,true'].y).toBeTypeOf('number');
3789
3791
  });
3790
3792
  });
3791
3793
 
@@ -491,10 +491,10 @@ export class Style extends Evented<MapEventType> {
491
491
  this.glyphManager.setURL(nextState.glyphs);
492
492
  this._createLayers();
493
493
 
494
- this.light = new Light(this.stylesheet.light);
494
+ this.light = new Light(this.stylesheet.light ?? {}, this._globalState);
495
495
  this._setProjectionInternal(this.stylesheet.projection?.type || 'mercator');
496
496
 
497
- this.sky = new Sky(this.stylesheet.sky);
497
+ this.sky = new Sky(this.stylesheet.sky, this._globalState);
498
498
 
499
499
  // The stylesheet's terrain was already validated as part of the style itself.
500
500
  this.map.setTerrain(this.stylesheet.terrain ?? null, {validate: false});
@@ -1760,7 +1760,7 @@ export class Style extends Evented<MapEventType> {
1760
1760
  }
1761
1761
 
1762
1762
  _setProjectionInternal(name: ProjectionSpecification['type']): void {
1763
- const projectionObjects = createProjectionFromName(name, this.map._camera?.transform.constrainOverride);
1763
+ const projectionObjects = createProjectionFromName(name, this.map._camera?.transform.constrainOverride, this._globalState);
1764
1764
  this.projection = projectionObjects.projection;
1765
1765
  this.map.migrateProjection(projectionObjects.transform, projectionObjects.cameraHelper);
1766
1766
  for (const key in this.tileManagers) {
@@ -20,7 +20,7 @@ describe('ColorReliefStyleLayer', () => {
20
20
  const layer = createStyleLayer(layerSpec, {});
21
21
  expect(layer).toBeInstanceOf(ColorReliefStyleLayer);
22
22
  const colorReliefStyleLayer = layer as ColorReliefStyleLayer;
23
- expect(colorReliefStyleLayer.paint.get('color-relief-opacity')).toEqual(1);
23
+ expect(colorReliefStyleLayer.paint.get('color-relief-opacity')).toBe(1);
24
24
  const colorRamp = colorReliefStyleLayer._createColorRamp(256);
25
25
  expect(colorRamp.elevationStops).toEqual([0,1]);
26
26
  expect(colorRamp.colorStops).toEqual([Color.transparent,Color.transparent]);
@@ -3,13 +3,13 @@ import {type QueryIntersectsFeatureParams, StyleLayer} from '../style_layer.ts';
3
3
  import {FillExtrusionBucket} from '../../data/bucket/fill_extrusion_bucket.ts';
4
4
  import {polygonIntersectsPolygon, polygonIntersectsMultiPolygon} from '../../util/intersection_tests.ts';
5
5
  import {translateDistance, translate} from '../query_utils.ts';
6
- import properties, {type FillExtrusionPaintPropsPossiblyEvaluated} from './fill_extrusion_style_layer_properties.g.ts';
7
- import {type Transitionable, type Transitioning, type PossiblyEvaluated} from '../properties.ts';
6
+ import properties, {type FillExtrusionLayoutPropsPossiblyEvaluated, type FillExtrusionPaintPropsPossiblyEvaluated} from './fill_extrusion_style_layer_properties.g.ts';
7
+ import {type Layout, type Transitionable, type Transitioning, type PossiblyEvaluated} from '../properties.ts';
8
8
  import {type mat4, vec4} from 'gl-matrix';
9
9
  import Point from '@mapbox/point-geometry';
10
10
  import type {LayerSpecification} from '@maplibre/maplibre-gl-style-spec';
11
11
  import type {BucketParameters} from '../../data/bucket.ts';
12
- import type {FillExtrusionPaintProps} from './fill_extrusion_style_layer_properties.g.ts';
12
+ import type {FillExtrusionLayoutProps, FillExtrusionPaintProps} from './fill_extrusion_style_layer_properties.g.ts';
13
13
 
14
14
  export class Point3D extends Point {
15
15
  z: number;
@@ -18,6 +18,9 @@ export class Point3D extends Point {
18
18
  export const isFillExtrusionStyleLayer = (layer: StyleLayer): layer is FillExtrusionStyleLayer => layer.type === 'fill-extrusion';
19
19
 
20
20
  export class FillExtrusionStyleLayer extends StyleLayer {
21
+ _unevaluatedLayout: Layout<FillExtrusionLayoutProps>;
22
+ layout: PossiblyEvaluated<FillExtrusionLayoutProps, FillExtrusionLayoutPropsPossiblyEvaluated>;
23
+
21
24
  _transitionablePaint: Transitionable<FillExtrusionPaintProps>;
22
25
  _transitioningPaint: Transitioning<FillExtrusionPaintProps>;
23
26
  paint: PossiblyEvaluated<FillExtrusionPaintProps, FillExtrusionPaintPropsPossiblyEvaluated>;
@@ -18,6 +18,19 @@ import type {Color, Formatted, Padding, NumberArray, ColorArray, ResolvedImage,
18
18
  import {StylePropertySpecification} from '@maplibre/maplibre-gl-style-spec';
19
19
 
20
20
 
21
+ export type FillExtrusionLayoutProps = {
22
+ "fill-extrusion-rounded-corner-distance": DataConstantProperty<number>,
23
+ };
24
+
25
+ export type FillExtrusionLayoutPropsPossiblyEvaluated = {
26
+ "fill-extrusion-rounded-corner-distance": number,
27
+ };
28
+
29
+ let layout: Properties<FillExtrusionLayoutProps>;
30
+ const getLayout = (): Properties<FillExtrusionLayoutProps> => layout = layout || new Properties({
31
+ "fill-extrusion-rounded-corner-distance": new DataConstantProperty(styleSpec["layout_fill-extrusion"]["fill-extrusion-rounded-corner-distance"] as any as StylePropertySpecification, "fill-extrusion-rounded-corner-distance"),
32
+ });
33
+
21
34
  export type FillExtrusionPaintProps = {
22
35
  "fill-extrusion-opacity": DataConstantProperty<number>,
23
36
  "fill-extrusion-color": DataDrivenProperty<Color>,
@@ -52,4 +65,4 @@ const getPaint = (): Properties<FillExtrusionPaintProps> => paint = paint || new
52
65
  "fill-extrusion-vertical-gradient": new DataConstantProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-vertical-gradient"] as any as StylePropertySpecification, "fill-extrusion-vertical-gradient"),
53
66
  });
54
67
 
55
- export default ({ get paint(): Properties<FillExtrusionPaintProps> { return getPaint() } });
68
+ export default ({ get paint(): Properties<FillExtrusionPaintProps> { return getPaint() }, get layout(): Properties<FillExtrusionLayoutProps> { return getLayout() } });
@@ -18,7 +18,7 @@ describe('RasterStyleLayer correctly handles "resampling" and "raster-resampling
18
18
  const layer = createStyleLayer(layerSpec, {});
19
19
 
20
20
  const rasterResampling = layer.getPaintProperty('raster-resampling');
21
- expect(rasterResampling).toEqual(undefined);
21
+ expect(rasterResampling).toBeUndefined();
22
22
  });
23
23
 
24
24
  test('"resampling" is undefined when instantiated with "raster-resampling"', () => {
@@ -26,7 +26,7 @@ describe('RasterStyleLayer correctly handles "resampling" and "raster-resampling
26
26
  const layer = createStyleLayer(layerSpec, {});
27
27
 
28
28
  const resampling = layer.getPaintProperty('resampling');
29
- expect(resampling).toEqual(undefined);
29
+ expect(resampling).toBeUndefined();
30
30
  });
31
31
 
32
32
  });
@@ -1,4 +1,4 @@
1
- import {describe, test, expect} from 'vitest';
1
+ import {describe, test, expect, vi} from 'vitest';
2
2
  import {createStyleLayer} from './create_style_layer.ts';
3
3
  import {FillStyleLayer} from './style_layer/fill_style_layer.ts';
4
4
  import {extend} from '../util/util.ts';
@@ -171,8 +171,8 @@ describe('StyleLayer.setPaintProperty', () => {
171
171
  layer.updateTransitions({} as TransitionParameters);
172
172
  layer.recalculate({zoom: 0, zoomHistory: {}} as EvaluationParameters, undefined);
173
173
 
174
- layer.paint.get('fill-outline-color');
175
-
174
+ const outlineColor = layer.paint.get('fill-outline-color');
175
+ expect(outlineColor.value).toMatchObject({kind: 'constant', value: {r: 1, g: 0, b: 0, a: 1}});
176
176
  });
177
177
 
178
178
  test('sets null property value', () => {
@@ -379,6 +379,7 @@ describe('StyleLayer.getLayoutAffectingGlobalStateRefs', () => {
379
379
  });
380
380
 
381
381
  test('returns global-state references from visibility', () => {
382
+ vi.spyOn(console, 'warn').mockImplementation(() => {});
382
383
  const layer = createStyleLayer({
383
384
  id: 'background',
384
385
  type: 'background',
@@ -507,54 +508,7 @@ describe('StyleLayer.serialize', () => {
507
508
 
508
509
  });
509
510
 
510
- describe('StyleLayer.serialize', () => {
511
-
512
- function createSymbolLayer(layer?) {
513
- return extend({
514
- id: 'symbol',
515
- type: 'symbol',
516
- paint: {
517
- 'text-color': 'blue'
518
- },
519
- layout: {
520
- 'text-transform': 'uppercase'
521
- }
522
- }, layer);
523
- }
524
-
525
- test('serializes layers', () => {
526
- expect(createStyleLayer(createSymbolLayer(), {}).serialize()).toEqual(createSymbolLayer());
527
- });
528
-
529
- test('serializes functions', () => {
530
- const layerPaint = {
531
- 'text-color': {
532
- base: 2,
533
- stops: [[0, 'red'], [1, 'blue']]
534
- }
535
- };
536
-
537
- expect(createStyleLayer(createSymbolLayer({paint: layerPaint}), {}).serialize().paint).toEqual(layerPaint);
538
- });
539
-
540
- test('serializes added paint properties', () => {
541
- const layer = createStyleLayer(createSymbolLayer(), {});
542
- layer.setPaintProperty('text-halo-color', 'orange');
543
-
544
- expect(layer.serialize().paint['text-halo-color']).toBe('orange');
545
- expect(layer.serialize().paint['text-color']).toBe('blue');
546
-
547
- });
548
-
549
- test('serializes added layout properties', () => {
550
- const layer = createStyleLayer(createSymbolLayer(), {});
551
- layer.setLayoutProperty('text-size', 20);
552
-
553
- expect(layer.serialize().layout['text-transform']).toBe('uppercase');
554
- expect(layer.serialize().layout['text-size']).toBe(20);
555
-
556
- });
557
-
511
+ describe('StyleLayer.paint', () => {
558
512
  test('layer.paint is never undefined', () => {
559
513
  const layer = createStyleLayer({type: 'fill'} as LayerSpecification, {});
560
514
  // paint is never undefined
@@ -1,7 +1,7 @@
1
1
  import {describe, test, expect, vi, afterEach} from 'vitest';
2
2
  import {validateAndEmit, validateStyle, validateStyleAndEmit} from './validate_style.ts';
3
- import type {StyleSpecification} from '@maplibre/maplibre-gl-style-spec';
4
3
  import {Evented} from '../util/evented.ts';
4
+ import type {StyleSpecification} from '@maplibre/maplibre-gl-style-spec';
5
5
 
6
6
  class TestEmitter extends Evented {}
7
7
 
@@ -10,7 +10,7 @@ describe('CollisionIndex', () => {
10
10
  const transform = new MercatorTransform({minZoom: 0, maxZoom: 22, minPitch: 0, maxPitch: 60, renderWorldCopies: true});
11
11
  transform.resize(200, 200);
12
12
  const tile = new UnwrappedTileID(0, new CanonicalTileID(0, 0, 0));
13
- vi.spyOn(transform, 'calculatePosMatrix').mockImplementation(() => createIdentityMat4f64());
13
+ vi.spyOn(transform, 'calculatePosMatrix').mockReturnValue(createIdentityMat4f64());
14
14
 
15
15
  const ci = new CollisionIndex(transform);
16
16
  expect(ci.projectAndGetPerspectiveRatio(x, y, tile, null).x).toBeCloseTo(10000212.3456, 10);
@@ -86,7 +86,7 @@ describe('GridIndex', () => {
86
86
  // differs from y_boundary_a by less than 1e-10 (1-2 ULPs)
87
87
  const y_boundary_b = 406.2043266199999;
88
88
  // y_boundary_b < y_boundary_a, so strict >= would fail
89
- expect(y_boundary_b >= y_boundary_a).toBe(false);
89
+ expect(y_boundary_b).toBeLessThan(y_boundary_a);
90
90
 
91
91
  // Despite the floating-point difference, hitTest should detect overlap
92
92
  expect(grid.hitTest(660, 366, y_boundary_b, y_boundary_b, 'never')).toBeFalsy();
@@ -1,4 +1,4 @@
1
- import {describe, beforeAll, afterAll, test, expect, vi, type Mock} from 'vitest';
1
+ import {describe, beforeAll, afterAll, test, expect, vi} from 'vitest';
2
2
  import {TerrainTileManager} from './terrain_tile_manager.ts';
3
3
  import {Style} from '../style/style.ts';
4
4
  import {RequestManager} from '../util/request_manager.ts';
@@ -248,7 +248,7 @@ describe('TerrainTileManager', () => {
248
248
 
249
249
  tsc.releaseAllRTT();
250
250
 
251
- expect((painter.releaseRTT as Mock<typeof painter.releaseRTT>).mock.calls.length).toBe(Object.keys(tiles).length);
251
+ expect((vi.mocked(painter.releaseRTT))).toHaveBeenCalledTimes(Object.keys(tiles).length);
252
252
  for (const key in rttObjects) {
253
253
  expect(painter.releaseRTT).toHaveBeenCalledWith(rttObjects[key]);
254
254
  expect(tiles[key].getRTT(0)).toBeUndefined();
@@ -7,16 +7,16 @@ describe('CanonicalTileID', () => {
7
7
  test('constructor', () => {
8
8
  expect(() => {
9
9
  new CanonicalTileID(MIN_TILE_ZOOM - 1, 0, 0);
10
- }).toThrow();
10
+ }).toThrow(`x=0, y=0, z=${MIN_TILE_ZOOM - 1} outside of bounds`);
11
11
  expect(() => {
12
12
  new CanonicalTileID(MAX_TILE_ZOOM + 1, 0, 0);
13
- }).toThrow();
13
+ }).toThrow(`x=0, y=0, z=${MAX_TILE_ZOOM + 1} outside of bounds`);
14
14
  expect(() => {
15
15
  new CanonicalTileID(2, 4, 0);
16
- }).toThrow();
16
+ }).toThrow('x=4, y=0, z=2 outside of bounds');
17
17
  expect(() => {
18
18
  new CanonicalTileID(2, 0, 4);
19
- }).toThrow();
19
+ }).toThrow('x=0, y=4, z=2 outside of bounds');
20
20
  });
21
21
 
22
22
  test('.key', () => {
@@ -67,7 +67,7 @@ describe('OverscaledTileID', () => {
67
67
  });
68
68
 
69
69
  test('constructor - deeper canonicalZ than overscaledZ disallowed', () => {
70
- expect(() => new OverscaledTileID(7, 0, 8, 0, 0)).toThrow();
70
+ expect(() => new OverscaledTileID(7, 0, 8, 0, 0)).toThrow('overscaledZ should be >= z; overscaledZ = 7; z = 8');
71
71
  });
72
72
 
73
73
  test('.key', () => {