astro-viewer 3.0.0 → 3.1.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 (110) hide show
  1. package/dist/astroviewer.cjs +2505 -1335
  2. package/dist/astroviewer.js +1 -1
  3. package/dist/astroviewer.min.js +1 -1
  4. package/lib-esm/AstroSphere.d.ts +26 -6
  5. package/lib-esm/AstroSphere.js +215 -18
  6. package/lib-esm/AstroViewer.d.ts +18 -5
  7. package/lib-esm/AstroViewer.js +47 -0
  8. package/lib-esm/Camera.js +24 -8
  9. package/lib-esm/Config.js +12 -0
  10. package/lib-esm/Global.js +12 -0
  11. package/lib-esm/index.d.ts +6 -4
  12. package/lib-esm/index.js +16 -3
  13. package/lib-esm/model/AbstractSkyEntity.js +12 -0
  14. package/lib-esm/model/AstroGL.js +12 -0
  15. package/lib-esm/model/ColorMaps.js +12 -0
  16. package/lib-esm/model/MetadataColumn.js +12 -0
  17. package/lib-esm/model/MetadataManager.js +12 -0
  18. package/lib-esm/model/Point.js +12 -0
  19. package/lib-esm/model/Point2D.js +12 -0
  20. package/lib-esm/model/Source.js +12 -0
  21. package/lib-esm/model/SphereFoV.d.ts +30 -0
  22. package/lib-esm/model/SphereFoV.js +195 -0
  23. package/lib-esm/model/catalogues/CatalogueGL.js +12 -0
  24. package/lib-esm/model/catalogues/CatalogueProps.js +13 -1
  25. package/lib-esm/model/earth/{wmts/WMTSAdapter.d.ts → WMTSAdapter.d.ts} +2 -1
  26. package/lib-esm/model/earth/{wmts/WMTSAdapter.js → WMTSAdapter.js} +12 -0
  27. package/lib-esm/model/earth/XYZAnchestorTile.d.ts +17 -0
  28. package/lib-esm/model/earth/XYZAnchestorTile.js +87 -0
  29. package/lib-esm/model/earth/{types.d.ts → XYZConfig.d.ts} +2 -17
  30. package/lib-esm/model/earth/XYZConfig.js +13 -0
  31. package/lib-esm/model/earth/XYZFoVHelper.d.ts +9 -0
  32. package/lib-esm/model/earth/XYZFoVHelper.js +101 -0
  33. package/lib-esm/model/earth/XYZMap.d.ts +31 -0
  34. package/lib-esm/model/earth/XYZMap.js +208 -0
  35. package/lib-esm/model/earth/XYZMapDescriptor.d.ts +29 -0
  36. package/lib-esm/model/earth/XYZMapDescriptor.js +77 -0
  37. package/lib-esm/model/earth/XYZMeshBuilder.d.ts +1 -1
  38. package/lib-esm/model/earth/XYZMeshBuilder.js +13 -2
  39. package/lib-esm/model/earth/XYZTile.d.ts +20 -21
  40. package/lib-esm/model/earth/XYZTile.js +82 -102
  41. package/lib-esm/model/earth/XYZTileBuffer.d.ts +24 -26
  42. package/lib-esm/model/earth/XYZTileBuffer.js +60 -70
  43. package/lib-esm/model/earth/XYZTileRequestScheduler.d.ts +1 -1
  44. package/lib-esm/model/earth/XYZTileRequestScheduler.js +13 -2
  45. package/lib-esm/model/earth/XYZTypes.d.ts +24 -0
  46. package/lib-esm/model/earth/XYZTypes.js +13 -0
  47. package/lib-esm/model/earth/XYZVisibleTilesManager.d.ts +16 -27
  48. package/lib-esm/model/earth/XYZVisibleTilesManager.js +61 -192
  49. package/lib-esm/model/footprints/Footprint.js +12 -0
  50. package/lib-esm/model/footprints/FootprintProps.js +13 -1
  51. package/lib-esm/model/footprints/FootprintSetGL.js +12 -0
  52. package/lib-esm/model/grid/EquatorialGrid.js +20 -6
  53. package/lib-esm/model/grid/GridTextHelper.d.ts +10 -19
  54. package/lib-esm/model/grid/GridTextHelper.js +70 -67
  55. package/lib-esm/model/grid/HealpixGrid.d.ts +4 -4
  56. package/lib-esm/model/grid/HealpixGrid.js +19 -6
  57. package/lib-esm/model/grid/LonLatGrid.d.ts +40 -0
  58. package/lib-esm/model/grid/LonLatGrid.js +258 -0
  59. package/lib-esm/model/hips/AllSky.js +12 -0
  60. package/lib-esm/model/hips/AncestorTile.js +12 -0
  61. package/lib-esm/model/hips/FoVHelper.js +12 -0
  62. package/lib-esm/model/hips/HiPS.js +12 -9
  63. package/lib-esm/model/hips/HiPSDescriptor.js +12 -0
  64. package/lib-esm/model/hips/Tile.js +12 -0
  65. package/lib-esm/model/hips/TileBuffer.js +12 -0
  66. package/lib-esm/model/hips/VisibleTilesManager.js +12 -0
  67. package/lib-esm/model/tap/TapMetadata.js +12 -0
  68. package/lib-esm/model/tap/TapMetadataList.js +12 -0
  69. package/lib-esm/model/tap/TapRepo.js +12 -0
  70. package/lib-esm/model/terra/TerraFootprintSetGL.js +12 -0
  71. package/lib-esm/model/terra/TerraPointSetGL.js +12 -0
  72. package/lib-esm/services/SesameService.js +11 -3
  73. package/lib-esm/services/helpers.js +12 -0
  74. package/lib-esm/services/hipsNodeService.js +12 -0
  75. package/lib-esm/services/parse-hipslist.js +12 -0
  76. package/lib-esm/services/queryCatalogueByFoV.js +13 -1
  77. package/lib-esm/services/queryFootprintSetByFov.js +13 -1
  78. package/lib-esm/services/tapRepoService.js +13 -1
  79. package/lib-esm/services/types.js +12 -0
  80. package/lib-esm/shader/CatalogueShaderProgram.js +12 -0
  81. package/lib-esm/shader/FootprintShaderProgram.js +12 -0
  82. package/lib-esm/shader/GridShaderManager.js +12 -0
  83. package/lib-esm/shader/HiPSShaderProgram.js +12 -0
  84. package/lib-esm/shader/ShaderManager.js +12 -1
  85. package/lib-esm/shader/ShaderManagerMutliHiPS.js +12 -1
  86. package/lib-esm/shader/XYZShaderProgram.d.ts +14 -1
  87. package/lib-esm/shader/XYZShaderProgram.js +127 -2
  88. package/lib-esm/utils/CoordsType.js +12 -0
  89. package/lib-esm/utils/FoVUtils.js +12 -0
  90. package/lib-esm/utils/GeomUtils.js +12 -0
  91. package/lib-esm/utils/MouseHelper.js +12 -0
  92. package/lib-esm/utils/PerspectiveMatrixManager.js +12 -0
  93. package/lib-esm/utils/RayPickingUtils.js +12 -0
  94. package/lib-esm/utils/STCSParser.js +12 -0
  95. package/lib-esm/utils/ShaderUtility.js +13 -1
  96. package/lib-esm/utils/Utils.js +12 -0
  97. package/lib-esm/utils/XYZRayPickingUtils.d.ts +27 -0
  98. package/lib-esm/utils/XYZRayPickingUtils.js +226 -0
  99. package/package.json +1 -1
  100. package/lib-esm/model/FoV.d.ts +0 -62
  101. package/lib-esm/model/FoV.js +0 -274
  102. package/lib-esm/model/earth/XYZAncestorMeshCache.d.ts +0 -10
  103. package/lib-esm/model/earth/XYZAncestorMeshCache.js +0 -31
  104. package/lib-esm/model/earth/XYZLayer.d.ts +0 -31
  105. package/lib-esm/model/earth/XYZLayer.js +0 -231
  106. package/lib-esm/model/earth/XYZTileProvider.d.ts +0 -29
  107. package/lib-esm/model/earth/XYZTileProvider.js +0 -187
  108. package/lib-esm/model/earth/types.js +0 -1
  109. package/lib-esm/model/earth/wmts/types.d.ts +0 -1
  110. package/lib-esm/model/earth/wmts/types.js +0 -1
