@deck.gl/geo-layers 8.6.5 → 8.7.0-alpha.7

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 (66) hide show
  1. package/dist/dist.dev.js +6922 -3752
  2. package/dist/es5/great-circle-layer/great-circle-layer.js +1 -1
  3. package/dist/es5/h3-layers/h3-cluster-layer.js +3 -3
  4. package/dist/es5/h3-layers/h3-cluster-layer.js.map +1 -1
  5. package/dist/es5/h3-layers/h3-hexagon-layer.js +10 -9
  6. package/dist/es5/h3-layers/h3-hexagon-layer.js.map +1 -1
  7. package/dist/es5/index.js.map +1 -1
  8. package/dist/es5/mesh-layer/mesh-layer-vertex.glsl.js +1 -1
  9. package/dist/es5/mesh-layer/mesh-layer.js +5 -10
  10. package/dist/es5/mesh-layer/mesh-layer.js.map +1 -1
  11. package/dist/es5/mvt-layer/coordinate-transform.js +4 -4
  12. package/dist/es5/mvt-layer/coordinate-transform.js.map +1 -1
  13. package/dist/es5/mvt-layer/find-index-binary.js +1 -1
  14. package/dist/es5/mvt-layer/find-index-binary.js.map +1 -1
  15. package/dist/es5/mvt-layer/mvt-layer.js +12 -12
  16. package/dist/es5/mvt-layer/mvt-layer.js.map +1 -1
  17. package/dist/es5/s2-layer/s2-layer.js +2 -2
  18. package/dist/es5/s2-layer/s2-layer.js.map +1 -1
  19. package/dist/es5/s2-layer/s2-utils.js.map +1 -1
  20. package/dist/es5/terrain-layer/terrain-layer.js +2 -2
  21. package/dist/es5/terrain-layer/terrain-layer.js.map +1 -1
  22. package/dist/es5/tile-3d-layer/tile-3d-layer.js +11 -9
  23. package/dist/es5/tile-3d-layer/tile-3d-layer.js.map +1 -1
  24. package/dist/es5/tile-layer/tile-2d-header.js +35 -35
  25. package/dist/es5/tile-layer/tile-2d-header.js.map +1 -1
  26. package/dist/es5/tile-layer/tile-2d-traversal.js +13 -13
  27. package/dist/es5/tile-layer/tile-2d-traversal.js.map +1 -1
  28. package/dist/es5/tile-layer/tile-layer.js +20 -22
  29. package/dist/es5/tile-layer/tile-layer.js.map +1 -1
  30. package/dist/es5/tile-layer/tileset-2d.js +215 -141
  31. package/dist/es5/tile-layer/tileset-2d.js.map +1 -1
  32. package/dist/es5/tile-layer/utils.js.map +1 -1
  33. package/dist/es5/trips-layer/trips-layer.js +2 -2
  34. package/dist/es5/trips-layer/trips-layer.js.map +1 -1
  35. package/dist/esm/h3-layers/h3-hexagon-layer.js +2 -1
  36. package/dist/esm/h3-layers/h3-hexagon-layer.js.map +1 -1
  37. package/dist/esm/index.js.map +1 -1
  38. package/dist/esm/mesh-layer/mesh-layer-vertex.glsl.js +1 -1
  39. package/dist/esm/mesh-layer/mesh-layer-vertex.glsl.js.map +1 -1
  40. package/dist/esm/mesh-layer/mesh-layer.js +2 -8
  41. package/dist/esm/mesh-layer/mesh-layer.js.map +1 -1
  42. package/dist/esm/mvt-layer/coordinate-transform.js +1 -1
  43. package/dist/esm/mvt-layer/coordinate-transform.js.map +1 -1
  44. package/dist/esm/mvt-layer/mvt-layer.js +1 -1
  45. package/dist/esm/mvt-layer/mvt-layer.js.map +1 -1
  46. package/dist/esm/s2-layer/s2-utils.js.map +1 -1
  47. package/dist/esm/tile-3d-layer/tile-3d-layer.js +2 -1
  48. package/dist/esm/tile-3d-layer/tile-3d-layer.js.map +1 -1
  49. package/dist/esm/tile-layer/tile-2d-traversal.js.map +1 -1
  50. package/dist/esm/tile-layer/tile-layer.js +2 -8
  51. package/dist/esm/tile-layer/tile-layer.js.map +1 -1
  52. package/dist/esm/tile-layer/tileset-2d.js +85 -79
  53. package/dist/esm/tile-layer/tileset-2d.js.map +1 -1
  54. package/dist.min.js +2 -2
  55. package/package.json +12 -12
  56. package/src/h3-layers/h3-hexagon-layer.js +2 -1
  57. package/src/{index.js → index.ts} +0 -0
  58. package/src/mesh-layer/mesh-layer-vertex.glsl.js +24 -23
  59. package/src/mesh-layer/mesh-layer.js +5 -4
  60. package/src/mvt-layer/coordinate-transform.js +1 -1
  61. package/src/mvt-layer/mvt-layer.js +1 -1
  62. package/src/s2-layer/s2-utils.js +7 -1
  63. package/src/tile-3d-layer/tile-3d-layer.js +12 -9
  64. package/src/tile-layer/tile-2d-traversal.js +17 -3
  65. package/src/tile-layer/tile-layer.js +2 -6
  66. package/src/tile-layer/tileset-2d.js +103 -90
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@deck.gl/geo-layers",
3
3
  "description": "deck.gl layers supporting geospatial use cases and GIS formats",
