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

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 +9723 -9576
  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 +14 -10
  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/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,