@@ -1,231 +0,0 @@
1
- import { AbstractSkyEntity } from '../AbstractSkyEntity.js';
2
- import { XYZShaderProgram } from '../../shader/XYZShaderProgram.js';
3
- import { XYZAncestorMeshCache } from './XYZAncestorMeshCache.js';
4
- import { XYZMeshBuilder } from './XYZMeshBuilder.js';
5
- import { XYZTileBuffer } from './XYZTileBuffer.js';
6
- import { XYZTileProvider } from './XYZTileProvider.js';
7
- import { XYZVisibleTilesManager } from './XYZVisibleTilesManager.js';
8
- export class XYZLayer extends AbstractSkyEntity {
9
- static DEFAULT_MAX_CACHED_TILES = 384;
10
- _config;
11
- _provider;
12
- _visibleTilesManager;
13
- _meshBuilder;
14
- _xyzShaderProgram;
15
- _tileBuffer;
16
- _ancestorMeshCache;
17
- _visibleTileKeys = [];
18
- _fallbackVisibleTileKeys = [];
19
- _baseVisibleTileKeys = [];
20
- _tilePriorities = new Map();
21
- _tileSelectionKey = null;
22
- _currentTileCount = 0;
23
- _fallbackTileCount = 0;
24
- _coreTileCount = 0;
25
- _coverageTileCount = 0;
26
- constructor(config, webgl) {
27
- super(1, [0, 0, 0], 0, 0, 'XYZ Earth Layer', webgl, false);
28
- this._config = config;
29
- this._provider = new XYZTileProvider(config);
30
- this._visibleTilesManager = new XYZVisibleTilesManager(this._provider);
31
- this._meshBuilder = new XYZMeshBuilder();
32
- this._xyzShaderProgram = new XYZShaderProgram(webgl);
33
- this._tileBuffer = new XYZTileBuffer(1, webgl, this._meshBuilder, this._xyzShaderProgram);
34
- this._ancestorMeshCache = new XYZAncestorMeshCache(webgl, this._meshBuilder);
35
- this.initGL(webgl);
36
- this.bootstrapTiles(180, null, null);
37
- }
38
- get config() {
39
- return this._config;
40
- }
41
- getDebugStats() {
42
- let readyTileCount = 0;
43
- let loadingTileCount = 0;
44
- let coolingDownTileCount = 0;
45
- const now = Date.now();
46
- const allTiles = [
47
- ...Array.from(this._tileBuffer.activeTiles.values(), (entry) => entry.tile),
48
- ...Array.from(this._tileBuffer.cachedTiles.values(), (entry) => entry.tile),
49
- ];
50
- for (const tile of allTiles) {
51
- if (tile.ready) {
52
- readyTileCount += 1;
53
- }
54
- if (tile.loading) {
55
- loadingTileCount += 1;
56
- }
57
- if (tile.failedUntil > now) {
58
- coolingDownTileCount += 1;
59
- }
60
- }
61
- const currentZoom = this._visibleTileKeys.reduce((maxZoom, tileKey) => {
62
- const zoom = Number.parseInt(tileKey.split('/')[0] ?? '', 10);
63
- if (!Number.isFinite(zoom)) {
64
- return maxZoom;
65
- }
66
- return maxZoom == null ? zoom : Math.max(maxZoom, zoom);
67
- }, null);
68
- return {
69
- cacheSize: this._tileBuffer.size,
70
- visibleTileCount: this._visibleTileKeys.length,
71
- currentTileCount: this._currentTileCount,
72
- fallbackTileCount: this._fallbackTileCount,
73
- coreTileCount: this._coreTileCount,
74
- coverageTileCount: this._coverageTileCount,
75
- readyTileCount,
76
- loadingTileCount,
77
- coolingDownTileCount,
78
- currentZoom,
79
- tileSelectionKey: this._tileSelectionKey,
80
- isSettling: false,
81
- coarseTileCount: 0,
82
- hasPendingSelection: false,
83
- pendingSelectionKey: null,
84
- };
85
- }
86
- bootstrapTiles(fovDeg, camera, centerSphericalDeg, fovPolygon = null, viewportSphericalSamples = null) {
87
- const selection = camera
88
- ? this._visibleTilesManager.selectTiles({
89
- fovDeg,
90
- camera,
91
- pMatrix: new Float32Array(),
92
- centerSphericalDeg: centerSphericalDeg ?? undefined,
93
- fovPolygon: fovPolygon ?? undefined,
94
- viewportSphericalSamples: viewportSphericalSamples ?? undefined,
95
- })
96
- : {
97
- key: 'initial',
98
- currentTiles: this._provider.getInitialTiles(),
99
- fallbackTiles: [],
100
- currentZoom: 1,
101
- coreTileCount: this._provider.getInitialTiles().length,
102
- coverageTileCount: 0,
103
- };
104
- if (selection.key === this._tileSelectionKey) {
105
- return;
106
- }
107
- this._tileSelectionKey = selection.key;
108
- this._currentTileCount = selection.currentTiles.length;
109
- this._fallbackTileCount = selection.fallbackTiles.length;
110
- this._coreTileCount = selection.coreTileCount;
111
- this._coverageTileCount = selection.coverageTileCount;
112
- const segments = this._config.segmentsPerSide ?? 16;
113
- const baseTiles = this._provider.getInitialTiles();
114
- const coreTileKeys = new Set(selection.currentTiles
115
- .slice(0, selection.coreTileCount)
116
- .map((tileCoord) => this.getTileKey(tileCoord)));
117
- const baseTileKeys = new Set(baseTiles.map((tileCoord) => this.getTileKey(tileCoord)));
118
- const prioritizedBaseTiles = baseTiles.map((tileCoord, index) => ({
119
- tileCoord,
120
- priority: 5000 + (baseTiles.length - index),
121
- role: 'base',
122
- }));
123
- const prioritizedCurrentTiles = selection.currentTiles.map((tileCoord, index) => ({
124
- tileCoord,
125
- priority: 10000 + (selection.currentTiles.length - index),
126
- role: coreTileKeys.has(this.getTileKey(tileCoord)) ? 'current' : 'coverage',
127
- }));
128
- const prioritizedFallbackTiles = selection.fallbackTiles.map((tileCoord, index) => ({
129
- tileCoord,
130
- priority: 1000 + (selection.fallbackTiles.length - index),
131
- role: 'fallback',
132
- }));
133
- const requestedTiles = [...prioritizedBaseTiles, ...prioritizedCurrentTiles, ...prioritizedFallbackTiles];
134
- this._tilePriorities.clear();
135
- this._fallbackVisibleTileKeys = [];
136
- this._baseVisibleTileKeys = [];
137
- const orderedRequests = requestedTiles
138
- .sort((a, b) => a.tileCoord.z - b.tileCoord.z)
139
- .map(({ tileCoord, priority, role }) => {
140
- const tileKey = this.getTileKey(tileCoord);
141
- this._tilePriorities.set(tileKey, priority);
142
- return {
143
- tileCoord,
144
- priority,
145
- url: this._provider.getTileUrl(tileCoord),
146
- role,
147
- };
148
- });
149
- const ensuredKeys = this._tileBuffer.ensureTiles(orderedRequests, segments);
150
- const fallbackKeySet = new Set(selection.fallbackTiles.map((tileCoord) => this.getTileKey(tileCoord)));
151
- this._baseVisibleTileKeys = ensuredKeys.filter((tileKey) => baseTileKeys.has(tileKey));
152
- this._fallbackVisibleTileKeys = ensuredKeys.filter((tileKey) => fallbackKeySet.has(tileKey) && !baseTileKeys.has(tileKey));
153
- this._visibleTileKeys = ensuredKeys.filter((tileKey) => !fallbackKeySet.has(tileKey) && !baseTileKeys.has(tileKey));
154
- this.evictCache();
155
- }
156
- draw(input) {
157
- const vMatrix = input.camera.getCameraMatrix();
158
- if (!vMatrix)
159
- return;
160
- this.bootstrapTiles(input.fovDeg ?? 180, input.camera, input.centerSphericalDeg ?? null, input.fovPolygon ?? null, input.viewportSphericalSamples ?? null);
161
- const pMatrix = input.pMatrix;
162
- const mMatrix = this.getModelMatrix();
163
- for (const tileKey of this._baseVisibleTileKeys) {
164
- const tile = this._tileBuffer.getActiveTile(tileKey);
165
- if (!tile)
166
- continue;
167
- tile.draw(pMatrix, vMatrix, mMatrix, this._tilePriorities.get(tileKey) ?? 0);
168
- }
169
- for (const tileKey of this._fallbackVisibleTileKeys) {
170
- const tile = this._tileBuffer.getActiveTile(tileKey);
171
- if (!tile)
172
- continue;
173
- tile.draw(pMatrix, vMatrix, mMatrix, this._tilePriorities.get(tileKey) ?? 0, false);
174
- }
175
- for (const tileKey of this._visibleTileKeys) {
176
- const tile = this._tileBuffer.getActiveTile(tileKey);
177
- if (tile?.ready) {
178
- tile.draw(pMatrix, vMatrix, mMatrix, this._tilePriorities.get(tileKey) ?? 0);
179
- continue;
180
- }
181
- const targetCoord = this.parseTileKey(tileKey);
182
- if (targetCoord) {
183
- const ancestorTile = this.findBestAvailableAncestor(targetCoord);
184
- if (ancestorTile) {
185
- const ancestorMesh = this._ancestorMeshCache.getMesh(targetCoord, ancestorTile.coord, this._config.segmentsPerSide ?? 16);
186
- ancestorTile.drawRemapped(ancestorMesh, pMatrix, vMatrix, mMatrix);
187
- }
188
- }
189
- tile?.draw(pMatrix, vMatrix, mMatrix, this._tilePriorities.get(tileKey) ?? 0);
190
- }
191
- }
192
- evictCache() {
193
- const maxCachedTiles = this._config.maxCachedTiles ?? XYZLayer.DEFAULT_MAX_CACHED_TILES;
194
- this._tileBuffer.evictCached(maxCachedTiles);
195
- }
196
- disposeTiles() {
197
- this._tileBuffer.dispose();
198
- this._ancestorMeshCache.dispose();
199
- this._visibleTileKeys = [];
200
- this._fallbackVisibleTileKeys = [];
201
- this._baseVisibleTileKeys = [];
202
- }
203
- getTileKey(tileCoord) {
204
- return `${tileCoord.z}/${tileCoord.x}/${tileCoord.y}`;
205
- }
206
- parseTileKey(tileKey) {
207
- const [zRaw, xRaw, yRaw] = tileKey.split('/');
208
- const z = Number.parseInt(zRaw ?? '', 10);
209
- const x = Number.parseInt(xRaw ?? '', 10);
210
- const y = Number.parseInt(yRaw ?? '', 10);
211
- if (!Number.isFinite(z) || !Number.isFinite(x) || !Number.isFinite(y)) {
212
- return null;
213
- }
214
- return { z, x, y };
215
- }
216
- findBestAvailableAncestor(targetCoord) {
217
- for (let z = targetCoord.z - 1; z >= this._provider.minZoom; z--) {
218
- const dz = targetCoord.z - z;
219
- const ancestorCoord = {
220
- z,
221
- x: targetCoord.x >> dz,
222
- y: targetCoord.y >> dz,
223
- };
224
- const ancestor = this._tileBuffer.getAnyTile(this.getTileKey(ancestorCoord));
225
- if (ancestor?.ready) {
226
- return ancestor;
227
- }
228
- }
229
- return null;
230
- }
231
- }
@@ -1,29 +0,0 @@
1
- import { Point } from '../Point.js';
2
- import type { XYZLayerConfig, XYZTileCoord } from './types.js';
3
- type ViewCenterSpherical = {
4
- phi: number;
5
- theta: number;
6
- };
7
- export declare class XYZTileProvider {
8
- private _config;
9
- constructor(config: XYZLayerConfig);
10
- get config(): XYZLayerConfig;
11
- get minZoom(): number;
12
- get maxZoom(): number;
13
- getInitialTiles(): XYZTileCoord[];
14
- getTileUrl(tile: XYZTileCoord): string;
15
- resolveZoom(fovDeg: number): number;
16
- private clampZoom;
17
- private getEffectiveTileY;
18
- private getSubdomain;
19
- getVisibleTilesAtZoom(z: number, centerSphericalDeg: ViewCenterSpherical | null, fovPolygon: Point[], viewportSphericalSamples: ViewCenterSpherical[], padding?: number): XYZTileCoord[];
20
- tileFromSpherical(zoom: number, sphericalDeg: ViewCenterSpherical): XYZTileCoord;
21
- getNeighborTiles(tile: XYZTileCoord, ring?: number): XYZTileCoord[];
22
- deduplicateTiles(tiles: XYZTileCoord[]): XYZTileCoord[];
23
- private resolveViewCenter;
24
- private latToTileY;
25
- private wrapTileX;
26
- private normalizeLonAround;
27
- private clampTileY;
28
- }
29
- export {};
@@ -1,187 +0,0 @@
1
- import global from '../../Global.js';
2
- const MAX_MERCATOR_LAT = 85.0511287798066;
3
- export class XYZTileProvider {
4
- _config;
5
- constructor(config) {
6
- this._config = config;
7
- }
8
- get config() {
9
- return this._config;
10
- }
11
- get minZoom() {
12
- return Math.max(0, Math.floor(this._config.minZoom ?? 0));
13
- }
14
- get maxZoom() {
15
- return Math.max(this.minZoom, Math.floor(this._config.maxZoom ?? 6));
16
- }
17
- getInitialTiles() {
18
- return this.getVisibleTilesAtZoom(1, null, [], [], 1);
19
- }
20
- getTileUrl(tile) {
21
- if (this._config.urlResolver) {
22
- return this._config.urlResolver(tile);
23
- }
24
- const effectiveY = this.getEffectiveTileY(tile);
25
- const subdomain = this.getSubdomain(tile);
26
- return this._config.urlTemplate
27
- .replace(/\{z\}/g, String(tile.z))
28
- .replace(/\{x\}/g, String(tile.x))
29
- .replace(/\{y\}/g, String(effectiveY))
30
- .replace(/\{s\}/g, subdomain);
31
- }
32
- resolveZoom(fovDeg) {
33
- const safeFov = Math.max(0.01, Math.min(180, fovDeg));
34
- const targetTileWidthDeg = Math.max(0.01, safeFov / 2);
35
- const rawZoom = Math.ceil(Math.log2(360 / targetTileWidthDeg));
36
- return this.clampZoom(rawZoom);
37
- }
38
- clampZoom(zoom) {
39
- return Math.max(this.minZoom, Math.min(this.maxZoom, zoom));
40
- }
41
- getEffectiveTileY(tile) {
42
- if (!this._config.flipY) {
43
- return tile.y;
44
- }
45
- const dim = 2 ** tile.z;
46
- return dim - 1 - tile.y;
47
- }
48
- getSubdomain(tile) {
49
- const subdomains = this._config.subdomains ?? [];
50
- if (subdomains.length === 0) {
51
- return '';
52
- }
53
- const index = Math.abs(tile.x + tile.y + tile.z) % subdomains.length;
54
- return subdomains[index] ?? '';
55
- }
56
- getVisibleTilesAtZoom(z, centerSphericalDeg, fovPolygon, viewportSphericalSamples, padding = 1) {
57
- const dim = 2 ** z;
58
- const center = this.resolveViewCenter(null, centerSphericalDeg);
59
- const normalizedCenterLon = this.normalizeLonAround(center.lonDeg, center.lonDeg);
60
- const polygonPoints = fovPolygon.length > 0
61
- ? fovPolygon.map((point) => ({
62
- lonDeg: this.normalizeLonAround(point.raDeg > 180 ? point.raDeg - 360 : point.raDeg, normalizedCenterLon),
63
- latDeg: point.decDeg,
64
- }))
65
- : [center];
66
- const samplePoints = viewportSphericalSamples.map((sample) => ({
67
- lonDeg: this.normalizeLonAround(sample.phi > 180 ? sample.phi - 360 : sample.phi, normalizedCenterLon),
68
- latDeg: 90 - sample.theta,
69
- }));
70
- const coveragePoints = [center, ...polygonPoints, ...samplePoints];
71
- let minLon = normalizedCenterLon;
72
- let maxLon = normalizedCenterLon;
73
- let minLat = center.latDeg;
74
- let maxLat = center.latDeg;
75
- for (const point of coveragePoints) {
76
- minLon = Math.min(minLon, point.lonDeg);
77
- maxLon = Math.max(maxLon, point.lonDeg);
78
- minLat = Math.min(minLat, point.latDeg);
79
- maxLat = Math.max(maxLat, point.latDeg);
80
- }
81
- const adaptivePadding = Math.max(padding, Math.min(3, Math.max(1, Math.ceil(z / 3))));
82
- const minX = Math.floor(((minLon + 180) / 360) * dim) - adaptivePadding;
83
- const maxX = Math.floor(((maxLon + 180) / 360) * dim) + adaptivePadding;
84
- const minY = Math.floor(this.latToTileY(maxLat, z)) - adaptivePadding;
85
- const maxY = Math.floor(this.latToTileY(minLat, z)) + adaptivePadding;
86
- const tiles = [];
87
- for (let x = minX; x <= maxX; x++) {
88
- for (let y = minY; y <= maxY; y++) {
89
- tiles.push({
90
- z,
91
- x: this.wrapTileX(x, dim),
92
- y: this.clampTileY(y, dim),
93
- });
94
- }
95
- }
96
- for (const point of coveragePoints) {
97
- const centerTileX = Math.floor(((point.lonDeg + 180) / 360) * dim);
98
- const centerTileY = Math.floor(this.latToTileY(point.latDeg, z));
99
- for (let dx = -adaptivePadding; dx <= adaptivePadding; dx++) {
100
- for (let dy = -adaptivePadding; dy <= adaptivePadding; dy++) {
101
- tiles.push({
102
- z,
103
- x: this.wrapTileX(centerTileX + dx, dim),
104
- y: this.clampTileY(centerTileY + dy, dim),
105
- });
106
- }
107
- }
108
- }
109
- return this.deduplicateTiles(tiles);
110
- }
111
- tileFromSpherical(zoom, sphericalDeg) {
112
- const lonDeg = sphericalDeg.phi > 180 ? sphericalDeg.phi - 360 : sphericalDeg.phi;
113
- const latDeg = 90 - sphericalDeg.theta;
114
- const dim = 2 ** zoom;
115
- const x = Math.floor(((lonDeg + 180) / 360) * dim);
116
- const y = Math.floor(this.latToTileY(latDeg, zoom));
117
- return {
118
- z: zoom,
119
- x: this.wrapTileX(x, dim),
120
- y: this.clampTileY(y, dim),
121
- };
122
- }
123
- getNeighborTiles(tile, ring = 1) {
124
- const dim = 2 ** tile.z;
125
- const neighbors = [];
126
- for (let dx = -ring; dx <= ring; dx++) {
127
- for (let dy = -ring; dy <= ring; dy++) {
128
- neighbors.push({
129
- z: tile.z,
130
- x: this.wrapTileX(tile.x + dx, dim),
131
- y: this.clampTileY(tile.y + dy, dim),
132
- });
133
- }
134
- }
135
- return this.deduplicateTiles(neighbors);
136
- }
137
- deduplicateTiles(tiles) {
138
- const unique = new Map();
139
- for (const tile of tiles) {
140
- unique.set(`${tile.z}/${tile.x}/${tile.y}`, tile);
141
- }
142
- return Array.from(unique.values());
143
- }
144
- resolveViewCenter(camera, centerSphericalDeg) {
145
- if (centerSphericalDeg) {
146
- return {
147
- lonDeg: centerSphericalDeg.phi > 180 ? centerSphericalDeg.phi - 360 : centerSphericalDeg.phi,
148
- latDeg: 90 - centerSphericalDeg.theta,
149
- };
150
- }
151
- if (!camera) {
152
- return { lonDeg: 0, latDeg: 0 };
153
- }
154
- const [x, y, z] = camera.getCameraPosition();
155
- const len = Math.hypot(x, y, z);
156
- if (!Number.isFinite(len) || len === 0) {
157
- return { lonDeg: 0, latDeg: 0 };
158
- }
159
- const scale = global.insideSphere ? 1 / len : -1 / len;
160
- const vx = x * scale;
161
- const vy = y * scale;
162
- const vz = z * scale;
163
- const lonDeg = (Math.atan2(vy, vx) * 180) / Math.PI;
164
- const latDeg = (Math.asin(Math.max(-1, Math.min(1, vz))) * 180) / Math.PI;
165
- return { lonDeg, latDeg };
166
- }
167
- latToTileY(latDeg, z) {
168
- const lat = Math.max(-MAX_MERCATOR_LAT, Math.min(MAX_MERCATOR_LAT, latDeg));
169
- const latRad = (lat * Math.PI) / 180;
170
- const n = 2 ** z;
171
- return ((1 - Math.asinh(Math.tan(latRad)) / Math.PI) / 2) * n;
172
- }
173
- wrapTileX(x, dim) {
174
- return ((x % dim) + dim) % dim;
175
- }
176
- normalizeLonAround(lonDeg, referenceLonDeg) {
177
- let lon = lonDeg;
178
- while (lon - referenceLonDeg > 180)
179
- lon -= 360;
180
- while (lon - referenceLonDeg < -180)
181
- lon += 360;
182
- return lon;
183
- }
184
- clampTileY(y, dim) {
185
- return Math.max(0, Math.min(dim - 1, y));
186
- }
187
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export type {};
@@ -1 +0,0 @@
1
- export {};