4
4
  "license": "MIT",
5
- "version": "8.6.5",
5
+ "version": "8.7.0-alpha.7",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -29,18 +29,18 @@
29
29
  "prepublishOnly": "npm run build-bundle && npm run build-bundle -- --env.dev"
30
30
  },
31
31
  "dependencies": {
32
- "@loaders.gl/3d-tiles": "^3.0.8",
33
- "@loaders.gl/gis": "^3.0.8",
34
- "@loaders.gl/loader-utils": "^3.0.8",
35
- "@loaders.gl/mvt": "^3.0.8",
36
- "@loaders.gl/terrain": "^3.0.8",
37
- "@loaders.gl/tiles": "^3.0.8",
32
+ "@loaders.gl/3d-tiles": "^3.1.0",
33
+ "@loaders.gl/gis": "^3.1.0",
34
+ "@loaders.gl/loader-utils": "^3.1.0",
35
+ "@loaders.gl/mvt": "^3.1.0",
36
+ "@loaders.gl/terrain": "^3.1.0",
37
+ "@loaders.gl/tiles": "^3.1.0",
38
38
  "@luma.gl/experimental": "^8.5.10",
39
- "@math.gl/culling": "^3.5.4",
40
- "@math.gl/web-mercator": "^3.5.4",
39
+ "@math.gl/core": "^3.5.6",
40
+ "@math.gl/culling": "^3.5.6",
41
+ "@math.gl/web-mercator": "^3.5.6",
41
42
  "h3-js": "^3.6.0",
42
- "long": "^3.2.0",
43
- "math.gl": "^3.5.4"
43
+ "long": "^3.2.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@deck.gl/core": "^8.0.0",
@@ -49,5 +49,5 @@
49
49
  "@deck.gl/mesh-layers": "^8.0.0",
50
50
  "@loaders.gl/core": "^3.0.0"
51
51
  },
52
- "gitHead": "62726f0bd67091a673f3dca276515199276e83bd"
52
+ "gitHead": "5187031e307035c0ef59f83cd2437443e58218c6"
53
53
  }
@@ -8,7 +8,7 @@ import {
8
8
  edgeLength,
9
9
  UNITS
10
10
  } from 'h3-js';
11
- import {lerp} from 'math.gl';
11
+ import {lerp} from '@math.gl/core';
12
12
  import {CompositeLayer, createIterable} from '@deck.gl/core';
13
13
  import {ColumnLayer, PolygonLayer} from '@deck.gl/layers';
14
14
 
