maplibre-gl 2.2.0-pre.2 → 2.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 (169) hide show
  1. package/README.md +73 -8
  2. package/build/generate-debug-index-file.ts +19 -0
  3. package/build/generate-style-code.ts +6 -1
  4. package/build/generate-style-spec.ts +151 -35
  5. package/build/rollup_plugins.ts +4 -1
  6. package/dist/maplibre-gl-csp-worker.js +1 -1
  7. package/dist/maplibre-gl-csp-worker.js.map +1 -1
  8. package/dist/maplibre-gl-csp.js +1 -1
  9. package/dist/maplibre-gl-csp.js.map +1 -1
  10. package/dist/maplibre-gl-dev.js +1317 -4304
  11. package/dist/maplibre-gl.css +1 -1
  12. package/dist/maplibre-gl.d.ts +443 -145
  13. package/dist/maplibre-gl.js +4 -4
  14. package/dist/maplibre-gl.js.map +1 -1
  15. package/package.json +70 -67
  16. package/src/css/maplibre-gl.css +48 -32
  17. package/src/data/bucket/fill_bucket.test.ts +1 -0
  18. package/src/data/bucket/symbol_bucket.test.ts +2 -0
  19. package/src/data/bucket/symbol_bucket.ts +1 -1
  20. package/src/data/evaluation_feature.ts +1 -1
  21. package/src/data/program_configuration.ts +2 -2
  22. package/src/geo/transform.test.ts +34 -1
  23. package/src/geo/transform.ts +25 -15
  24. package/src/gl/vertex_buffer.ts +4 -4
  25. package/src/index.ts +1 -1
  26. package/src/render/draw_debug.ts +1 -1
  27. package/src/render/draw_symbol.test.ts +2 -23
  28. package/src/render/draw_terrain.ts +1 -1
  29. package/src/render/image_atlas.ts +1 -0
  30. package/src/render/image_manager.ts +1 -0
  31. package/src/render/program/debug_program.ts +1 -1
  32. package/src/render/render_to_texture.ts +3 -0
  33. package/src/render/terrain.test.ts +119 -17
  34. package/src/render/terrain.ts +39 -21
  35. package/src/shaders/README.md +2 -2
  36. package/src/shaders/shaders.ts +3 -1
  37. package/src/source/geojson_worker_source.test.ts +2 -2
  38. package/src/source/geojson_wrapper.test.ts +1 -1
  39. package/src/source/image_source.test.ts +8 -8
  40. package/src/source/image_source.ts +1 -1
  41. package/src/source/load_tilejson.ts +6 -1
  42. package/src/source/pixels_to_tile_units.ts +1 -1
  43. package/src/source/raster_tile_source.test.ts +1 -1
  44. package/src/source/source_cache.test.ts +12 -12
  45. package/src/source/source_cache.ts +1 -1
  46. package/src/source/terrain_source_cache.test.ts +17 -2
  47. package/src/source/terrain_source_cache.ts +16 -12
  48. package/src/source/vector_tile_source.test.ts +1 -1
  49. package/src/source/vector_tile_worker_source.test.ts +1 -1
  50. package/src/source/video_source.test.ts +2 -2
  51. package/src/style/light.test.ts +1 -1
  52. package/src/style/load_sprite.ts +1 -1
  53. package/src/style/parse_glyph_pbf.ts +1 -1
  54. package/src/style/style.test.ts +3 -3
  55. package/src/style/style.ts +2 -2
  56. package/src/style/style_layer/background_style_layer_properties.g.ts +1 -0
  57. package/src/style/style_layer/circle_style_layer_properties.g.ts +1 -0
  58. package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +1 -0
  59. package/src/style/style_layer/fill_style_layer_properties.g.ts +1 -0
  60. package/src/style/style_layer/heatmap_style_layer_properties.g.ts +1 -0
  61. package/src/style/style_layer/hillshade_style_layer_properties.g.ts +1 -0
  62. package/src/style/style_layer/line_style_layer_properties.g.ts +1 -0
  63. package/src/style/style_layer/raster_style_layer_properties.g.ts +1 -0
  64. package/src/style/style_layer/symbol_style_layer.ts +16 -1
  65. package/src/style/style_layer/symbol_style_layer_properties.g.ts +4 -3
  66. package/src/style-spec/CHANGELOG.md +5 -0
  67. package/src/style-spec/composite.test.ts +2 -0
  68. package/src/style-spec/composite.ts +3 -2
  69. package/src/style-spec/diff.test.ts +3 -3
  70. package/src/style-spec/empty.ts +3 -2
  71. package/src/style-spec/expression/compound_expression.ts +0 -4
  72. package/src/style-spec/expression/definitions/assertion.ts +0 -18
  73. package/src/style-spec/expression/definitions/at.ts +0 -4
  74. package/src/style-spec/expression/definitions/case.ts +0 -6
  75. package/src/style-spec/expression/definitions/coalesce.ts +0 -6
  76. package/src/style-spec/expression/definitions/coercion.ts +13 -18
  77. package/src/style-spec/expression/definitions/collator.ts +0 -10
  78. package/src/style-spec/expression/definitions/comparison.ts +0 -6
  79. package/src/style-spec/expression/definitions/format.ts +0 -19
  80. package/src/style-spec/expression/definitions/image.ts +0 -4
  81. package/src/style-spec/expression/definitions/in.ts +0 -4
  82. package/src/style-spec/expression/definitions/index_of.ts +0 -8
  83. package/src/style-spec/expression/definitions/interpolate.ts +1 -25
  84. package/src/style-spec/expression/definitions/length.ts +0 -6
  85. package/src/style-spec/expression/definitions/let.ts +0 -9
  86. package/src/style-spec/expression/definitions/literal.ts +1 -23
  87. package/src/style-spec/expression/definitions/match.ts +0 -41
  88. package/src/style-spec/expression/definitions/number_format.ts +0 -17
  89. package/src/style-spec/expression/definitions/slice.ts +0 -8
  90. package/src/style-spec/expression/definitions/step.ts +0 -11
  91. package/src/style-spec/expression/definitions/var.ts +0 -4
  92. package/src/style-spec/expression/definitions/within.ts +0 -5
  93. package/src/style-spec/expression/expression.test.ts +1 -1
  94. package/src/style-spec/expression/expression.ts +3 -3
  95. package/src/style-spec/expression/index.ts +8 -2
  96. package/src/style-spec/expression/parsing_context.ts +2 -0
  97. package/src/style-spec/expression/types/formatted.ts +0 -23
  98. package/src/style-spec/expression/types/resolved_image.ts +0 -4
  99. package/src/style-spec/expression/types.ts +6 -1
  100. package/src/style-spec/expression/values.ts +9 -4
  101. package/src/style-spec/feature_filter/convert.ts +65 -65
  102. package/src/style-spec/feature_filter/feature_filter.test.ts +45 -4
  103. package/src/style-spec/feature_filter/index.ts +2 -1
  104. package/src/style-spec/function/index.test.ts +117 -1
  105. package/src/style-spec/function/index.ts +24 -12
  106. package/src/style-spec/migrate/expressions.ts +2 -2
  107. package/src/style-spec/migrate/v8.test.ts +2 -0
  108. package/src/style-spec/migrate/v8.ts +8 -7
  109. package/src/style-spec/migrate/v9.test.ts +6 -4
  110. package/src/style-spec/migrate/v9.ts +3 -2
  111. package/src/style-spec/migrate.test.ts +3 -1
  112. package/src/style-spec/migrate.ts +5 -4
  113. package/src/style-spec/package.json +1 -1
  114. package/src/style-spec/read_style.ts +2 -1
  115. package/src/style-spec/reference/latest.ts +1 -1
  116. package/src/style-spec/reference/v8.json +9 -6
  117. package/src/style-spec/style-spec.test.ts +2 -1
  118. package/src/style-spec/style-spec.ts +8 -0
  119. package/src/style-spec/types.g.ts +152 -36
  120. package/src/style-spec/util/extend.ts +1 -1
  121. package/src/style-spec/util/interpolate.test.ts +5 -0
  122. package/src/style-spec/util/interpolate.ts +12 -0
  123. package/src/style-spec/util/padding.test.ts +27 -0
  124. package/src/style-spec/util/padding.ts +64 -0
  125. package/src/style-spec/util/ref_properties.ts +2 -1
  126. package/src/style-spec/validate/validate.ts +3 -1
  127. package/src/style-spec/validate/validate_expression.ts +2 -1
  128. package/src/style-spec/validate/validate_function.ts +2 -2
  129. package/src/style-spec/validate/validate_glyphs_url.ts +1 -1
  130. package/src/style-spec/validate/validate_object.ts +2 -2
  131. package/src/style-spec/validate/validate_padding.test.ts +82 -0
  132. package/src/style-spec/validate/validate_padding.ts +36 -0
  133. package/src/style-spec/validate_style.min.ts +4 -3
  134. package/src/style-spec/validate_style.ts +4 -3
  135. package/src/symbol/check_max_angle.test.ts +5 -5
  136. package/src/symbol/collision_feature.test.ts +22 -5
  137. package/src/symbol/collision_feature.ts +7 -5
  138. package/src/symbol/collision_index.ts +1 -1
  139. package/src/symbol/get_anchors.test.ts +4 -4
  140. package/src/symbol/{mergelines.test.ts → merge_lines.test.ts} +1 -1
  141. package/src/symbol/{mergelines.ts → merge_lines.ts} +1 -1
  142. package/src/symbol/projection.ts +1 -1
  143. package/src/symbol/quads.test.ts +1 -1
  144. package/src/symbol/shaping.ts +10 -10
  145. package/src/symbol/symbol_layout.ts +5 -4
  146. package/src/symbol/symbol_style_layer.test.ts +1 -1
  147. package/src/symbol/transform_text.ts +3 -3
  148. package/src/ui/camera.test.ts +11 -11
  149. package/src/ui/control/geolocate_control.ts +1 -1
  150. package/src/ui/control/terrain_control.ts +4 -4
  151. package/src/ui/handler/cooperative_gestures.test.ts +167 -0
  152. package/src/ui/handler/drag_pan.test.ts +2 -1
  153. package/src/ui/handler/scroll_zoom.ts +7 -0
  154. package/src/ui/handler/touch_pan.ts +22 -2
  155. package/src/ui/handler/touch_zoom_rotate.ts +18 -1
  156. package/src/ui/handler_manager.ts +2 -2
  157. package/src/ui/map.test.ts +17 -17
  158. package/src/ui/map.ts +76 -8
  159. package/src/ui/map_events.test.ts +33 -32
  160. package/src/ui/popup.test.ts +2 -2
  161. package/src/util/ajax.test.ts +5 -5
  162. package/src/util/ajax.ts +1 -1
  163. package/src/util/classify_rings.test.ts +27 -27
  164. package/src/util/find_pole_of_inaccessibility.ts +1 -1
  165. package/src/util/primitives.ts +4 -4
  166. package/src/util/resolve_tokens.test.ts +1 -1
  167. package/src/util/smart_wrap.ts +1 -1
  168. package/src/util/tile_request_cache.test.ts +5 -5
  169. package/src/util/util.test.ts +5 -5
