astro-viewer 3.1.0 → 3.2.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 +706 -204
- package/dist/astroviewer.js +1 -1
- package/dist/astroviewer.min.js +1 -1
- package/lib-esm/AstroSphere.d.ts +19 -15
- package/lib-esm/AstroSphere.js +163 -94
- package/lib-esm/AstroViewer.d.ts +2 -0
- package/lib-esm/AstroViewer.js +3 -0
- package/lib-esm/Camera.js +4 -6
- package/lib-esm/Config.d.ts +2 -0
- package/lib-esm/Config.js +3 -1
- package/lib-esm/index.d.ts +2 -0
- package/lib-esm/index.js +1 -0
- package/lib-esm/model/AbstractSkyEntity.d.ts +1 -0
- package/lib-esm/model/MetadataManager.d.ts +1 -0
- package/lib-esm/model/MetadataManager.js +4 -1
- package/lib-esm/model/Point.d.ts +9 -1
- package/lib-esm/model/Point.js +18 -0
- package/lib-esm/model/SphereFoV.js +4 -3
- package/lib-esm/model/earth/XYZConfig.d.ts +4 -0
- package/lib-esm/model/earth/XYZFoVHelper.d.ts +5 -2
- package/lib-esm/model/earth/XYZFoVHelper.js +40 -3
- package/lib-esm/model/footprints/Footprint.d.ts +4 -1
- package/lib-esm/model/footprints/Footprint.js +18 -2
- package/lib-esm/model/footprints/FootprintSetGL.d.ts +4 -2
- package/lib-esm/model/footprints/FootprintSetGL.js +9 -6
- package/lib-esm/model/grid/EquatorialGrid.d.ts +2 -1
- package/lib-esm/model/grid/EquatorialGrid.js +10 -6
- package/lib-esm/model/grid/HealpixGrid.js +5 -2
- package/lib-esm/model/grid/LonLatGrid.d.ts +3 -0
- package/lib-esm/model/grid/LonLatGrid.js +61 -10
- package/lib-esm/model/hips/FoVHelper.d.ts +5 -2
- package/lib-esm/model/hips/FoVHelper.js +40 -3
- package/lib-esm/model/hips/HiPS.d.ts +2 -0
- package/lib-esm/model/hips/HiPS.js +26 -5
- package/lib-esm/model/hips/HiPSConfig.d.ts +13 -0
- package/lib-esm/model/hips/HiPSConfig.js +1 -0
- package/lib-esm/model/hips/Tile.d.ts +1 -0
- package/lib-esm/model/hips/Tile.js +3 -0
- package/lib-esm/model/hips/TileBuffer.d.ts +5 -0
- package/lib-esm/model/hips/TileBuffer.js +49 -0
- package/lib-esm/model/terra/TerraFootprintSetGL.d.ts +6 -0
- package/lib-esm/model/terra/TerraFootprintSetGL.js +42 -0
- package/lib-esm/utils/CoordsType.d.ts +2 -1
- package/lib-esm/utils/CoordsType.js +1 -0
- package/lib-esm/utils/GeoJSONParser.d.ts +19 -0
- package/lib-esm/utils/GeoJSONParser.js +112 -0
- package/lib-esm/utils/PerspectiveMatrixManager.js +4 -1
- package/lib-esm/utils/STCSParser.d.ts +7 -3
- package/lib-esm/utils/STCSParser.js +15 -9
- package/package.json +2 -2
package/lib-esm/AstroSphere.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import Camera from
|
|
2
|
-
import { AstroCoords, HMS, SphericalCoords, DMS } from
|
|
3
|
-
import { HiPS } from
|
|
4
|
-
import { HiPSDescriptor } from
|
|
5
|
-
import { SphereFoV } from
|
|
6
|
-
import { Point } from
|
|
7
|
-
import { CatalogueGL } from
|
|
8
|
-
import { FootprintSetGL, HoveredFootprintDetail } from
|
|
9
|
-
import { EquatorialGrid } from
|
|
10
|
-
import { HealpixGrid } from
|
|
11
|
-
import { ColorMap } from
|
|
12
|
-
import type { WMTSLayerConfig, XYZDebugStats, XYZLayerConfig } from
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
1
|
+
import Camera from "./Camera.js";
|
|
2
|
+
import { AstroCoords, HMS, SphericalCoords, DMS } from "./utils/Utils.js";
|
|
3
|
+
import { HiPS } from "./model/hips/HiPS.js";
|
|
4
|
+
import { HiPSDescriptor } from "./model/hips/HiPSDescriptor.js";
|
|
5
|
+
import { SphereFoV } from "./model/SphereFoV.js";
|
|
6
|
+
import { Point } from "./model/Point.js";
|
|
7
|
+
import { CatalogueGL } from "./model/catalogues/CatalogueGL.js";
|
|
8
|
+
import { FootprintSetGL, HoveredFootprintDetail } from "./model/footprints/FootprintSetGL.js";
|
|
9
|
+
import { EquatorialGrid } from "./model/grid/EquatorialGrid.js";
|
|
10
|
+
import { HealpixGrid } from "./model/grid/HealpixGrid.js";
|
|
11
|
+
import { ColorMap } from "./model/ColorMaps.js";
|
|
12
|
+
import type { WMTSLayerConfig, XYZDebugStats, XYZLayerConfig } from "./model/earth/XYZConfig.js";
|
|
13
|
+
import type { HiPSDebugStats } from "./model/hips/HiPSConfig.js";
|
|
14
|
+
import { XYZMapDescriptor } from "./model/earth/XYZMapDescriptor.js";
|
|
15
|
+
import { XYZMap } from "./model/earth/XYZMap.js";
|
|
15
16
|
export type PointCoordinates = {
|
|
16
17
|
astroDeg: AstroCoords;
|
|
17
18
|
raHMS: HMS;
|
|
@@ -66,6 +67,8 @@ declare class AstroSphere {
|
|
|
66
67
|
private _webgl;
|
|
67
68
|
private _selectedColorMap;
|
|
68
69
|
private _cameraStatusChanged;
|
|
70
|
+
private lastCameraChangedAt;
|
|
71
|
+
private lastCameraMotionAt;
|
|
69
72
|
private lastHoveredSource;
|
|
70
73
|
private lastHoveredCatalogue;
|
|
71
74
|
private zoomSensitivity;
|
|
@@ -107,7 +110,7 @@ declare class AstroSphere {
|
|
|
107
110
|
deleteFootprintSet(footprintSet: FootprintSetGL): void;
|
|
108
111
|
getHoveredFootprints(): HoveredFootprintDetail[];
|
|
109
112
|
goTo(raDeg: number, decDeg: number): void;
|
|
110
|
-
getActiveCoordinateMode():
|
|
113
|
+
getActiveCoordinateMode(): "equatorial" | "galactic" | "lonlat";
|
|
111
114
|
resetAxesOrientation(): void;
|
|
112
115
|
setKeepCameraNorthUp(enabled: boolean): void;
|
|
113
116
|
isKeepCameraNorthUp(): boolean;
|
|
@@ -136,6 +139,7 @@ declare class AstroSphere {
|
|
|
136
139
|
setNorthSouthRotationLocked(locked: boolean): void;
|
|
137
140
|
isNorthSouthRotationLocked(): boolean;
|
|
138
141
|
getXYZDebugStats(): XYZDebugStats;
|
|
142
|
+
getHiPSDebugStats(): HiPSDebugStats | null;
|
|
139
143
|
draw(canvas: HTMLCanvasElement): void;
|
|
140
144
|
private emitHoveredSourceIfChanged;
|
|
141
145
|
}
|
package/lib-esm/AstroSphere.js
CHANGED
|
@@ -10,25 +10,25 @@
|
|
|
10
10
|
*
|
|
11
11
|
* See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
|
|
12
12
|
*/
|
|
13
|
-
import { bootSetup } from
|
|
14
|
-
import Camera from
|
|
15
|
-
import RayPickingUtils from
|
|
16
|
-
import global from
|
|
17
|
-
import MouseHelper from
|
|
18
|
-
import { cartesianToSpherical, sphericalToAstroDeg, raDegToHMS, decDegToDMS, } from
|
|
19
|
-
import { HiPS } from
|
|
20
|
-
import { PerspectiveMatrixManager } from
|
|
21
|
-
import { Point } from
|
|
22
|
-
import { FoVUtils } from
|
|
23
|
-
import { EquatorialGrid } from
|
|
24
|
-
import { HealpixGrid } from
|
|
25
|
-
import { CoordsType } from
|
|
26
|
-
import ColorMaps from
|
|
27
|
-
import { xyzTileRequestScheduler } from
|
|
28
|
-
import { WMTSAdapter } from
|
|
29
|
-
import { XYZMapDescriptor } from
|
|
30
|
-
import { XYZMap } from
|
|
31
|
-
import { mat4, vec3, vec4 } from
|
|
13
|
+
import { bootSetup } from "./Config.js";
|
|
14
|
+
import Camera from "./Camera.js";
|
|
15
|
+
import RayPickingUtils from "./utils/RayPickingUtils.js";
|
|
16
|
+
import global from "./Global.js";
|
|
17
|
+
import MouseHelper from "./utils/MouseHelper.js";
|
|
18
|
+
import { cartesianToSpherical, sphericalToAstroDeg, raDegToHMS, decDegToDMS, } from "./utils/Utils.js";
|
|
19
|
+
import { HiPS } from "./model/hips/HiPS.js";
|
|
20
|
+
import { PerspectiveMatrixManager } from "./utils/PerspectiveMatrixManager.js";
|
|
21
|
+
import { Point } from "./model/Point.js";
|
|
22
|
+
import { FoVUtils } from "./utils/FoVUtils.js";
|
|
23
|
+
import { EquatorialGrid } from "./model/grid/EquatorialGrid.js";
|
|
24
|
+
import { HealpixGrid } from "./model/grid/HealpixGrid.js";
|
|
25
|
+
import { CoordsType } from "./utils/CoordsType.js";
|
|
26
|
+
import ColorMaps from "./model/ColorMaps.js";
|
|
27
|
+
import { xyzTileRequestScheduler } from "./model/earth/XYZTileRequestScheduler.js";
|
|
28
|
+
import { WMTSAdapter } from "./model/earth/WMTSAdapter.js";
|
|
29
|
+
import { XYZMapDescriptor } from "./model/earth/XYZMapDescriptor.js";
|
|
30
|
+
import { XYZMap } from "./model/earth/XYZMap.js";
|
|
31
|
+
import { mat4, vec3, vec4 } from "gl-matrix";
|
|
32
32
|
/**
|
|
33
33
|
* AstroSphere — main WebGL scene controller (TS port)
|
|
34
34
|
*/
|
|
@@ -62,19 +62,21 @@ class AstroSphere {
|
|
|
62
62
|
_webgl;
|
|
63
63
|
_selectedColorMap;
|
|
64
64
|
_cameraStatusChanged = false;
|
|
65
|
+
lastCameraChangedAt = 0;
|
|
66
|
+
lastCameraMotionAt = 0;
|
|
65
67
|
lastHoveredSource = null;
|
|
66
68
|
lastHoveredCatalogue = null;
|
|
67
69
|
zoomSensitivity = 1.0;
|
|
68
70
|
lockedEastWestRaDeg = null;
|
|
69
71
|
lockedNorthSouthDecDeg = null;
|
|
70
|
-
keepCameraNorthUp =
|
|
72
|
+
keepCameraNorthUp = true;
|
|
71
73
|
constructor(canvas, webgl) {
|
|
72
|
-
console.log(
|
|
74
|
+
console.log("[AstroSphere] new instance for canvas", canvas.id);
|
|
73
75
|
// Keep global GL context (as in original JS)
|
|
74
76
|
this._webgl = webgl;
|
|
75
77
|
this.mouseHelper = new MouseHelper();
|
|
76
78
|
this.canvas = canvas;
|
|
77
|
-
const nativeColorMap =
|
|
79
|
+
const nativeColorMap = "native";
|
|
78
80
|
this._selectedColorMap = ColorMaps[nativeColorMap];
|
|
79
81
|
global.insideSphere = bootSetup.insideSphere;
|
|
80
82
|
this.initCamera();
|
|
@@ -122,20 +124,26 @@ class AstroSphere {
|
|
|
122
124
|
astroDeg: astroCoords,
|
|
123
125
|
sphericalDeg: sphericalCoords,
|
|
124
126
|
raHMS: raHMS,
|
|
125
|
-
decDMS: decDMS
|
|
127
|
+
decDMS: decDMS,
|
|
126
128
|
};
|
|
127
129
|
return this.centralPoinCoords;
|
|
128
130
|
}
|
|
129
131
|
updateLastMousePoint() {
|
|
130
|
-
const sphericalCoords = {
|
|
131
|
-
|
|
132
|
+
const sphericalCoords = {
|
|
133
|
+
phi: this.mouseHelper.phi,
|
|
134
|
+
theta: this.mouseHelper.theta,
|
|
135
|
+
};
|
|
136
|
+
const astroCoords = {
|
|
137
|
+
ra: this.mouseHelper.ra,
|
|
138
|
+
dec: this.mouseHelper.dec,
|
|
139
|
+
};
|
|
132
140
|
const raHMS = this.mouseHelper.raHMS;
|
|
133
141
|
const decDMS = this.mouseHelper.decDMS;
|
|
134
142
|
this.mousePointCoords = {
|
|
135
143
|
astroDeg: astroCoords,
|
|
136
144
|
sphericalDeg: sphericalCoords,
|
|
137
145
|
raHMS: raHMS,
|
|
138
|
-
decDMS: decDMS
|
|
146
|
+
decDMS: decDMS,
|
|
139
147
|
};
|
|
140
148
|
return this.mousePointCoords;
|
|
141
149
|
}
|
|
@@ -155,9 +163,6 @@ class AstroSphere {
|
|
|
155
163
|
computeZoomStep(currentFov, deltaY) {
|
|
156
164
|
const direction = deltaY < 0 ? -1 : 1;
|
|
157
165
|
const wheelScale = this.clamp(Math.abs(deltaY) / 120, AstroSphere.MIN_WHEEL_SCALE, AstroSphere.MAX_WHEEL_SCALE);
|
|
158
|
-
// Continuous wheel response:
|
|
159
|
-
// - broad FoV stays responsive without large jumps
|
|
160
|
-
// - narrow FoV keeps a usable floor to avoid the 0.1 -> 0.02 deg stall
|
|
161
166
|
const baseMagnitude = this.clamp(0.0012 + 0.0025 * Math.sqrt(Math.max(currentFov, 0)), 0.0012, 0.04);
|
|
162
167
|
return direction * baseMagnitude * wheelScale * this.zoomSensitivity;
|
|
163
168
|
}
|
|
@@ -247,7 +252,8 @@ class AstroSphere {
|
|
|
247
252
|
};
|
|
248
253
|
}
|
|
249
254
|
enforceAstronomicalRotationLocks() {
|
|
250
|
-
if (this.lockedEastWestRaDeg == null &&
|
|
255
|
+
if (this.lockedEastWestRaDeg == null &&
|
|
256
|
+
this.lockedNorthSouthDecDeg == null) {
|
|
251
257
|
return false;
|
|
252
258
|
}
|
|
253
259
|
const center = this.updateCentralPoint();
|
|
@@ -290,7 +296,7 @@ class AstroSphere {
|
|
|
290
296
|
return;
|
|
291
297
|
// optional debug
|
|
292
298
|
// console.log('[AstroSphere] emit camera-changed:', reason);
|
|
293
|
-
this.canvas.dispatchEvent(new CustomEvent(
|
|
299
|
+
this.canvas.dispatchEvent(new CustomEvent("camera-changed", {
|
|
294
300
|
detail,
|
|
295
301
|
bubbles: true,
|
|
296
302
|
composed: true,
|
|
@@ -298,7 +304,7 @@ class AstroSphere {
|
|
|
298
304
|
}
|
|
299
305
|
addEventListeners(canvas) {
|
|
300
306
|
if (global.debug) {
|
|
301
|
-
console.log(
|
|
307
|
+
console.log("[AstroSphere::addEventListeners]");
|
|
302
308
|
}
|
|
303
309
|
const CLICK_MAX_DISTANCE_PX = 4;
|
|
304
310
|
const CLICK_MAX_DURATION_MS = 250;
|
|
@@ -328,7 +334,7 @@ class AstroSphere {
|
|
|
328
334
|
const handleMouseUp = (event) => {
|
|
329
335
|
canvas.releasePointerCapture(event.pointerId);
|
|
330
336
|
this.mouseDown = false;
|
|
331
|
-
document.body.style.cursor =
|
|
337
|
+
document.body.style.cursor = "auto";
|
|
332
338
|
if (event.button !== 0) {
|
|
333
339
|
event.preventDefault();
|
|
334
340
|
return false;
|
|
@@ -350,7 +356,7 @@ class AstroSphere {
|
|
|
350
356
|
const clickResult = cat.selectPrimarySourceFromClick(this.mouseHelper);
|
|
351
357
|
if (!clickResult?.sources.length)
|
|
352
358
|
continue;
|
|
353
|
-
this._webgl.canvas.dispatchEvent(new CustomEvent(
|
|
359
|
+
this._webgl.canvas.dispatchEvent(new CustomEvent("source-clicked", {
|
|
354
360
|
detail: {
|
|
355
361
|
source: clickResult.sources,
|
|
356
362
|
selectionState: clickResult.selectionState,
|
|
@@ -364,7 +370,7 @@ class AstroSphere {
|
|
|
364
370
|
const clickResult = fset.selectPrimaryFootprintFromClick(this.mouseHelper);
|
|
365
371
|
if (!clickResult?.footprints.length)
|
|
366
372
|
continue;
|
|
367
|
-
this._webgl.canvas.dispatchEvent(new CustomEvent(
|
|
373
|
+
this._webgl.canvas.dispatchEvent(new CustomEvent("footprint-clicked", {
|
|
368
374
|
detail: {
|
|
369
375
|
footprint: clickResult.footprints,
|
|
370
376
|
selectionState: clickResult.selectionState,
|
|
@@ -391,10 +397,13 @@ class AstroSphere {
|
|
|
391
397
|
if (!this._healpixGrid)
|
|
392
398
|
return;
|
|
393
399
|
if (this.mouseDown) {
|
|
394
|
-
document.body.style.cursor =
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
const
|
|
400
|
+
document.body.style.cursor = "grab";
|
|
401
|
+
const dragDirection = global.insideSphere ? -1 : 1;
|
|
402
|
+
const dragSpeed = global.insideSphere ? 10.0 : 1;
|
|
403
|
+
const deltaX = (dragDirection * dragSpeed * (newX - (this.lastMouseX ?? newX)) * Math.PI) /
|
|
404
|
+
canvas.width;
|
|
405
|
+
const deltaY = (dragDirection * dragSpeed * (newY - (this.lastMouseY ?? newY)) * Math.PI) /
|
|
406
|
+
canvas.height;
|
|
398
407
|
const filteredDelta = this.filterRotationDeltaByAstroLocks(deltaX, deltaY);
|
|
399
408
|
this.inertiaX += 0.1 * filteredDelta.deltaX;
|
|
400
409
|
this.inertiaY += 0.1 * filteredDelta.deltaY;
|
|
@@ -429,10 +438,11 @@ class AstroSphere {
|
|
|
429
438
|
// direction feels responsive instead of "buffered".
|
|
430
439
|
this.zoomInertia = 0;
|
|
431
440
|
this._camera.zoom(zoomStep);
|
|
441
|
+
this.lastCameraMotionAt = performance.now();
|
|
432
442
|
this.fov = this._healpixGrid.refreshFoV(this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
433
443
|
this._camera.refreshFoV(this.fov.minFoV);
|
|
434
444
|
this._cameraStatusChanged = true;
|
|
435
|
-
this.emitCameraChanged(
|
|
445
|
+
this.emitCameraChanged("wheel");
|
|
436
446
|
event.preventDefault();
|
|
437
447
|
};
|
|
438
448
|
const handleContextMenu = (event) => {
|
|
@@ -450,7 +460,7 @@ class AstroSphere {
|
|
|
450
460
|
const pickResult = cat.getSourcesFromPointer(this.mouseHelper);
|
|
451
461
|
if (!pickResult?.sources.length)
|
|
452
462
|
continue;
|
|
453
|
-
this._webgl.canvas.dispatchEvent(new CustomEvent(
|
|
463
|
+
this._webgl.canvas.dispatchEvent(new CustomEvent("source-contextmenu", {
|
|
454
464
|
detail: {
|
|
455
465
|
source: pickResult.sources,
|
|
456
466
|
catalogue: cat,
|
|
@@ -466,7 +476,7 @@ class AstroSphere {
|
|
|
466
476
|
const pickResult = fset.getFootprintsFromPointer(this.mouseHelper);
|
|
467
477
|
if (!pickResult?.footprints.length)
|
|
468
478
|
continue;
|
|
469
|
-
this._webgl.canvas.dispatchEvent(new CustomEvent(
|
|
479
|
+
this._webgl.canvas.dispatchEvent(new CustomEvent("footprint-contextmenu", {
|
|
470
480
|
detail: {
|
|
471
481
|
footprint: pickResult.footprints,
|
|
472
482
|
footprintSet: fset,
|
|
@@ -486,40 +496,40 @@ class AstroSphere {
|
|
|
486
496
|
}
|
|
487
497
|
// console.log('[AstroSphere::onKeyDown] key=', evt.key)
|
|
488
498
|
switch (evt.key) {
|
|
489
|
-
case
|
|
499
|
+
case "1":
|
|
490
500
|
// Free camera
|
|
491
501
|
this._camera.clearRotationLock();
|
|
492
502
|
break;
|
|
493
|
-
case
|
|
503
|
+
case "2":
|
|
494
504
|
// Lock X axis rotation
|
|
495
505
|
this._camera.setRotationLock({ x: true, y: false, z: false });
|
|
496
506
|
break;
|
|
497
|
-
case
|
|
507
|
+
case "3":
|
|
498
508
|
// Lock Y axis rotation
|
|
499
509
|
this._camera.setRotationLock({ x: false, y: true, z: false });
|
|
500
510
|
break;
|
|
501
|
-
case
|
|
511
|
+
case "4":
|
|
502
512
|
// Lock Z axis rotation
|
|
503
513
|
this._camera.setRotationLock({ x: false, y: false, z: true });
|
|
504
514
|
break;
|
|
505
515
|
}
|
|
506
516
|
};
|
|
507
|
-
console.log(
|
|
517
|
+
console.log("[AstroSphere] registering pointer and wheel listeners on canvas");
|
|
508
518
|
canvas.onpointerdown = handleMouseDown;
|
|
509
519
|
canvas.onpointerup = handleMouseUp;
|
|
510
520
|
canvas.onpointermove = handleMouseMove;
|
|
511
521
|
canvas.onpointerleave = () => {
|
|
512
522
|
this.clearLastMousePoint();
|
|
513
523
|
this._cameraStatusChanged = true;
|
|
514
|
-
this.emitCameraChanged(
|
|
524
|
+
this.emitCameraChanged("pointerleave");
|
|
515
525
|
};
|
|
516
|
-
console.log(
|
|
517
|
-
canvas.addEventListener(
|
|
518
|
-
canvas.addEventListener(
|
|
519
|
-
console.log(
|
|
520
|
-
document.addEventListener(
|
|
526
|
+
console.log("[AstroSphere] adding wheel event listener with passive: false");
|
|
527
|
+
canvas.addEventListener("wheel", handleMouseWheel, { passive: false });
|
|
528
|
+
canvas.addEventListener("contextmenu", handleContextMenu);
|
|
529
|
+
console.log("[AstroSphere] registering global keydown listener on document");
|
|
530
|
+
document.addEventListener("keydown", onKeyDown, { capture: true });
|
|
521
531
|
}
|
|
522
|
-
// REVIEW THIS METHOD AND MOVE IT
|
|
532
|
+
// REVIEW THIS METHOD AND MOVE IT
|
|
523
533
|
getPhiThetaDeg(canvas) {
|
|
524
534
|
const rect = canvas.getBoundingClientRect();
|
|
525
535
|
const maxX = rect.width;
|
|
@@ -546,21 +556,21 @@ class AstroSphere {
|
|
|
546
556
|
}
|
|
547
557
|
activateHiPS(hipsDescriptor) {
|
|
548
558
|
this._activeHiPS = new HiPS(1, [0.0, 0.0, 0.0], 0, 0, hipsDescriptor, this._webgl, this._healpixGrid);
|
|
549
|
-
this._activeBaseLayer =
|
|
559
|
+
this._activeBaseLayer = "hips";
|
|
550
560
|
}
|
|
551
561
|
activateXYZ(config) {
|
|
552
|
-
this.activateXYZ2(new XYZMapDescriptor(config.name ??
|
|
553
|
-
this._activeBaseLayer =
|
|
562
|
+
this.activateXYZ2(new XYZMapDescriptor(config.name ?? "XYZ Earth2 Layer", config.urlTemplate, config.minZoom ?? 0, config.maxZoom ?? 8, config.segmentsPerSide ?? 48, config.maxCachedTiles ?? 384, 8, config.urlResolver));
|
|
563
|
+
this._activeBaseLayer = "xyz";
|
|
554
564
|
}
|
|
555
565
|
activateXYZ2(config) {
|
|
556
566
|
this._activeXYZ2 = new XYZMap(1, [0.0, 0.0, 0.0], 0, 0, config, this._webgl);
|
|
557
|
-
this._activeBaseLayer =
|
|
567
|
+
this._activeBaseLayer = "xyz";
|
|
558
568
|
}
|
|
559
569
|
activateWMTS(config) {
|
|
560
570
|
const adapter = new WMTSAdapter(config);
|
|
561
571
|
const xyzConfig = adapter.toXYZLayerConfig();
|
|
562
|
-
this._activeXYZ2 = new XYZMap(1, [0.0, 0.0, 0.0], 0, 0, new XYZMapDescriptor(config.layer ? `WMTS ${config.layer}` :
|
|
563
|
-
this._activeBaseLayer =
|
|
572
|
+
this._activeXYZ2 = new XYZMap(1, [0.0, 0.0, 0.0], 0, 0, new XYZMapDescriptor(config.layer ? `WMTS ${config.layer}` : "WMTS Earth2 Layer", xyzConfig.urlTemplate, xyzConfig.minZoom ?? 0, xyzConfig.maxZoom ?? 8, xyzConfig.segmentsPerSide ?? 48, xyzConfig.maxCachedTiles ?? 384, 8, xyzConfig.urlResolver), this._webgl);
|
|
573
|
+
this._activeBaseLayer = "xyz";
|
|
564
574
|
}
|
|
565
575
|
// Catalogue section
|
|
566
576
|
async showCatalogue(cat) {
|
|
@@ -570,7 +580,7 @@ class AstroSphere {
|
|
|
570
580
|
return cat;
|
|
571
581
|
}
|
|
572
582
|
deleteCatalogue(catalogue) {
|
|
573
|
-
this.activeCatalogues = this.activeCatalogues.filter(c => c !== catalogue);
|
|
583
|
+
this.activeCatalogues = this.activeCatalogues.filter((c) => c !== catalogue);
|
|
574
584
|
}
|
|
575
585
|
// End Catalogue section
|
|
576
586
|
// Footprint section
|
|
@@ -581,11 +591,11 @@ class AstroSphere {
|
|
|
581
591
|
return fset;
|
|
582
592
|
}
|
|
583
593
|
deleteFootprintSet(footprintSet) {
|
|
584
|
-
this.activeFootprintSets = this.activeFootprintSets.filter(fst => fst !== footprintSet);
|
|
594
|
+
this.activeFootprintSets = this.activeFootprintSets.filter((fst) => fst !== footprintSet);
|
|
585
595
|
}
|
|
586
596
|
getHoveredFootprints() {
|
|
587
597
|
let footprintsHovered = [];
|
|
588
|
-
this.activeFootprintSets.forEach(fset => {
|
|
598
|
+
this.activeFootprintSets.forEach((fset) => {
|
|
589
599
|
footprintsHovered.push(fset.hoveredFootprints);
|
|
590
600
|
});
|
|
591
601
|
return footprintsHovered;
|
|
@@ -595,13 +605,13 @@ class AstroSphere {
|
|
|
595
605
|
this._camera.goTo(raDeg, decDeg);
|
|
596
606
|
}
|
|
597
607
|
getActiveCoordinateMode() {
|
|
598
|
-
if (this._activeBaseLayer ===
|
|
599
|
-
return
|
|
608
|
+
if (this._activeBaseLayer === "xyz") {
|
|
609
|
+
return "lonlat";
|
|
600
610
|
}
|
|
601
|
-
if (this._activeBaseLayer ===
|
|
602
|
-
return
|
|
611
|
+
if (this._activeBaseLayer === "hips" && this._activeHiPS?.isGalacticHips) {
|
|
612
|
+
return "galactic";
|
|
603
613
|
}
|
|
604
|
-
return
|
|
614
|
+
return "equatorial";
|
|
605
615
|
}
|
|
606
616
|
resetAxesOrientation() {
|
|
607
617
|
const center = this.updateCentralPoint();
|
|
@@ -624,7 +634,7 @@ class AstroSphere {
|
|
|
624
634
|
return this.keepCameraNorthUp;
|
|
625
635
|
}
|
|
626
636
|
getFoV() {
|
|
627
|
-
if (this._activeBaseLayer ===
|
|
637
|
+
if (this._activeBaseLayer === "xyz" && this._activeXYZ2) {
|
|
628
638
|
return this._activeXYZ2.getFoV();
|
|
629
639
|
}
|
|
630
640
|
return this.fov;
|
|
@@ -641,11 +651,15 @@ class AstroSphere {
|
|
|
641
651
|
this._camera.refreshFoV(this.fov.minFoV);
|
|
642
652
|
}
|
|
643
653
|
changeFoV2(deg) {
|
|
644
|
-
const newCameraPos = this._healpixGrid
|
|
654
|
+
const newCameraPos = this._healpixGrid
|
|
655
|
+
.getFoV()
|
|
656
|
+
.computeCameraPositionForFoV(deg);
|
|
645
657
|
this._camera.setCameraPosition(newCameraPos);
|
|
646
658
|
}
|
|
647
659
|
changeFoV3(deg) {
|
|
648
|
-
const newPos = this._healpixGrid
|
|
660
|
+
const newPos = this._healpixGrid
|
|
661
|
+
.getFoV()
|
|
662
|
+
.computeCameraPositionForAngularDiameter(deg);
|
|
649
663
|
this._camera.setCameraPosition(newPos);
|
|
650
664
|
// Recompute projection after moving the camera
|
|
651
665
|
this._perspectiveMatrixManager.computePerspectiveMatrix(this.canvas, this._camera, bootSetup.camera_fov_deg, bootSetup.camera_near_plane, false);
|
|
@@ -654,9 +668,22 @@ class AstroSphere {
|
|
|
654
668
|
return global.insideSphere;
|
|
655
669
|
}
|
|
656
670
|
toggleInsideSphere() {
|
|
671
|
+
const centerBeforeToggle = this.updateCentralPoint();
|
|
672
|
+
this.inertiaX = 0;
|
|
673
|
+
this.inertiaY = 0;
|
|
674
|
+
this.zoomInertia = 0;
|
|
657
675
|
global.insideSphere = !global.insideSphere;
|
|
658
676
|
// console.log(global.insideSphere)
|
|
659
677
|
this._camera.toggleInsideSphere();
|
|
678
|
+
this._camera.goTo(centerBeforeToggle.astroDeg.ra, centerBeforeToggle.astroDeg.dec);
|
|
679
|
+
this._perspectiveMatrixManager.computePerspectiveMatrix(this.canvas, this._camera, bootSetup.camera_fov_deg, bootSetup.camera_near_plane, global.insideSphere);
|
|
680
|
+
this.fov = this._healpixGrid.refreshFoV(this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
681
|
+
this._camera.refreshFoV(this.fov.minFoV);
|
|
682
|
+
this.updateCentralPoint();
|
|
683
|
+
this.lastCameraMotionAt = performance.now();
|
|
684
|
+
this._cameraStatusChanged = true;
|
|
685
|
+
this.emitCameraChanged("inside-sphere-toggle");
|
|
686
|
+
requestAnimationFrame(() => this.draw(this.canvas));
|
|
660
687
|
}
|
|
661
688
|
// imposta posizione camera
|
|
662
689
|
setCameraPosition(pos) {
|
|
@@ -705,7 +732,7 @@ class AstroSphere {
|
|
|
705
732
|
centralPoint: new Point({ raDeg: centralradeg, decDeg: centraldecdeg }, CoordsType.ASTRO),
|
|
706
733
|
mouseHoverPoint: this.mousePointCoords,
|
|
707
734
|
colorMap: this._selectedColorMap,
|
|
708
|
-
getFoVPolygon:
|
|
735
|
+
getFoVPolygon: [],
|
|
709
736
|
};
|
|
710
737
|
return detail;
|
|
711
738
|
// }
|
|
@@ -737,7 +764,9 @@ class AstroSphere {
|
|
|
737
764
|
this._camera.setRotationLock({ y: locked });
|
|
738
765
|
if (locked)
|
|
739
766
|
this.inertiaX = 0;
|
|
740
|
-
this.lockedEastWestRaDeg = locked
|
|
767
|
+
this.lockedEastWestRaDeg = locked
|
|
768
|
+
? (this.updateCentralPoint()?.astroDeg.ra ?? null)
|
|
769
|
+
: null;
|
|
741
770
|
}
|
|
742
771
|
isEastWestRotationLocked() {
|
|
743
772
|
return this._camera.isRotationLockedY();
|
|
@@ -746,7 +775,9 @@ class AstroSphere {
|
|
|
746
775
|
this._camera.setRotationLock({ x: locked });
|
|
747
776
|
if (locked)
|
|
748
777
|
this.inertiaY = 0;
|
|
749
|
-
this.lockedNorthSouthDecDeg = locked
|
|
778
|
+
this.lockedNorthSouthDecDeg = locked
|
|
779
|
+
? (this.updateCentralPoint()?.astroDeg.dec ?? null)
|
|
780
|
+
: null;
|
|
750
781
|
}
|
|
751
782
|
isNorthSouthRotationLocked() {
|
|
752
783
|
return this._camera.isRotationLockedX();
|
|
@@ -758,6 +789,11 @@ class AstroSphere {
|
|
|
758
789
|
requests: xyzTileRequestScheduler.getDebugStats(),
|
|
759
790
|
};
|
|
760
791
|
}
|
|
792
|
+
getHiPSDebugStats() {
|
|
793
|
+
if (!this._activeHiPS)
|
|
794
|
+
return null;
|
|
795
|
+
return this._activeHiPS.getDebugStats();
|
|
796
|
+
}
|
|
761
797
|
draw(canvas) {
|
|
762
798
|
if (this._refreshingStatus)
|
|
763
799
|
return;
|
|
@@ -783,6 +819,7 @@ class AstroSphere {
|
|
|
783
819
|
if (Math.abs(this.zoomInertia) > 0.0001) {
|
|
784
820
|
this._camera.zoom(this.zoomInertia);
|
|
785
821
|
this.zoomInertia *= 0.95;
|
|
822
|
+
this.lastCameraMotionAt = performance.now();
|
|
786
823
|
this.fov = this._healpixGrid.refreshFoV(this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
787
824
|
this._camera.refreshFoV(this.fov.minFoV);
|
|
788
825
|
if (this.prevFov !== this.fov.minFoV) {
|
|
@@ -798,7 +835,9 @@ class AstroSphere {
|
|
|
798
835
|
this._cameraStatusChanged = true;
|
|
799
836
|
}
|
|
800
837
|
// Rotation inertia
|
|
801
|
-
if (this.mouseDown ||
|
|
838
|
+
if (this.mouseDown ||
|
|
839
|
+
Math.abs(this.inertiaX) > 0.02 ||
|
|
840
|
+
Math.abs(this.inertiaY) > 0.02) {
|
|
802
841
|
cameraRotated = true;
|
|
803
842
|
const filteredInertia = this.filterRotationDeltaByAstroLocks(this.inertiaX, this.inertiaY);
|
|
804
843
|
PHI = filteredInertia.deltaX;
|
|
@@ -806,6 +845,7 @@ class AstroSphere {
|
|
|
806
845
|
this.inertiaX = filteredInertia.deltaX * 0.95;
|
|
807
846
|
this.inertiaY = filteredInertia.deltaY * 0.95;
|
|
808
847
|
this._camera.rotate(PHI, THETA);
|
|
848
|
+
this.lastCameraMotionAt = performance.now();
|
|
809
849
|
this._perspectiveMatrixManager.computePerspectiveMatrix(canvas, this._camera, bootSetup.camera_fov_deg, bootSetup.camera_near_plane, global.insideSphere);
|
|
810
850
|
const lockCorrected = this.enforceAstronomicalRotationLocks();
|
|
811
851
|
if (!lockCorrected) {
|
|
@@ -816,6 +856,12 @@ class AstroSphere {
|
|
|
816
856
|
this.inertiaY = 0;
|
|
817
857
|
this.inertiaX = 0;
|
|
818
858
|
}
|
|
859
|
+
const nextFoV = this._healpixGrid.refreshFoV(this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
860
|
+
if (Number.isFinite(nextFoV.minFoV) && nextFoV.minFoV > 0) {
|
|
861
|
+
this.fov = nextFoV;
|
|
862
|
+
this._camera.refreshFoV(this.fov.minFoV);
|
|
863
|
+
this.prevFov = this.fov.minFoV;
|
|
864
|
+
}
|
|
819
865
|
// Se la camera è ruotata (anche solo per inerzia), aggiorna punto centrale + emetti cameraChanged
|
|
820
866
|
if (cameraRotated) {
|
|
821
867
|
// Ricalcola il punto centrale
|
|
@@ -833,16 +879,20 @@ class AstroSphere {
|
|
|
833
879
|
}
|
|
834
880
|
}
|
|
835
881
|
if (this._cameraStatusChanged) {
|
|
836
|
-
const
|
|
882
|
+
const now = performance.now();
|
|
883
|
+
const shouldEmitCameraChanged = !this.mouseDown || now - this.lastCameraChangedAt > 100;
|
|
884
|
+
const detail = shouldEmitCameraChanged ? this.getCurrentStatus() : null;
|
|
837
885
|
if (detail) {
|
|
838
886
|
// console.log('[AstroSphere::draw] emitting camera-changed event due to camera status change', detail)
|
|
839
887
|
// console.log('[AstroSphere::draw] inertia', this.zoomInertia, this.inertiaX, this.inertiaY)
|
|
840
|
-
this.canvas.dispatchEvent(new CustomEvent(
|
|
888
|
+
this.canvas.dispatchEvent(new CustomEvent("camera-changed", {
|
|
841
889
|
detail,
|
|
842
|
-
bubbles: true,
|
|
890
|
+
bubbles: true,
|
|
891
|
+
composed: true,
|
|
843
892
|
}));
|
|
893
|
+
this.lastCameraChangedAt = now;
|
|
844
894
|
}
|
|
845
|
-
if (!this.startup) {
|
|
895
|
+
if (!this.startup && shouldEmitCameraChanged) {
|
|
846
896
|
this._cameraStatusChanged = false;
|
|
847
897
|
}
|
|
848
898
|
}
|
|
@@ -852,23 +902,39 @@ class AstroSphere {
|
|
|
852
902
|
this._webgl.enable(this._webgl.CULL_FACE);
|
|
853
903
|
this._webgl.cullFace(global.insideSphere ? this._webgl.FRONT : this._webgl.BACK);
|
|
854
904
|
this._webgl.blendFunc(this._webgl.SRC_ALPHA, this._webgl.ONE_MINUS_SRC_ALPHA);
|
|
855
|
-
if (this._activeBaseLayer ===
|
|
905
|
+
if (this._activeBaseLayer === "hips" && this._activeHiPS) {
|
|
856
906
|
const visibleOrder = Math.min(this._healpixGrid.visibleorder, this._activeHiPS.maxOrder);
|
|
857
907
|
this._healpixGrid.visibleTilesManager.computeVisiblePixels(visibleOrder, this._webgl, this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
858
908
|
}
|
|
859
909
|
// DRAW HiPS
|
|
910
|
+
const stableFovDeg = this.fov?.minFoV ?? this._healpixGrid.getMinFoV();
|
|
911
|
+
const nowForGrid = performance.now();
|
|
912
|
+
const cameraMovingForGrid = this.mouseDown ||
|
|
913
|
+
Math.abs(this.zoomInertia) > 0.0001 ||
|
|
914
|
+
Math.abs(this.inertiaX) > 0.02 ||
|
|
915
|
+
Math.abs(this.inertiaY) > 0.02 ||
|
|
916
|
+
nowForGrid - this.lastCameraMotionAt < 220;
|
|
917
|
+
// const skyEntityDrawInput: SkyEntityDrawInput = {
|
|
918
|
+
// fovDeg: this._healpixGrid.getMinFoV(),
|
|
919
|
+
// camera: this._camera,
|
|
920
|
+
// pMatrix: this._perspectiveMatrixManager.pMatrix,
|
|
921
|
+
// centerSphericalDeg: this.updateCentralPoint().sphericalDeg,
|
|
922
|
+
// fovPolygon: this._activeBaseLayer === 'xyz' ? this.getFoVPolygon() : undefined,
|
|
923
|
+
// viewportSphericalSamples: this._activeBaseLayer === 'xyz' ? this.collectViewportSphericalSamples(7) : undefined,
|
|
924
|
+
// }
|
|
860
925
|
const skyEntityDrawInput = {
|
|
861
|
-
fovDeg:
|
|
926
|
+
fovDeg: stableFovDeg,
|
|
862
927
|
camera: this._camera,
|
|
863
928
|
pMatrix: this._perspectiveMatrixManager.pMatrix,
|
|
864
929
|
centerSphericalDeg: this.updateCentralPoint().sphericalDeg,
|
|
865
|
-
fovPolygon:
|
|
866
|
-
viewportSphericalSamples:
|
|
930
|
+
fovPolygon: undefined,
|
|
931
|
+
viewportSphericalSamples: undefined,
|
|
932
|
+
cameraMoving: cameraMovingForGrid,
|
|
867
933
|
};
|
|
868
|
-
if (this._activeBaseLayer ===
|
|
934
|
+
if (this._activeBaseLayer === "hips") {
|
|
869
935
|
this._activeHiPS?.draw(skyEntityDrawInput);
|
|
870
936
|
}
|
|
871
|
-
if (this._activeBaseLayer ===
|
|
937
|
+
if (this._activeBaseLayer === "xyz") {
|
|
872
938
|
this._activeXYZ2?.draw(skyEntityDrawInput);
|
|
873
939
|
}
|
|
874
940
|
this._healpixGrid.draw(skyEntityDrawInput);
|
|
@@ -881,24 +947,27 @@ class AstroSphere {
|
|
|
881
947
|
const raDecDeg = sphericalToAstroDeg(phiTheta.phi, phiTheta.theta);
|
|
882
948
|
const raHMS = raDegToHMS(raDecDeg.ra);
|
|
883
949
|
const decDMS = decDegToDMS(raDecDeg.dec);
|
|
884
|
-
this.prevFov = this._healpixGrid.getMinFoV();
|
|
950
|
+
// this.prevFov = this._healpixGrid.getMinFoV();
|
|
951
|
+
this.prevFov = this.fov?.minFoV ?? this._healpixGrid.getMinFoV();
|
|
885
952
|
this._cameraStatusChanged = true;
|
|
886
|
-
console.log(
|
|
953
|
+
console.log("(startup coords)", {
|
|
887
954
|
raDeg: raDecDeg.ra,
|
|
888
955
|
decDeg: raDecDeg.dec,
|
|
889
956
|
raHMS,
|
|
890
957
|
decDMS,
|
|
891
958
|
});
|
|
892
959
|
}
|
|
893
|
-
this.activeCatalogues.forEach(cat => {
|
|
894
|
-
const activeModelMatrix = this._activeHiPS?.getModelMatrix() ??
|
|
960
|
+
this.activeCatalogues.forEach((cat) => {
|
|
961
|
+
const activeModelMatrix = this._activeHiPS?.getModelMatrix() ??
|
|
962
|
+
this._activeXYZ2?.getModelMatrix();
|
|
895
963
|
if (activeModelMatrix) {
|
|
896
964
|
cat.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
897
965
|
}
|
|
898
966
|
});
|
|
899
967
|
this.emitHoveredSourceIfChanged();
|
|
900
|
-
this.activeFootprintSets.forEach(fst => {
|
|
901
|
-
const activeModelMatrix = this._activeHiPS?.getModelMatrix() ??
|
|
968
|
+
this.activeFootprintSets.forEach((fst) => {
|
|
969
|
+
const activeModelMatrix = this._activeHiPS?.getModelMatrix() ??
|
|
970
|
+
this._activeXYZ2?.getModelMatrix();
|
|
902
971
|
if (activeModelMatrix) {
|
|
903
972
|
fst.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
904
973
|
}
|
|
@@ -915,13 +984,13 @@ class AstroSphere {
|
|
|
915
984
|
nextHoveredCatalogue = cat;
|
|
916
985
|
break;
|
|
917
986
|
}
|
|
918
|
-
const unchanged = nextHoveredSource === this.lastHoveredSource
|
|
919
|
-
|
|
987
|
+
const unchanged = nextHoveredSource === this.lastHoveredSource &&
|
|
988
|
+
nextHoveredCatalogue === this.lastHoveredCatalogue;
|
|
920
989
|
if (unchanged)
|
|
921
990
|
return;
|
|
922
991
|
this.lastHoveredSource = nextHoveredSource;
|
|
923
992
|
this.lastHoveredCatalogue = nextHoveredCatalogue;
|
|
924
|
-
this._webgl.canvas.dispatchEvent(new CustomEvent(
|
|
993
|
+
this._webgl.canvas.dispatchEvent(new CustomEvent("source-hovered", {
|
|
925
994
|
detail: { source: nextHoveredSource, catalogue: nextHoveredCatalogue },
|
|
926
995
|
bubbles: true,
|
|
927
996
|
composed: true,
|