@deck.gl/geo-layers 9.3.7 → 9.4.0-alpha.1

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 (33) hide show
  1. package/dist/dist.dev.js +159 -26
  2. package/dist/index.cjs +151 -27
  3. package/dist/index.cjs.map +3 -3
  4. package/dist/mesh-layer/mesh-layer-vertex.glsl.d.ts +1 -1
  5. package/dist/mesh-layer/mesh-layer-vertex.glsl.d.ts.map +1 -1
  6. package/dist/mesh-layer/mesh-layer-vertex.glsl.js +3 -4
  7. package/dist/mesh-layer/mesh-layer-vertex.glsl.js.map +1 -1
  8. package/dist/mesh-layer/mesh-layer.d.ts +1 -1
  9. package/dist/mesh-layer/mesh-layer.d.ts.map +1 -1
  10. package/dist/mesh-layer/mesh-layer.js +7 -14
  11. package/dist/mesh-layer/mesh-layer.js.map +1 -1
  12. package/dist/terrain-layer/terrain-layer.d.ts.map +1 -1
  13. package/dist/terrain-layer/terrain-layer.js +45 -5
  14. package/dist/terrain-layer/terrain-layer.js.map +1 -1
  15. package/dist/tileset-2d/tile-2d-header.d.ts +1 -0
  16. package/dist/tileset-2d/tile-2d-header.d.ts.map +1 -1
  17. package/dist/tileset-2d/tile-2d-header.js +3 -5
  18. package/dist/tileset-2d/tile-2d-header.js.map +1 -1
  19. package/dist/tileset-2d/tile-2d-traversal.d.ts.map +1 -1
  20. package/dist/tileset-2d/tile-2d-traversal.js +23 -1
  21. package/dist/tileset-2d/tile-2d-traversal.js.map +1 -1
  22. package/dist/tileset-2d/tileset-2d.d.ts +5 -0
  23. package/dist/tileset-2d/tileset-2d.d.ts.map +1 -1
  24. package/dist/tileset-2d/tileset-2d.js +85 -0
  25. package/dist/tileset-2d/tileset-2d.js.map +1 -1
  26. package/dist.min.js +21 -22
  27. package/package.json +6 -6
  28. package/src/mesh-layer/mesh-layer-vertex.glsl.ts +3 -4
  29. package/src/mesh-layer/mesh-layer.ts +7 -17
  30. package/src/terrain-layer/terrain-layer.ts +64 -4
  31. package/src/tileset-2d/tile-2d-header.ts +4 -4
  32. package/src/tileset-2d/tile-2d-traversal.ts +33 -1
  33. package/src/tileset-2d/tileset-2d.ts +101 -1
