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.
- package/dist/astroviewer.cjs +2505 -1335
- package/dist/astroviewer.js +1 -1
- package/dist/astroviewer.min.js +1 -1
- package/lib-esm/AstroSphere.d.ts +26 -6
- package/lib-esm/AstroSphere.js +215 -18
- package/lib-esm/AstroViewer.d.ts +18 -5
- package/lib-esm/AstroViewer.js +47 -0
- package/lib-esm/Camera.js +24 -8
- package/lib-esm/Config.js +12 -0
- package/lib-esm/Global.js +12 -0
- package/lib-esm/index.d.ts +6 -4
- package/lib-esm/index.js +16 -3
- package/lib-esm/model/AbstractSkyEntity.js +12 -0
- package/lib-esm/model/AstroGL.js +12 -0
- package/lib-esm/model/ColorMaps.js +12 -0
- package/lib-esm/model/MetadataColumn.js +12 -0
- package/lib-esm/model/MetadataManager.js +12 -0
- package/lib-esm/model/Point.js +12 -0
- package/lib-esm/model/Point2D.js +12 -0
- package/lib-esm/model/Source.js +12 -0
- package/lib-esm/model/SphereFoV.d.ts +30 -0
- package/lib-esm/model/SphereFoV.js +195 -0
- package/lib-esm/model/catalogues/CatalogueGL.js +12 -0
- package/lib-esm/model/catalogues/CatalogueProps.js +13 -1
- package/lib-esm/model/earth/{wmts/WMTSAdapter.d.ts → WMTSAdapter.d.ts} +2 -1
- package/lib-esm/model/earth/{wmts/WMTSAdapter.js → WMTSAdapter.js} +12 -0
- package/lib-esm/model/earth/XYZAnchestorTile.d.ts +17 -0
- package/lib-esm/model/earth/XYZAnchestorTile.js +87 -0
- package/lib-esm/model/earth/{types.d.ts → XYZConfig.d.ts} +2 -17
- package/lib-esm/model/earth/XYZConfig.js +13 -0
- package/lib-esm/model/earth/XYZFoVHelper.d.ts +9 -0
- package/lib-esm/model/earth/XYZFoVHelper.js +101 -0
- package/lib-esm/model/earth/XYZMap.d.ts +31 -0
- package/lib-esm/model/earth/XYZMap.js +208 -0
- package/lib-esm/model/earth/XYZMapDescriptor.d.ts +29 -0
- package/lib-esm/model/earth/XYZMapDescriptor.js +77 -0
- package/lib-esm/model/earth/XYZMeshBuilder.d.ts +1 -1
- package/lib-esm/model/earth/XYZMeshBuilder.js +13 -2
- package/lib-esm/model/earth/XYZTile.d.ts +20 -21
- package/lib-esm/model/earth/XYZTile.js +82 -102
- package/lib-esm/model/earth/XYZTileBuffer.d.ts +24 -26
- package/lib-esm/model/earth/XYZTileBuffer.js +60 -70
- package/lib-esm/model/earth/XYZTileRequestScheduler.d.ts +1 -1
- package/lib-esm/model/earth/XYZTileRequestScheduler.js +13 -2
- package/lib-esm/model/earth/XYZTypes.d.ts +24 -0
- package/lib-esm/model/earth/XYZTypes.js +13 -0
- package/lib-esm/model/earth/XYZVisibleTilesManager.d.ts +16 -27
- package/lib-esm/model/earth/XYZVisibleTilesManager.js +61 -192
- package/lib-esm/model/footprints/Footprint.js +12 -0
- package/lib-esm/model/footprints/FootprintProps.js +13 -1
- package/lib-esm/model/footprints/FootprintSetGL.js +12 -0
- package/lib-esm/model/grid/EquatorialGrid.js +20 -6
- package/lib-esm/model/grid/GridTextHelper.d.ts +10 -19
- package/lib-esm/model/grid/GridTextHelper.js +70 -67
- package/lib-esm/model/grid/HealpixGrid.d.ts +4 -4
- package/lib-esm/model/grid/HealpixGrid.js +19 -6
- package/lib-esm/model/grid/LonLatGrid.d.ts +40 -0
- package/lib-esm/model/grid/LonLatGrid.js +258 -0
- package/lib-esm/model/hips/AllSky.js +12 -0
- package/lib-esm/model/hips/AncestorTile.js +12 -0
- package/lib-esm/model/hips/FoVHelper.js +12 -0
- package/lib-esm/model/hips/HiPS.js +12 -9
- package/lib-esm/model/hips/HiPSDescriptor.js +12 -0
- package/lib-esm/model/hips/Tile.js +12 -0
- package/lib-esm/model/hips/TileBuffer.js +12 -0
- package/lib-esm/model/hips/VisibleTilesManager.js +12 -0
- package/lib-esm/model/tap/TapMetadata.js +12 -0
- package/lib-esm/model/tap/TapMetadataList.js +12 -0
- package/lib-esm/model/tap/TapRepo.js +12 -0
- package/lib-esm/model/terra/TerraFootprintSetGL.js +12 -0
- package/lib-esm/model/terra/TerraPointSetGL.js +12 -0
- package/lib-esm/services/SesameService.js +11 -3
- package/lib-esm/services/helpers.js +12 -0
- package/lib-esm/services/hipsNodeService.js +12 -0
- package/lib-esm/services/parse-hipslist.js +12 -0
- package/lib-esm/services/queryCatalogueByFoV.js +13 -1
- package/lib-esm/services/queryFootprintSetByFov.js +13 -1
- package/lib-esm/services/tapRepoService.js +13 -1
- package/lib-esm/services/types.js +12 -0
- package/lib-esm/shader/CatalogueShaderProgram.js +12 -0
- package/lib-esm/shader/FootprintShaderProgram.js +12 -0
- package/lib-esm/shader/GridShaderManager.js +12 -0
- package/lib-esm/shader/HiPSShaderProgram.js +12 -0
- package/lib-esm/shader/ShaderManager.js +12 -1
- package/lib-esm/shader/ShaderManagerMutliHiPS.js +12 -1
- package/lib-esm/shader/XYZShaderProgram.d.ts +14 -1
- package/lib-esm/shader/XYZShaderProgram.js +127 -2
- package/lib-esm/utils/CoordsType.js +12 -0
- package/lib-esm/utils/FoVUtils.js +12 -0
- package/lib-esm/utils/GeomUtils.js +12 -0
- package/lib-esm/utils/MouseHelper.js +12 -0
- package/lib-esm/utils/PerspectiveMatrixManager.js +12 -0
- package/lib-esm/utils/RayPickingUtils.js +12 -0
- package/lib-esm/utils/STCSParser.js +12 -0
- package/lib-esm/utils/ShaderUtility.js +13 -1
- package/lib-esm/utils/Utils.js +12 -0
- package/lib-esm/utils/XYZRayPickingUtils.d.ts +27 -0
- package/lib-esm/utils/XYZRayPickingUtils.js +226 -0
- package/package.json +1 -1
- package/lib-esm/model/FoV.d.ts +0 -62
- package/lib-esm/model/FoV.js +0 -274
- package/lib-esm/model/earth/XYZAncestorMeshCache.d.ts +0 -10
- package/lib-esm/model/earth/XYZAncestorMeshCache.js +0 -31
- package/lib-esm/model/earth/XYZLayer.d.ts +0 -31
- package/lib-esm/model/earth/XYZLayer.js +0 -231
- package/lib-esm/model/earth/XYZTileProvider.d.ts +0 -29
- package/lib-esm/model/earth/XYZTileProvider.js +0 -187
- package/lib-esm/model/earth/types.js +0 -1
- package/lib-esm/model/earth/wmts/types.d.ts +0 -1
- package/lib-esm/model/earth/wmts/types.js +0 -1
|
@@ -1,206 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AstroViewer
|
|
3
|
+
* Copyright (C) Fabrizio Giordano
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
|
|
5
|
+
*
|
|
6
|
+
* This file is part of AstroViewer.
|
|
7
|
+
* AstroViewer is distributed under a dual-license model.
|
|
8
|
+
* Commercial use requires a separate commercial license.
|
|
9
|
+
* Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
|
|
10
|
+
*
|
|
11
|
+
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
12
|
+
*/
|
|
13
|
+
import XYZRayPickingUtils from '../../utils/XYZRayPickingUtils.js';
|
|
1
14
|
export class XYZVisibleTilesManager {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
_ancestorsMap = new Map();
|
|
16
|
+
_visibleTilesMap = new Map();
|
|
17
|
+
_visibleTiles = [];
|
|
18
|
+
_selection = {
|
|
19
|
+
key: '0:',
|
|
20
|
+
currentZoom: 0,
|
|
21
|
+
visibleTiles: [],
|
|
22
|
+
visibleTilesMap: new Map(),
|
|
23
|
+
ancestorsMap: new Map(),
|
|
24
|
+
};
|
|
25
|
+
get ancestorsMap() {
|
|
26
|
+
return this._ancestorsMap;
|
|
27
|
+
}
|
|
28
|
+
get visibleTiles() {
|
|
29
|
+
return this._visibleTiles;
|
|
30
|
+
}
|
|
31
|
+
get visibleTilesMap() {
|
|
32
|
+
return this._visibleTilesMap;
|
|
33
|
+
}
|
|
34
|
+
get selection() {
|
|
35
|
+
return this._selection;
|
|
36
|
+
}
|
|
37
|
+
computeVisibleTiles(z, xyzModel, webgl, camera, pMatrix, sampleCount = 9, padding = 2) {
|
|
38
|
+
this._visibleTiles = XYZRayPickingUtils.getVisibleTilesFromViewport(z, xyzModel, webgl, camera, pMatrix, sampleCount, padding);
|
|
39
|
+
this._visibleTilesMap = this.buildTileMap(this._visibleTiles);
|
|
40
|
+
this.refreshAncestorsMap(this._visibleTiles);
|
|
41
|
+
this._selection = {
|
|
42
|
+
key: this.buildSelectionKey(z, this._visibleTiles),
|
|
43
|
+
currentZoom: z,
|
|
44
|
+
visibleTiles: this._visibleTiles,
|
|
45
|
+
visibleTilesMap: this._visibleTilesMap,
|
|
46
|
+
ancestorsMap: this._ancestorsMap,
|
|
21
47
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
tiles.push(this._provider.tileFromSpherical(currentZoom, sample));
|
|
31
|
-
}
|
|
32
|
-
return this._provider.deduplicateTiles(tiles);
|
|
33
|
-
}
|
|
34
|
-
buildCoverageTiles(currentZoom, input, coreTiles) {
|
|
35
|
-
if (coreTiles.length === 0) {
|
|
36
|
-
return [];
|
|
37
|
-
}
|
|
38
|
-
const ring = this.getNeighborRing(currentZoom, input.fovDeg ?? 180);
|
|
39
|
-
if (ring <= 0) {
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
const coreSet = new Set(coreTiles.map((tile) => this.key(tile)));
|
|
43
|
-
const coverageTiles = [];
|
|
44
|
-
for (const tile of coreTiles) {
|
|
45
|
-
if (!this.isBoundaryTile(tile, coreSet)) {
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
const neighbors = this._provider.getNeighborTiles(tile, ring);
|
|
49
|
-
for (const neighbor of neighbors) {
|
|
50
|
-
const neighborKey = this.key(neighbor);
|
|
51
|
-
if (coreSet.has(neighborKey)) {
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
coverageTiles.push(neighbor);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return this._provider.deduplicateTiles(coverageTiles);
|
|
58
|
-
}
|
|
59
|
-
collectCoverageSamples(input) {
|
|
60
|
-
const samples = [];
|
|
61
|
-
if (input.centerSphericalDeg) {
|
|
62
|
-
samples.push(input.centerSphericalDeg);
|
|
63
|
-
}
|
|
64
|
-
for (const sample of input.viewportSphericalSamples ?? []) {
|
|
65
|
-
samples.push(sample);
|
|
66
|
-
}
|
|
67
|
-
const polygonSamples = this.interpolateFoVPolygon(input.fovPolygon ?? []);
|
|
68
|
-
for (const sample of polygonSamples) {
|
|
69
|
-
samples.push(sample);
|
|
70
|
-
}
|
|
71
|
-
return samples;
|
|
72
|
-
}
|
|
73
|
-
interpolateFoVPolygon(fovPolygon) {
|
|
74
|
-
if (fovPolygon.length === 0) {
|
|
75
|
-
return [];
|
|
76
|
-
}
|
|
77
|
-
const polygonSpherical = fovPolygon.map((point) => ({
|
|
78
|
-
phi: point.raDeg < 0 ? point.raDeg + 360 : point.raDeg,
|
|
79
|
-
theta: 90 - point.decDeg,
|
|
80
|
-
}));
|
|
81
|
-
const samples = [...polygonSpherical];
|
|
82
|
-
const segmentInterpolationCount = polygonSpherical.length >= 4 ? 3 : 1;
|
|
83
|
-
for (let i = 0; i < polygonSpherical.length; i++) {
|
|
84
|
-
const start = polygonSpherical[i];
|
|
85
|
-
const end = polygonSpherical[(i + 1) % polygonSpherical.length];
|
|
86
|
-
if (!start || !end)
|
|
87
|
-
continue;
|
|
88
|
-
const startPhi = this.normalizePhi(start.phi);
|
|
89
|
-
let endPhi = this.normalizePhi(end.phi);
|
|
90
|
-
if (Math.abs(endPhi - startPhi) > 180) {
|
|
91
|
-
endPhi += endPhi > startPhi ? -360 : 360;
|
|
92
|
-
}
|
|
93
|
-
for (let step = 1; step <= segmentInterpolationCount; step++) {
|
|
94
|
-
const t = step / (segmentInterpolationCount + 1);
|
|
95
|
-
const phi = this.normalizePhi(startPhi + (endPhi - startPhi) * t);
|
|
96
|
-
const theta = start.theta + (end.theta - start.theta) * t;
|
|
97
|
-
samples.push({ phi, theta });
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return samples;
|
|
101
|
-
}
|
|
102
|
-
getNeighborRing(currentZoom, fovDeg) {
|
|
103
|
-
if (currentZoom >= 14 && fovDeg < 10) {
|
|
104
|
-
return 0;
|
|
105
|
-
}
|
|
106
|
-
return 1;
|
|
107
|
-
}
|
|
108
|
-
isBoundaryTile(tile, coreTileKeys) {
|
|
109
|
-
const directNeighbors = [
|
|
110
|
-
{ z: tile.z, x: tile.x - 1, y: tile.y },
|
|
111
|
-
{ z: tile.z, x: tile.x + 1, y: tile.y },
|
|
112
|
-
{ z: tile.z, x: tile.x, y: tile.y - 1 },
|
|
113
|
-
{ z: tile.z, x: tile.x, y: tile.y + 1 },
|
|
114
|
-
];
|
|
115
|
-
return directNeighbors.some((neighbor) => !coreTileKeys.has(this.key(this.normalizeTile(neighbor))));
|
|
116
|
-
}
|
|
117
|
-
normalizeTile(tile) {
|
|
118
|
-
const dim = 2 ** tile.z;
|
|
119
|
-
return {
|
|
120
|
-
z: tile.z,
|
|
121
|
-
x: ((tile.x % dim) + dim) % dim,
|
|
122
|
-
y: Math.max(0, Math.min(dim - 1, tile.y)),
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
normalizePhi(phi) {
|
|
126
|
-
let value = phi;
|
|
127
|
-
while (value < 0)
|
|
128
|
-
value += 360;
|
|
129
|
-
while (value >= 360)
|
|
130
|
-
value -= 360;
|
|
131
|
-
return value;
|
|
132
|
-
}
|
|
133
|
-
buildFallbackMap(currentTiles, currentZoom) {
|
|
134
|
-
const fallbackMap = new Map();
|
|
135
|
-
const minFallbackZoom = Math.max(this._provider.minZoom, currentZoom - 2);
|
|
136
|
-
for (let z = currentZoom - 1; z >= minFallbackZoom; z--) {
|
|
137
|
-
const dz = currentZoom - z;
|
|
138
|
-
for (const tile of currentTiles) {
|
|
139
|
-
const fallback = {
|
|
48
|
+
return this._selection;
|
|
49
|
+
}
|
|
50
|
+
refreshAncestorsMap(visibleTiles) {
|
|
51
|
+
this._ancestorsMap.clear();
|
|
52
|
+
for (const tile of visibleTiles) {
|
|
53
|
+
for (let z = tile.z - 1; z >= 0; z--) {
|
|
54
|
+
const dz = tile.z - z;
|
|
55
|
+
const ancestor = {
|
|
140
56
|
z,
|
|
141
57
|
x: tile.x >> dz,
|
|
142
58
|
y: tile.y >> dz,
|
|
143
59
|
};
|
|
144
|
-
|
|
60
|
+
this._ancestorsMap.set(`${ancestor.z}/${ancestor.x}/${ancestor.y}`, ancestor);
|
|
145
61
|
}
|
|
146
62
|
}
|
|
147
|
-
return fallbackMap;
|
|
148
63
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const centerTile = this.getCenterTileCoord(zoom, centerSphericalDeg);
|
|
154
|
-
if (!centerTile) {
|
|
155
|
-
return coreTiles;
|
|
64
|
+
buildTileMap(tiles) {
|
|
65
|
+
const map = new Map();
|
|
66
|
+
for (const tile of tiles) {
|
|
67
|
+
map.set(this.key(tile), tile);
|
|
156
68
|
}
|
|
157
|
-
|
|
158
|
-
if (coreTiles.some((tile) => this.key(tile) === centerKey)) {
|
|
159
|
-
return coreTiles;
|
|
160
|
-
}
|
|
161
|
-
return [...coreTiles, centerTile];
|
|
162
|
-
}
|
|
163
|
-
orderTilesByScreenRelevance(tiles, zoom, centerSphericalDeg) {
|
|
164
|
-
const centerTile = this.getCenterTileCoord(zoom, centerSphericalDeg);
|
|
165
|
-
if (!centerTile) {
|
|
166
|
-
return tiles;
|
|
167
|
-
}
|
|
168
|
-
return [...tiles].sort((a, b) => {
|
|
169
|
-
const distanceA = Math.abs(a.x - centerTile.x) + Math.abs(a.y - centerTile.y);
|
|
170
|
-
const distanceB = Math.abs(b.x - centerTile.x) + Math.abs(b.y - centerTile.y);
|
|
171
|
-
return distanceA - distanceB;
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
orderFallbackTiles(tiles, currentZoom, centerSphericalDeg) {
|
|
175
|
-
return [...tiles].sort((a, b) => {
|
|
176
|
-
if (b.z !== a.z) {
|
|
177
|
-
return b.z - a.z;
|
|
178
|
-
}
|
|
179
|
-
const centerTileA = this.getCenterTileCoord(a.z, centerSphericalDeg);
|
|
180
|
-
const centerTileB = this.getCenterTileCoord(b.z, centerSphericalDeg);
|
|
181
|
-
if (!centerTileA || !centerTileB) {
|
|
182
|
-
return 0;
|
|
183
|
-
}
|
|
184
|
-
const distanceA = Math.abs(a.x - centerTileA.x) + Math.abs(a.y - centerTileA.y);
|
|
185
|
-
const distanceB = Math.abs(b.x - centerTileB.x) + Math.abs(b.y - centerTileB.y);
|
|
186
|
-
return distanceA - distanceB || currentZoom - a.z - (currentZoom - b.z);
|
|
187
|
-
});
|
|
69
|
+
return map;
|
|
188
70
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return null;
|
|
192
|
-
}
|
|
193
|
-
const lonDeg = centerSphericalDeg.phi > 180 ? centerSphericalDeg.phi - 360 : centerSphericalDeg.phi;
|
|
194
|
-
const latDeg = 90 - centerSphericalDeg.theta;
|
|
195
|
-
const dim = 2 ** zoom;
|
|
196
|
-
const x = Math.floor(((lonDeg + 180) / 360) * dim);
|
|
197
|
-
const latRad = (Math.max(-85.0511287798066, Math.min(85.0511287798066, latDeg)) * Math.PI) / 180;
|
|
198
|
-
const y = Math.floor(((1 - Math.asinh(Math.tan(latRad)) / Math.PI) / 2) * dim);
|
|
199
|
-
return {
|
|
200
|
-
z: zoom,
|
|
201
|
-
x: ((x % dim) + dim) % dim,
|
|
202
|
-
y: Math.max(0, Math.min(dim - 1, y)),
|
|
203
|
-
};
|
|
71
|
+
buildSelectionKey(z, tiles) {
|
|
72
|
+
return `${z}:${tiles.map((tile) => `${tile.x}/${tile.y}`).join('|')}`;
|
|
204
73
|
}
|
|
205
74
|
key(tile) {
|
|
206
75
|
return `${tile.z}/${tile.x}/${tile.y}`;
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AstroViewer
|
|
3
|
+
* Copyright (C) Fabrizio Giordano
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
|
|
5
|
+
*
|
|
6
|
+
* This file is part of AstroViewer.
|
|
7
|
+
* AstroViewer is distributed under a dual-license model.
|
|
8
|
+
* Commercial use requires a separate commercial license.
|
|
9
|
+
* Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
|
|
10
|
+
*
|
|
11
|
+
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
12
|
+
*/
|
|
1
13
|
'use strict';
|
|
2
14
|
/**
|
|
3
15
|
* @author Fabrizio Giordano (Fab)
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AstroViewer
|
|
3
|
+
* Copyright (C) Fabrizio Giordano
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
|
|
5
|
+
*
|
|
6
|
+
* This file is part of AstroViewer.
|
|
7
|
+
* AstroViewer is distributed under a dual-license model.
|
|
8
|
+
* Commercial use requires a separate commercial license.
|
|
9
|
+
* Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
|
|
10
|
+
*
|
|
11
|
+
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
1
14
|
// import {Metadata} from '../tap/TapMetadata.js';
|
|
2
15
|
// import {TapMetadataList} from '../tap/TapMetadataList.js';
|
|
3
|
-
export {};
|
|
4
16
|
// export default class FootprintProps {
|
|
5
17
|
// // resolved columns
|
|
6
18
|
// pgSphereColumn?: Metadata;
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AstroViewer
|
|
3
|
+
* Copyright (C) Fabrizio Giordano
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
|
|
5
|
+
*
|
|
6
|
+
* This file is part of AstroViewer.
|
|
7
|
+
* AstroViewer is distributed under a dual-license model.
|
|
8
|
+
* Commercial use requires a separate commercial license.
|
|
9
|
+
* Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
|
|
10
|
+
*
|
|
11
|
+
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
12
|
+
*/
|
|
1
13
|
import { Footprint } from "./Footprint.js";
|
|
2
14
|
import { colorHex2RGB } from "../../utils/Utils.js";
|
|
3
15
|
import { FootprintShaderProgram } from "../../shader/FootprintShaderProgram.js";
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AstroViewer
|
|
3
|
+
* Copyright (C) Fabrizio Giordano
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
|
|
5
|
+
*
|
|
6
|
+
* This file is part of AstroViewer.
|
|
7
|
+
* AstroViewer is distributed under a dual-license model.
|
|
8
|
+
* Commercial use requires a separate commercial license.
|
|
9
|
+
* Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
|
|
10
|
+
*
|
|
11
|
+
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
12
|
+
*/
|
|
1
13
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
14
|
import { vec4, mat4 } from 'gl-matrix';
|
|
3
15
|
import { fovHelper } from '../hips/FoVHelper.js';
|
|
@@ -19,7 +31,7 @@ export class EquatorialGrid extends AbstractSkyEntity {
|
|
|
19
31
|
_vertexShader;
|
|
20
32
|
_fragmentShader;
|
|
21
33
|
defaultColor = '#41d421';
|
|
22
|
-
gridText = new GridTextHelper();
|
|
34
|
+
gridText = new GridTextHelper('equatorial');
|
|
23
35
|
_attribLocations = {
|
|
24
36
|
position: 0,
|
|
25
37
|
selected: 1,
|
|
@@ -260,9 +272,10 @@ export class EquatorialGrid extends AbstractSkyEntity {
|
|
|
260
272
|
// perspective divide
|
|
261
273
|
clipspace[0] /= clipspace[3];
|
|
262
274
|
clipspace[1] /= clipspace[3];
|
|
263
|
-
// clip->
|
|
264
|
-
const
|
|
265
|
-
const
|
|
275
|
+
// clip -> CSS pixels
|
|
276
|
+
const canvasRect = super.webgl.canvas.getBoundingClientRect();
|
|
277
|
+
const pixelX = canvasRect.left + (clipspace[0] * 0.5 + 0.5) * canvasRect.width;
|
|
278
|
+
const pixelY = canvasRect.top + (clipspace[1] * -0.5 + 0.5) * canvasRect.height;
|
|
266
279
|
this.gridText.addEqDivSet(decDeg.toFixed(2), pixelX, pixelY, 'dec');
|
|
267
280
|
// gridTextHelper.addEqDivSet(decDeg.toFixed(2), pixelX, pixelY, 'dec');
|
|
268
281
|
}
|
|
@@ -283,8 +296,9 @@ export class EquatorialGrid extends AbstractSkyEntity {
|
|
|
283
296
|
vec4.transformMat4(clipspace, phiPoint, mvpMatrix);
|
|
284
297
|
clipspace[0] /= clipspace[3];
|
|
285
298
|
clipspace[1] /= clipspace[3];
|
|
286
|
-
const
|
|
287
|
-
const
|
|
299
|
+
const canvasRect = super.webgl.canvas.getBoundingClientRect();
|
|
300
|
+
const pixelX = canvasRect.left + (clipspace[0] * 0.5 + 0.5) * canvasRect.width;
|
|
301
|
+
const pixelY = canvasRect.top + (clipspace[1] * -0.5 + 0.5) * canvasRect.height;
|
|
288
302
|
// gridTextHelper.addEqDivSet(raDeg.toFixed(2), pixelX, pixelY, 'ra');
|
|
289
303
|
this.gridText.addEqDivSet(raDeg.toFixed(2), pixelX, pixelY, 'ra');
|
|
290
304
|
}
|
|
@@ -1,25 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
* @author Fabrizio Giordano (Fab)
|
|
3
|
-
* @param in_radius - number
|
|
4
|
-
* @param in_gl - GL context
|
|
5
|
-
* @param in_position - array of double e.g. [0.0, 0.0, 0.0]
|
|
6
|
-
*/
|
|
1
|
+
type GridLabelLayer = 'healpix' | 'equatorial' | 'lonlat';
|
|
7
2
|
declare class GridTextHelper {
|
|
8
|
-
private
|
|
9
|
-
private
|
|
10
|
-
|
|
11
|
-
private _divSetNdx;
|
|
12
|
-
constructor();
|
|
3
|
+
private static layers;
|
|
4
|
+
private layer;
|
|
5
|
+
constructor(layer?: GridLabelLayer);
|
|
13
6
|
initHtml(): void;
|
|
14
|
-
resetDivSets(): void;
|
|
15
|
-
/**
|
|
16
|
-
* Add / reuse a floating label for HPX coordinates
|
|
17
|
-
*/
|
|
7
|
+
resetDivSets(layer?: GridLabelLayer): void;
|
|
18
8
|
addHPXDivSet(msg: string, x: number, y: number): void;
|
|
19
|
-
/**
|
|
20
|
-
* Add / reuse a floating label for Equatorial coords
|
|
21
|
-
* @param type 'ra' or 'dec'
|
|
22
|
-
*/
|
|
23
9
|
addEqDivSet(msg: string, x: number, y: number, type: 'ra' | 'dec'): void;
|
|
10
|
+
addLonLatDivSet(msg: string, x: number, y: number, type: 'lon' | 'lat'): void;
|
|
11
|
+
private addLabel;
|
|
12
|
+
private classNameForKind;
|
|
13
|
+
private static getLayerState;
|
|
14
|
+
private static resolveContainer;
|
|
24
15
|
}
|
|
25
16
|
export default GridTextHelper;
|
|
@@ -1,91 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
1
|
+
/*
|
|
2
|
+
* AstroViewer
|
|
3
|
+
* Copyright (C) Fabrizio Giordano
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
|
|
5
|
+
*
|
|
6
|
+
* This file is part of AstroViewer.
|
|
7
|
+
* AstroViewer is distributed under a dual-license model.
|
|
8
|
+
* Commercial use requires a separate commercial license.
|
|
9
|
+
* Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
|
|
10
|
+
*
|
|
11
|
+
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
6
12
|
*/
|
|
7
13
|
class GridTextHelper {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this._divEqContainerElement = document.querySelector('#gridcoords');
|
|
14
|
-
this._divHPXContainerElement = document.querySelector('#gridhpx');
|
|
15
|
-
this._divSetNdx = 0;
|
|
16
|
-
this._divSets = [];
|
|
14
|
+
static layers = new Map();
|
|
15
|
+
layer;
|
|
16
|
+
constructor(layer = 'equatorial') {
|
|
17
|
+
this.layer = layer;
|
|
18
|
+
GridTextHelper.getLayerState(layer);
|
|
17
19
|
}
|
|
18
20
|
initHtml() {
|
|
19
|
-
|
|
21
|
+
GridTextHelper.getLayerState(this.layer);
|
|
20
22
|
}
|
|
21
|
-
resetDivSets() {
|
|
22
|
-
|
|
23
|
-
for (;
|
|
24
|
-
|
|
23
|
+
resetDivSets(layer = this.layer) {
|
|
24
|
+
const state = GridTextHelper.getLayerState(layer);
|
|
25
|
+
for (; state.divSetNdx < state.divSets.length; ++state.divSetNdx) {
|
|
26
|
+
state.divSets[state.divSetNdx].style.display = 'none';
|
|
25
27
|
}
|
|
26
|
-
|
|
28
|
+
state.divSetNdx = 0;
|
|
27
29
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Add / reuse a floating label for HPX coordinates
|
|
30
|
-
*/
|
|
31
30
|
addHPXDivSet(msg, x, y) {
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
this.addLabel('healpix', msg, x + 25, y, 'hpx');
|
|
32
|
+
}
|
|
33
|
+
addEqDivSet(msg, x, y, type) {
|
|
34
|
+
this.addLabel('equatorial', msg, type === 'ra' ? x + 25 : x, type === 'ra' ? y : y + 25, type);
|
|
35
|
+
}
|
|
36
|
+
addLonLatDivSet(msg, x, y, type) {
|
|
37
|
+
this.addLabel('lonlat', msg, type === 'lon' ? x + 25 : x, type === 'lon' ? y : y + 25, type);
|
|
38
|
+
}
|
|
39
|
+
addLabel(layer, msg, x, y, kind) {
|
|
40
|
+
const state = GridTextHelper.getLayerState(layer);
|
|
41
|
+
if (!state.container)
|
|
42
|
+
return;
|
|
43
|
+
let divSet = state.divSets[state.divSetNdx++];
|
|
34
44
|
if (!divSet) {
|
|
35
45
|
const div = document.createElement('div');
|
|
36
46
|
const textNode = document.createTextNode('');
|
|
37
|
-
div.className = 'floating-div-ra'; // style like RA tags
|
|
38
47
|
div.appendChild(textNode);
|
|
39
|
-
|
|
40
|
-
this._divHPXContainerElement = document.querySelector('#gridhpx');
|
|
41
|
-
}
|
|
42
|
-
if (!this._divHPXContainerElement) {
|
|
43
|
-
// If container is still missing, abort gracefully
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
this._divHPXContainerElement.appendChild(div);
|
|
48
|
+
state.container.appendChild(div);
|
|
47
49
|
divSet = { div, textNode, style: div.style };
|
|
48
|
-
|
|
50
|
+
state.divSets.push(divSet);
|
|
49
51
|
}
|
|
50
|
-
|
|
52
|
+
divSet.div.className = this.classNameForKind(kind);
|
|
51
53
|
divSet.style.display = 'block';
|
|
52
|
-
divSet.style.left = `${Math.floor(x
|
|
54
|
+
divSet.style.left = `${Math.floor(x)}px`;
|
|
53
55
|
divSet.style.top = `${Math.floor(y)}px`;
|
|
54
56
|
divSet.textNode.nodeValue = msg;
|
|
55
57
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this._divEqContainerElement = document.querySelector('#gridcoords');
|
|
69
|
-
}
|
|
70
|
-
if (!this._divEqContainerElement) {
|
|
71
|
-
// If container is still missing, abort gracefully
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
this._divEqContainerElement.appendChild(div);
|
|
75
|
-
divSet = { div, textNode, style: div.style };
|
|
76
|
-
this._divSets.push(divSet);
|
|
58
|
+
classNameForKind(kind) {
|
|
59
|
+
switch (kind) {
|
|
60
|
+
case 'dec':
|
|
61
|
+
return 'floating-div-dec';
|
|
62
|
+
case 'lat':
|
|
63
|
+
return 'floating-div-lat';
|
|
64
|
+
case 'lon':
|
|
65
|
+
return 'floating-div-lon';
|
|
66
|
+
case 'hpx':
|
|
67
|
+
case 'ra':
|
|
68
|
+
default:
|
|
69
|
+
return 'floating-div-ra';
|
|
77
70
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
}
|
|
72
|
+
static getLayerState(layer) {
|
|
73
|
+
const current = GridTextHelper.layers.get(layer);
|
|
74
|
+
if (current) {
|
|
75
|
+
if (!current.container)
|
|
76
|
+
current.container = GridTextHelper.resolveContainer(layer);
|
|
77
|
+
return current;
|
|
82
78
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
const state = {
|
|
80
|
+
container: GridTextHelper.resolveContainer(layer),
|
|
81
|
+
divSets: [],
|
|
82
|
+
divSetNdx: 0,
|
|
83
|
+
};
|
|
84
|
+
GridTextHelper.layers.set(layer, state);
|
|
85
|
+
return state;
|
|
86
|
+
}
|
|
87
|
+
static resolveContainer(layer) {
|
|
88
|
+
if (layer === 'healpix') {
|
|
89
|
+
return document.querySelector('#gridhpx');
|
|
86
90
|
}
|
|
87
|
-
|
|
91
|
+
return document.querySelector('#gridcoords');
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
|
-
// export const gridTextHelper = new GridTextHelper();
|
|
91
94
|
export default GridTextHelper;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbstractSkyEntity, SkyEntityDrawInput } from '../AbstractSkyEntity.js';
|
|
2
2
|
import { ReadonlyMat4 } from 'gl-matrix';
|
|
3
|
-
import {
|
|
3
|
+
import { SphereFoV } from '../SphereFoV.js';
|
|
4
4
|
import { VisibleTilesManager } from '../hips/VisibleTilesManager.js';
|
|
5
5
|
import Camera from '../../Camera.js';
|
|
6
6
|
export declare class HealpixGrid extends AbstractSkyEntity {
|
|
@@ -28,13 +28,13 @@ export declare class HealpixGrid extends AbstractSkyEntity {
|
|
|
28
28
|
private _visibleTilesManager;
|
|
29
29
|
constructor(webgl: WebGL2RenderingContext);
|
|
30
30
|
init(): void;
|
|
31
|
-
get fovObj():
|
|
31
|
+
get fovObj(): SphereFoV;
|
|
32
32
|
get RADIUS(): number;
|
|
33
33
|
get INITIAL_POSITION(): [number, number, number];
|
|
34
34
|
get INITIAL_PhiRad(): number;
|
|
35
35
|
get INITIAL_ThetaRad(): number;
|
|
36
|
-
refreshFoV(camera: Camera, pMatrix: ReadonlyMat4):
|
|
37
|
-
getFoV():
|
|
36
|
+
refreshFoV(camera: Camera, pMatrix: ReadonlyMat4): SphereFoV;
|
|
37
|
+
getFoV(): SphereFoV;
|
|
38
38
|
getMinFoV(): number;
|
|
39
39
|
private initShaders;
|
|
40
40
|
initBuffers(pixels: number[], order: number): void;
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AstroViewer
|
|
3
|
+
* Copyright (C) Fabrizio Giordano
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
|
|
5
|
+
*
|
|
6
|
+
* This file is part of AstroViewer.
|
|
7
|
+
* AstroViewer is distributed under a dual-license model.
|
|
8
|
+
* Commercial use requires a separate commercial license.
|
|
9
|
+
* Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
|
|
10
|
+
*
|
|
11
|
+
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
12
|
+
*/
|
|
1
13
|
'use strict';
|
|
2
14
|
import { AbstractSkyEntity } from '../AbstractSkyEntity.js';
|
|
3
15
|
import global from '../../Global.js';
|
|
4
16
|
import { mat4, vec4 } from 'gl-matrix';
|
|
5
17
|
import { fovHelper } from '../hips/FoVHelper.js';
|
|
6
18
|
import { FoVUtils } from '../../utils/FoVUtils.js';
|
|
7
|
-
import {
|
|
19
|
+
import { SphereFoV } from '../SphereFoV.js';
|
|
8
20
|
import { CoordsType } from '../../utils/CoordsType.js';
|
|
9
21
|
import { Point } from '../Point.js';
|
|
10
22
|
import GridShaderManager from '../../shader/GridShaderManager.js';
|
|
@@ -22,7 +34,7 @@ export class HealpixGrid extends AbstractSkyEntity {
|
|
|
22
34
|
fragmentShader;
|
|
23
35
|
vertexShader;
|
|
24
36
|
defaultColor = '#ec0acaff';
|
|
25
|
-
gridText = new GridTextHelper();
|
|
37
|
+
gridText = new GridTextHelper('healpix');
|
|
26
38
|
// private _hipsShaderProgram: HiPSShaderProgram
|
|
27
39
|
_attribLocations = {
|
|
28
40
|
position: 0,
|
|
@@ -59,7 +71,7 @@ export class HealpixGrid extends AbstractSkyEntity {
|
|
|
59
71
|
this._vertexCataloguePositionBuffer = super.webgl.createBuffer();
|
|
60
72
|
this._indexBuffer = super.webgl.createBuffer();
|
|
61
73
|
this._vertexCataloguePosition = new Float32Array(0);
|
|
62
|
-
this._fovObj = new
|
|
74
|
+
this._fovObj = new SphereFoV(super.webgl);
|
|
63
75
|
}
|
|
64
76
|
get fovObj() {
|
|
65
77
|
return this._fovObj;
|
|
@@ -288,9 +300,10 @@ export class HealpixGrid extends AbstractSkyEntity {
|
|
|
288
300
|
// NDC divide
|
|
289
301
|
clipspace[0] /= clipspace[3];
|
|
290
302
|
clipspace[1] /= clipspace[3];
|
|
291
|
-
// clip
|
|
292
|
-
const
|
|
293
|
-
const
|
|
303
|
+
// clip -> CSS pixels
|
|
304
|
+
const canvasRect = gl.canvas.getBoundingClientRect();
|
|
305
|
+
const pixelX = canvasRect.left + (clipspace[0] * 0.5 + 0.5) * canvasRect.width;
|
|
306
|
+
const pixelY = canvasRect.top + (clipspace[1] * -0.5 + 0.5) * canvasRect.height;
|
|
294
307
|
this.gridText.addHPXDivSet(this._visibleorder + '/' + pixels[p], pixelX, pixelY);
|
|
295
308
|
// gridTextHelper.addHPXDivSet(this._visibleorder + '/' + pixels[p], pixelX, pixelY);
|
|
296
309
|
}
|