@@ -304,6 +304,7 @@ export default class H3HexagonLayer extends CompositeLayer {
304
304
  forwardProps,
305
305
  this.getSubLayerProps({
306
306
  id: 'hexagon-cell',
307
+ flatShading: true,
307
308
  updateTriggers: forwardProps.updateTriggers
308
309
  }),
309
310
  {
File without changes
@@ -26,12 +26,18 @@ out vec3 normals_commonspace;
26
26
  out vec4 position_commonspace;
27
27
  out vec4 vColor;
28
28
 
29
- void main(void) {
30
- // https://github.com/Esri/i3s-spec/blob/master/docs/1.7/geometryUVRegion.cmn.md
31
- vec2 uv = fract(texCoords) * (uvRegions.zw - uvRegions.xy) + uvRegions.xy;
29
+ vec2 applyUVRegion(vec2 uv) {
30
+ #ifdef HAS_UV_REGIONS
31
+ // https://github.com/Esri/i3s-spec/blob/master/docs/1.7/geometryUVRegion.cmn.md
32
+ return fract(uv) * (uvRegions.zw - uvRegions.xy) + uvRegions.xy;
33
+ #else
34
+ return uv;
35
+ #endif
36
+ }
32
37
 
38
+ void main(void) {
39
+ vec2 uv = applyUVRegion(texCoords);
33
40
  geometry.uv = uv;
34
- geometry.uv = texCoords;
35
41
 
36
42
  if (u_pickFeatureIds) {
37
43
  geometry.pickingColor = featureIdsPickingColors;
@@ -39,26 +45,9 @@ void main(void) {
39
45
  geometry.pickingColor = instancePickingColors;
40
46
  }
41
47
 
42
- #ifdef MODULE_PBR
43
- // set PBR data
44
- #ifdef HAS_NORMALS
45
- pbr_vNormal = project_normal(instanceModelMatrix * normals);
46
- geometry.normal = pbr_vNormal;
47
- #endif
48
-
49
- #ifdef HAS_UV
50
- pbr_vUV = uv;
51
- #else
52
- pbr_vUV = vec2(0., 0.);
53
- #endif
54
- geometry.uv = pbr_vUV;
55
- #endif
56
-
57
48
  vTexCoord = uv;
58
49
  cameraPosition = project_uCameraPosition;
59
- normals_commonspace = project_normal(instanceModelMatrix * normals);
60
50
  vColor = vec4(colors * instanceColors.rgb, instanceColors.a);
61
- geometry.normal = normals_commonspace;
62
51
 
63
52
  vec3 pos = (instanceModelMatrix * positions) * sizeScale;
64
53
  vec3 projectedPosition = project_position(positions);
@@ -66,13 +55,25 @@ void main(void) {
66
55
  gl_Position = project_common_position_to_clipspace(position_commonspace);
67
56
 
68
57
  geometry.position = position_commonspace;
58
+ normals_commonspace = project_normal(instanceModelMatrix * normals);
59
+ geometry.normal = normals_commonspace;
60
+
61
+ DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
69
62
 
70
63
  #ifdef MODULE_PBR
71
64
  // set PBR data
72
65
  pbr_vPosition = geometry.position.xyz;
73
- #endif
66
+ #ifdef HAS_NORMALS
67
+ pbr_vNormal = geometry.normal;
68
+ #endif
74
69
 
75
- DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
70
+ #ifdef HAS_UV
71
+ pbr_vUV = uv;
72
+ #else
73
+ pbr_vUV = vec2(0., 0.);
74
+ #endif
75
+ geometry.uv = pbr_vUV;
76
+ #endif
76
77
 
77
78
  DECKGL_FILTER_COLOR(vColor, geometry);
78
79
  }
@@ -11,9 +11,6 @@ function validateGeometryAttributes(attributes) {
11
11
  if (!hasColorAttribute) {
12
12
  attributes.colors = {constant: true, value: new Float32Array([1, 1, 1])};
13
13
  }
14
- if (!attributes.uvRegions) {
15
- attributes.uvRegions = {constant: true, value: new Float32Array([0, 0, 1, 1])};
16
- }
17
14
  }
18
15
 
19
16
  const defaultProps = {
@@ -76,7 +73,11 @@ export default class _MeshLayer extends SimpleMeshLayer {
76
73
  ...this.getShaders(),
77
74
  id,
78
75
  geometry: mesh,
79
- defines: {...shaders.defines, ...materialParser?.defines},
76
+ defines: {
77
+ ...shaders.defines,
78
+ ...materialParser?.defines,
79
+ HAS_UV_REGIONS: mesh.attributes.uvRegions
80
+ },
80
81
  parameters: materialParser?.parameters,
81
82
  isInstanced: true
82
83
  });
@@ -1,4 +1,4 @@
1
- import {lerp} from 'math.gl';
1
+ import {lerp} from '@math.gl/core';
2
2
 
3
3
  const availableTransformations = {
4
4
  Point,
@@ -1,5 +1,5 @@
1
1
  import {log} from '@deck.gl/core';
2
- import {Matrix4} from 'math.gl';
2
+ import {Matrix4} from '@math.gl/core';
3
3
  import {MVTWorkerLoader} from '@loaders.gl/mvt';
4
4
  import {binaryToGeojson} from '@loaders.gl/gis';
5
5
  import {COORDINATE_SYSTEM} from '@deck.gl/core';
@@ -25,7 +25,13 @@ const MAX_RESOLUTION = 100;
25
25
  /* Adapted from s2-geometry's S2Cell.getCornerLatLngs */
26
26
  /* eslint-disable max-statements */
27
27
  function getGeoBounds({face, ij, level}) {
28
- const offsets = [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]];
28
+ const offsets = [
29
+ [0, 0],
30
+ [0, 1],
31
+ [1, 1],
32
+ [1, 0],
33
+ [0, 0]
34
+ ];
29
35
 
30
36
  // The S2 cell edge is curved: http://s2geometry.io/
31
37
  // This is more prominent at lower levels
@@ -192,13 +192,8 @@ export default class Tile3DLayer extends CompositeLayer {
192
192
  }
193
193
 
194
194
  _makePointCloudLayer(tileHeader, oldLayer) {
195
- const {
196
- attributes,
197
- pointCount,
198
- constantRGBA,
199
- cartographicOrigin,
200
- modelMatrix
201
- } = tileHeader.content;
195
+ const {attributes, pointCount, constantRGBA, cartographicOrigin, modelMatrix} =
196
+ tileHeader.content;
202
197
  const {positions, normals, colors} = attributes;
203
198
 
204
199
  if (!positions) {
@@ -267,7 +262,15 @@ export default class Tile3DLayer extends CompositeLayer {
267
262
 
268
263
  _makeSimpleMeshLayer(tileHeader, oldLayer) {
269
264
  const content = tileHeader.content;
270
- const {attributes, indices, modelMatrix, cartographicOrigin, material, featureIds} = content;
265
+ const {
266
+ attributes,
267
+ indices,
268
+ modelMatrix,
269
+ cartographicOrigin,
270
+ coordinateSystem = COORDINATE_SYSTEM.METER_OFFSETS,
271
+ material,
272
+ featureIds
273
+ } = content;
271
274
  const {_getMeshColor} = this.props;
272
275
 
273
276
  const geometry =
@@ -293,7 +296,7 @@ export default class Tile3DLayer extends CompositeLayer {
293
296
  pbrMaterial: material,
294
297
  modelMatrix,
295
298
  coordinateOrigin: cartographicOrigin,
296
- coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS,
299
+ coordinateSystem,
297
300
  featureIds,
298
301
  _offset: 0
299
302
  }
@@ -12,9 +12,23 @@ const TILE_SIZE = 512;
12
12
  // number of world copies to check
13
13
  const MAX_MAPS = 3;
14
14
  // for calculating bounding volume of a tile in a non-web-mercator viewport
15
- const REF_POINTS_5 = [[0.5, 0.5], [0, 0], [0, 1], [1, 0], [1, 1]]; // 4 corners and center
16
- const REF_POINTS_9 = REF_POINTS_5.concat([[0, 0.5], [0.5, 0], [1, 0.5], [0.5, 1]]); // 4 corners, center and 4 mid points
17
- const REF_POINTS_11 = REF_POINTS_9.concat([[0.25, 0.5], [0.75, 0.5]]); // 2 additional points on equator for top tile
15
+ const REF_POINTS_5 = [
16
+ [0.5, 0.5],
17
+ [0, 0],
18
+ [0, 1],
19
+ [1, 0],
20
+ [1, 1]
21
+ ]; // 4 corners and center
22
+ const REF_POINTS_9 = REF_POINTS_5.concat([
23
+ [0, 0.5],
24
+ [0.5, 0],
25
+ [1, 0.5],
26
+ [0.5, 1]
27
+ ]); // 4 corners, center and 4 mid points
28
+ const REF_POINTS_11 = REF_POINTS_9.concat([
29
+ [0.25, 0.5],
30
+ [0.75, 0.5]
31
+ ]); // 2 additional points on equator for top tile
18
32
 
19
33
  class OSMNode {
20
34
  constructor(x, y, z) {
@@ -144,18 +144,14 @@ export default class TileLayer extends CompositeLayer {
144
144
  this.props.onTileLoad(tile);
145
145
  tile.layers = null;
146
146
 
147
- if (tile.isVisible) {
148
- this.setNeedsUpdate();
149
- }
147
+ this.setNeedsUpdate();
150
148
  }
151
149
 
152
150
  _onTileError(error, tile) {
153
151
  this.props.onTileError(error);
154
152
  tile.layers = null;
155
153
 
156
- if (tile.isVisible) {
157
- this.setNeedsUpdate();
158
- }
154
+ this.setNeedsUpdate();
159
155
  }
160
156
 
161
157
  _onTileUnload(tile) {
@@ -1,10 +1,11 @@
1
1
  import Tile2DHeader from './tile-2d-header';
2
2
  import {getTileIndices, tileToBoundingBox} from './utils';
3
3
  import {RequestScheduler} from '@loaders.gl/loader-utils';
4
- import {Matrix4} from 'math.gl';
4
+ import {Matrix4} from '@math.gl/core';
5
5
 
6
- const TILE_STATE_UNKNOWN = 0;
7
- const TILE_STATE_VISIBLE = 1;
6
+ // bit masks
7
+ const TILE_STATE_VISITED = 1;
8
+ const TILE_STATE_VISIBLE = 2;
8
9
  /*
9
10
  show cached parent tile if children are loading
10
11
  +-----------+ +-----+ +-----+-----+
@@ -23,10 +24,6 @@ const TILE_STATE_VISIBLE = 1;
23
24
  +-------+---- --> |
24
25
  | | |
25
26
  */
26
- const TILE_STATE_PLACEHOLDER = 3;
27
- const TILE_STATE_HIDDEN = 4;
28
- // tiles that should be displayed in the current viewport
29
- const TILE_STATE_SELECTED = 5;
30
27
 
31
28
  export const STRATEGY_NEVER = 'never';
32
29
  export const STRATEGY_REPLACE = 'no-overlap';
@@ -34,6 +31,12 @@ export const STRATEGY_DEFAULT = 'best-available';
34
31
 
35
32
  const DEFAULT_CACHE_SCALE = 5;
36
33
 
34
+ const STRATEGIES = {
35
+ [STRATEGY_DEFAULT]: updateTileStateDefault,
36
+ [STRATEGY_REPLACE]: updateTileStateReplace,
37
+ [STRATEGY_NEVER]: () => {}
38
+ };
39
+
37
40
  /**
38
41
  * Manages loading and purging of tiles data. This class caches recently visited tiles
39
42
  * and only create new tiles if they are present.
@@ -153,6 +156,7 @@ export default class Tileset2D {
153
156
 
154
157
  // Update tile states
155
158
  const changed = this.updateTileStates();
159
+ this._pruneRequests();
156
160
 
157
161
  if (this._dirty) {
158
162
  // cache size is either the user defined maxSize or 5 * number of current tiles in the viewport.
@@ -201,46 +205,63 @@ export default class Tileset2D {
201
205
 
202
206
  // Returns true if any tile's visibility changed
203
207
  updateTileStates() {
204
- this._updateTileStates(this.selectedTiles);
208
+ const refinementStrategy = this.opts.refinementStrategy || STRATEGY_DEFAULT;
205
209
 
206
- const {maxRequests} = this.opts;
210
+ const visibilities = new Array(this._cache.size);
211
+ let i = 0;
212
+ // Reset state
213
+ for (const tile of this._cache.values()) {
214
+ // save previous state
215
+ visibilities[i++] = tile.isVisible;
216
+ tile.isSelected = false;
217
+ tile.isVisible = false;
218
+ }
219
+ for (const tile of this._selectedTiles) {
220
+ tile.isSelected = true;
221
+ tile.isVisible = true;
222
+ }
207
223
 
208
- const abortCandidates = [];
209
- let ongoingRequestCount = 0;
210
- let changed = false;
224
+ // Strategy-specific state logic
225
+ (typeof refinementStrategy === 'function'
226
+ ? refinementStrategy
227
+ : STRATEGIES[refinementStrategy])(Array.from(this._cache.values()));
228
+
229
+ i = 0;
230
+ // Check if any visibility has changed
211
231
  for (const tile of this._cache.values()) {
212
- const isVisible = Boolean(tile.state & TILE_STATE_VISIBLE);
213
- if (tile.isVisible !== isVisible) {
214
- changed = true;
215
- tile.isVisible = isVisible;
232
+ if (visibilities[i++] !== tile.isVisible) {
233
+ return true;
216
234
  }
235
+ }
236
+
237
+ return false;
238
+ }
239
+
240
+ /* Private methods */
217
241
 
218
- // isSelected used in request scheduler
219
- tile.isSelected = tile.state === TILE_STATE_SELECTED;
242
+ _pruneRequests() {
243
+ const {maxRequests} = this.opts;
220
244
 
245
+ const abortCandidates = [];
246
+ let ongoingRequestCount = 0;
247
+ for (const tile of this._cache.values()) {
221
248
  // Keep track of all the ongoing requests
222
249
  if (tile.isLoading) {
223
250
  ongoingRequestCount++;
224
- if (!tile.isSelected) {
251
+ if (!tile.isSelected && !tile.isVisible) {
225
252
  abortCandidates.push(tile);
226
253
  }
227
254
  }
228
255
  }
229
256
 
230
- if (maxRequests > 0) {
231
- while (ongoingRequestCount > maxRequests && abortCandidates.length > 0) {
232
- // There are too many ongoing requests, so abort some that are unselected
233
- const tile = abortCandidates.shift();
234
- tile.abort();
235
- ongoingRequestCount--;
236
- }
257
+ while (maxRequests > 0 && ongoingRequestCount > maxRequests && abortCandidates.length > 0) {
258
+ // There are too many ongoing requests, so abort some that are unselected
259
+ const tile = abortCandidates.shift();
260
+ tile.abort();
261
+ ongoingRequestCount--;
237
262
  }
238
-
239
- return changed;
240
263
  }
241
264
 
242
- /* Private methods */
243
-
244
265
  // This needs to be called every time some tiles have been added/removed from cache
245
266
  _rebuildTree() {
246
267
  const {_cache} = this;
@@ -261,40 +282,6 @@ export default class Tileset2D {
261
282
  }
262
283
  }
263
284
 
264
- // A selected tile is always visible.
265
- // Never show two overlapping tiles.
266
- // If a selected tile is loading, try showing a cached ancester with the closest z
267
- // If a selected tile is loading, and no ancester is shown - try showing cached
268
- // descendants with the closest z
269
- _updateTileStates(selectedTiles) {
270
- const {_cache} = this;
271
- const refinementStrategy = this.opts.refinementStrategy || STRATEGY_DEFAULT;
272
-
273
- // Reset states
274
- for (const tile of _cache.values()) {
275
- tile.state = TILE_STATE_UNKNOWN;
276
- }
277
-
278
- // For all the selected && pending tiles:
279
- // - pick the closest ancestor as placeholder
280
- // - if no ancestor is visible, pick the closest children as placeholder
281
- for (const tile of selectedTiles) {
282
- tile.state = TILE_STATE_SELECTED;
283
- }
284
-
285
- if (refinementStrategy === STRATEGY_NEVER) {
286
- return;
287
- }
288
- for (const tile of selectedTiles) {
289
- getPlaceholderInAncestors(tile, refinementStrategy);
290
- }
291
- for (const tile of selectedTiles) {
292
- if (needsPlaceholder(tile)) {
293
- getPlaceholderInChildren(tile);
294
- }
295
- }
296
- }
297
-
298
285
  /**
299
286
  * Clear tiles that are not visible when the cache is full
300
287
  */
@@ -375,44 +362,70 @@ export default class Tileset2D {
375
362
  }
376
363
  }
377
364
 
378
- // A selected tile needs placeholder from its children if
379
- // - it is not loaded
380
- // - none of its ancestors is visible and loaded
381
- function needsPlaceholder(tile) {
382
- let t = tile;
383
- while (t) {
384
- if (t.state & (TILE_STATE_VISIBLE === 0)) {
385
- return true;
386
- }
387
- if (t.isLoaded) {
388
- return false;
365
+ /* -- Refinement strategies --*/
366
+ /* eslint-disable max-depth */
367
+
368
+ // For all the selected && pending tiles:
369
+ // - pick the closest ancestor as placeholder
370
+ // - if no ancestor is visible, pick the closest children as placeholder
371
+ function updateTileStateDefault(allTiles) {
372
+ for (const tile of allTiles) {
373
+ tile.state = 0;
374
+ }
375
+ for (const tile of allTiles) {
376
+ if (tile.isSelected && !getPlaceholderInAncestors(tile)) {
377
+ getPlaceholderInChildren(tile);
389
378
  }
390
- t = t.parent;
391
379
  }
392
- return true;
380
+ for (const tile of allTiles) {
381
+ tile.isVisible = Boolean(tile.state & TILE_STATE_VISIBLE);
382
+ }
393
383
  }
394
384
 
395
- function getPlaceholderInAncestors(tile, refinementStrategy) {
396
- let parent;
397
- let state = TILE_STATE_PLACEHOLDER;
398
- while ((parent = tile.parent)) {
399
- if (tile.isLoaded) {
400
- // If a tile is loaded, mark all its ancestors as hidden
401
- state = TILE_STATE_HIDDEN;
402
- if (refinementStrategy === STRATEGY_DEFAULT) {
403
- return;
385
+ // Until a selected tile and all its selected siblings are loaded, use the closest ancestor as placeholder
386
+ function updateTileStateReplace(allTiles) {
387
+ for (const tile of allTiles) {
388
+ tile.state = 0;
389
+ }
390
+ for (const tile of allTiles) {
391
+ if (tile.isSelected) {
392
+ getPlaceholderInAncestors(tile);
393
+ }
394
+ }
395
+ // Always process parents first
396
+ const sortedTiles = Array.from(allTiles).sort((t1, t2) => t1.z - t2.z);
397
+ for (const tile of sortedTiles) {
398
+ tile.isVisible = Boolean(tile.state & TILE_STATE_VISIBLE);
399
+
400
+ if (tile.isVisible || tile.state & TILE_STATE_VISITED) {
401
+ // If the tile is rendered, or if the tile has been explicitly hidden, hide all of its children
402
+ for (const child of tile.children) {
403
+ child.state = TILE_STATE_VISITED;
404
404
  }
405
+ } else if (tile.isSelected) {
406
+ getPlaceholderInChildren(tile);
407
+ }
408
+ }
409
+ }
410
+
411
+ // Walk up the tree until we find one ancestor that is loaded. Returns true if successful.
412
+ function getPlaceholderInAncestors(tile) {
413
+ while (tile) {
414
+ if (tile.isLoaded || tile.content) {
415
+ tile.state |= TILE_STATE_VISIBLE;
416
+ return true;
405
417
  }
406
- parent.state = Math.max(parent.state, state);
407
- tile = parent;
418
+ tile = tile.parent;
408
419
  }
420
+ return false;
409
421
  }
410
422
 
411
423
  // Recursively set children as placeholder
412
424
  function getPlaceholderInChildren(tile) {
413
425
  for (const child of tile.children) {
414
- child.state = Math.max(child.state, TILE_STATE_PLACEHOLDER);
415
- if (!child.isLoaded) {
426
+ if (child.isLoaded || child.content) {
427
+ child.state |= TILE_STATE_VISIBLE;
428
+ } else {
416
429
  getPlaceholderInChildren(child);
417
430
  }
418
431
  }