package/dist/dist.dev.js CHANGED
@@ -14338,6 +14338,7 @@ var __exports__ = (() => {
14338
14338
  /* eslint-disable max-statements */
14339
14339
  async _loadData({
14340
14340
  getData,
14341
+ getRequestPriority,
14341
14342
  requestScheduler,
14342
14343
  onLoad,
14343
14344
  onError
@@ -14346,9 +14347,7 @@ var __exports__ = (() => {
14346
14347
  const loaderId = this._loaderId;
14347
14348
  this._abortController = new AbortController();
14348
14349
  const { signal } = this._abortController;
14349
- const requestToken = await requestScheduler.scheduleRequest(this, (tile) => {
14350
- return tile.isSelected ? 1 : -1;
14351
- });
14350
+ const requestToken = await requestScheduler.scheduleRequest(this, getRequestPriority);
14352
14351
  if (!requestToken) {
14353
14352
  this._isCancelled = true;
14354
14353
  return;
@@ -15224,6 +15223,9 @@ var __exports__ = (() => {
15224
15223
  if (isInside < 0) {
15225
15224
  return false;
15226
15225
  }
15226
+ if (project && this.beyondHorizon(viewport.cameraPosition, project, elevationBounds[1])) {
15227
+ return false;
15228
+ }
15227
15229
  if (!this.childVisible) {
15228
15230
  let { z } = this;
15229
15231
  if (z < maxZ && z >= minZ) {
@@ -15253,6 +15255,24 @@ var __exports__ = (() => {
15253
15255
  }
15254
15256
  return result;
15255
15257
  }
15258
+ beyondHorizon(cameraPosition, project, elevation) {
15259
+ const cx = cameraPosition[0];
15260
+ const cy = cameraPosition[1];
15261
+ const cz = cameraPosition[2];
15262
+ const cMag = Math.sqrt(cx * cx + cy * cy + cz * cz);
15263
+ const camLng = Math.atan2(cx, -cy) * 180 / Math.PI;
15264
+ const camLat = Math.asin(cz / cMag) * 180 / Math.PI;
15265
+ const [west, north] = osmTile2lngLat(this.x, this.y, this.z);
15266
+ const [east, south] = osmTile2lngLat(this.x + 1, this.y + 1, this.z);
15267
+ const tileCenterLng = (west + east) / 2;
15268
+ const wrappedCamLng = tileCenterLng + ((camLng - tileCenterLng + 540) % 360 - 180);
15269
+ const closestLng = Math.max(west, Math.min(wrappedCamLng, east));
15270
+ const closestLat = Math.max(south, Math.min(camLat, north));
15271
+ const closest = project([closestLng, closestLat, elevation]);
15272
+ const dot8 = closest[0] * cx + closest[1] * cy + closest[2] * cz;
15273
+ const magSq = closest[0] * closest[0] + closest[1] * closest[1] + closest[2] * closest[2];
15274
+ return dot8 <= magSq;
15275
+ }
15256
15276
  insideBounds([minX, minY, maxX, maxY]) {
15257
15277
  const scale12 = Math.pow(2, this.z);
15258
15278
  const extent = TILE_SIZE3 / scale12;
@@ -15284,7 +15304,7 @@ var __exports__ = (() => {
15284
15304
  }
15285
15305
  };
15286
15306
  function getOSMTileIndices(viewport, maxZ, zRange, bounds) {
15287
- const project = viewport instanceof import_core14._GlobeViewport && viewport.resolution ? (
15307
+ const project = viewport instanceof import_core14._GlobeViewport ? (
15288
15308
  // eslint-disable-next-line @typescript-eslint/unbound-method
15289
15309
  viewport.projectPosition
15290
15310
  ) : null;
@@ -15603,6 +15623,9 @@ var __exports__ = (() => {
15603
15623
  var STRATEGY_REPLACE = "no-overlap";
15604
15624
  var STRATEGY_DEFAULT = "best-available";
15605
15625
  var DEFAULT_CACHE_SCALE = 5;
15626
+ var SELECTED_TILE_PRIORITY = 0;
15627
+ var VISIBLE_TILE_PRIORITY = 1e8;
15628
+ var MAX_TILE_DISTANCE_PRIORITY = VISIBLE_TILE_PRIORITY - SELECTED_TILE_PRIORITY - 1;
15606
15629
  var STRATEGIES = {
15607
15630
  [STRATEGY_DEFAULT]: updateTileStateDefault,
15608
15631
  [STRATEGY_REPLACE]: updateTileStateReplace,
@@ -15854,6 +15877,81 @@ var __exports__ = (() => {
15854
15877
  }
15855
15878
  return false;
15856
15879
  }
15880
+ _getRequestPriority(tile) {
15881
+ if (!tile.isSelected && !tile.isVisible) {
15882
+ return -1;
15883
+ }
15884
+ const distance4 = this._getTileDistancePriority(tile);
15885
+ if (tile.isSelected) {
15886
+ return SELECTED_TILE_PRIORITY + distance4;
15887
+ }
15888
+ return VISIBLE_TILE_PRIORITY + distance4;
15889
+ }
15890
+ _getTileDistancePriority(tile) {
15891
+ const { width, height } = this._viewport || {};
15892
+ if (!this._viewport || !width || !height) {
15893
+ return 0;
15894
+ }
15895
+ try {
15896
+ const points = this._getTileScreenCorners(tile.bbox);
15897
+ const center2 = [width / 2, height / 2];
15898
+ if (points.length === 4) {
15899
+ if (this._isPointInPolygon(center2, points)) {
15900
+ return 0;
15901
+ }
15902
+ const distance4 = points.reduce((minDistance, point, i) => {
15903
+ const nextPoint = points[(i + 1) % points.length];
15904
+ return Math.min(
15905
+ minDistance,
15906
+ this._getPointToSegmentDistanceSquared(center2, point, nextPoint)
15907
+ );
15908
+ }, Number.MAX_SAFE_INTEGER);
15909
+ return Math.min(distance4, MAX_TILE_DISTANCE_PRIORITY);
15910
+ }
15911
+ } catch {
15912
+ }
15913
+ return MAX_TILE_DISTANCE_PRIORITY;
15914
+ }
15915
+ _getTileScreenCorners(bbox) {
15916
+ const coordinates = "west" in bbox ? [
15917
+ [bbox.west, bbox.south],
15918
+ [bbox.east, bbox.south],
15919
+ [bbox.east, bbox.north],
15920
+ [bbox.west, bbox.north]
15921
+ ] : [
15922
+ [bbox.left, bbox.top],
15923
+ [bbox.right, bbox.top],
15924
+ [bbox.right, bbox.bottom],
15925
+ [bbox.left, bbox.bottom]
15926
+ ];
15927
+ return coordinates.map((coordinate) => this._viewport.project(coordinate)).filter(([x, y]) => Number.isFinite(x) && Number.isFinite(y));
15928
+ }
15929
+ _isPointInPolygon(point, polygon) {
15930
+ let inside = false;
15931
+ const [x, y] = point;
15932
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
15933
+ const [xi, yi] = polygon[i];
15934
+ const [xj, yj] = polygon[j];
15935
+ if (yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi) {
15936
+ inside = !inside;
15937
+ }
15938
+ }
15939
+ return inside;
15940
+ }
15941
+ _getPointToSegmentDistanceSquared(point, segmentStart, segmentEnd) {
15942
+ const [x, y] = point;
15943
+ const [x1, y1] = segmentStart;
15944
+ const [x2, y2] = segmentEnd;
15945
+ const dx = x2 - x1;
15946
+ const dy = y2 - y1;
15947
+ const lengthSquared = dx * dx + dy * dy;
15948
+ const t = lengthSquared ? Math.max(0, Math.min(1, ((x - x1) * dx + (y - y1) * dy) / lengthSquared)) : 0;
15949
+ const segmentX = x1 + t * dx;
15950
+ const segmentY = y1 + t * dy;
15951
+ const distanceX = x - segmentX;
15952
+ const distanceY = y - segmentY;
15953
+ return distanceX * distanceX + distanceY * distanceY;
15954
+ }
15857
15955
  _pruneRequests() {
15858
15956
  const { maxRequests = 0 } = this.opts;
15859
15957
  const abortCandidates = [];
@@ -15935,6 +16033,7 @@ var __exports__ = (() => {
15935
16033
  if (tile && needsReload) {
15936
16034
  tile.loadData({
15937
16035
  getData: this.opts.getTileData,
16036
+ getRequestPriority: this._getRequestPriority.bind(this),
15938
16037
  requestScheduler: this._requestScheduler,
15939
16038
  onLoad: this.onTileLoad,
15940
16039
  onError: this.opts.onTileError
@@ -20356,11 +20455,10 @@ in vec3 normals;
20356
20455
  in vec3 colors;
20357
20456
  in vec2 texCoords;
20358
20457
  in vec4 uvRegions;
20359
- in vec3 featureIdsPickingColors;
20458
+ in float rowIndexes;
20360
20459
 
20361
20460
  // Instance attributes
20362
20461
  in vec4 instanceColors;
20363
- in vec3 instancePickingColors;
20364
20462
  in vec3 instanceModelMatrixCol0;
20365
20463
  in vec3 instanceModelMatrixCol1;
20366
20464
  in vec3 instanceModelMatrixCol2;
@@ -20386,9 +20484,9 @@ void main(void) {
20386
20484
  geometry.uv = uv;
20387
20485
 
20388
20486
  if (mesh.pickFeatureIds) {
20389
- geometry.pickingColor = featureIdsPickingColors;
20487
+ geometry.pickingColor = picking_getPickingColorFromIndex(rowIndexes);
20390
20488
  } else {
20391
- geometry.pickingColor = instancePickingColors;
20489
+ geometry.pickingColor = picking_getPickingColorFromInstanceID();
20392
20490
  }
20393
20491
 
20394
20492
  mat3 instanceModelMatrix = mat3(instanceModelMatrixCol0, instanceModelMatrixCol1, instanceModelMatrixCol2);
@@ -20504,12 +20602,13 @@ void main(void) {
20504
20602
  const attributeManager = this.getAttributeManager();
20505
20603
  if (featureIds) {
20506
20604
  attributeManager.add({
20507
- featureIdsPickingColors: {
20508
- type: "uint8",
20509
- size: 3,
20605
+ /** Feature id for each mesh vertex. */
20606
+ rowIndexes: {
20607
+ type: "uint32",
20608
+ size: 1,
20510
20609
  noAlloc: true,
20511
20610
  // eslint-disable-next-line @typescript-eslint/unbound-method
20512
- update: this.calculateFeatureIdsPickingColors
20611
+ update: this.calculateFeatureIdsPickingIndexes
20513
20612
  }
20514
20613
  });
20515
20614
  }
@@ -20594,17 +20693,9 @@ void main(void) {
20594
20693
  }
20595
20694
  );
20596
20695
  }
20597
- calculateFeatureIdsPickingColors(attribute) {
20696
+ calculateFeatureIdsPickingIndexes(attribute) {
20598
20697
  const featureIds = this.props.featureIds;
20599
- const value = new Uint8ClampedArray(featureIds.length * attribute.size);
20600
- const pickingColor = [];
20601
- for (let index = 0; index < featureIds.length; index++) {
20602
- this.encodePickingColor(featureIds[index], pickingColor);
20603
- value[index * 3] = pickingColor[0];
20604
- value[index * 3 + 1] = pickingColor[1];
20605
- value[index * 3 + 2] = pickingColor[2];
20606
- }
20607
- attribute.value = value;
20698
+ attribute.value = new Uint32Array(featureIds);
20608
20699
  }
20609
20700
  finalizeState(context) {
20610
20701
  super.finalizeState(context);
@@ -32686,6 +32777,10 @@ void main(void) {
32686
32777
 
32687
32778
  // src/terrain-layer/terrain-layer.ts
32688
32779
  var DUMMY_DATA = [1];
32780
+ var TILE_OVERLAP_PIXELS = 1;
32781
+ var MIN_TERRAIN_MESH_MAX_ERROR = 1;
32782
+ var MAX_LATITUDE2 = 90;
32783
+ var MAX_LONGITUDE = 180;
32689
32784
  var defaultProps13 = {
32690
32785
  ...TileLayer.defaultProps,
32691
32786
  // Image url that encodes height data
@@ -32721,6 +32816,31 @@ void main(void) {
32721
32816
  }
32722
32817
  return template || "";
32723
32818
  }
32819
+ function getOverlappedBounds(bounds, tileSize, clampLngLat) {
32820
+ const xPad = (bounds[2] - bounds[0]) / tileSize * TILE_OVERLAP_PIXELS;
32821
+ const yPad = (bounds[3] - bounds[1]) / tileSize * TILE_OVERLAP_PIXELS;
32822
+ const overlappedBounds = [
32823
+ bounds[0] - xPad,
32824
+ bounds[1] - yPad,
32825
+ bounds[2] + xPad,
32826
+ bounds[3] + yPad
32827
+ ];
32828
+ if (!clampLngLat) {
32829
+ return overlappedBounds;
32830
+ }
32831
+ return [
32832
+ Math.max(overlappedBounds[0], -MAX_LONGITUDE),
32833
+ Math.max(overlappedBounds[1], -MAX_LATITUDE2),
32834
+ Math.min(overlappedBounds[2], MAX_LONGITUDE),
32835
+ Math.min(overlappedBounds[3], MAX_LATITUDE2)
32836
+ ];
32837
+ }
32838
+ function getEffectiveMeshMaxError(meshMaxError) {
32839
+ if (!Number.isFinite(meshMaxError) || meshMaxError <= 0) {
32840
+ return MIN_TERRAIN_MESH_MAX_ERROR;
32841
+ }
32842
+ return Math.max(meshMaxError, MIN_TERRAIN_MESH_MAX_ERROR);
32843
+ }
32724
32844
  var TerrainLayer = class extends import_core49.CompositeLayer {
32725
32845
  updateState({ props, oldProps }) {
32726
32846
  const elevationDataChanged = props.elevationData !== oldProps.elevationData;
@@ -32748,14 +32868,15 @@ void main(void) {
32748
32868
  if (!elevationData) {
32749
32869
  return null;
32750
32870
  }
32871
+ const effectiveMeshMaxError = getEffectiveMeshMaxError(meshMaxError);
32751
32872
  let loadOptions = this.getLoadOptions();
32752
32873
  loadOptions = {
32753
32874
  ...loadOptions,
32754
32875
  terrain: {
32755
- skirtHeight: this.state.isTiled ? meshMaxError * 2 : 0,
32876
+ skirtHeight: this.state.isTiled ? effectiveMeshMaxError * 2 : 0,
32756
32877
  ...loadOptions?.terrain,
32757
32878
  bounds,
32758
- meshMaxError,
32879
+ meshMaxError: effectiveMeshMaxError,
32759
32880
  elevationDecoder
32760
32881
  }
32761
32882
  };
@@ -32780,9 +32901,14 @@ void main(void) {
32780
32901
  topRight = [bbox.right, bbox.top];
32781
32902
  }
32782
32903
  const bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
32904
+ const overlappedBounds = getOverlappedBounds(
32905
+ bounds,
32906
+ this.props.tileSize,
32907
+ viewport instanceof import_core49._GlobeViewport
32908
+ );
32783
32909
  const terrain = this.loadTerrain({
32784
32910
  elevationData: dataUrl,
32785
- bounds,
32911
+ bounds: overlappedBounds,
32786
32912
  elevationDecoder,
32787
32913
  meshMaxError,
32788
32914
  signal
@@ -32801,12 +32927,19 @@ void main(void) {
32801
32927
  return null;
32802
32928
  }
32803
32929
  const [mesh, texture] = data;
32930
+ const { viewport } = this.context;
32931
+ const isGlobe = viewport instanceof import_core49._GlobeViewport;
32932
+ const boundingBox = mesh?.header?.boundingBox;
32933
+ const hasLngLatBounds = boundingBox && boundingBox.every(
32934
+ ([x, y]) => x >= -MAX_LONGITUDE && x <= MAX_LONGITUDE && y >= -MAX_LATITUDE2 && y <= MAX_LATITUDE2
32935
+ );
32936
+ const coordinateSystem = isGlobe && hasLngLatBounds ? import_core49.COORDINATE_SYSTEM.LNGLAT : import_core49.COORDINATE_SYSTEM.CARTESIAN;
32804
32937
  return new SubLayerClass(props, {
32805
32938
  data: DUMMY_DATA,
32806
32939
  mesh,
32807
32940
  texture,
32808
32941
  _instanced: false,
32809
- coordinateSystem: import_core49.COORDINATE_SYSTEM.CARTESIAN,
32942
+ coordinateSystem,
32810
32943
  getPosition: (d2) => [0, 0, 0],
32811
32944
  getColor: color,
32812
32945
  wireframe,
package/dist/index.cjs CHANGED
@@ -667,14 +667,12 @@ var Tile2DHeader = class {
667
667
  return result;
668
668
  }
669
669
  /* eslint-disable max-statements */
670
- async _loadData({ getData, requestScheduler, onLoad, onError }) {
670
+ async _loadData({ getData, getRequestPriority, requestScheduler, onLoad, onError }) {
671
671
  const { index, id, bbox, userData, zoom } = this;
672
672
  const loaderId = this._loaderId;
673
673
  this._abortController = new AbortController();
674
674
  const { signal } = this._abortController;
675
- const requestToken = await requestScheduler.scheduleRequest(this, (tile) => {
676
- return tile.isSelected ? 1 : -1;
677
- });
675
+ const requestToken = await requestScheduler.scheduleRequest(this, getRequestPriority);
678
676
  if (!requestToken) {
679
677
  this._isCancelled = true;
680
678
  return;
@@ -788,6 +786,9 @@ var OSMNode = class {
788
786
  if (isInside < 0) {
789
787
  return false;
790
788
  }
789
+ if (project && this.beyondHorizon(viewport.cameraPosition, project, elevationBounds[1])) {
790
+ return false;
791
+ }
791
792
  if (!this.childVisible) {
792
793
  let { z } = this;
793
794
  if (z < maxZ && z >= minZ) {
@@ -817,6 +818,24 @@ var OSMNode = class {
817
818
  }
818
819
  return result;
819
820
  }
821
+ beyondHorizon(cameraPosition, project, elevation) {
822
+ const cx = cameraPosition[0];
823
+ const cy = cameraPosition[1];
824
+ const cz = cameraPosition[2];
825
+ const cMag = Math.sqrt(cx * cx + cy * cy + cz * cz);
826
+ const camLng = Math.atan2(cx, -cy) * 180 / Math.PI;
827
+ const camLat = Math.asin(cz / cMag) * 180 / Math.PI;
828
+ const [west, north] = osmTile2lngLat(this.x, this.y, this.z);
829
+ const [east, south] = osmTile2lngLat(this.x + 1, this.y + 1, this.z);
830
+ const tileCenterLng = (west + east) / 2;
831
+ const wrappedCamLng = tileCenterLng + ((camLng - tileCenterLng + 540) % 360 - 180);
832
+ const closestLng = Math.max(west, Math.min(wrappedCamLng, east));
833
+ const closestLat = Math.max(south, Math.min(camLat, north));
834
+ const closest = project([closestLng, closestLat, elevation]);
835
+ const dot = closest[0] * cx + closest[1] * cy + closest[2] * cz;
836
+ const magSq = closest[0] * closest[0] + closest[1] * closest[1] + closest[2] * closest[2];
837
+ return dot <= magSq;
838
+ }
820
839
  insideBounds([minX, minY, maxX, maxY]) {
821
840
  const scale = Math.pow(2, this.z);
822
841
  const extent = TILE_SIZE2 / scale;
@@ -845,7 +864,7 @@ var OSMNode = class {
845
864
  }
846
865
  };
847
866
  function getOSMTileIndices(viewport, maxZ, zRange, bounds) {
848
- const project = viewport instanceof import_core5._GlobeViewport && viewport.resolution ? (
867
+ const project = viewport instanceof import_core5._GlobeViewport ? (
849
868
  // eslint-disable-next-line @typescript-eslint/unbound-method
850
869
  viewport.projectPosition
851
870
  ) : null;
@@ -1138,6 +1157,9 @@ var STRATEGY_NEVER = "never";
1138
1157
  var STRATEGY_REPLACE = "no-overlap";
1139
1158
  var STRATEGY_DEFAULT = "best-available";
1140
1159
  var DEFAULT_CACHE_SCALE = 5;
1160
+ var SELECTED_TILE_PRIORITY = 0;
1161
+ var VISIBLE_TILE_PRIORITY = 1e8;
1162
+ var MAX_TILE_DISTANCE_PRIORITY = VISIBLE_TILE_PRIORITY - SELECTED_TILE_PRIORITY - 1;
1141
1163
  var STRATEGIES = {
1142
1164
  [STRATEGY_DEFAULT]: updateTileStateDefault,
1143
1165
  [STRATEGY_REPLACE]: updateTileStateReplace,
@@ -1379,6 +1401,78 @@ var Tileset2D = class {
1379
1401
  }
1380
1402
  return false;
1381
1403
  }
1404
+ _getRequestPriority(tile) {
1405
+ if (!tile.isSelected && !tile.isVisible) {
1406
+ return -1;
1407
+ }
1408
+ const distance = this._getTileDistancePriority(tile);
1409
+ if (tile.isSelected) {
1410
+ return SELECTED_TILE_PRIORITY + distance;
1411
+ }
1412
+ return VISIBLE_TILE_PRIORITY + distance;
1413
+ }
1414
+ _getTileDistancePriority(tile) {
1415
+ const { width, height } = this._viewport || {};
1416
+ if (!this._viewport || !width || !height) {
1417
+ return 0;
1418
+ }
1419
+ try {
1420
+ const points = this._getTileScreenCorners(tile.bbox);
1421
+ const center = [width / 2, height / 2];
1422
+ if (points.length === 4) {
1423
+ if (this._isPointInPolygon(center, points)) {
1424
+ return 0;
1425
+ }
1426
+ const distance = points.reduce((minDistance, point, i) => {
1427
+ const nextPoint = points[(i + 1) % points.length];
1428
+ return Math.min(minDistance, this._getPointToSegmentDistanceSquared(center, point, nextPoint));
1429
+ }, Number.MAX_SAFE_INTEGER);
1430
+ return Math.min(distance, MAX_TILE_DISTANCE_PRIORITY);
1431
+ }
1432
+ } catch {
1433
+ }
1434
+ return MAX_TILE_DISTANCE_PRIORITY;
1435
+ }
1436
+ _getTileScreenCorners(bbox) {
1437
+ const coordinates = "west" in bbox ? [
1438
+ [bbox.west, bbox.south],
1439
+ [bbox.east, bbox.south],
1440
+ [bbox.east, bbox.north],
1441
+ [bbox.west, bbox.north]
1442
+ ] : [
1443
+ [bbox.left, bbox.top],
1444
+ [bbox.right, bbox.top],
1445
+ [bbox.right, bbox.bottom],
1446
+ [bbox.left, bbox.bottom]
1447
+ ];
1448
+ return coordinates.map((coordinate) => this._viewport.project(coordinate)).filter(([x, y]) => Number.isFinite(x) && Number.isFinite(y));
1449
+ }
1450
+ _isPointInPolygon(point, polygon) {
1451
+ let inside = false;
1452
+ const [x, y] = point;
1453
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1454
+ const [xi, yi] = polygon[i];
1455
+ const [xj, yj] = polygon[j];
1456
+ if (yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi) {
1457
+ inside = !inside;
1458
+ }
1459
+ }
1460
+ return inside;
1461
+ }
1462
+ _getPointToSegmentDistanceSquared(point, segmentStart, segmentEnd) {
1463
+ const [x, y] = point;
1464
+ const [x1, y1] = segmentStart;
1465
+ const [x2, y2] = segmentEnd;
1466
+ const dx = x2 - x1;
1467
+ const dy = y2 - y1;
1468
+ const lengthSquared = dx * dx + dy * dy;
1469
+ const t = lengthSquared ? Math.max(0, Math.min(1, ((x - x1) * dx + (y - y1) * dy) / lengthSquared)) : 0;
1470
+ const segmentX = x1 + t * dx;
1471
+ const segmentY = y1 + t * dy;
1472
+ const distanceX = x - segmentX;
1473
+ const distanceY = y - segmentY;
1474
+ return distanceX * distanceX + distanceY * distanceY;
1475
+ }
1382
1476
  _pruneRequests() {
1383
1477
  const { maxRequests = 0 } = this.opts;
1384
1478
  const abortCandidates = [];
@@ -1461,6 +1555,7 @@ var Tileset2D = class {
1461
1555
  if (tile && needsReload) {
1462
1556
  tile.loadData({
1463
1557
  getData: this.opts.getTileData,
1558
+ getRequestPriority: this._getRequestPriority.bind(this),
1464
1559
  requestScheduler: this._requestScheduler,
1465
1560
  onLoad: this.onTileLoad,
1466
1561
  onError: this.opts.onTileError
@@ -2094,9 +2189,8 @@ in vec3 normals;
2094
2189
  in vec3 colors;
2095
2190
  in vec2 texCoords;
2096
2191
  in vec4 uvRegions;
2097
- in vec3 featureIdsPickingColors;
2192
+ in float rowIndexes;
2098
2193
  in vec4 instanceColors;
2099
- in vec3 instancePickingColors;
2100
2194
  in vec3 instanceModelMatrixCol0;
2101
2195
  in vec3 instanceModelMatrixCol1;
2102
2196
  in vec3 instanceModelMatrixCol2;
@@ -2116,9 +2210,9 @@ void main(void) {
2116
2210
  vec2 uv = applyUVRegion(texCoords);
2117
2211
  geometry.uv = uv;
2118
2212
  if (mesh.pickFeatureIds) {
2119
- geometry.pickingColor = featureIdsPickingColors;
2213
+ geometry.pickingColor = picking_getPickingColorFromIndex(rowIndexes);
2120
2214
  } else {
2121
- geometry.pickingColor = instancePickingColors;
2215
+ geometry.pickingColor = picking_getPickingColorFromInstanceID();
2122
2216
  }
2123
2217
  mat3 instanceModelMatrix = mat3(instanceModelMatrixCol0, instanceModelMatrixCol1, instanceModelMatrixCol2);
2124
2218
  vTexCoord = uv;
@@ -2211,12 +2305,13 @@ var MeshLayer = class extends import_mesh_layers.SimpleMeshLayer {
2211
2305
  const attributeManager = this.getAttributeManager();
2212
2306
  if (featureIds) {
2213
2307
  attributeManager.add({
2214
- featureIdsPickingColors: {
2215
- type: "uint8",
2216
- size: 3,
2308
+ /** Feature id for each mesh vertex. */
2309
+ rowIndexes: {
2310
+ type: "uint32",
2311
+ size: 1,
2217
2312
  noAlloc: true,
2218
2313
  // eslint-disable-next-line @typescript-eslint/unbound-method
2219
- update: this.calculateFeatureIdsPickingColors
2314
+ update: this.calculateFeatureIdsPickingIndexes
2220
2315
  }
2221
2316
  });
2222
2317
  }
@@ -2294,17 +2389,9 @@ var MeshLayer = class extends import_mesh_layers.SimpleMeshLayer {
2294
2389
  useTangents: false
2295
2390
  });
2296
2391
  }
2297
- calculateFeatureIdsPickingColors(attribute) {
2392
+ calculateFeatureIdsPickingIndexes(attribute) {
2298
2393
  const featureIds = this.props.featureIds;
2299
- const value = new Uint8ClampedArray(featureIds.length * attribute.size);
2300
- const pickingColor = [];
2301
- for (let index = 0; index < featureIds.length; index++) {
2302
- this.encodePickingColor(featureIds[index], pickingColor);
2303
- value[index * 3] = pickingColor[0];
2304
- value[index * 3 + 1] = pickingColor[1];
2305
- value[index * 3 + 2] = pickingColor[2];
2306
- }
2307
- attribute.value = value;
2394
+ attribute.value = new Uint32Array(featureIds);
2308
2395
  }
2309
2396
  finalizeState(context) {
2310
2397
  var _a;
@@ -2645,6 +2732,10 @@ var import_core13 = require("@deck.gl/core");
2645
2732
  var import_mesh_layers3 = require("@deck.gl/mesh-layers");
2646
2733
  var import_terrain = require("@loaders.gl/terrain");
2647
2734
  var DUMMY_DATA = [1];
2735
+ var TILE_OVERLAP_PIXELS = 1;
2736
+ var MIN_TERRAIN_MESH_MAX_ERROR = 1;
2737
+ var MAX_LATITUDE = 90;
2738
+ var MAX_LONGITUDE = 180;
2648
2739
  var defaultProps13 = {
2649
2740
  ...tile_layer_default.defaultProps,
2650
2741
  // Image url that encodes height data
@@ -2680,6 +2771,31 @@ function urlTemplateToUpdateTrigger(template) {
2680
2771
  }
2681
2772
  return template || "";
2682
2773
  }
2774
+ function getOverlappedBounds(bounds, tileSize, clampLngLat) {
2775
+ const xPad = (bounds[2] - bounds[0]) / tileSize * TILE_OVERLAP_PIXELS;
2776
+ const yPad = (bounds[3] - bounds[1]) / tileSize * TILE_OVERLAP_PIXELS;
2777
+ const overlappedBounds = [
2778
+ bounds[0] - xPad,
2779
+ bounds[1] - yPad,
2780
+ bounds[2] + xPad,
2781
+ bounds[3] + yPad
2782
+ ];
2783
+ if (!clampLngLat) {
2784
+ return overlappedBounds;
2785
+ }
2786
+ return [
2787
+ Math.max(overlappedBounds[0], -MAX_LONGITUDE),
2788
+ Math.max(overlappedBounds[1], -MAX_LATITUDE),
2789
+ Math.min(overlappedBounds[2], MAX_LONGITUDE),
2790
+ Math.min(overlappedBounds[3], MAX_LATITUDE)
2791
+ ];
2792
+ }
2793
+ function getEffectiveMeshMaxError(meshMaxError) {
2794
+ if (!Number.isFinite(meshMaxError) || meshMaxError <= 0) {
2795
+ return MIN_TERRAIN_MESH_MAX_ERROR;
2796
+ }
2797
+ return Math.max(meshMaxError, MIN_TERRAIN_MESH_MAX_ERROR);
2798
+ }
2683
2799
  var TerrainLayer = class extends import_core13.CompositeLayer {
2684
2800
  updateState({ props, oldProps }) {
2685
2801
  const elevationDataChanged = props.elevationData !== oldProps.elevationData;
@@ -2701,14 +2817,15 @@ var TerrainLayer = class extends import_core13.CompositeLayer {
2701
2817
  if (!elevationData) {
2702
2818
  return null;
2703
2819
  }
2820
+ const effectiveMeshMaxError = getEffectiveMeshMaxError(meshMaxError);
2704
2821
  let loadOptions = this.getLoadOptions();
2705
2822
  loadOptions = {
2706
2823
  ...loadOptions,
2707
2824
  terrain: {
2708
- skirtHeight: this.state.isTiled ? meshMaxError * 2 : 0,
2825
+ skirtHeight: this.state.isTiled ? effectiveMeshMaxError * 2 : 0,
2709
2826
  ...loadOptions == null ? void 0 : loadOptions.terrain,
2710
2827
  bounds,
2711
- meshMaxError,
2828
+ meshMaxError: effectiveMeshMaxError,
2712
2829
  elevationDecoder
2713
2830
  }
2714
2831
  };
@@ -2733,9 +2850,10 @@ var TerrainLayer = class extends import_core13.CompositeLayer {
2733
2850
  topRight = [bbox.right, bbox.top];
2734
2851
  }
2735
2852
  const bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
2853
+ const overlappedBounds = getOverlappedBounds(bounds, this.props.tileSize, viewport instanceof import_core13._GlobeViewport);
2736
2854
  const terrain = this.loadTerrain({
2737
2855
  elevationData: dataUrl,
2738
- bounds,
2856
+ bounds: overlappedBounds,
2739
2857
  elevationDecoder,
2740
2858
  meshMaxError,
2741
2859
  signal
@@ -2747,6 +2865,7 @@ var TerrainLayer = class extends import_core13.CompositeLayer {
2747
2865
  return Promise.all([terrain, surface]);
2748
2866
  }
2749
2867
  renderSubLayers(props) {
2868
+ var _a;
2750
2869
  const SubLayerClass = this.getSubLayerClass("mesh", import_mesh_layers3.SimpleMeshLayer);
2751
2870
  const { color, wireframe, material } = this.props;
2752
2871
  const { data } = props;
@@ -2754,12 +2873,17 @@ var TerrainLayer = class extends import_core13.CompositeLayer {
2754
2873
  return null;
2755
2874
  }
2756
2875
  const [mesh, texture] = data;
2876
+ const { viewport } = this.context;
2877
+ const isGlobe = viewport instanceof import_core13._GlobeViewport;
2878
+ const boundingBox = (_a = mesh == null ? void 0 : mesh.header) == null ? void 0 : _a.boundingBox;
2879
+ const hasLngLatBounds = boundingBox && boundingBox.every(([x, y]) => x >= -MAX_LONGITUDE && x <= MAX_LONGITUDE && y >= -MAX_LATITUDE && y <= MAX_LATITUDE);
2880
+ const coordinateSystem = isGlobe && hasLngLatBounds ? import_core13.COORDINATE_SYSTEM.LNGLAT : import_core13.COORDINATE_SYSTEM.CARTESIAN;
2757
2881
  return new SubLayerClass(props, {
2758
2882
  data: DUMMY_DATA,
2759
2883
  mesh,
2760
2884
  texture,
2761
2885
  _instanced: false,
2762
- coordinateSystem: import_core13.COORDINATE_SYSTEM.CARTESIAN,
2886
+ coordinateSystem,
2763
2887
  getPosition: (d) => [0, 0, 0],
2764
2888
  getColor: color,
2765
2889
  wireframe,