@@ -16,7 +16,7 @@ const debugUniforms = (context: Context, locations: UniformLocations): DebugUnif
16
16
  'u_color': new UniformColor(context, locations.u_color),
17
17
  'u_matrix': new UniformMatrix4f(context, locations.u_matrix),
18
18
  'u_overlay': new Uniform1i(context, locations.u_overlay),
19
- 'u_overlay_scale': new Uniform1f(context, locations.u_overlay_scale)
19
+ 'u_overlay_scale': new Uniform1f(context, locations.u_overlay_scale)
20
20
  });
21
21
 
22
22
  const debugUniformValues = (matrix: mat4, color: Color, scaleRatio: number = 1): UniformValues<DebugUniformsType> => ({
@@ -5,6 +5,9 @@ import {OverscaledTileID} from '../source/tile_id';
5
5
  import {prepareTerrain, drawTerrain} from './draw_terrain';
6
6
  import type StyleLayer from '../style/style_layer';
7
7
 
8
+ /**
9
+ * RenderToTexture
10
+ */
8
11
  export default class RenderToTexture {
9
12
  painter: Painter;
10
13
  // this object holds a lookup table which layers should rendered to texture
@@ -6,8 +6,11 @@ import {RGBAImage} from '../util/image';
6
6
  import Texture from './texture';
7
7
  import type Style from '../style/style';
8
8
  import type SourceCache from '../source/source_cache';
9
- import type TerrainSourceCache from '../source/terrain_source_cache';
9
+ import {OverscaledTileID} from '../source/tile_id';
10
10
  import type {TerrainSpecification} from '../style-spec/types.g';
11
+ import type DEMData from '../data/dem_data';
12
+ import TileCache from '../source/tile_cache';
13
+ import Tile from '../source/tile';
11
14
 
12
15
  describe('Terrain', () => {
13
16
  test('pointCoordiate should not return null', () => {
@@ -21,23 +24,24 @@ describe('Terrain', () => {
21
24
  }
22
25
  } as any as Style;
23
26
  const sourceCache = {
24
- getTileByID: (tileID) => {
25
- if (tileID !== 'abcd') {
26
- return null;
27
- }
28
- return {
29
- tileID: {
30
- canonical: {
31
- x: 0,
32
- y: 0,
33
- z: 0
34
- }
35
- }
36
- };
27
+ _cache: {max: 100} as TileCache
28
+ } as SourceCache;
29
+ const getTileByID = (tileID) : Tile => {
30
+ if (tileID !== 'abcd') {
31
+ return null as any as Tile;
37
32
  }
38
- } as any as TerrainSourceCache;
39
- const terrain = new Terrain(style, {} as any as SourceCache, {} as any as TerrainSpecification);
40
- terrain.sourceCache = sourceCache;
33
+ return {
34
+ tileID: {
35
+ canonical: {
36
+ x: 0,
37
+ y: 0,
38
+ z: 0
39
+ }
40
+ }
41
+ } as any as Tile;
42
+ };
43
+ const terrain = new Terrain(style, sourceCache, {} as any as TerrainSpecification);
44
+ terrain.sourceCache.getTileByID = getTileByID;
41
45
  const context = style.map.painter.context as Context;
42
46
  const pixels = new Uint8Array([0, 0, 255, 255]);
43
47
  const image = new RGBAImage({width: 1, height: 1}, pixels);
@@ -50,4 +54,102 @@ describe('Terrain', () => {
50
54
 
51
55
  expect(coordinate).not.toBeNull();
52
56
  });
57
+
58
+ test('Calculate tile minimum and maximum elevation', () => {
59
+ const tileID = new OverscaledTileID(5, 0, 5, 17, 11);
60
+ const tile = new Tile(tileID, 256);
61
+ tile.dem = {
62
+ min: 0,
63
+ max: 100,
64
+ getPixels: () => new RGBAImage({width: 1, height: 1}, new Uint8Array(1 * 4)),
65
+ getUnpackVector: () => [6553.6, 25.6, 0.1, 10000.0],
66
+ } as any as DEMData;
67
+ const style = {
68
+ map: {
69
+ painter: {
70
+ context: new Context(gl(1, 1)),
71
+ width: 1,
72
+ height: 1,
73
+ getTileTexture: () => null
74
+ }
75
+ }
76
+ } as any as Style;
77
+ const sourceCache = {
78
+ _source: {maxzoom: 12},
79
+ _cache: {max: 10},
80
+ getTileByID: () => {
81
+ return tile;
82
+ },
83
+ } as any as SourceCache;
84
+ const terrain = new Terrain(
85
+ style,
86
+ sourceCache,
87
+ {exaggeration: 2, elevationOffset: 50} as any as TerrainSpecification,
88
+ );
89
+
90
+ terrain.sourceCache._tiles[tileID.key] = tile;
91
+ const {minElevation, maxElevation} = terrain.getMinMaxElevation(tileID);
92
+
93
+ expect(minElevation).toBe(100);
94
+ expect(maxElevation).toBe(300);
95
+ });
96
+
97
+ test('Return null elevation values when no tile', () => {
98
+ const tileID = new OverscaledTileID(5, 0, 5, 17, 11);
99
+ const style = {
100
+ map: {
101
+ painter: {
102
+ context: new Context(gl(1, 1)),
103
+ width: 1,
104
+ height: 1,
105
+ }
106
+ }
107
+ } as any as Style;
108
+ const sourceCache = {
109
+ _source: {maxzoom: 12},
110
+ _cache: {max: 10},
111
+ getTileByID: () => null,
112
+ } as any as SourceCache;
113
+ const terrain = new Terrain(
114
+ style,
115
+ sourceCache,
116
+ {exaggeration: 2, elevationOffset: 50} as any as TerrainSpecification,
117
+ );
118
+
119
+ const minMaxNoTile = terrain.getMinMaxElevation(tileID);
120
+
121
+ expect(minMaxNoTile.minElevation).toBeNull();
122
+ expect(minMaxNoTile.maxElevation).toBeNull();
123
+ });
124
+
125
+ test('Return null elevation values when no DEM', () => {
126
+ const tileID = new OverscaledTileID(5, 0, 5, 17, 11);
127
+ const tile = new Tile(tileID, 256);
128
+ tile.dem = null as any as DEMData;
129
+ const style = {
130
+ map: {
131
+ painter: {
132
+ context: new Context(gl(1, 1)),
133
+ width: 1,
134
+ height: 1,
135
+ }
136
+ }
137
+ } as any as Style;
138
+ const sourceCache = {
139
+ _source: {maxzoom: 12},
140
+ _cache: {max: 10},
141
+ getTileByID: () => {
142
+ return tile;
143
+ },
144
+ } as any as SourceCache;
145
+ const terrain = new Terrain(
146
+ style,
147
+ sourceCache,
148
+ {exaggeration: 2, elevationOffset: 50} as any as TerrainSpecification,
149
+ );
150
+ const minMaxNoDEM = terrain.getMinMaxElevation(tileID);
151
+
152
+ expect(minMaxNoDEM.minElevation).toBeNull();
153
+ expect(minMaxNoDEM.maxElevation).toBeNull();
154
+ });
53
155
  });
@@ -20,6 +20,25 @@ import EXTENT from '../data/extent';
20
20
  import {number as mix} from '../style-spec/util/interpolate';
21
21
  import type {TerrainSpecification} from '../style-spec/types.g';
22
22
 
23
+ export type TerrainData = {
24
+ 'u_depth': number;
25
+ 'u_terrain': number;
26
+ 'u_terrain_dim': number;
27
+ 'u_terrain_matrix': mat4;
28
+ 'u_terrain_unpack': number[];
29
+ 'u_terrain_offset': number;
30
+ 'u_terrain_exaggeration': number;
31
+ texture: WebGLTexture;
32
+ depthTexture: WebGLTexture;
33
+ tile: Tile;
34
+ }
35
+
36
+ export type TerrainMesh = {
37
+ indexBuffer: IndexBuffer;
38
+ vertexBuffer: VertexBuffer;
39
+ segments: SegmentVector;
40
+ }
41
+
23
42
  /**
24
43
  * This is the main class which handles most of the 3D Terrain logic. It has the follwing topics:
25
44
  * 1) loads raster-dem tiles via the internal sourceCache this.sourceCache
@@ -48,25 +67,6 @@ import type {TerrainSpecification} from '../style-spec/types.g';
48
67
  *
49
68
  */
50
69
 
51
- export type TerrainData = {
52
- 'u_depth': number;
53
- 'u_terrain': number;
54
- 'u_terrain_dim': number;
55
- 'u_terrain_matrix': mat4;
56
- 'u_terrain_unpack': number[];
57
- 'u_terrain_offset': number;
58
- 'u_terrain_exaggeration': number;
59
- texture: WebGLTexture;
60
- depthTexture: WebGLTexture;
61
- tile: Tile;
62
- }
63
-
64
- export type TerrainMesh = {
65
- indexBuffer: IndexBuffer;
66
- vertexBuffer: VertexBuffer;
67
- segments: SegmentVector;
68
- }
69
-
70
70
  export default class Terrain {
71
71
  // The style this terrain crresponds to
72
72
  style: Style;
@@ -143,8 +143,8 @@ export default class Terrain {
143
143
  const terrain = this.getTerrainData(tileID);
144
144
  if (terrain.tile && terrain.tile.dem) {
145
145
  const pos = vec2.transformMat4([] as any, [x / extent * EXTENT, y / extent * EXTENT], terrain.u_terrain_matrix);
146
- const coord = [ pos[0] * terrain.tile.dem.dim, pos[1] * terrain.tile.dem.dim ];
147
- const c = [ Math.floor(coord[0]), Math.floor(coord[1]) ];
146
+ const coord = [pos[0] * terrain.tile.dem.dim, pos[1] * terrain.tile.dem.dim];
147
+ const c = [Math.floor(coord[0]), Math.floor(coord[1])];
148
148
  const tl = terrain.tile.dem.get(c[0], c[1]);
149
149
  const tr = terrain.tile.dem.get(c[0], c[1] + 1);
150
150
  const bl = terrain.tile.dem.get(c[0] + 1, c[1]);
@@ -366,4 +366,22 @@ export default class Terrain {
366
366
  return this._mesh;
367
367
  }
368
368
 
369
+ /**
370
+ * Get the minimum and maximum elevation contained in a tile. This includes any elevation offset
371
+ * and exaggeration included in the terrain.
372
+ *
373
+ * @param tileID Id of the tile to be used as a source for the min/max elevation
374
+ * @returns {Object} Minimum and maximum elevation found in the tile, including the terrain's
375
+ * elevation offset and exaggeration
376
+ */
377
+ getMinMaxElevation(tileID: OverscaledTileID): {minElevation: number | null; maxElevation: number | null} {
378
+ const tile = this.getTerrainData(tileID).tile;
379
+ const minMax = {minElevation: null, maxElevation: null};
380
+ if (tile && tile.dem) {
381
+ minMax.minElevation = (tile.dem.min + this.elevationOffset) * this.exaggeration;
382
+ minMax.maxElevation = (tile.dem.max + this.elevationOffset) * this.exaggeration;
383
+ }
384
+ return minMax;
385
+ }
386
+
369
387
  }
@@ -1,6 +1,6 @@
1
- # Mapbox GL Shaders
1
+ # MapLibre GL Shaders
2
2
 
3
- This repository contains GL shaders which are shared by [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) and [Mapbox GL Native](https://github.com/mapbox/mapbox-gl-native).
3
+ This repository contains GL shaders which are shared by [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) and [MapLibre GL Native](https://github.com/maplibre/maplibre-gl-native).
4
4
 
5
5
  ## Pragmas
6
6
 
@@ -58,7 +58,7 @@ import terrainCoordsFrag from './terrain_coords.fragment.glsl.g';
58
58
  import terrainFrag from './terrain.fragment.glsl.g';
59
59
  import terrainVert from './terrain.vertex.glsl.g';
60
60
 
61
- export default {
61
+ const shaders = {
62
62
  prelude: compile(preludeFrag, preludeVert),
63
63
  background: compile(backgroundFrag, backgroundVert),
64
64
  backgroundPattern: compile(backgroundPatternFrag, backgroundPatternVert),
@@ -90,6 +90,8 @@ export default {
90
90
  terrainCoords: compile(terrainCoordsFrag, terrainVert)
91
91
  };
92
92
 
93
+ export default shaders;
94
+
93
95
  // Expand #pragmas to #ifdefs.
94
96
 
95
97
  function compile(fragmentSource, vertexSource) {
@@ -130,7 +130,7 @@ describe('resourceTiming', () => {
130
130
  secureConnectionStart: 0
131
131
  } as any as PerformanceEntry;
132
132
 
133
- window.performance.getEntriesByName = jest.fn().mockReturnValue([ exampleResourceTiming ]);
133
+ window.performance.getEntriesByName = jest.fn().mockReturnValue([exampleResourceTiming]);
134
134
 
135
135
  const layerIndex = new StyleLayerIndex(layers);
136
136
  const source = new GeoJSONWorkerSource(actor, layerIndex, [], (params, callback) => {
@@ -140,7 +140,7 @@ describe('resourceTiming', () => {
140
140
 
141
141
  source.loadData({source: 'testSource', request: {url: 'http://localhost/nonexistent', collectResourceTiming: true}} as LoadGeoJSONParameters, (err, result) => {
142
142
  expect(err).toBeNull();
143
- expect(result.resourceTiming.testSource).toEqual([ exampleResourceTiming ]);
143
+ expect(result.resourceTiming.testSource).toEqual([exampleResourceTiming]);
144
144
  done();
145
145
  });
146
146
  });
@@ -14,7 +14,7 @@ describe('geojsonwrapper', () => {
14
14
  expect(feature).toBeTruthy();
15
15
  expect(feature.loadGeometry()).toEqual([[{x: 0, y: 0}, {x: 10, y: 10}]]);
16
16
  expect(feature.type).toBe(2);
17
- expect(feature.properties).toEqual({hello:'world'});
17
+ expect(feature.properties).toEqual({hello: 'world'});
18
18
 
19
19
  });
20
20
 
@@ -47,7 +47,7 @@ describe('ImageSource', () => {
47
47
  };
48
48
 
49
49
  test('constructor', () => {
50
- const source = createSource({url : '/image.png'});
50
+ const source = createSource({url: '/image.png'});
51
51
 
52
52
  expect(source.minzoom).toBe(0);
53
53
  expect(source.maxzoom).toBe(22);
@@ -55,7 +55,7 @@ describe('ImageSource', () => {
55
55
  });
56
56
 
57
57
  test('fires dataloading event', () => {
58
- const source = createSource({url : '/image.png'});
58
+ const source = createSource({url: '/image.png'});
59
59
  source.on('dataloading', (e) => {
60
60
  expect(e.dataType).toBe('source');
61
61
  });
@@ -65,7 +65,7 @@ describe('ImageSource', () => {
65
65
  });
66
66
 
67
67
  test('transforms url request', () => {
68
- const source = createSource({url : '/image.png'});
68
+ const source = createSource({url: '/image.png'});
69
69
  const map = new StubMap() as any;
70
70
  const spy = jest.spyOn(map._requestManager, 'transformRequest');
71
71
  source.onAdd(map);
@@ -76,7 +76,7 @@ describe('ImageSource', () => {
76
76
  });
77
77
 
78
78
  test('updates url from updateImage', () => {
79
- const source = createSource({url : '/image.png'});
79
+ const source = createSource({url: '/image.png'});
80
80
  const map = new StubMap() as any;
81
81
  const spy = jest.spyOn(map._requestManager, 'transformRequest');
82
82
  source.onAdd(map);
@@ -92,7 +92,7 @@ describe('ImageSource', () => {
92
92
  });
93
93
 
94
94
  test('sets coordinates', () => {
95
- const source = createSource({url : '/image.png'});
95
+ const source = createSource({url: '/image.png'});
96
96
  const map = new StubMap() as any;
97
97
  source.onAdd(map);
98
98
  respond();
@@ -104,7 +104,7 @@ describe('ImageSource', () => {
104
104
  });
105
105
 
106
106
  test('sets coordinates via updateImage', () => {
107
- const source = createSource({url : '/image.png'});
107
+ const source = createSource({url: '/image.png'});
108
108
  const map = new StubMap() as any;
109
109
  source.onAdd(map);
110
110
  respond();
@@ -120,7 +120,7 @@ describe('ImageSource', () => {
120
120
  });
121
121
 
122
122
  test('fires data event when content is loaded', done => {
123
- const source = createSource({url : '/image.png'});
123
+ const source = createSource({url: '/image.png'});
124
124
  source.on('data', (e) => {
125
125
  if (e.dataType === 'source' && e.sourceDataType === 'content') {
126
126
  expect(typeof source.tileID == 'object').toBeTruthy();
@@ -132,7 +132,7 @@ describe('ImageSource', () => {
132
132
  });
133
133
 
134
134
  test('fires data event when metadata is loaded', done => {
135
- const source = createSource({url : '/image.png'});
135
+ const source = createSource({url: '/image.png'});
136
136
  source.on('data', (e) => {
137
137
  if (e.dataType === 'source' && e.sourceDataType === 'metadata') {
138
138
  done();
@@ -209,7 +209,7 @@ class ImageSource extends Evented implements Source {
209
209
  delete this.boundsBuffer;
210
210
  }
211
211
 
212
- this.fire(new Event('data', {dataType:'source', sourceDataType: 'content'}));
212
+ this.fire(new Event('data', {dataType: 'source', sourceDataType: 'content'}));
213
213
  return this;
214
214
  }
215
215
 
@@ -7,8 +7,13 @@ import type {RequestManager} from '../util/request_manager';
7
7
  import type {Callback} from '../types/callback';
8
8
  import type {TileJSON} from '../types/tilejson';
9
9
  import type {Cancelable} from '../types/cancelable';
10
+ import type {RasterDEMSourceSpecification, RasterSourceSpecification, VectorSourceSpecification} from '../style-spec/types.g';
10
11
 
11
- export default function(options: any, requestManager: RequestManager, callback: Callback<TileJSON>): Cancelable {
12
+ export default function loadTileJson(
13
+ options: RasterSourceSpecification | RasterDEMSourceSpecification | VectorSourceSpecification,
14
+ requestManager: RequestManager,
15
+ callback: Callback<TileJSON>
16
+ ): Cancelable {
12
17
  const loaded = function(err: Error, tileJSON: any) {
13
18
  if (err) {
14
19
  return callback(err);
@@ -14,7 +14,7 @@ import type {OverscaledTileID} from './tile_id';
14
14
  * @returns value in tile units
15
15
  * @private
16
16
  */
17
- export default function(
17
+ export default function pixelsToTileUnits(
18
18
  tile: {
19
19
  tileID: OverscaledTileID;
20
20
  tileSize: number;
@@ -79,7 +79,7 @@ describe('RasterTileSource', () => {
79
79
 
80
80
  source.on('data', (e) => {
81
81
  if (e.sourceDataType === 'metadata') {
82
- expect(source.tileBounds.bounds).toEqual({_sw:{lng: -47, lat: -7}, _ne:{lng: -45, lat: 90}});
82
+ expect(source.tileBounds.bounds).toEqual({_sw: {lng: -47, lat: -7}, _ne: {lng: -45, lat: 90}});
83
83
  done();
84
84
  }
85
85
  });
@@ -485,7 +485,7 @@ describe('SourceCache / Source lifecycle', () => {
485
485
  transform.resize(511, 511);
486
486
  transform.zoom = 0;
487
487
 
488
- const expected = [ new OverscaledTileID(0, 0, 0, 0, 0).key, new OverscaledTileID(0, 0, 0, 0, 0).key ];
488
+ const expected = [new OverscaledTileID(0, 0, 0, 0, 0).key, new OverscaledTileID(0, 0, 0, 0, 0).key];
489
489
  expect.assertions(expected.length);
490
490
 
491
491
  const sourceCache = createSourceCache({
@@ -1054,9 +1054,9 @@ describe('SourceCache#_updateRetainedTiles', () => {
1054
1054
 
1055
1055
  expect(retained).toEqual({
1056
1056
  // parent of ideal tile 0/0/0
1057
- '000' : new OverscaledTileID(0, 0, 0, 0, 0),
1057
+ '000': new OverscaledTileID(0, 0, 0, 0, 0),
1058
1058
  // ideal tile id 1/0/1
1059
- '211' : new OverscaledTileID(1, 0, 1, 0, 1)
1059
+ '211': new OverscaledTileID(1, 0, 1, 0, 1)
1060
1060
  });
1061
1061
 
1062
1062
  addTileSpy.mockClear();
@@ -1069,7 +1069,7 @@ describe('SourceCache#_updateRetainedTiles', () => {
1069
1069
  expect(getTileSpy).not.toHaveBeenCalled();
1070
1070
  expect(retainedLoaded).toEqual({
1071
1071
  // only ideal tile retained
1072
- '211' : new OverscaledTileID(1, 0, 1, 0, 1)
1072
+ '211': new OverscaledTileID(1, 0, 1, 0, 1)
1073
1073
  });
1074
1074
  });
1075
1075
 
@@ -1119,9 +1119,9 @@ describe('SourceCache#_updateRetainedTiles', () => {
1119
1119
  expect(retained).toEqual({
1120
1120
  // parent of ideal tile (0, 0, 0) (only partially covered by loaded child
1121
1121
  // tiles, so we still need to load the parent)
1122
- '000' : new OverscaledTileID(0, 0, 0, 0, 0),
1122
+ '000': new OverscaledTileID(0, 0, 0, 0, 0),
1123
1123
  // ideal tile id (1, 0, 0)
1124
- '011' : new OverscaledTileID(1, 0, 1, 0, 0),
1124
+ '011': new OverscaledTileID(1, 0, 1, 0, 0),
1125
1125
  // loaded child tile (2, 0, 0)
1126
1126
  '022': new OverscaledTileID(2, 0, 2, 0, 0)
1127
1127
  });
@@ -1134,9 +1134,9 @@ describe('SourceCache#_updateRetainedTiles', () => {
1134
1134
  expect(retained).toEqual({
1135
1135
  // parent of ideal tile (0, 0, 0) (only partially covered by loaded child
1136
1136
  // tiles, so we still need to load the parent)
1137
- '000' : new OverscaledTileID(0, 0, 0, 0, 0),
1137
+ '000': new OverscaledTileID(0, 0, 0, 0, 0),
1138
1138
  // ideal tile id (1, 0, 0)
1139
- '011' : new OverscaledTileID(1, 0, 1, 0, 0)
1139
+ '011': new OverscaledTileID(1, 0, 1, 0, 0)
1140
1140
  });
1141
1141
 
1142
1142
  });
@@ -1163,7 +1163,7 @@ describe('SourceCache#_updateRetainedTiles', () => {
1163
1163
 
1164
1164
  expect(retained).toEqual({
1165
1165
  // ideal tile id (2, 0, 0)
1166
- '022' : new OverscaledTileID(2, 0, 2, 0, 0)
1166
+ '022': new OverscaledTileID(2, 0, 2, 0, 0)
1167
1167
  });
1168
1168
 
1169
1169
  });
@@ -1191,7 +1191,7 @@ describe('SourceCache#_updateRetainedTiles', () => {
1191
1191
 
1192
1192
  expect(retained).toEqual({
1193
1193
  // ideal tile id (2, 0, 0)
1194
- '022' : new OverscaledTileID(2, 0, 2, 0, 0)
1194
+ '022': new OverscaledTileID(2, 0, 2, 0, 0)
1195
1195
  });
1196
1196
 
1197
1197
  });
@@ -1352,7 +1352,7 @@ describe('SourceCache#tilesIn', () => {
1352
1352
  expect(tiles[0].tile.tileID.key).toBe('011');
1353
1353
  expect(tiles[0].tile.tileSize).toBe(512);
1354
1354
  expect(tiles[0].scale).toBe(1);
1355
- expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x:12288, y: 8146}]);
1355
+ expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x: 12288, y: 8146}]);
1356
1356
 
1357
1357
  expect(tiles[1].tile.tileID.key).toBe('111');
1358
1358
  expect(tiles[1].tile.tileSize).toBe(512);
@@ -1404,7 +1404,7 @@ describe('SourceCache#tilesIn', () => {
1404
1404
  expect(tiles[0].tile.tileID.key).toBe('012');
1405
1405
  expect(tiles[0].tile.tileSize).toBe(1024);
1406
1406
  expect(tiles[0].scale).toBe(1);
1407
- expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x:12288, y: 8146}]);
1407
+ expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x: 12288, y: 8146}]);
1408
1408
 
1409
1409
  expect(tiles[1].tile.tileID.key).toBe('112');
1410
1410
  expect(tiles[1].tile.tileSize).toBe(1024);
@@ -492,7 +492,7 @@ class SourceCache extends Evented {
492
492
  * are inside the viewport.
493
493
  * @private
494
494
  */
495
- update(transform: Transform, terrain: Terrain) {
495
+ update(transform: Transform, terrain?: Terrain) {
496
496
  this.transform = transform;
497
497
  this.terrain = terrain;
498
498
  if (!this._sourceLoaded || this._paused) { return; }
@@ -9,6 +9,9 @@ import Painter from '../render/painter';
9
9
  import Context from '../gl/context';
10
10
  import gl from 'gl';
11
11
  import RasterDEMTileSource from './raster_dem_tile_source';
12
+ import {OverscaledTileID} from './tile_id';
13
+ import Tile from './tile';
14
+ import DEMData from '../data/dem_data';
12
15
 
13
16
  const context = new Context(gl(10, 10));
14
17
  const transform = new Transform();
@@ -54,8 +57,8 @@ describe('TerrainSourceCache', () => {
54
57
  global.fetch = null;
55
58
  server = fakeServer.create();
56
59
  server.respondWith('/source.json', JSON.stringify({
57
- minzoom: 0,
58
- maxzoom: 22,
60
+ minzoom: 5,
61
+ maxzoom: 12,
59
62
  attribution: 'MapLibre',
60
63
  tiles: ['http://example.com/{z}/{x}/{y}.pngraw'],
61
64
  bounds: [-47, -7, -45, -5]
@@ -86,4 +89,16 @@ describe('TerrainSourceCache', () => {
86
89
  expect(tsc.sourceCache.tileSize).toBe(tsc.tileSize * 2 ** tsc.deltaZoom);
87
90
  });
88
91
 
92
+ test('#getSourceTile', () => {
93
+ const tileID = new OverscaledTileID(5, 0, 5, 17, 11);
94
+ const tile = new Tile(tileID, 256);
95
+ tile.dem = {} as DEMData;
96
+ tsc.sourceCache._tiles[tileID.key] = tile;
97
+ expect(tsc.deltaZoom).toBe(1);
98
+ expect(tsc.getSourceTile(tileID)).toBeFalsy();
99
+ expect(tsc.getSourceTile(tileID.children(12)[0])).toBeTruthy();
100
+ expect(tsc.getSourceTile(tileID.children(12)[0].children(12)[0])).toBeFalsy();
101
+ expect(tsc.getSourceTile(tileID.children(12)[0].children(12)[0], true)).toBeTruthy();
102
+ });
103
+
89
104
  });
@@ -50,7 +50,7 @@ export default class TerrainSourceCache extends Evented {
50
50
  this.maxzoom = 22;
51
51
  this.tileSize = 512;
52
52
  this.deltaZoom = 1;
53
- this.renderHistorySize = 150;
53
+ this.renderHistorySize = sourceCache._cache.max;
54
54
  sourceCache.usedForTerrain = true;
55
55
  sourceCache.tileSize = this.tileSize * 2 ** this.deltaZoom;
56
56
  }
@@ -98,15 +98,19 @@ export default class TerrainSourceCache extends Evented {
98
98
  removeOutdated(painter: Painter) {
99
99
  // create lookuptable for actual needed tiles
100
100
  const tileIDs = {};
101
+ // remove duplicates from renderHistory and chop to renderHistorySize
102
+ this.renderHistory = this.renderHistory.filter((i, p) => {
103
+ return this.renderHistory.indexOf(i) === p;
104
+ }).slice(0, this.renderHistorySize);
105
+ // fill lookuptable with current rendered tiles
101
106
  for (const key of this._renderableTilesKeys) tileIDs[key] = true;
102
- // remove duplicates from renderHistory
103
- this.renderHistory = this.renderHistory.filter((i, p) => this.renderHistory.indexOf(i) === p);
107
+ // fill lookuptable with most recent rendered tiles outside the viewport
108
+ for (const key of this.renderHistory) tileIDs[key] = true;
104
109
  // free (GPU) memory from previously rendered not needed tiles
105
- while (this.renderHistory.length > this.renderHistorySize) {
106
- const tile = this.sourceCache._tiles[this.renderHistory.shift()];
107
- if (tile && !tileIDs[tile.tileID.key]) {
108
- tile.clearTextures(painter);
109
- delete this.sourceCache._tiles[tile.tileID.key];
110
+ for (const key in this._tiles) {
111
+ if (!tileIDs[key]) {
112
+ this._tiles[key].clearTextures(painter);
113
+ delete this._tiles[key];
110
114
  }
111
115
  }
112
116
  }
@@ -129,11 +133,11 @@ export default class TerrainSourceCache extends Evented {
129
133
  }
130
134
 
131
135
  /**
132
- * searches for the corresponding current renderable terrain-tiles
136
+ * Searches for the corresponding current renderable terrain-tiles
133
137
  * @param {OverscaledTileID} tileID - the tile to look for
134
- * @returns {[_:string]: Tile} - the tiles that were found
138
+ * @returns {Record<string, OverscaledTileID>} - the tiles that were found
135
139
  */
136
- getTerrainCoords(tileID: OverscaledTileID): {[_: string]: OverscaledTileID} {
140
+ getTerrainCoords(tileID: OverscaledTileID): Record<string, OverscaledTileID> {
137
141
  const coords = {};
138
142
  for (const key of this._renderableTilesKeys) {
139
143
  const _tileID = this._tiles[key].tileID;
@@ -185,7 +189,7 @@ export default class TerrainSourceCache extends Evented {
185
189
  let tile = this.sourceCache.getTileByID(this._sourceTileCache[tileID.key]);
186
190
  // during tile-loading phase look if parent tiles (with loaded dem) are available.
187
191
  if (!(tile && tile.dem) && searchForDEM)
188
- while (z > source.minzoom && !(tile && tile.dem))
192
+ while (z >= source.minzoom && !(tile && tile.dem))
189
193
  tile = this.sourceCache.getTileByID(tileID.scaledTo(z--).key);
190
194
  return tile;
191
195
  }
@@ -253,7 +253,7 @@ describe('VectorTileSource', () => {
253
253
 
254
254
  source.on('data', (e) => {
255
255
  if (e.sourceDataType === 'metadata') {
256
- expect(source.tileBounds.bounds).toEqual({_sw:{lng: -47, lat: -7}, _ne:{lng: -45, lat: 90}});
256
+ expect(source.tileBounds.bounds).toEqual({_sw: {lng: -47, lat: -7}, _ne: {lng: -45, lat: 90}});
257
257
  done();
258
258
  }
259
259
  });
@@ -236,7 +236,7 @@ describe('vector tile worker source', () => {
236
236
 
237
237
  const source = new VectorTileWorkerSource(actor, layerIndex, [], loadVectorData);
238
238
 
239
- window.performance.getEntriesByName = jest.fn().mockReturnValue([ exampleResourceTiming ]);
239
+ window.performance.getEntriesByName = jest.fn().mockReturnValue([exampleResourceTiming]);
240
240
 
241
241
  source.loadTile({
242
242
  source: 'source',