astro-viewer 3.6.0 → 3.7.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/64.astroviewer.cjs +37 -0
- package/dist/64.astroviewer.cjs.map +1 -0
- package/dist/64.astroviewer.js +41 -0
- package/dist/64.astroviewer.js.map +1 -0
- package/dist/64.astroviewer.min.js +2 -0
- package/dist/64.astroviewer.min.js.map +1 -0
- package/dist/911.astroviewer.cjs +4047 -0
- package/dist/911.astroviewer.cjs.map +1 -0
- package/dist/911.astroviewer.js +735 -0
- package/dist/911.astroviewer.js.map +1 -0
- package/dist/911.astroviewer.min.js +2 -0
- package/dist/911.astroviewer.min.js.map +1 -0
- package/dist/astroviewer.cjs +2704 -510
- package/dist/astroviewer.cjs.map +1 -1
- package/dist/astroviewer.js +2861 -512
- package/dist/astroviewer.js.map +1 -1
- package/dist/astroviewer.min.js +1 -1
- package/dist/astroviewer.min.js.map +1 -1
- package/lib-esm/AstroSphere.d.ts +1 -1
- package/lib-esm/AstroSphere.d.ts.map +1 -1
- package/lib-esm/AstroSphere.js +15 -25
- package/lib-esm/AstroSphere.js.map +1 -1
- package/lib-esm/AstroViewer.d.ts +25 -23
- package/lib-esm/AstroViewer.d.ts.map +1 -1
- package/lib-esm/AstroViewer.js +97 -67
- package/lib-esm/AstroViewer.js.map +1 -1
- package/lib-esm/model/hips/AllSky.d.ts +7 -3
- package/lib-esm/model/hips/AllSky.d.ts.map +1 -1
- package/lib-esm/model/hips/AllSky.js +93 -28
- package/lib-esm/model/hips/AllSky.js.map +1 -1
- package/lib-esm/model/hips/AncestorTile.d.ts +7 -4
- package/lib-esm/model/hips/AncestorTile.d.ts.map +1 -1
- package/lib-esm/model/hips/AncestorTile.js +91 -52
- package/lib-esm/model/hips/AncestorTile.js.map +1 -1
- package/lib-esm/model/hips/FitsTileLoader.d.ts +9 -0
- package/lib-esm/model/hips/FitsTileLoader.d.ts.map +1 -0
- package/lib-esm/model/hips/FitsTileLoader.js +65 -0
- package/lib-esm/model/hips/FitsTileLoader.js.map +1 -0
- package/lib-esm/model/hips/HiPS.d.ts +9 -5
- package/lib-esm/model/hips/HiPS.d.ts.map +1 -1
- package/lib-esm/model/hips/HiPS.js +120 -72
- package/lib-esm/model/hips/HiPS.js.map +1 -1
- package/lib-esm/model/hips/HiPSCoverage.d.ts +15 -0
- package/lib-esm/model/hips/HiPSCoverage.d.ts.map +1 -0
- package/lib-esm/model/hips/HiPSCoverage.js +148 -0
- package/lib-esm/model/hips/HiPSCoverage.js.map +1 -0
- package/lib-esm/model/hips/Tile.d.ts +8 -4
- package/lib-esm/model/hips/Tile.d.ts.map +1 -1
- package/lib-esm/model/hips/Tile.js +111 -55
- package/lib-esm/model/hips/Tile.js.map +1 -1
- package/lib-esm/model/hips/TileBuffer.d.ts +13 -4
- package/lib-esm/model/hips/TileBuffer.d.ts.map +1 -1
- package/lib-esm/model/hips/TileBuffer.js +46 -11
- package/lib-esm/model/hips/TileBuffer.js.map +1 -1
- package/lib-esm/model/hips/VisibleTilesManager.d.ts +5 -5
- package/lib-esm/model/hips/VisibleTilesManager.d.ts.map +1 -1
- package/lib-esm/model/hips/VisibleTilesManager.js +6 -20
- package/lib-esm/model/hips/VisibleTilesManager.js.map +1 -1
- package/lib-esm/shader/HiPSShaderProgram.d.ts +9 -2
- package/lib-esm/shader/HiPSShaderProgram.d.ts.map +1 -1
- package/lib-esm/shader/HiPSShaderProgram.js +91 -53
- package/lib-esm/shader/HiPSShaderProgram.js.map +1 -1
- package/lib-esm/shader/ShaderManager.d.ts +2 -0
- package/lib-esm/shader/ShaderManager.d.ts.map +1 -1
- package/lib-esm/shader/ShaderManager.js +193 -94
- package/lib-esm/shader/ShaderManager.js.map +1 -1
- package/package.json +3 -3
package/dist/astroviewer.js
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
root["astroviewer"] = factory();
|
|
10
10
|
})(self, () => {
|
|
11
11
|
return /******/ (() => { // webpackBootstrap
|
|
12
|
-
/******/ "use strict";
|
|
13
12
|
/******/ var __webpack_modules__ = ({
|
|
14
13
|
|
|
15
14
|
/***/ 3890
|
|
16
15
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
17
16
|
|
|
17
|
+
"use strict";
|
|
18
18
|
|
|
19
19
|
// EXPORTS
|
|
20
20
|
__webpack_require__.d(__webpack_exports__, {
|
|
@@ -3578,6 +3578,7 @@ var vec4_forEach = function () {
|
|
|
3578
3578
|
/***/ 4723
|
|
3579
3579
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
3580
3580
|
|
|
3581
|
+
"use strict";
|
|
3581
3582
|
|
|
3582
3583
|
/*
|
|
3583
3584
|
* AstroViewer
|
|
@@ -3990,9 +3991,15 @@ class AstroSphere {
|
|
|
3990
3991
|
document.body.style.cursor = "grab";
|
|
3991
3992
|
const dragDirection = Global_js_1.default.insideSphere ? -1 : 1;
|
|
3992
3993
|
const dragSpeed = Global_js_1.default.insideSphere ? 10.0 : 1;
|
|
3993
|
-
const deltaX = (dragDirection *
|
|
3994
|
+
const deltaX = (dragDirection *
|
|
3995
|
+
dragSpeed *
|
|
3996
|
+
(newX - (this.lastMouseX ?? newX)) *
|
|
3997
|
+
Math.PI) /
|
|
3994
3998
|
canvas.width;
|
|
3995
|
-
const deltaY = (dragDirection *
|
|
3999
|
+
const deltaY = (dragDirection *
|
|
4000
|
+
dragSpeed *
|
|
4001
|
+
(newY - (this.lastMouseY ?? newY)) *
|
|
4002
|
+
Math.PI) /
|
|
3996
4003
|
canvas.height;
|
|
3997
4004
|
const filteredDelta = this.filterRotationDeltaByAstroLocks(deltaX, deltaY);
|
|
3998
4005
|
this.inertiaX += 0.1 * filteredDelta.deltaX;
|
|
@@ -4127,24 +4134,16 @@ class AstroSphere {
|
|
|
4127
4134
|
const pickerPoint = RayPickingUtils_js_1.default.getIntersectionPointWithSingleModel(maxX / 2, maxY / 2, this._healpixGrid, this._webgl, this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
4128
4135
|
return (0, Utils_js_1.cartesianToSpherical)(pickerPoint);
|
|
4129
4136
|
}
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
const height = rect.height;
|
|
4134
|
-
const samples = [];
|
|
4135
|
-
for (let ix = 0; ix < sampleCount; ix++) {
|
|
4136
|
-
const x = sampleCount === 1 ? width / 2 : (ix / (sampleCount - 1)) * width;
|
|
4137
|
-
for (let iy = 0; iy < sampleCount; iy++) {
|
|
4138
|
-
const y = sampleCount === 1 ? height / 2 : (iy / (sampleCount - 1)) * height;
|
|
4139
|
-
const hit = RayPickingUtils_js_1.default.getIntersectionPointWithSingleModel(x, y, this._healpixGrid, this._webgl, this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
4140
|
-
if (hit && hit.length > 0) {
|
|
4141
|
-
samples.push((0, Utils_js_1.cartesianToSpherical)(hit));
|
|
4142
|
-
}
|
|
4143
|
-
}
|
|
4137
|
+
changeHiPSFormat(format) {
|
|
4138
|
+
if (!this._activeHiPS) {
|
|
4139
|
+
throw new Error("No active HiPS.");
|
|
4144
4140
|
}
|
|
4145
|
-
|
|
4141
|
+
this._activeHiPS.changeFormat(format);
|
|
4146
4142
|
}
|
|
4147
4143
|
activateHiPS(hipsDescriptor) {
|
|
4144
|
+
if (this._activeHiPS) {
|
|
4145
|
+
this._healpixGrid.visibleTilesManager.tileBuffer.removeHiPS(this._activeHiPS);
|
|
4146
|
+
}
|
|
4148
4147
|
this._activeHiPS = new HiPS_js_1.HiPS(1, [0.0, 0.0, 0.0], 0, 0, hipsDescriptor, this._webgl, this._healpixGrid);
|
|
4149
4148
|
this._activeBaseLayer = "hips";
|
|
4150
4149
|
}
|
|
@@ -4554,14 +4553,6 @@ class AstroSphere {
|
|
|
4554
4553
|
Math.abs(this.inertiaX) > 0.02 ||
|
|
4555
4554
|
Math.abs(this.inertiaY) > 0.02 ||
|
|
4556
4555
|
nowForGrid - this.lastCameraMotionAt < 220;
|
|
4557
|
-
// const skyEntityDrawInput: SkyEntityDrawInput = {
|
|
4558
|
-
// fovDeg: this._healpixGrid.getMinFoV(),
|
|
4559
|
-
// camera: this._camera,
|
|
4560
|
-
// pMatrix: this._perspectiveMatrixManager.pMatrix,
|
|
4561
|
-
// centerSphericalDeg: this.updateCentralPoint().sphericalDeg,
|
|
4562
|
-
// fovPolygon: this._activeBaseLayer === 'xyz' ? this.getFoVPolygon() : undefined,
|
|
4563
|
-
// viewportSphericalSamples: this._activeBaseLayer === 'xyz' ? this.collectViewportSphericalSamples(7) : undefined,
|
|
4564
|
-
// }
|
|
4565
4556
|
const skyEntityDrawInput = {
|
|
4566
4557
|
fovDeg: stableFovDeg,
|
|
4567
4558
|
camera: this._camera,
|
|
@@ -4674,6 +4665,7 @@ exports["default"] = AstroSphere;
|
|
|
4674
4665
|
/***/ 772
|
|
4675
4666
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
4676
4667
|
|
|
4668
|
+
"use strict";
|
|
4677
4669
|
|
|
4678
4670
|
/*
|
|
4679
4671
|
* AstroViewer
|
|
@@ -4713,7 +4705,7 @@ class AstroViewer {
|
|
|
4713
4705
|
webglContextList = new Map();
|
|
4714
4706
|
viewfinderEl = null;
|
|
4715
4707
|
viewfinderVisible = Config_js_1.bootSetup.showViewfinder;
|
|
4716
|
-
viewfinderColor =
|
|
4708
|
+
viewfinderColor = "rgba(75,148,226,0.68)";
|
|
4717
4709
|
options = {};
|
|
4718
4710
|
// API
|
|
4719
4711
|
run() {
|
|
@@ -4851,7 +4843,7 @@ class AstroViewer {
|
|
|
4851
4843
|
this.astroSphere.activateXYZ(config);
|
|
4852
4844
|
}
|
|
4853
4845
|
activateXYZ2(config) {
|
|
4854
|
-
const descriptor = new XYZMapDescriptor_js_1.XYZMapDescriptor(config.name ??
|
|
4846
|
+
const descriptor = new XYZMapDescriptor_js_1.XYZMapDescriptor(config.name ?? "XYZ Earth2 Layer", config.urlTemplate, config.minZoom ?? 0, config.maxZoom ?? 8, config.segmentsPerSide ?? 48, config.maxCachedTiles ?? 384, 8, config.urlResolver);
|
|
4855
4847
|
this.astroSphere.activateXYZ2(descriptor);
|
|
4856
4848
|
}
|
|
4857
4849
|
activateWMTS(config) {
|
|
@@ -4876,8 +4868,8 @@ class AstroViewer {
|
|
|
4876
4868
|
return this.astroSphere.getMeshHiPSDebugStats();
|
|
4877
4869
|
}
|
|
4878
4870
|
async loadHiPS(baseUrl) {
|
|
4879
|
-
const hipsUrl = baseUrl.endsWith(
|
|
4880
|
-
const resp = await fetch(hipsUrl +
|
|
4871
|
+
const hipsUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/";
|
|
4872
|
+
const resp = await fetch(hipsUrl + "properties");
|
|
4881
4873
|
if (!resp.ok)
|
|
4882
4874
|
throw new Error(`HTTP ${resp.status} fetching properties`);
|
|
4883
4875
|
const propsText = await resp.text();
|
|
@@ -4887,20 +4879,20 @@ class AstroViewer {
|
|
|
4887
4879
|
// this.activateHiPS(desc);
|
|
4888
4880
|
}
|
|
4889
4881
|
async loadMeshHiPS(baseUrl, config = {}) {
|
|
4890
|
-
const meshHiPSUrl = baseUrl.endsWith(
|
|
4891
|
-
let propsText =
|
|
4892
|
-
const resp = await fetch(meshHiPSUrl +
|
|
4882
|
+
const meshHiPSUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/";
|
|
4883
|
+
let propsText = "";
|
|
4884
|
+
const resp = await fetch(meshHiPSUrl + "properties");
|
|
4893
4885
|
if (resp.ok) {
|
|
4894
4886
|
propsText = await resp.text();
|
|
4895
4887
|
}
|
|
4896
4888
|
else {
|
|
4897
|
-
const jsonResp = await fetch(meshHiPSUrl +
|
|
4889
|
+
const jsonResp = await fetch(meshHiPSUrl + "properties.json");
|
|
4898
4890
|
if (!jsonResp.ok)
|
|
4899
4891
|
throw new Error(`HTTP ${jsonResp.status} fetching MeshHiPS properties`);
|
|
4900
4892
|
const json = await jsonResp.json();
|
|
4901
4893
|
propsText = Object.entries(json)
|
|
4902
4894
|
.map(([key, value]) => `${key}=${String(value)}`)
|
|
4903
|
-
.join(
|
|
4895
|
+
.join("\n");
|
|
4904
4896
|
}
|
|
4905
4897
|
const desc = new MeshHiPSDescriptor_js_1.MeshHiPSDescriptor({ ...config, baseUrl: meshHiPSUrl }, propsText);
|
|
4906
4898
|
this.astroSphere.activateMeshHiPS(desc);
|
|
@@ -4918,6 +4910,12 @@ class AstroViewer {
|
|
|
4918
4910
|
getActiveHiPS() {
|
|
4919
4911
|
return this.astroSphere.activeHiPS;
|
|
4920
4912
|
}
|
|
4913
|
+
changeHiPSFormat(format) {
|
|
4914
|
+
this.astroSphere.changeHiPSFormat(format);
|
|
4915
|
+
}
|
|
4916
|
+
getActiveHiPSFormats() {
|
|
4917
|
+
return this.astroSphere.activeHiPS?.availableFormats ?? [];
|
|
4918
|
+
}
|
|
4921
4919
|
getActiveXYZ() {
|
|
4922
4920
|
return this.astroSphere.activeXYZ;
|
|
4923
4921
|
}
|
|
@@ -5005,13 +5003,13 @@ class AstroViewer {
|
|
|
5005
5003
|
return this.astroSphere.getFoVPolygon();
|
|
5006
5004
|
}
|
|
5007
5005
|
changeFoV(deg) {
|
|
5008
|
-
this, this.astroSphere.changeFoV(deg);
|
|
5006
|
+
(this, this.astroSphere.changeFoV(deg));
|
|
5009
5007
|
}
|
|
5010
5008
|
changeFoV2(deg) {
|
|
5011
|
-
this, this.astroSphere.changeFoV2(deg);
|
|
5009
|
+
(this, this.astroSphere.changeFoV2(deg));
|
|
5012
5010
|
}
|
|
5013
5011
|
changeFoV3(deg) {
|
|
5014
|
-
this, this.astroSphere.changeFoV3(deg);
|
|
5012
|
+
(this, this.astroSphere.changeFoV3(deg));
|
|
5015
5013
|
}
|
|
5016
5014
|
getInsideSphere() {
|
|
5017
5015
|
return this.astroSphere.getInsideSphere();
|
|
@@ -5057,13 +5055,13 @@ class AstroViewer {
|
|
|
5057
5055
|
this.webglContextList = new Map();
|
|
5058
5056
|
}
|
|
5059
5057
|
init(canvasEl) {
|
|
5060
|
-
console.log(
|
|
5058
|
+
console.log("init webgl");
|
|
5061
5059
|
this.canvas = canvasEl;
|
|
5062
5060
|
this.initViewfinder();
|
|
5063
|
-
const gl = this.canvas.getContext(
|
|
5061
|
+
const gl = this.canvas.getContext("webgl2", { alpha: false });
|
|
5064
5062
|
if (!gl) {
|
|
5065
|
-
alert(
|
|
5066
|
-
throw new Error(
|
|
5063
|
+
alert("Could not initialise WebGL, sorry :-(");
|
|
5064
|
+
throw new Error("WebGL2 not available");
|
|
5067
5065
|
}
|
|
5068
5066
|
// Extend with custom fields used elsewhere
|
|
5069
5067
|
this.webgl = gl;
|
|
@@ -5074,7 +5072,7 @@ class AstroViewer {
|
|
|
5074
5072
|
this.webgl.clearColor(0 * 0.00392156862, 16 * 0.00392156862, 50 * 0.00392156862, 0.7);
|
|
5075
5073
|
}
|
|
5076
5074
|
catch (e) {
|
|
5077
|
-
console.log(
|
|
5075
|
+
console.log("Error instantiating WebGL context");
|
|
5078
5076
|
}
|
|
5079
5077
|
this.initListeners();
|
|
5080
5078
|
// ; (global as any).gl = this.webgl
|
|
@@ -5086,40 +5084,64 @@ class AstroViewer {
|
|
|
5086
5084
|
const parent = this.canvas.parentElement;
|
|
5087
5085
|
if (!parent)
|
|
5088
5086
|
return;
|
|
5089
|
-
if (window.getComputedStyle(parent).position ===
|
|
5090
|
-
parent.style.position =
|
|
5091
|
-
}
|
|
5092
|
-
const viewfinder = document.createElement(
|
|
5093
|
-
viewfinder.setAttribute(
|
|
5094
|
-
viewfinder.setAttribute(
|
|
5095
|
-
viewfinder.style.position =
|
|
5096
|
-
viewfinder.style.left =
|
|
5097
|
-
viewfinder.style.top =
|
|
5098
|
-
viewfinder.style.width =
|
|
5099
|
-
viewfinder.style.height =
|
|
5100
|
-
viewfinder.style.transform =
|
|
5101
|
-
viewfinder.style.pointerEvents =
|
|
5102
|
-
viewfinder.style.zIndex =
|
|
5103
|
-
viewfinder.style.boxSizing =
|
|
5087
|
+
if (window.getComputedStyle(parent).position === "static") {
|
|
5088
|
+
parent.style.position = "relative";
|
|
5089
|
+
}
|
|
5090
|
+
const viewfinder = document.createElement("div");
|
|
5091
|
+
viewfinder.setAttribute("data-astro-viewfinder", "true");
|
|
5092
|
+
viewfinder.setAttribute("aria-hidden", "true");
|
|
5093
|
+
viewfinder.style.position = "absolute";
|
|
5094
|
+
viewfinder.style.left = "50%";
|
|
5095
|
+
viewfinder.style.top = "50%";
|
|
5096
|
+
viewfinder.style.width = "44px";
|
|
5097
|
+
viewfinder.style.height = "44px";
|
|
5098
|
+
viewfinder.style.transform = "translate(-50%, -50%)";
|
|
5099
|
+
viewfinder.style.pointerEvents = "none";
|
|
5100
|
+
viewfinder.style.zIndex = "1";
|
|
5101
|
+
viewfinder.style.boxSizing = "border-box";
|
|
5104
5102
|
const segments = [
|
|
5105
|
-
{
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5103
|
+
{
|
|
5104
|
+
left: "50%",
|
|
5105
|
+
top: "7px",
|
|
5106
|
+
width: "1px",
|
|
5107
|
+
height: "11px",
|
|
5108
|
+
transform: "translateX(-50%)",
|
|
5109
|
+
},
|
|
5110
|
+
{
|
|
5111
|
+
left: "50%",
|
|
5112
|
+
bottom: "7px",
|
|
5113
|
+
width: "1px",
|
|
5114
|
+
height: "11px",
|
|
5115
|
+
transform: "translateX(-50%)",
|
|
5116
|
+
},
|
|
5117
|
+
{
|
|
5118
|
+
left: "7px",
|
|
5119
|
+
top: "50%",
|
|
5120
|
+
width: "11px",
|
|
5121
|
+
height: "1px",
|
|
5122
|
+
transform: "translateY(-50%)",
|
|
5123
|
+
},
|
|
5124
|
+
{
|
|
5125
|
+
right: "7px",
|
|
5126
|
+
top: "50%",
|
|
5127
|
+
width: "11px",
|
|
5128
|
+
height: "1px",
|
|
5129
|
+
transform: "translateY(-50%)",
|
|
5130
|
+
},
|
|
5109
5131
|
];
|
|
5110
5132
|
for (const segmentDef of segments) {
|
|
5111
|
-
const segment = document.createElement(
|
|
5112
|
-
segment.style.position =
|
|
5113
|
-
segment.style.left = segmentDef.left ??
|
|
5114
|
-
segment.style.right = segmentDef.right ??
|
|
5115
|
-
segment.style.top = segmentDef.top ??
|
|
5116
|
-
segment.style.bottom = segmentDef.bottom ??
|
|
5133
|
+
const segment = document.createElement("div");
|
|
5134
|
+
segment.style.position = "absolute";
|
|
5135
|
+
segment.style.left = segmentDef.left ?? "auto";
|
|
5136
|
+
segment.style.right = segmentDef.right ?? "auto";
|
|
5137
|
+
segment.style.top = segmentDef.top ?? "auto";
|
|
5138
|
+
segment.style.bottom = segmentDef.bottom ?? "auto";
|
|
5117
5139
|
segment.style.width = segmentDef.width;
|
|
5118
5140
|
segment.style.height = segmentDef.height;
|
|
5119
5141
|
segment.style.transform = segmentDef.transform;
|
|
5120
|
-
segment.style.background =
|
|
5121
|
-
segment.style.borderRadius =
|
|
5122
|
-
segment.style.boxShadow =
|
|
5142
|
+
segment.style.background = "currentColor";
|
|
5143
|
+
segment.style.borderRadius = "999px";
|
|
5144
|
+
segment.style.boxShadow = "0 0 0 1px rgba(0, 0, 0, 0.14)";
|
|
5123
5145
|
viewfinder.appendChild(segment);
|
|
5124
5146
|
}
|
|
5125
5147
|
parent.appendChild(viewfinder);
|
|
@@ -5130,7 +5152,7 @@ class AstroViewer {
|
|
|
5130
5152
|
syncViewfinderVisibility() {
|
|
5131
5153
|
if (!this.viewfinderEl)
|
|
5132
5154
|
return;
|
|
5133
|
-
this.viewfinderEl.style.display = this.viewfinderVisible ?
|
|
5155
|
+
this.viewfinderEl.style.display = this.viewfinderVisible ? "block" : "none";
|
|
5134
5156
|
}
|
|
5135
5157
|
syncViewfinderColor() {
|
|
5136
5158
|
if (!this.viewfinderEl)
|
|
@@ -5138,9 +5160,9 @@ class AstroViewer {
|
|
|
5138
5160
|
this.viewfinderEl.style.color = this.viewfinderColor;
|
|
5139
5161
|
}
|
|
5140
5162
|
initListeners() {
|
|
5141
|
-
console.log(
|
|
5163
|
+
console.log("inside initListeners");
|
|
5142
5164
|
const resizeCanvas = () => {
|
|
5143
|
-
console.log(
|
|
5165
|
+
console.log("[resizeCanvas]");
|
|
5144
5166
|
const rect = this.canvas.getBoundingClientRect();
|
|
5145
5167
|
const dpr = window.devicePixelRatio || 1;
|
|
5146
5168
|
const newWidth = Math.max(1, Math.floor(rect.width * dpr));
|
|
@@ -5154,7 +5176,7 @@ class AstroViewer {
|
|
|
5154
5176
|
}
|
|
5155
5177
|
};
|
|
5156
5178
|
const handleContextLost = (event) => {
|
|
5157
|
-
console.log(
|
|
5179
|
+
console.log("[handleContextLost]");
|
|
5158
5180
|
event.preventDefault();
|
|
5159
5181
|
if (this.rafId !== null) {
|
|
5160
5182
|
cancelAnimationFrame(this.rafId);
|
|
@@ -5162,7 +5184,7 @@ class AstroViewer {
|
|
|
5162
5184
|
}
|
|
5163
5185
|
};
|
|
5164
5186
|
const handleContextRestored = (_event) => {
|
|
5165
|
-
console.log(
|
|
5187
|
+
console.log("[handleContextRestored]");
|
|
5166
5188
|
// this.webgl.viewportWidth = this.canvas.width
|
|
5167
5189
|
// this.webgl.viewportHeight = this.canvas.height
|
|
5168
5190
|
this.webgl.clearColor(0 * 0.00392156862, 16 * 0.00392156862, 50 * 0.00392156862, 0.7);
|
|
@@ -5170,16 +5192,16 @@ class AstroViewer {
|
|
|
5170
5192
|
this.rafId = requestAnimationFrame(() => this.tick());
|
|
5171
5193
|
};
|
|
5172
5194
|
// 🔥 ResizeObserver per pannelli / split / layout dinamici
|
|
5173
|
-
if (
|
|
5195
|
+
if ("ResizeObserver" in window) {
|
|
5174
5196
|
const ro = new ResizeObserver(() => {
|
|
5175
5197
|
resizeCanvas();
|
|
5176
5198
|
});
|
|
5177
5199
|
// Osserva il canvas o il suo parent (a tua scelta)
|
|
5178
5200
|
ro.observe(this.canvas);
|
|
5179
5201
|
}
|
|
5180
|
-
window.addEventListener(
|
|
5181
|
-
this.canvas.addEventListener(
|
|
5182
|
-
this.canvas.addEventListener(
|
|
5202
|
+
window.addEventListener("resize", resizeCanvas);
|
|
5203
|
+
this.canvas.addEventListener("webglcontextlost", handleContextLost, false);
|
|
5204
|
+
this.canvas.addEventListener("webglcontextrestored", handleContextRestored, false);
|
|
5183
5205
|
resizeCanvas();
|
|
5184
5206
|
}
|
|
5185
5207
|
tick() {
|
|
@@ -5199,6 +5221,7 @@ exports.AstroViewer = AstroViewer;
|
|
|
5199
5221
|
/***/ 7734
|
|
5200
5222
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
5201
5223
|
|
|
5224
|
+
"use strict";
|
|
5202
5225
|
|
|
5203
5226
|
/*
|
|
5204
5227
|
* AstroViewer
|
|
@@ -5554,6 +5577,7 @@ exports["default"] = Camera;
|
|
|
5554
5577
|
/***/ 2919
|
|
5555
5578
|
(__unused_webpack_module, exports) {
|
|
5556
5579
|
|
|
5580
|
+
"use strict";
|
|
5557
5581
|
var __webpack_unused_export__;
|
|
5558
5582
|
|
|
5559
5583
|
/*
|
|
@@ -5608,6 +5632,7 @@ exports.bootSetup = {
|
|
|
5608
5632
|
/***/ 4382
|
|
5609
5633
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
5610
5634
|
|
|
5635
|
+
"use strict";
|
|
5611
5636
|
/*
|
|
5612
5637
|
* AstroViewer
|
|
5613
5638
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -5677,6 +5702,7 @@ exports["default"] = global;
|
|
|
5677
5702
|
/***/ 1229
|
|
5678
5703
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
5679
5704
|
|
|
5705
|
+
"use strict";
|
|
5680
5706
|
|
|
5681
5707
|
/*
|
|
5682
5708
|
* AstroViewer
|
|
@@ -5765,6 +5791,7 @@ console.log('astroviewer UMD loaded');
|
|
|
5765
5791
|
/***/ 4735
|
|
5766
5792
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
5767
5793
|
|
|
5794
|
+
"use strict";
|
|
5768
5795
|
var __webpack_unused_export__;
|
|
5769
5796
|
|
|
5770
5797
|
/*
|
|
@@ -5931,6 +5958,7 @@ exports.AbstractSkyEntity = AbstractSkyEntity;
|
|
|
5931
5958
|
/***/ 619
|
|
5932
5959
|
(__unused_webpack_module, exports) {
|
|
5933
5960
|
|
|
5961
|
+
"use strict";
|
|
5934
5962
|
|
|
5935
5963
|
/*
|
|
5936
5964
|
* AstroViewer
|
|
@@ -7239,6 +7267,7 @@ exports["default"] = exports.ColorMaps;
|
|
|
7239
7267
|
/***/ 1072
|
|
7240
7268
|
(__unused_webpack_module, exports) {
|
|
7241
7269
|
|
|
7270
|
+
"use strict";
|
|
7242
7271
|
/*
|
|
7243
7272
|
* AstroViewer
|
|
7244
7273
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -7353,6 +7382,7 @@ exports.MetadataColumn = MetadataColumn;
|
|
|
7353
7382
|
/***/ 5403
|
|
7354
7383
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
7355
7384
|
|
|
7385
|
+
"use strict";
|
|
7356
7386
|
|
|
7357
7387
|
/*
|
|
7358
7388
|
* AstroViewer
|
|
@@ -7493,6 +7523,7 @@ exports.MetadataManager = MetadataManager;
|
|
|
7493
7523
|
/***/ 6553
|
|
7494
7524
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
7495
7525
|
|
|
7526
|
+
"use strict";
|
|
7496
7527
|
/*
|
|
7497
7528
|
* AstroViewer
|
|
7498
7529
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -7666,6 +7697,7 @@ exports.Point = Point;
|
|
|
7666
7697
|
/***/ 7559
|
|
7667
7698
|
(__unused_webpack_module, exports) {
|
|
7668
7699
|
|
|
7700
|
+
"use strict";
|
|
7669
7701
|
|
|
7670
7702
|
/*
|
|
7671
7703
|
* AstroViewer
|
|
@@ -7700,6 +7732,7 @@ exports["default"] = Point2D;
|
|
|
7700
7732
|
/***/ 146
|
|
7701
7733
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
7702
7734
|
|
|
7735
|
+
"use strict";
|
|
7703
7736
|
/*
|
|
7704
7737
|
* AstroViewer
|
|
7705
7738
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -7785,6 +7818,7 @@ exports.Source = Source;
|
|
|
7785
7818
|
/***/ 5803
|
|
7786
7819
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
7787
7820
|
|
|
7821
|
+
"use strict";
|
|
7788
7822
|
|
|
7789
7823
|
/*
|
|
7790
7824
|
* AstroViewer
|
|
@@ -7990,6 +8024,7 @@ exports.SphereFoV = SphereFoV;
|
|
|
7990
8024
|
/***/ 1232
|
|
7991
8025
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
7992
8026
|
|
|
8027
|
+
"use strict";
|
|
7993
8028
|
|
|
7994
8029
|
/*
|
|
7995
8030
|
* AstroViewer
|
|
@@ -8624,6 +8659,7 @@ exports.CatalogueGL = CatalogueGL;
|
|
|
8624
8659
|
/***/ 3956
|
|
8625
8660
|
(__unused_webpack_module, exports) {
|
|
8626
8661
|
|
|
8662
|
+
"use strict";
|
|
8627
8663
|
|
|
8628
8664
|
/*
|
|
8629
8665
|
* AstroViewer
|
|
@@ -8730,6 +8766,7 @@ exports.WMTSAdapter = WMTSAdapter;
|
|
|
8730
8766
|
/***/ 3174
|
|
8731
8767
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
8732
8768
|
|
|
8769
|
+
"use strict";
|
|
8733
8770
|
var __webpack_unused_export__;
|
|
8734
8771
|
|
|
8735
8772
|
/*
|
|
@@ -8827,6 +8864,7 @@ __webpack_unused_export__ = XYZAnchestorTile;
|
|
|
8827
8864
|
/***/ 8284
|
|
8828
8865
|
(__unused_webpack_module, exports) {
|
|
8829
8866
|
|
|
8867
|
+
"use strict";
|
|
8830
8868
|
var __webpack_unused_export__;
|
|
8831
8869
|
/*
|
|
8832
8870
|
* AstroViewer
|
|
@@ -8973,6 +9011,7 @@ __webpack_unused_export__ = XYZFoVHelper;
|
|
|
8973
9011
|
/***/ 1741
|
|
8974
9012
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
8975
9013
|
|
|
9014
|
+
"use strict";
|
|
8976
9015
|
|
|
8977
9016
|
/*
|
|
8978
9017
|
* AstroViewer
|
|
@@ -9190,6 +9229,7 @@ exports.XYZMap = XYZMap;
|
|
|
9190
9229
|
/***/ 8868
|
|
9191
9230
|
(__unused_webpack_module, exports) {
|
|
9192
9231
|
|
|
9232
|
+
"use strict";
|
|
9193
9233
|
var __webpack_unused_export__;
|
|
9194
9234
|
|
|
9195
9235
|
/*
|
|
@@ -9277,6 +9317,7 @@ exports.XYZMapDescriptor = XYZMapDescriptor;
|
|
|
9277
9317
|
/***/ 8819
|
|
9278
9318
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
9279
9319
|
|
|
9320
|
+
"use strict";
|
|
9280
9321
|
var __webpack_unused_export__;
|
|
9281
9322
|
|
|
9282
9323
|
/*
|
|
@@ -9395,6 +9436,7 @@ exports.XYZMeshBuilder = XYZMeshBuilder;
|
|
|
9395
9436
|
/***/ 1375
|
|
9396
9437
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
9397
9438
|
|
|
9439
|
+
"use strict";
|
|
9398
9440
|
var __webpack_unused_export__;
|
|
9399
9441
|
|
|
9400
9442
|
/*
|
|
@@ -9572,6 +9614,7 @@ exports.XYZTile = XYZTile;
|
|
|
9572
9614
|
/***/ 2737
|
|
9573
9615
|
(__unused_webpack_module, exports) {
|
|
9574
9616
|
|
|
9617
|
+
"use strict";
|
|
9575
9618
|
var __webpack_unused_export__;
|
|
9576
9619
|
|
|
9577
9620
|
/*
|
|
@@ -9721,6 +9764,7 @@ exports.XYZTileBuffer = XYZTileBuffer;
|
|
|
9721
9764
|
/***/ 5409
|
|
9722
9765
|
(__unused_webpack_module, exports) {
|
|
9723
9766
|
|
|
9767
|
+
"use strict";
|
|
9724
9768
|
var __webpack_unused_export__;
|
|
9725
9769
|
|
|
9726
9770
|
/*
|
|
@@ -9904,6 +9948,7 @@ exports.xyzTileRequestScheduler = new XYZTileRequestScheduler();
|
|
|
9904
9948
|
/***/ 6937
|
|
9905
9949
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
9906
9950
|
|
|
9951
|
+
"use strict";
|
|
9907
9952
|
|
|
9908
9953
|
/*
|
|
9909
9954
|
* AstroViewer
|
|
@@ -9993,6 +10038,7 @@ exports.XYZVisibleTilesManager = XYZVisibleTilesManager;
|
|
|
9993
10038
|
/***/ 2475
|
|
9994
10039
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
9995
10040
|
|
|
10041
|
+
"use strict";
|
|
9996
10042
|
/*
|
|
9997
10043
|
* AstroViewer
|
|
9998
10044
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -10132,6 +10178,7 @@ exports.Footprint = Footprint;
|
|
|
10132
10178
|
/***/ 592
|
|
10133
10179
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
10134
10180
|
|
|
10181
|
+
"use strict";
|
|
10135
10182
|
|
|
10136
10183
|
/*
|
|
10137
10184
|
* AstroViewer
|
|
@@ -10750,6 +10797,7 @@ exports.FootprintSetGL = FootprintSetGL;
|
|
|
10750
10797
|
/***/ 9839
|
|
10751
10798
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
10752
10799
|
|
|
10800
|
+
"use strict";
|
|
10753
10801
|
|
|
10754
10802
|
/*
|
|
10755
10803
|
* AstroViewer
|
|
@@ -11082,6 +11130,7 @@ exports.EquatorialGrid = EquatorialGrid;
|
|
|
11082
11130
|
/***/ 5361
|
|
11083
11131
|
(__unused_webpack_module, exports) {
|
|
11084
11132
|
|
|
11133
|
+
"use strict";
|
|
11085
11134
|
|
|
11086
11135
|
/*
|
|
11087
11136
|
* AstroViewer
|
|
@@ -11226,6 +11275,7 @@ exports["default"] = GridTextHelper;
|
|
|
11226
11275
|
/***/ 4595
|
|
11227
11276
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
11228
11277
|
|
|
11278
|
+
"use strict";
|
|
11229
11279
|
/*
|
|
11230
11280
|
* AstroViewer
|
|
11231
11281
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -11559,6 +11609,7 @@ exports.HealpixGrid = HealpixGrid;
|
|
|
11559
11609
|
/***/ 8124
|
|
11560
11610
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
11561
11611
|
|
|
11612
|
+
"use strict";
|
|
11562
11613
|
|
|
11563
11614
|
/*
|
|
11564
11615
|
* AstroViewer
|
|
@@ -11881,6 +11932,7 @@ exports.LatLonGrid = LatLonGrid;
|
|
|
11881
11932
|
/***/ 2368
|
|
11882
11933
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
11883
11934
|
|
|
11935
|
+
"use strict";
|
|
11884
11936
|
/*
|
|
11885
11937
|
* AstroViewer
|
|
11886
11938
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -11897,6 +11949,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11897
11949
|
};
|
|
11898
11950
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
11899
11951
|
const Global_js_1 = __importDefault(__webpack_require__(4382));
|
|
11952
|
+
const FitsTileLoader_js_1 = __webpack_require__(1399);
|
|
11900
11953
|
class AllSky {
|
|
11901
11954
|
_ready = false;
|
|
11902
11955
|
_hips;
|
|
@@ -11909,6 +11962,7 @@ class AllSky {
|
|
|
11909
11962
|
_texture = null;
|
|
11910
11963
|
_image;
|
|
11911
11964
|
_texurl;
|
|
11965
|
+
_fitsTile;
|
|
11912
11966
|
_textureLoaded = false;
|
|
11913
11967
|
_maxTiles = 0;
|
|
11914
11968
|
_numFacesXTile = 0;
|
|
@@ -11931,15 +11985,34 @@ class AllSky {
|
|
|
11931
11985
|
this.initImage();
|
|
11932
11986
|
}
|
|
11933
11987
|
initImage() {
|
|
11934
|
-
this._image = new Image();
|
|
11935
11988
|
this._texurl = `${this._baseurl}/Norder3/Allsky.${this._format}`;
|
|
11989
|
+
if (this._format === "fits") {
|
|
11990
|
+
void this.loadFits();
|
|
11991
|
+
return;
|
|
11992
|
+
}
|
|
11993
|
+
this.loadImage();
|
|
11994
|
+
}
|
|
11995
|
+
loadImage() {
|
|
11996
|
+
this._image = new Image();
|
|
11936
11997
|
this._image.onload = () => this.imageLoaded();
|
|
11937
11998
|
this._image.onerror = () => {
|
|
11938
|
-
console.error(
|
|
11999
|
+
console.error("File not found? %s", this._texurl);
|
|
11939
12000
|
};
|
|
11940
|
-
this._image.setAttribute(
|
|
12001
|
+
this._image.setAttribute("crossorigin", "anonymous");
|
|
11941
12002
|
this._image.src = this._texurl;
|
|
11942
12003
|
}
|
|
12004
|
+
async loadFits() {
|
|
12005
|
+
try {
|
|
12006
|
+
this._fitsTile = await (0, FitsTileLoader_js_1.loadFitsTile)(this._texurl);
|
|
12007
|
+
this.textureLoaded();
|
|
12008
|
+
this.initModelBuffer();
|
|
12009
|
+
this._textureLoaded = true;
|
|
12010
|
+
this._ready = true;
|
|
12011
|
+
}
|
|
12012
|
+
catch (error) {
|
|
12013
|
+
console.error(`[AllSky] Unable to load FITS atlas ${this._texurl}`, error);
|
|
12014
|
+
}
|
|
12015
|
+
}
|
|
11943
12016
|
imageLoaded() {
|
|
11944
12017
|
this.textureLoaded();
|
|
11945
12018
|
this.initModelBuffer();
|
|
@@ -11947,31 +12020,58 @@ class AllSky {
|
|
|
11947
12020
|
this._ready = true;
|
|
11948
12021
|
}
|
|
11949
12022
|
textureLoaded() {
|
|
11950
|
-
// hipsShaderProgram.enableProgram()
|
|
11951
12023
|
this._hipsShaderProgram.enableProgram();
|
|
11952
12024
|
const gl = this._webgl;
|
|
11953
12025
|
this._texture = gl.createTexture();
|
|
11954
12026
|
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
11955
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,
|
|
12027
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._format !== "fits");
|
|
11956
12028
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
11957
|
-
|
|
11958
|
-
|
|
11959
|
-
|
|
12029
|
+
if (this._format === "fits") {
|
|
12030
|
+
const fits = this._fitsTile;
|
|
12031
|
+
if (!fits) {
|
|
12032
|
+
throw new Error(`FITS AllSky data not loaded: ${this._texurl}`);
|
|
12033
|
+
}
|
|
12034
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, fits.width, fits.height, 0, gl.RED, gl.FLOAT, fits.pixels);
|
|
12035
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
12036
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
12037
|
+
}
|
|
12038
|
+
else {
|
|
12039
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
|
|
12040
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
|
|
12041
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
12042
|
+
gl.generateMipmap(gl.TEXTURE_2D);
|
|
11960
12043
|
}
|
|
11961
|
-
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
11962
|
-
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
11963
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
|
|
11964
12044
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
11965
12045
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
|
|
11971
|
-
|
|
11972
|
-
|
|
11973
|
-
|
|
11974
|
-
|
|
12046
|
+
if (!gl.isTexture(this._texture)) {
|
|
12047
|
+
console.log("error in texture");
|
|
12048
|
+
}
|
|
12049
|
+
}
|
|
12050
|
+
getFitsDataRange() {
|
|
12051
|
+
const hipsRange = this._hips.dataRange;
|
|
12052
|
+
if (hipsRange.min !== undefined &&
|
|
12053
|
+
hipsRange.max !== undefined &&
|
|
12054
|
+
Number.isFinite(hipsRange.min) &&
|
|
12055
|
+
Number.isFinite(hipsRange.max) &&
|
|
12056
|
+
hipsRange.max > hipsRange.min) {
|
|
12057
|
+
return {
|
|
12058
|
+
min: hipsRange.min,
|
|
12059
|
+
max: hipsRange.max,
|
|
12060
|
+
};
|
|
12061
|
+
}
|
|
12062
|
+
const fits = this._fitsTile;
|
|
12063
|
+
if (fits &&
|
|
12064
|
+
fits.dataMin !== null &&
|
|
12065
|
+
fits.dataMax !== null &&
|
|
12066
|
+
Number.isFinite(fits.dataMin) &&
|
|
12067
|
+
Number.isFinite(fits.dataMax) &&
|
|
12068
|
+
fits.dataMax > fits.dataMin) {
|
|
12069
|
+
return {
|
|
12070
|
+
min: fits.dataMin,
|
|
12071
|
+
max: fits.dataMax,
|
|
12072
|
+
};
|
|
12073
|
+
}
|
|
12074
|
+
return null;
|
|
11975
12075
|
}
|
|
11976
12076
|
initModelBuffer() {
|
|
11977
12077
|
const gl = this._webgl;
|
|
@@ -12036,13 +12136,16 @@ class AllSky {
|
|
|
12036
12136
|
this.vertexPosition[20 * this.vidx] = facesVec3Array[0].x;
|
|
12037
12137
|
this.vertexPosition[20 * this.vidx + 1] = facesVec3Array[0].y;
|
|
12038
12138
|
this.vertexPosition[20 * this.vidx + 2] = facesVec3Array[0].z;
|
|
12039
|
-
this.vertexPosition[20 * this.vidx + 3] =
|
|
12040
|
-
|
|
12139
|
+
this.vertexPosition[20 * this.vidx + 3] =
|
|
12140
|
+
s_step + base_s - s_pixel_size;
|
|
12141
|
+
this.vertexPosition[20 * this.vidx + 4] =
|
|
12142
|
+
1 - (t_step + base_t) + t_pixel_size;
|
|
12041
12143
|
// top right
|
|
12042
12144
|
this.vertexPosition[20 * this.vidx + 5] = facesVec3Array[1].x;
|
|
12043
12145
|
this.vertexPosition[20 * this.vidx + 6] = facesVec3Array[1].y;
|
|
12044
12146
|
this.vertexPosition[20 * this.vidx + 7] = facesVec3Array[1].z;
|
|
12045
|
-
this.vertexPosition[20 * this.vidx + 8] =
|
|
12147
|
+
this.vertexPosition[20 * this.vidx + 8] =
|
|
12148
|
+
s_step + base_s - s_pixel_size;
|
|
12046
12149
|
this.vertexPosition[20 * this.vidx + 9] = 1 - base_t - t_pixel_size;
|
|
12047
12150
|
// top left
|
|
12048
12151
|
this.vertexPosition[20 * this.vidx + 10] = facesVec3Array[2].x;
|
|
@@ -12055,7 +12158,8 @@ class AllSky {
|
|
|
12055
12158
|
this.vertexPosition[20 * this.vidx + 16] = facesVec3Array[3].y;
|
|
12056
12159
|
this.vertexPosition[20 * this.vidx + 17] = facesVec3Array[3].z;
|
|
12057
12160
|
this.vertexPosition[20 * this.vidx + 18] = base_s + s_pixel_size;
|
|
12058
|
-
this.vertexPosition[20 * this.vidx + 19] =
|
|
12161
|
+
this.vertexPosition[20 * this.vidx + 19] =
|
|
12162
|
+
1 - (t_step + base_t) + t_pixel_size;
|
|
12059
12163
|
this.vidx++;
|
|
12060
12164
|
}
|
|
12061
12165
|
}
|
|
@@ -12075,6 +12179,17 @@ class AllSky {
|
|
|
12075
12179
|
}
|
|
12076
12180
|
const gl = this._webgl;
|
|
12077
12181
|
this._hipsShaderProgram.enableShaders(pMatrix, vMatrix, mMatrix, colorMapIdx);
|
|
12182
|
+
if (this._format === "fits") {
|
|
12183
|
+
const range = this.getFitsDataRange();
|
|
12184
|
+
if (!range) {
|
|
12185
|
+
console.error(`[AllSky] No display range available for FITS atlas ${this._texurl}`);
|
|
12186
|
+
return false;
|
|
12187
|
+
}
|
|
12188
|
+
this._hipsShaderProgram.setTextureDataMode(this._hipsShaderIndex, true, range.min, range.max);
|
|
12189
|
+
}
|
|
12190
|
+
else {
|
|
12191
|
+
this._hipsShaderProgram.setTextureDataMode(this._hipsShaderIndex, false);
|
|
12192
|
+
}
|
|
12078
12193
|
gl.enableVertexAttribArray(this._hipsShaderProgram.locations.vertexPositionAttribute);
|
|
12079
12194
|
gl.enableVertexAttribArray(this._hipsShaderProgram.locations.textureCoordAttribute);
|
|
12080
12195
|
// hipsShaderProgram.enableShaders(pMatrix, vMatrix, mMatrix, colorMapIdx)
|
|
@@ -12082,8 +12197,10 @@ class AllSky {
|
|
|
12082
12197
|
// gl.enableVertexAttribArray((hipsShaderProgram as any).locations.textureCoordAttribute)
|
|
12083
12198
|
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
12084
12199
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
12085
|
-
|
|
12086
|
-
|
|
12200
|
+
const factorLocation = this._hipsShaderProgram.locations.textureAlpha[this._hipsShaderIndex];
|
|
12201
|
+
if (factorLocation) {
|
|
12202
|
+
gl.uniform1f(factorLocation, this.opacity);
|
|
12203
|
+
}
|
|
12087
12204
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
|
|
12088
12205
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
|
|
12089
12206
|
gl.vertexAttribPointer(
|
|
@@ -12134,6 +12251,7 @@ exports["default"] = AllSky;
|
|
|
12134
12251
|
/***/ 2885
|
|
12135
12252
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
12136
12253
|
|
|
12254
|
+
"use strict";
|
|
12137
12255
|
/*
|
|
12138
12256
|
* AstroViewer
|
|
12139
12257
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -12151,6 +12269,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12151
12269
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
12152
12270
|
const Global_js_1 = __importDefault(__webpack_require__(4382));
|
|
12153
12271
|
const FoVHelper_js_1 = __webpack_require__(229);
|
|
12272
|
+
const FitsTileLoader_js_1 = __webpack_require__(1399);
|
|
12154
12273
|
class AncestorTile {
|
|
12155
12274
|
_hips;
|
|
12156
12275
|
_tileno;
|
|
@@ -12164,7 +12283,8 @@ class AncestorTile {
|
|
|
12164
12283
|
_pixels = [];
|
|
12165
12284
|
_texture = null;
|
|
12166
12285
|
_image;
|
|
12167
|
-
_texurl =
|
|
12286
|
+
_texurl = "";
|
|
12287
|
+
_fitsTile;
|
|
12168
12288
|
vertexPosition;
|
|
12169
12289
|
vertexPositionBuffer;
|
|
12170
12290
|
vertexIndices;
|
|
@@ -12190,14 +12310,41 @@ class AncestorTile {
|
|
|
12190
12310
|
}
|
|
12191
12311
|
initImage() {
|
|
12192
12312
|
const dirnumber = Math.floor(this._tileno / 10000) * 10000;
|
|
12193
|
-
this._texurl =
|
|
12313
|
+
this._texurl =
|
|
12314
|
+
`${this._baseurl}/Norder${this._order}/Dir${dirnumber}` +
|
|
12315
|
+
`/Npix${this._tileno}.${this._format}`;
|
|
12316
|
+
if (this._format === "fits") {
|
|
12317
|
+
void this.loadFits();
|
|
12318
|
+
return;
|
|
12319
|
+
}
|
|
12320
|
+
this.loadImage();
|
|
12321
|
+
}
|
|
12322
|
+
async loadFits() {
|
|
12323
|
+
try {
|
|
12324
|
+
this._fitsTile = await (0, FitsTileLoader_js_1.loadFitsTile)(this._texurl);
|
|
12325
|
+
this.textureLoaded();
|
|
12326
|
+
const fits = this._fitsTile;
|
|
12327
|
+
if (!fits) {
|
|
12328
|
+
throw new Error(`FITS tile data not loaded: ${this._texurl}`);
|
|
12329
|
+
}
|
|
12330
|
+
const gl = this._webgl;
|
|
12331
|
+
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
12332
|
+
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
12333
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, fits.width, fits.height, 0, gl.RED, gl.FLOAT, fits.pixels);
|
|
12334
|
+
this.initModelBuffer();
|
|
12335
|
+
this._ready = true;
|
|
12336
|
+
}
|
|
12337
|
+
catch (error) {
|
|
12338
|
+
console.error(`[AncestorTile] Unable to load FITS tile ${this._texurl}`, error);
|
|
12339
|
+
}
|
|
12340
|
+
}
|
|
12341
|
+
loadImage() {
|
|
12194
12342
|
this._image = new Image();
|
|
12195
12343
|
this._image.onload = () => this.imageLoaded();
|
|
12196
12344
|
this._image.onerror = () => {
|
|
12197
|
-
console.error(
|
|
12345
|
+
console.error("File not found? %s", this._texurl);
|
|
12198
12346
|
};
|
|
12199
|
-
this._image.crossOrigin =
|
|
12200
|
-
// If you ever need FITS handling, call this.loadImage() instead.
|
|
12347
|
+
this._image.crossOrigin = "anonymous";
|
|
12201
12348
|
this._image.src = this._texurl;
|
|
12202
12349
|
}
|
|
12203
12350
|
imageLoaded() {
|
|
@@ -12215,15 +12362,47 @@ class AncestorTile {
|
|
|
12215
12362
|
const gl = this._webgl;
|
|
12216
12363
|
this._texture = gl.createTexture();
|
|
12217
12364
|
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
12218
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,
|
|
12365
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._format !== "fits");
|
|
12219
12366
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
12220
12367
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
12221
12368
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
12222
|
-
|
|
12223
|
-
|
|
12369
|
+
if (this._format === "fits") {
|
|
12370
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
12371
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
12372
|
+
}
|
|
12373
|
+
else {
|
|
12374
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
12375
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
12376
|
+
}
|
|
12224
12377
|
if (!gl.isTexture(this._texture)) {
|
|
12225
|
-
console.log(
|
|
12378
|
+
console.log("error in texture");
|
|
12379
|
+
}
|
|
12380
|
+
}
|
|
12381
|
+
getFitsDataRange() {
|
|
12382
|
+
const hipsRange = this._hips.dataRange;
|
|
12383
|
+
if (hipsRange.min !== undefined &&
|
|
12384
|
+
hipsRange.max !== undefined &&
|
|
12385
|
+
Number.isFinite(hipsRange.min) &&
|
|
12386
|
+
Number.isFinite(hipsRange.max) &&
|
|
12387
|
+
hipsRange.max > hipsRange.min) {
|
|
12388
|
+
return {
|
|
12389
|
+
min: hipsRange.min,
|
|
12390
|
+
max: hipsRange.max,
|
|
12391
|
+
};
|
|
12392
|
+
}
|
|
12393
|
+
const fits = this._fitsTile;
|
|
12394
|
+
if (fits &&
|
|
12395
|
+
fits.dataMin !== null &&
|
|
12396
|
+
fits.dataMax !== null &&
|
|
12397
|
+
Number.isFinite(fits.dataMin) &&
|
|
12398
|
+
Number.isFinite(fits.dataMax) &&
|
|
12399
|
+
fits.dataMax > fits.dataMin) {
|
|
12400
|
+
return {
|
|
12401
|
+
min: fits.dataMin,
|
|
12402
|
+
max: fits.dataMax,
|
|
12403
|
+
};
|
|
12226
12404
|
}
|
|
12405
|
+
return null;
|
|
12227
12406
|
}
|
|
12228
12407
|
initModelBuffer() {
|
|
12229
12408
|
const gl = this._webgl;
|
|
@@ -12266,43 +12445,6 @@ class AncestorTile {
|
|
|
12266
12445
|
}
|
|
12267
12446
|
return vertexIndices;
|
|
12268
12447
|
}
|
|
12269
|
-
// Version that uses getPointsForXyfNoStep (kept for reference; not used in this class)
|
|
12270
|
-
setupPositionAndTexture4Quadrant2(dxmin, dxmax, dymin, dymax, qidx, healpix, orderjump, origxyf) {
|
|
12271
|
-
this.vertexPosition[qidx] = new Float32Array(20 * (dxmax - dxmin) * (dymax - dymin));
|
|
12272
|
-
const step = 1 / (1 << orderjump);
|
|
12273
|
-
let p = 0;
|
|
12274
|
-
for (let dx = dxmin; dx < dxmax; dx++) {
|
|
12275
|
-
for (let dy = dymin; dy < dymax; dy++) {
|
|
12276
|
-
const facesVec3Array = healpix.getPointsForXyfNoStep(dx, dy, origxyf.face);
|
|
12277
|
-
const uindex = dy - (origxyf.iy << orderjump);
|
|
12278
|
-
const vindex = dx - (origxyf.ix << orderjump);
|
|
12279
|
-
this.vertexPosition[qidx][20 * p] = facesVec3Array[0].x;
|
|
12280
|
-
this.vertexPosition[qidx][20 * p + 1] = facesVec3Array[0].y;
|
|
12281
|
-
this.vertexPosition[qidx][20 * p + 2] = facesVec3Array[0].z;
|
|
12282
|
-
this.vertexPosition[qidx][20 * p + 3] = step + step * uindex;
|
|
12283
|
-
this.vertexPosition[qidx][20 * p + 4] = 1 - (step + step * vindex);
|
|
12284
|
-
this.vertexPosition[qidx][20 * p + 5] = facesVec3Array[1].x;
|
|
12285
|
-
this.vertexPosition[qidx][20 * p + 6] = facesVec3Array[1].y;
|
|
12286
|
-
this.vertexPosition[qidx][20 * p + 7] = facesVec3Array[1].z;
|
|
12287
|
-
this.vertexPosition[qidx][20 * p + 8] = step + step * uindex;
|
|
12288
|
-
this.vertexPosition[qidx][20 * p + 9] = 1 - step * vindex;
|
|
12289
|
-
this.vertexPosition[qidx][20 * p + 10] = facesVec3Array[2].x;
|
|
12290
|
-
this.vertexPosition[qidx][20 * p + 11] = facesVec3Array[2].y;
|
|
12291
|
-
this.vertexPosition[qidx][20 * p + 12] = facesVec3Array[2].z;
|
|
12292
|
-
this.vertexPosition[qidx][20 * p + 13] = step * uindex;
|
|
12293
|
-
this.vertexPosition[qidx][20 * p + 14] = 1 - step * vindex;
|
|
12294
|
-
this.vertexPosition[qidx][20 * p + 15] = facesVec3Array[3].x;
|
|
12295
|
-
this.vertexPosition[qidx][20 * p + 16] = facesVec3Array[3].y;
|
|
12296
|
-
this.vertexPosition[qidx][20 * p + 17] = facesVec3Array[3].z;
|
|
12297
|
-
this.vertexPosition[qidx][20 * p + 18] = step * uindex;
|
|
12298
|
-
this.vertexPosition[qidx][20 * p + 19] = 1 - (step + step * vindex);
|
|
12299
|
-
p++;
|
|
12300
|
-
}
|
|
12301
|
-
}
|
|
12302
|
-
this.vertexPositionBuffer[qidx] = this._webgl.createBuffer();
|
|
12303
|
-
this._webgl.bindBuffer(this._webgl.ARRAY_BUFFER, this.vertexPositionBuffer[qidx]);
|
|
12304
|
-
this._webgl.bufferData(this._webgl.ARRAY_BUFFER, this.vertexPosition[qidx], this._webgl.STATIC_DRAW);
|
|
12305
|
-
}
|
|
12306
12448
|
// Version used by the original JS, collecting _pixels via xyf2nest + getBoundaries
|
|
12307
12449
|
setupPositionAndTexture4Quadrant(dxmin, dxmax, dymin, dymax, qidx, healpix, orderjump, origxyf) {
|
|
12308
12450
|
const gl = this._webgl;
|
|
@@ -12354,12 +12496,26 @@ class AncestorTile {
|
|
|
12354
12496
|
quadrantsToDraw = q;
|
|
12355
12497
|
}
|
|
12356
12498
|
this._hipsShaderProgram.enableShaders(pMatrix, vMatrix, mMatrix, colorMapIdx);
|
|
12499
|
+
if (this._format === "fits") {
|
|
12500
|
+
const range = this.getFitsDataRange();
|
|
12501
|
+
if (!range) {
|
|
12502
|
+
console.error(`[AncestorTile] No display range available for FITS tile ${this._texurl}`);
|
|
12503
|
+
return false;
|
|
12504
|
+
}
|
|
12505
|
+
this._hipsShaderProgram.setTextureDataMode(this._hipsShaderIndex, true, range.min, range.max);
|
|
12506
|
+
}
|
|
12507
|
+
else {
|
|
12508
|
+
this._hipsShaderProgram.setTextureDataMode(this._hipsShaderIndex, false);
|
|
12509
|
+
}
|
|
12357
12510
|
const gl = this._webgl;
|
|
12358
12511
|
gl.enableVertexAttribArray(this._hipsShaderProgram.locations.vertexPositionAttribute);
|
|
12359
12512
|
gl.enableVertexAttribArray(this._hipsShaderProgram.locations.textureCoordAttribute);
|
|
12360
12513
|
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
12361
12514
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
12362
|
-
|
|
12515
|
+
const factorLocation = this._hipsShaderProgram.locations.textureAlpha[this._hipsShaderIndex];
|
|
12516
|
+
if (factorLocation) {
|
|
12517
|
+
gl.uniform1f(factorLocation, this.opacity);
|
|
12518
|
+
}
|
|
12363
12519
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
|
|
12364
12520
|
const elemno = this.vertexIndices.length;
|
|
12365
12521
|
quadrantsToDraw.forEach((qidx) => {
|
|
@@ -12386,8 +12542,9 @@ class AncestorTile {
|
|
|
12386
12542
|
: this._tileBuffer.getTile(childTileNo, childrenOrder, this._hips);
|
|
12387
12543
|
// childTile.draw(visibleOrder, visibleTilesMap, pMatrix, vMatrix, mMatrix, colorMapIdx)
|
|
12388
12544
|
childTile.draw(visibleOrder, visibleTilesMap, pMatrix, vMatrix, mMatrix, colorMapIdx, this._hipsShaderProgram);
|
|
12389
|
-
if (childTile.
|
|
12390
|
-
quadrantsToDraw.delete(
|
|
12545
|
+
if (childTile.getReadyState()) {
|
|
12546
|
+
quadrantsToDraw.delete(c);
|
|
12547
|
+
// quadrantsToDraw.delete((childTile as any)._tileno - (this._tileno << 2))
|
|
12391
12548
|
}
|
|
12392
12549
|
}
|
|
12393
12550
|
}
|
|
@@ -12397,11 +12554,88 @@ class AncestorTile {
|
|
|
12397
12554
|
exports["default"] = AncestorTile;
|
|
12398
12555
|
|
|
12399
12556
|
|
|
12557
|
+
/***/ },
|
|
12558
|
+
|
|
12559
|
+
/***/ 1399
|
|
12560
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
12561
|
+
|
|
12562
|
+
"use strict";
|
|
12563
|
+
var __webpack_unused_export__;
|
|
12564
|
+
|
|
12565
|
+
/*
|
|
12566
|
+
* AstroViewer
|
|
12567
|
+
* Copyright (C) Fabrizio Giordano
|
|
12568
|
+
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-AstroViewer-Commercial
|
|
12569
|
+
*
|
|
12570
|
+
* AstroViewer is dual-licensed under the GNU Affero General Public License
|
|
12571
|
+
* version 3 and a separate commercial license.
|
|
12572
|
+
*
|
|
12573
|
+
* See LICENSE.md, LICENSE-AGPL.md, and LICENSE-COMMERCIAL.md for details.
|
|
12574
|
+
*/
|
|
12575
|
+
__webpack_unused_export__ = ({ value: true });
|
|
12576
|
+
exports.loadFitsTile = loadFitsTile;
|
|
12577
|
+
const jsfitsio_1 = __webpack_require__(1677);
|
|
12578
|
+
async function loadFitsTile(url) {
|
|
12579
|
+
const fitsFile = await jsfitsio_1.FITSParser.loadFITSFile(url);
|
|
12580
|
+
if (!fitsFile?.primaryHDU) {
|
|
12581
|
+
throw new Error(`Unable to load FITS tile: ${url}`);
|
|
12582
|
+
}
|
|
12583
|
+
const image = fitsFile.primaryHDU;
|
|
12584
|
+
if (image.naxis !== 2) {
|
|
12585
|
+
throw new Error(`Expected a 2D FITS tile, got NAXIS=${image.naxis}: ${url}`);
|
|
12586
|
+
}
|
|
12587
|
+
const [width, height] = image.shape;
|
|
12588
|
+
if (!Number.isInteger(width) ||
|
|
12589
|
+
!Number.isInteger(height) ||
|
|
12590
|
+
width <= 0 ||
|
|
12591
|
+
height <= 0) {
|
|
12592
|
+
throw new Error(`Invalid FITS tile dimensions: ${url}`);
|
|
12593
|
+
}
|
|
12594
|
+
const data = image.typedData;
|
|
12595
|
+
if (!data || data.length !== width * height) {
|
|
12596
|
+
throw new Error(`Invalid FITS tile payload: ${url}`);
|
|
12597
|
+
}
|
|
12598
|
+
if (data instanceof BigInt64Array) {
|
|
12599
|
+
throw new Error(`BITPIX=64 FITS tiles are not supported for HiPS rendering: ${url}`);
|
|
12600
|
+
}
|
|
12601
|
+
const bscale = getNumericHeaderValue(image.header, jsfitsio_1.FITSHeaderManager.BSCALE) ?? 1;
|
|
12602
|
+
const bzero = getNumericHeaderValue(image.header, jsfitsio_1.FITSHeaderManager.BZERO) ?? 0;
|
|
12603
|
+
const blank = getNumericHeaderValue(image.header, jsfitsio_1.FITSHeaderManager.BLANK);
|
|
12604
|
+
const dataMin = getNumericHeaderValue(image.header, jsfitsio_1.FITSHeaderManager.DATAMIN);
|
|
12605
|
+
const dataMax = getNumericHeaderValue(image.header, jsfitsio_1.FITSHeaderManager.DATAMAX);
|
|
12606
|
+
const pixels = new Float32Array(data.length);
|
|
12607
|
+
for (let i = 0; i < data.length; i++) {
|
|
12608
|
+
const rawValue = data[i];
|
|
12609
|
+
if (!Number.isFinite(rawValue) || (blank !== null && rawValue === blank)) {
|
|
12610
|
+
pixels[i] = Number.NaN;
|
|
12611
|
+
continue;
|
|
12612
|
+
}
|
|
12613
|
+
pixels[i] = rawValue * bscale + bzero;
|
|
12614
|
+
}
|
|
12615
|
+
return {
|
|
12616
|
+
width,
|
|
12617
|
+
height,
|
|
12618
|
+
pixels,
|
|
12619
|
+
dataMin,
|
|
12620
|
+
dataMax,
|
|
12621
|
+
};
|
|
12622
|
+
}
|
|
12623
|
+
function getNumericHeaderValue(header, key) {
|
|
12624
|
+
const item = header.findById(key);
|
|
12625
|
+
if (!item) {
|
|
12626
|
+
return null;
|
|
12627
|
+
}
|
|
12628
|
+
const value = Number(item.value);
|
|
12629
|
+
return Number.isFinite(value) ? value : null;
|
|
12630
|
+
}
|
|
12631
|
+
|
|
12632
|
+
|
|
12400
12633
|
/***/ },
|
|
12401
12634
|
|
|
12402
12635
|
/***/ 229
|
|
12403
12636
|
(__unused_webpack_module, exports) {
|
|
12404
12637
|
|
|
12638
|
+
"use strict";
|
|
12405
12639
|
var __webpack_unused_export__;
|
|
12406
12640
|
/*
|
|
12407
12641
|
* AstroViewer
|
|
@@ -12565,6 +12799,7 @@ __webpack_unused_export__ = FoVHelper;
|
|
|
12565
12799
|
/***/ 3726
|
|
12566
12800
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
12567
12801
|
|
|
12802
|
+
"use strict";
|
|
12568
12803
|
/*
|
|
12569
12804
|
* AstroViewer
|
|
12570
12805
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -12601,30 +12836,47 @@ class HiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
12601
12836
|
_allSky = true;
|
|
12602
12837
|
samplerIdx = 0;
|
|
12603
12838
|
colorMapIdx = 0;
|
|
12604
|
-
colorMap = ColorMaps_js_1.default[
|
|
12839
|
+
colorMap = ColorMaps_js_1.default["native"];
|
|
12605
12840
|
_healpixGrid;
|
|
12606
12841
|
// exposed read-only helpers
|
|
12607
|
-
get maxOrder() {
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
get
|
|
12611
|
-
|
|
12612
|
-
|
|
12842
|
+
get maxOrder() {
|
|
12843
|
+
return this._maxorder;
|
|
12844
|
+
}
|
|
12845
|
+
get minOrder() {
|
|
12846
|
+
return this._minorder;
|
|
12847
|
+
}
|
|
12848
|
+
get baseURL() {
|
|
12849
|
+
return this._baseurl;
|
|
12850
|
+
}
|
|
12851
|
+
get format() {
|
|
12852
|
+
return this._format;
|
|
12853
|
+
}
|
|
12854
|
+
get propertiesRawText() {
|
|
12855
|
+
return this._descriptor.propertiesRawText;
|
|
12856
|
+
}
|
|
12857
|
+
get properties() {
|
|
12858
|
+
return this._descriptor.properties;
|
|
12859
|
+
}
|
|
12613
12860
|
constructor(radius, position, xrad, yrad, descriptor, webgl, healpixGrid) {
|
|
12614
12861
|
super(radius, position, xrad, yrad, descriptor.surveyName, webgl, descriptor.isGalactic);
|
|
12615
12862
|
this._descriptor = descriptor;
|
|
12616
12863
|
this.initGL(webgl);
|
|
12617
12864
|
this._healpixGrid = healpixGrid;
|
|
12618
|
-
this.
|
|
12619
|
-
// DEBUG logs kept from JS (optional)
|
|
12620
|
-
// eslint-disable-next-line no-console
|
|
12621
|
-
console.log('HiPS frame ' + descriptor.hipsFrame);
|
|
12622
|
-
// eslint-disable-next-line no-console
|
|
12623
|
-
console.log('HiPS minOrder ' + descriptor.minOrder);
|
|
12624
|
-
this._format = descriptor.imgFormats[0];
|
|
12865
|
+
this._format = this.selectDefaultFormat(descriptor.imgFormats);
|
|
12625
12866
|
this._baseurl = descriptor.url;
|
|
12626
12867
|
this._maxorder = descriptor.maxOrder;
|
|
12627
12868
|
this._minorder = descriptor.minOrder;
|
|
12869
|
+
if (this.isGalacticHips) {
|
|
12870
|
+
this._healpixGrid.visibleTilesManager.tileBuffer.addGalHiPS(this);
|
|
12871
|
+
}
|
|
12872
|
+
else {
|
|
12873
|
+
this._healpixGrid.visibleTilesManager.tileBuffer.addHiPS(this);
|
|
12874
|
+
}
|
|
12875
|
+
// DEBUG logs kept from JS (optional)
|
|
12876
|
+
// eslint-disable-next-line no-console
|
|
12877
|
+
console.log("HiPS frame " + descriptor.hipsFrame);
|
|
12878
|
+
// eslint-disable-next-line no-console
|
|
12879
|
+
console.log("HiPS minOrder " + descriptor.minOrder);
|
|
12628
12880
|
this.initShaders();
|
|
12629
12881
|
// pick initial order from a starting FoV
|
|
12630
12882
|
const fov = 180;
|
|
@@ -12634,39 +12886,52 @@ class HiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
12634
12886
|
this._allSkyTile = null;
|
|
12635
12887
|
// auto-detect all-sky: original code forces true
|
|
12636
12888
|
this._allSky = true;
|
|
12889
|
+
this.initBaseTiles();
|
|
12890
|
+
}
|
|
12891
|
+
initBaseTiles() {
|
|
12892
|
+
this._ancestorTiles = [];
|
|
12893
|
+
this._allSkyTile = null;
|
|
12637
12894
|
if (this._allSky) {
|
|
12638
12895
|
this._allSkyTile = new AllSky_js_1.default(this, this._webgl, this._healpixGrid.visibleTilesManager.tileBuffer, super.hipsShaderProgram);
|
|
12896
|
+
return;
|
|
12639
12897
|
}
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
this._ancestorTiles.push(new AncestorTile_js_1.default(t, 0, this, this._healpixGrid.visibleTilesManager.tileBuffer, super.hipsShaderProgram, this._webgl));
|
|
12643
|
-
}
|
|
12898
|
+
for (let t = 0; t < 12; t++) {
|
|
12899
|
+
this._ancestorTiles.push(new AncestorTile_js_1.default(t, 0, this, this._healpixGrid.visibleTilesManager.tileBuffer, super.hipsShaderProgram, this._webgl));
|
|
12644
12900
|
}
|
|
12645
12901
|
}
|
|
12646
12902
|
getProperty(key) {
|
|
12647
12903
|
return this._descriptor.getProperty(key);
|
|
12648
12904
|
}
|
|
12649
12905
|
changeFormat(format) {
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
|
|
12655
|
-
if (this.
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12906
|
+
const normalizedFormat = format.toLowerCase();
|
|
12907
|
+
if (!this._descriptor.imgFormats.includes(normalizedFormat)) {
|
|
12908
|
+
throw new Error(`HiPS format "${format}" is not supported. ` +
|
|
12909
|
+
`Available formats: ${this._descriptor.imgFormats.join(", ")}`);
|
|
12910
|
+
}
|
|
12911
|
+
if (normalizedFormat === this._format.toLowerCase()) {
|
|
12912
|
+
return;
|
|
12913
|
+
}
|
|
12914
|
+
const tileBuffer = this._healpixGrid.visibleTilesManager.tileBuffer;
|
|
12915
|
+
/*
|
|
12916
|
+
* Remove Tile instances created using the previous format.
|
|
12917
|
+
*
|
|
12918
|
+
* TileBuffer invalidates by HiPS identity/base URL rather than by the
|
|
12919
|
+
* current format, so both active and cached resources are discarded.
|
|
12920
|
+
*/
|
|
12921
|
+
tileBuffer.invalidateHiPS(this);
|
|
12922
|
+
/*
|
|
12923
|
+
* Change format before recreating AllSky/AncestorTile because their
|
|
12924
|
+
* constructors read hips.format.
|
|
12925
|
+
*/
|
|
12926
|
+
this._format = normalizedFormat;
|
|
12927
|
+
/*
|
|
12928
|
+
* AllSky and AncestorTile also keep the format they were constructed
|
|
12929
|
+
* with, so they must be recreated.
|
|
12930
|
+
*/
|
|
12931
|
+
this.initBaseTiles();
|
|
12932
|
+
}
|
|
12933
|
+
get availableFormats() {
|
|
12934
|
+
return this._descriptor.imgFormats;
|
|
12670
12935
|
}
|
|
12671
12936
|
/**
|
|
12672
12937
|
* Shader colormap switcher
|
|
@@ -12679,60 +12944,60 @@ class HiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
12679
12944
|
* 6 -> cubehelix
|
|
12680
12945
|
*/
|
|
12681
12946
|
changeColorMap(colorMap) {
|
|
12682
|
-
console.log(
|
|
12947
|
+
console.log("HiPS.changeColorMap -> shaderProgram", super.hipsShaderProgram.shaderProgram);
|
|
12683
12948
|
this.colorMap = colorMap;
|
|
12684
12949
|
switch (colorMap.name) {
|
|
12685
|
-
case
|
|
12950
|
+
case "grayscale":
|
|
12686
12951
|
this.colorMapIdx = 1;
|
|
12687
12952
|
// hipsShaderProgram.setGrayscaleShader()
|
|
12688
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12953
|
+
this.colorMap = ColorMaps_js_1.default["grayscale"];
|
|
12689
12954
|
super.hipsShaderProgram.setGrayscaleShader();
|
|
12690
12955
|
break;
|
|
12691
|
-
case
|
|
12956
|
+
case "planck":
|
|
12692
12957
|
this.colorMapIdx = 2;
|
|
12693
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12958
|
+
this.colorMap = ColorMaps_js_1.default["planck"];
|
|
12694
12959
|
// hipsShaderProgram.setColorMapShader()
|
|
12695
12960
|
super.hipsShaderProgram.setColorMapShader();
|
|
12696
12961
|
break;
|
|
12697
|
-
case
|
|
12962
|
+
case "cmb":
|
|
12698
12963
|
this.colorMapIdx = 3;
|
|
12699
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12964
|
+
this.colorMap = ColorMaps_js_1.default["cmb"];
|
|
12700
12965
|
// hipsShaderProgram.setColorMapShader()
|
|
12701
12966
|
super.hipsShaderProgram.setColorMapShader();
|
|
12702
12967
|
break;
|
|
12703
|
-
case
|
|
12968
|
+
case "rainbow":
|
|
12704
12969
|
this.colorMapIdx = 4;
|
|
12705
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12970
|
+
this.colorMap = ColorMaps_js_1.default["rainbow"];
|
|
12706
12971
|
// hipsShaderProgram.setColorMapShader()
|
|
12707
12972
|
super.hipsShaderProgram.setColorMapShader();
|
|
12708
12973
|
break;
|
|
12709
|
-
case
|
|
12974
|
+
case "eosb":
|
|
12710
12975
|
this.colorMapIdx = 5;
|
|
12711
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12976
|
+
this.colorMap = ColorMaps_js_1.default["eosb"];
|
|
12712
12977
|
super.hipsShaderProgram.setColorMapShader();
|
|
12713
12978
|
// hipsShaderProgram.setColorMapShader()
|
|
12714
12979
|
break;
|
|
12715
|
-
case
|
|
12980
|
+
case "cubehelix":
|
|
12716
12981
|
this.colorMapIdx = 6;
|
|
12717
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12982
|
+
this.colorMap = ColorMaps_js_1.default["cubehelix"];
|
|
12718
12983
|
super.hipsShaderProgram.setColorMapShader();
|
|
12719
12984
|
// hipsShaderProgram.setColorMapShader()
|
|
12720
12985
|
break;
|
|
12721
|
-
case
|
|
12986
|
+
case "hot":
|
|
12722
12987
|
this.colorMapIdx = 7;
|
|
12723
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12988
|
+
this.colorMap = ColorMaps_js_1.default["hot"];
|
|
12724
12989
|
super.hipsShaderProgram.setColorMapShader();
|
|
12725
12990
|
// hipsShaderProgram.setColorMapShader()
|
|
12726
12991
|
break;
|
|
12727
|
-
case
|
|
12992
|
+
case "gray":
|
|
12728
12993
|
this.colorMapIdx = 8;
|
|
12729
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
12994
|
+
this.colorMap = ColorMaps_js_1.default["gray"];
|
|
12730
12995
|
super.hipsShaderProgram.setColorMapShader();
|
|
12731
12996
|
// hipsShaderProgram.setColorMapShader()
|
|
12732
12997
|
break;
|
|
12733
|
-
case
|
|
12998
|
+
case "native":
|
|
12734
12999
|
this.colorMapIdx = 0;
|
|
12735
|
-
this.colorMap = ColorMaps_js_1.default[
|
|
13000
|
+
this.colorMap = ColorMaps_js_1.default["native"];
|
|
12736
13001
|
super.hipsShaderProgram.setNativeShader();
|
|
12737
13002
|
break;
|
|
12738
13003
|
default:
|
|
@@ -12747,6 +13012,30 @@ class HiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
12747
13012
|
// this.shaderProgram = super.hipsShaderProgram.shaderProgram
|
|
12748
13013
|
// this.shaderProgram = hipsShaderProgram.shaderProgram
|
|
12749
13014
|
}
|
|
13015
|
+
// private selectDefaultFormat(formats: string[]): string {
|
|
13016
|
+
// if (formats.includes("fits")) return "fits";
|
|
13017
|
+
// if (formats.includes("png")) return "png";
|
|
13018
|
+
// if (formats.includes("jpg")) return "jpg";
|
|
13019
|
+
// if (formats.length > 0) {
|
|
13020
|
+
// return formats[0];
|
|
13021
|
+
// }
|
|
13022
|
+
// throw new Error("HiPS descriptor does not define a tile format");
|
|
13023
|
+
// }
|
|
13024
|
+
selectDefaultFormat(formats) {
|
|
13025
|
+
if (formats.includes("png"))
|
|
13026
|
+
return "png";
|
|
13027
|
+
if (formats.includes("jpg"))
|
|
13028
|
+
return "jpg";
|
|
13029
|
+
if (formats.includes("fits"))
|
|
13030
|
+
return "fits";
|
|
13031
|
+
if (formats.length > 0) {
|
|
13032
|
+
return formats[0];
|
|
13033
|
+
}
|
|
13034
|
+
throw new Error("HiPS descriptor does not define a tile format");
|
|
13035
|
+
}
|
|
13036
|
+
get dataRange() {
|
|
13037
|
+
return this._descriptor.dataRange;
|
|
13038
|
+
}
|
|
12750
13039
|
getCurrentHealpixOrder() {
|
|
12751
13040
|
return this._visibleorder;
|
|
12752
13041
|
}
|
|
@@ -12756,7 +13045,7 @@ class HiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
12756
13045
|
? this._healpixGrid.visibleTilesManager.galVisibleTilesByOrder
|
|
12757
13046
|
: this._healpixGrid.visibleTilesManager.visibleTilesByOrder;
|
|
12758
13047
|
return {
|
|
12759
|
-
activeBaseLayer:
|
|
13048
|
+
activeBaseLayer: "hips",
|
|
12760
13049
|
hipsName: this._descriptor.surveyName,
|
|
12761
13050
|
hipsUrl: this._baseurl,
|
|
12762
13051
|
isGalactic: this.isGalacticHips,
|
|
@@ -12788,16 +13077,10 @@ class HiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
12788
13077
|
super.hipsShaderProgram.setRuntimeColorMap(this.colorMap);
|
|
12789
13078
|
if (this._allSky && this._allSkyTile) {
|
|
12790
13079
|
if (this.isGalacticHips) {
|
|
12791
|
-
this._allSkyTile.draw(this._healpixGrid.visibleTilesManager.galVisibleTilesByOrder.order, this._healpixGrid.visibleTilesManager.galAncestorsMap,
|
|
12792
|
-
// visibleTilesManager.galVisibleTilesByOrder.order,
|
|
12793
|
-
// visibleTilesManager.galAncestorsMap,
|
|
12794
|
-
pMatrix, vMatrix, mMatrix, this.colorMapIdx);
|
|
13080
|
+
this._allSkyTile.draw(this._healpixGrid.visibleTilesManager.galVisibleTilesByOrder.order, this._healpixGrid.visibleTilesManager.galAncestorsMap, pMatrix, vMatrix, mMatrix, this.colorMapIdx);
|
|
12795
13081
|
}
|
|
12796
13082
|
else {
|
|
12797
|
-
this._allSkyTile.draw(this._healpixGrid.visibleTilesManager.visibleTilesByOrder.order, this._healpixGrid.visibleTilesManager.ancestorsMap,
|
|
12798
|
-
// visibleTilesManager.visibleTilesByOrder.order,
|
|
12799
|
-
// visibleTilesManager.ancestorsMap,
|
|
12800
|
-
pMatrix, vMatrix, mMatrix, this.colorMapIdx);
|
|
13083
|
+
this._allSkyTile.draw(this._healpixGrid.visibleTilesManager.visibleTilesByOrder.order, this._healpixGrid.visibleTilesManager.ancestorsMap, pMatrix, vMatrix, mMatrix, this.colorMapIdx);
|
|
12801
13084
|
}
|
|
12802
13085
|
return;
|
|
12803
13086
|
}
|
|
@@ -12821,6 +13104,7 @@ exports.HiPS = HiPS;
|
|
|
12821
13104
|
/***/ 5087
|
|
12822
13105
|
(__unused_webpack_module, exports) {
|
|
12823
13106
|
|
|
13107
|
+
"use strict";
|
|
12824
13108
|
/*
|
|
12825
13109
|
* AstroViewer
|
|
12826
13110
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -12972,6 +13256,7 @@ exports.HiPSDescriptor = HiPSDescriptor;
|
|
|
12972
13256
|
/***/ 8256
|
|
12973
13257
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
12974
13258
|
|
|
13259
|
+
"use strict";
|
|
12975
13260
|
|
|
12976
13261
|
/*
|
|
12977
13262
|
* AstroViewer
|
|
@@ -12990,6 +13275,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
12990
13275
|
// Tile.ts
|
|
12991
13276
|
const Global_js_1 = __importDefault(__webpack_require__(4382));
|
|
12992
13277
|
const FoVHelper_js_1 = __webpack_require__(229);
|
|
13278
|
+
const FitsTileLoader_js_1 = __webpack_require__(1399);
|
|
12993
13279
|
// ------------------------------------------------------------------------
|
|
12994
13280
|
class Tile {
|
|
12995
13281
|
_hips;
|
|
@@ -13004,8 +13290,9 @@ class Tile {
|
|
|
13004
13290
|
_image;
|
|
13005
13291
|
_textureLoaded = false;
|
|
13006
13292
|
_texture;
|
|
13007
|
-
_texurl =
|
|
13293
|
+
_texurl = "";
|
|
13008
13294
|
_hipsShaderIndex = 0;
|
|
13295
|
+
_fitsTile;
|
|
13009
13296
|
_cacheTime0;
|
|
13010
13297
|
_inView = true;
|
|
13011
13298
|
_amIStillInFoV_requsetID;
|
|
@@ -13062,50 +13349,66 @@ class Tile {
|
|
|
13062
13349
|
console.warn(`[Tile] Skipping tile request above max order: requested order ${this._order}, max order ${this._maxorder}, url ${this._baseurl}`);
|
|
13063
13350
|
return;
|
|
13064
13351
|
}
|
|
13065
|
-
this._image = new Image();
|
|
13066
13352
|
const dirnumber = Math.floor(this._tileno / 10000) * 10000;
|
|
13067
13353
|
this._texurl = `${this._baseurl}/Norder${this._order}/Dir${dirnumber}/Npix${this._tileno}.${this._format}`;
|
|
13354
|
+
if (this._format === "fits") {
|
|
13355
|
+
void this.loadFits();
|
|
13356
|
+
return;
|
|
13357
|
+
}
|
|
13358
|
+
this.loadImage();
|
|
13359
|
+
}
|
|
13360
|
+
loadImage() {
|
|
13361
|
+
this._image = new Image();
|
|
13068
13362
|
this._image.onload = () => this.imageLoaded();
|
|
13069
13363
|
this._image.onerror = () => {
|
|
13070
|
-
// console.error('File not found?', this._texurl)
|
|
13071
13364
|
this._ready = false;
|
|
13072
13365
|
this._abort = true;
|
|
13073
13366
|
this.destroyIntervals();
|
|
13074
13367
|
};
|
|
13075
|
-
this._image.crossOrigin =
|
|
13368
|
+
this._image.crossOrigin = "anonymous";
|
|
13076
13369
|
this._image.src = this._texurl;
|
|
13077
13370
|
}
|
|
13371
|
+
async loadFits() {
|
|
13372
|
+
try {
|
|
13373
|
+
this._fitsTile = await (0, FitsTileLoader_js_1.loadFitsTile)(this._texurl);
|
|
13374
|
+
this._ready = true;
|
|
13375
|
+
}
|
|
13376
|
+
catch (error) {
|
|
13377
|
+
console.error(`[Tile] Unable to load FITS tile ${this._texurl}`, error);
|
|
13378
|
+
this._ready = false;
|
|
13379
|
+
this._abort = true;
|
|
13380
|
+
this.destroyIntervals();
|
|
13381
|
+
}
|
|
13382
|
+
}
|
|
13078
13383
|
imageLoaded() {
|
|
13079
13384
|
// this.textureLoaded()
|
|
13080
13385
|
// this.initModelBuffer()
|
|
13081
13386
|
// this._textureLoaded = true
|
|
13082
13387
|
this._ready = true;
|
|
13083
13388
|
}
|
|
13084
|
-
// private textureLoaded(): void {
|
|
13085
13389
|
textureLoaded(hipsShaderProgram) {
|
|
13086
|
-
// this._hipsShaderProgram.enableProgram()
|
|
13087
13390
|
hipsShaderProgram.enableProgram();
|
|
13088
13391
|
const gl = this._webgl;
|
|
13089
13392
|
this._texture = gl.createTexture();
|
|
13090
13393
|
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
13091
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,
|
|
13394
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._format !== "fits");
|
|
13092
13395
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
13093
|
-
if (
|
|
13094
|
-
|
|
13396
|
+
if (this._format === "fits") {
|
|
13397
|
+
const fits = this._fitsTile;
|
|
13398
|
+
if (!fits) {
|
|
13399
|
+
throw new Error(`FITS tile data not loaded: ${this._texurl}`);
|
|
13400
|
+
}
|
|
13401
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, fits.width, fits.height, 0, gl.RED, gl.FLOAT, fits.pixels);
|
|
13402
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
13403
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
13404
|
+
}
|
|
13405
|
+
else {
|
|
13406
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
|
|
13407
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
13408
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
13095
13409
|
}
|
|
13096
|
-
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
13097
|
-
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
13098
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
|
|
13099
13410
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
13100
13411
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
13101
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
13102
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
13103
|
-
// FIX: use the sampler location we fetched in enableShaders()
|
|
13104
|
-
// gl.uniform1i((this._hipsShaderProgram.locations as ShaderLocations).sampler, this._hipsShaderIndex)
|
|
13105
|
-
// gl.uniform1i((hipsShaderProgram.locations as ShaderLocations).sampler, this._hipsShaderIndex)
|
|
13106
|
-
if (!gl.isTexture(this._texture)) {
|
|
13107
|
-
console.warn('Texture creation failed');
|
|
13108
|
-
}
|
|
13109
13412
|
this.initModelBuffer();
|
|
13110
13413
|
this._textureLoaded = true;
|
|
13111
13414
|
}
|
|
@@ -13172,26 +13475,32 @@ class Tile {
|
|
|
13172
13475
|
this.vertexPosition[qidx][20 * p] = facesVec3Array[0].x;
|
|
13173
13476
|
this.vertexPosition[qidx][20 * p + 1] = facesVec3Array[0].y;
|
|
13174
13477
|
this.vertexPosition[qidx][20 * p + 2] = facesVec3Array[0].z;
|
|
13175
|
-
this.vertexPosition[qidx][20 * p + 3] =
|
|
13176
|
-
|
|
13478
|
+
this.vertexPosition[qidx][20 * p + 3] =
|
|
13479
|
+
step + step * uindex + s_pixel_size;
|
|
13480
|
+
this.vertexPosition[qidx][20 * p + 4] =
|
|
13481
|
+
1 - (step + step * vindex) - t_pixel_size;
|
|
13177
13482
|
// v1
|
|
13178
13483
|
this.vertexPosition[qidx][20 * p + 5] = facesVec3Array[1].x;
|
|
13179
13484
|
this.vertexPosition[qidx][20 * p + 6] = facesVec3Array[1].y;
|
|
13180
13485
|
this.vertexPosition[qidx][20 * p + 7] = facesVec3Array[1].z;
|
|
13181
|
-
this.vertexPosition[qidx][20 * p + 8] =
|
|
13182
|
-
|
|
13486
|
+
this.vertexPosition[qidx][20 * p + 8] =
|
|
13487
|
+
step + step * uindex + s_pixel_size;
|
|
13488
|
+
this.vertexPosition[qidx][20 * p + 9] =
|
|
13489
|
+
1 - step * vindex + t_pixel_size;
|
|
13183
13490
|
// v2
|
|
13184
13491
|
this.vertexPosition[qidx][20 * p + 10] = facesVec3Array[2].x;
|
|
13185
13492
|
this.vertexPosition[qidx][20 * p + 11] = facesVec3Array[2].y;
|
|
13186
13493
|
this.vertexPosition[qidx][20 * p + 12] = facesVec3Array[2].z;
|
|
13187
13494
|
this.vertexPosition[qidx][20 * p + 13] = step * uindex - s_pixel_size;
|
|
13188
|
-
this.vertexPosition[qidx][20 * p + 14] =
|
|
13495
|
+
this.vertexPosition[qidx][20 * p + 14] =
|
|
13496
|
+
1 - step * vindex + t_pixel_size;
|
|
13189
13497
|
// v3
|
|
13190
13498
|
this.vertexPosition[qidx][20 * p + 15] = facesVec3Array[3].x;
|
|
13191
13499
|
this.vertexPosition[qidx][20 * p + 16] = facesVec3Array[3].y;
|
|
13192
13500
|
this.vertexPosition[qidx][20 * p + 17] = facesVec3Array[3].z;
|
|
13193
13501
|
this.vertexPosition[qidx][20 * p + 18] = step * uindex - s_pixel_size;
|
|
13194
|
-
this.vertexPosition[qidx][20 * p + 19] =
|
|
13502
|
+
this.vertexPosition[qidx][20 * p + 19] =
|
|
13503
|
+
1 - (step + step * vindex) - t_pixel_size;
|
|
13195
13504
|
p++;
|
|
13196
13505
|
}
|
|
13197
13506
|
}
|
|
@@ -13199,6 +13508,32 @@ class Tile {
|
|
|
13199
13508
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer[qidx]);
|
|
13200
13509
|
gl.bufferData(gl.ARRAY_BUFFER, this.vertexPosition[qidx], gl.STATIC_DRAW);
|
|
13201
13510
|
}
|
|
13511
|
+
getFitsDataRange() {
|
|
13512
|
+
const hipsRange = this._hips.dataRange;
|
|
13513
|
+
if (hipsRange.min !== undefined &&
|
|
13514
|
+
hipsRange.max !== undefined &&
|
|
13515
|
+
Number.isFinite(hipsRange.min) &&
|
|
13516
|
+
Number.isFinite(hipsRange.max) &&
|
|
13517
|
+
hipsRange.max > hipsRange.min) {
|
|
13518
|
+
return {
|
|
13519
|
+
min: hipsRange.min,
|
|
13520
|
+
max: hipsRange.max,
|
|
13521
|
+
};
|
|
13522
|
+
}
|
|
13523
|
+
const fits = this._fitsTile;
|
|
13524
|
+
if (fits &&
|
|
13525
|
+
fits.dataMin !== null &&
|
|
13526
|
+
fits.dataMax !== null &&
|
|
13527
|
+
Number.isFinite(fits.dataMin) &&
|
|
13528
|
+
Number.isFinite(fits.dataMax) &&
|
|
13529
|
+
fits.dataMax > fits.dataMin) {
|
|
13530
|
+
return {
|
|
13531
|
+
min: fits.dataMin,
|
|
13532
|
+
max: fits.dataMax,
|
|
13533
|
+
};
|
|
13534
|
+
}
|
|
13535
|
+
return null;
|
|
13536
|
+
}
|
|
13202
13537
|
get inView() {
|
|
13203
13538
|
return this._inView;
|
|
13204
13539
|
}
|
|
@@ -13213,7 +13548,9 @@ class Tile {
|
|
|
13213
13548
|
this._ready = true;
|
|
13214
13549
|
if (this._isGalacticHips) {
|
|
13215
13550
|
if (this._visibleTileManager.galAncestorsMap.has(this._order)) {
|
|
13216
|
-
if (!this._visibleTileManager.galAncestorsMap
|
|
13551
|
+
if (!this._visibleTileManager.galAncestorsMap
|
|
13552
|
+
.get(this._order)
|
|
13553
|
+
.includes(this._tileno)) {
|
|
13217
13554
|
this.moveToCache();
|
|
13218
13555
|
}
|
|
13219
13556
|
else {
|
|
@@ -13245,7 +13582,9 @@ class Tile {
|
|
|
13245
13582
|
}
|
|
13246
13583
|
else {
|
|
13247
13584
|
if (this._visibleTileManager.ancestorsMap.has(this._order)) {
|
|
13248
|
-
if (!this._visibleTileManager.ancestorsMap
|
|
13585
|
+
if (!this._visibleTileManager.ancestorsMap
|
|
13586
|
+
.get(this._order)
|
|
13587
|
+
.includes(this._tileno)) {
|
|
13249
13588
|
this.moveToCache();
|
|
13250
13589
|
}
|
|
13251
13590
|
else {
|
|
@@ -13291,33 +13630,39 @@ class Tile {
|
|
|
13291
13630
|
}
|
|
13292
13631
|
const gl = this._webgl;
|
|
13293
13632
|
hipsShaderProgram.enableShaders(pMatrix, vMatrix, mMatrix, colorMapIdx);
|
|
13294
|
-
|
|
13295
|
-
|
|
13296
|
-
|
|
13297
|
-
|
|
13298
|
-
|
|
13299
|
-
|
|
13633
|
+
if (this._format === "fits") {
|
|
13634
|
+
const range = this.getFitsDataRange();
|
|
13635
|
+
if (!range) {
|
|
13636
|
+
console.error(`[Tile] No display range available for FITS tile ${this._texurl}`);
|
|
13637
|
+
return;
|
|
13638
|
+
}
|
|
13639
|
+
hipsShaderProgram.setTextureDataMode(this._hipsShaderIndex, true, range.min, range.max);
|
|
13640
|
+
}
|
|
13641
|
+
else {
|
|
13642
|
+
hipsShaderProgram.setTextureDataMode(this._hipsShaderIndex, false);
|
|
13643
|
+
}
|
|
13644
|
+
const locations = hipsShaderProgram.locations;
|
|
13645
|
+
gl.enableVertexAttribArray(locations.vertexPositionAttribute);
|
|
13646
|
+
gl.enableVertexAttribArray(locations.textureCoordAttribute);
|
|
13300
13647
|
gl.activeTexture(gl.TEXTURE0 + this._hipsShaderIndex);
|
|
13301
13648
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
13302
|
-
|
|
13303
|
-
|
|
13649
|
+
const factorLocation = locations.textureAlpha[this._hipsShaderIndex];
|
|
13650
|
+
if (factorLocation) {
|
|
13651
|
+
gl.uniform1f(factorLocation, this.opacity);
|
|
13652
|
+
}
|
|
13304
13653
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
|
|
13305
13654
|
const elemno = this.vertexIndices.length;
|
|
13306
|
-
const indexType = this.vertexIndices instanceof Uint32Array
|
|
13655
|
+
const indexType = this.vertexIndices instanceof Uint32Array
|
|
13656
|
+
? gl.UNSIGNED_INT
|
|
13657
|
+
: gl.UNSIGNED_SHORT;
|
|
13307
13658
|
quadrantsToDraw.forEach((qidx) => {
|
|
13308
13659
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer[qidx]);
|
|
13309
|
-
gl.vertexAttribPointer(
|
|
13310
|
-
|
|
13311
|
-
hipsShaderProgram.locations.vertexPositionAttribute, 3, gl.FLOAT, false, 5 * 4, 0);
|
|
13312
|
-
gl.vertexAttribPointer(
|
|
13313
|
-
// this._hipsShaderProgram.locations.textureCoordAttribute,
|
|
13314
|
-
hipsShaderProgram.locations.textureCoordAttribute, 2, gl.FLOAT, false, 5 * 4, 3 * 4);
|
|
13660
|
+
gl.vertexAttribPointer(locations.vertexPositionAttribute, 3, gl.FLOAT, false, 5 * 4, 0);
|
|
13661
|
+
gl.vertexAttribPointer(locations.textureCoordAttribute, 2, gl.FLOAT, false, 5 * 4, 3 * 4);
|
|
13315
13662
|
gl.drawElements(gl.TRIANGLES, elemno, indexType, 0);
|
|
13316
13663
|
});
|
|
13317
|
-
|
|
13318
|
-
|
|
13319
|
-
gl.disableVertexAttribArray(hipsShaderProgram.locations.vertexPositionAttribute);
|
|
13320
|
-
gl.disableVertexAttribArray(hipsShaderProgram.locations.textureCoordAttribute);
|
|
13664
|
+
gl.disableVertexAttribArray(locations.vertexPositionAttribute);
|
|
13665
|
+
gl.disableVertexAttribArray(locations.textureCoordAttribute);
|
|
13321
13666
|
}
|
|
13322
13667
|
drawChildren(visibleOrder, visibleTilesMap, pMatrix, vMatrix, mMatrix, colorMapIdx, hipsShaderProgram) {
|
|
13323
13668
|
const quadrantsToDraw = new Set([0, 1, 2, 3]);
|
|
@@ -13331,13 +13676,9 @@ class Tile {
|
|
|
13331
13676
|
const childTile = this._isGalacticHips
|
|
13332
13677
|
? this._tileBuffer.getGalTile(childTileNo, childrenOrder, this._hips)
|
|
13333
13678
|
: this._tileBuffer.getTile(childTileNo, childrenOrder, this._hips);
|
|
13334
|
-
// const childTile = this._isGalacticHips
|
|
13335
|
-
// ? newTileBuffer.getGalTile(childTileNo, childrenOrder, this._hips)
|
|
13336
|
-
// : newTileBuffer.getTile(childTileNo, childrenOrder, this._hips)
|
|
13337
|
-
// childTile.draw(visibleOrder, visibleTilesMap, pMatrix, vMatrix, mMatrix, colorMapIdx)
|
|
13338
13679
|
childTile.draw(visibleOrder, visibleTilesMap, pMatrix, vMatrix, mMatrix, colorMapIdx, hipsShaderProgram);
|
|
13339
|
-
if (childTile.
|
|
13340
|
-
quadrantsToDraw.delete(
|
|
13680
|
+
if (childTile.getReadyState()) {
|
|
13681
|
+
quadrantsToDraw.delete(c);
|
|
13341
13682
|
}
|
|
13342
13683
|
}
|
|
13343
13684
|
}
|
|
@@ -13352,6 +13693,7 @@ exports["default"] = Tile;
|
|
|
13352
13693
|
/***/ 4006
|
|
13353
13694
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
13354
13695
|
|
|
13696
|
+
"use strict";
|
|
13355
13697
|
|
|
13356
13698
|
/*
|
|
13357
13699
|
* AstroViewer
|
|
@@ -13403,7 +13745,7 @@ class TileBuffer {
|
|
|
13403
13745
|
/** Register an equatorial HiPS into the buffer. */
|
|
13404
13746
|
addHiPS(hips) {
|
|
13405
13747
|
if (this._activeHiPS.has(hips)) {
|
|
13406
|
-
console.error(
|
|
13748
|
+
console.error("HiPS already present in TileBuffer");
|
|
13407
13749
|
return;
|
|
13408
13750
|
}
|
|
13409
13751
|
this._activeHiPS.set(hips, new Map());
|
|
@@ -13411,7 +13753,7 @@ class TileBuffer {
|
|
|
13411
13753
|
/** Register a galactic HiPS into the buffer. */
|
|
13412
13754
|
addGalHiPS(hips) {
|
|
13413
13755
|
if (this._galActiveHiPS.has(hips)) {
|
|
13414
|
-
console.error(
|
|
13756
|
+
console.error("HiPS already present in TileBuffer");
|
|
13415
13757
|
return;
|
|
13416
13758
|
}
|
|
13417
13759
|
this._galActiveHiPS.set(hips, new Map());
|
|
@@ -13436,7 +13778,7 @@ class TileBuffer {
|
|
|
13436
13778
|
}
|
|
13437
13779
|
/** Fetch (or create) an equatorial tile, reviving from cache if present. */
|
|
13438
13780
|
getTile(tileno, order, hips) {
|
|
13439
|
-
const tileKey = this.key(order, tileno, hips
|
|
13781
|
+
const tileKey = this.key(order, tileno, hips);
|
|
13440
13782
|
if (!this._tiles.has(tileKey)) {
|
|
13441
13783
|
if (this._cachedTiles.has(tileKey)) {
|
|
13442
13784
|
const tile = this._cachedTiles.get(tileKey);
|
|
@@ -13454,7 +13796,7 @@ class TileBuffer {
|
|
|
13454
13796
|
}
|
|
13455
13797
|
/** Fetch (or create) a galactic tile, reviving from cache if present. */
|
|
13456
13798
|
getGalTile(tileno, order, hips) {
|
|
13457
|
-
const tileKey = this.key(order, tileno, hips
|
|
13799
|
+
const tileKey = this.key(order, tileno, hips);
|
|
13458
13800
|
if (!this._galTiles.has(tileKey)) {
|
|
13459
13801
|
if (this._galCachedTiles.has(tileKey)) {
|
|
13460
13802
|
const tile = this._galCachedTiles.get(tileKey);
|
|
@@ -13472,7 +13814,7 @@ class TileBuffer {
|
|
|
13472
13814
|
}
|
|
13473
13815
|
/** Move a tile (equatorial or galactic) into cache. */
|
|
13474
13816
|
moveTileToCache(tileno, order, hips) {
|
|
13475
|
-
const tileKey = this.key(order, tileno, hips
|
|
13817
|
+
const tileKey = this.key(order, tileno, hips);
|
|
13476
13818
|
if (this._tiles.has(tileKey)) {
|
|
13477
13819
|
const tile = this._tiles.get(tileKey);
|
|
13478
13820
|
tile.setCacheTime0();
|
|
@@ -13491,29 +13833,64 @@ class TileBuffer {
|
|
|
13491
13833
|
const now = Date.now();
|
|
13492
13834
|
for (const [tileKey, tile] of this._cachedTiles) {
|
|
13493
13835
|
const t0 = tile.cacheTime0;
|
|
13494
|
-
if (!tile.inView &&
|
|
13836
|
+
if (!tile.inView &&
|
|
13837
|
+
t0 !== undefined &&
|
|
13838
|
+
now - t0 > this._cacheAliveMilliSeconds) {
|
|
13495
13839
|
tile.destroyIntervals();
|
|
13496
13840
|
this._cachedTiles.delete(tileKey);
|
|
13497
13841
|
}
|
|
13498
13842
|
}
|
|
13499
13843
|
for (const [tileKey, tile] of this._galCachedTiles) {
|
|
13500
13844
|
const t0 = tile.cacheTime0;
|
|
13501
|
-
if (!tile.inView &&
|
|
13845
|
+
if (!tile.inView &&
|
|
13846
|
+
t0 !== undefined &&
|
|
13847
|
+
now - t0 > this._cacheAliveMilliSeconds) {
|
|
13502
13848
|
tile.destroyIntervals();
|
|
13503
13849
|
this._galCachedTiles.delete(tileKey);
|
|
13504
13850
|
}
|
|
13505
13851
|
}
|
|
13506
13852
|
}
|
|
13507
13853
|
/** Compose a stable key for maps. */
|
|
13508
|
-
key(order, tileno,
|
|
13509
|
-
return `${order}#${tileno}#${baseURL}`;
|
|
13854
|
+
key(order, tileno, hips) {
|
|
13855
|
+
return `${order}#${tileno}#${hips.baseURL}#${hips.format}`;
|
|
13856
|
+
}
|
|
13857
|
+
removeHiPS(hips) {
|
|
13858
|
+
this.invalidateHiPS(hips);
|
|
13859
|
+
this._activeHiPS.delete(hips);
|
|
13860
|
+
this._galActiveHiPS.delete(hips);
|
|
13861
|
+
}
|
|
13862
|
+
/**
|
|
13863
|
+
* Remove all active and cached tiles belonging to a specific HiPS.
|
|
13864
|
+
*
|
|
13865
|
+
* Tile keys contain the HiPS base URL and format. We intentionally
|
|
13866
|
+
* ignore the format here so that a format change removes resources
|
|
13867
|
+
* created with the previous format as well.
|
|
13868
|
+
*/
|
|
13869
|
+
invalidateHiPS(hips) {
|
|
13870
|
+
const belongsToHiPS = (tileKey) => tileKey.includes(`#${hips.baseURL}#`);
|
|
13871
|
+
const clearTiles = (tiles) => {
|
|
13872
|
+
for (const [tileKey, tile] of tiles) {
|
|
13873
|
+
if (!belongsToHiPS(tileKey)) {
|
|
13874
|
+
continue;
|
|
13875
|
+
}
|
|
13876
|
+
tile.destroyIntervals();
|
|
13877
|
+
tiles.delete(tileKey);
|
|
13878
|
+
}
|
|
13879
|
+
};
|
|
13880
|
+
clearTiles(this._tiles);
|
|
13881
|
+
clearTiles(this._cachedTiles);
|
|
13882
|
+
clearTiles(this._galTiles);
|
|
13883
|
+
clearTiles(this._galCachedTiles);
|
|
13510
13884
|
}
|
|
13511
13885
|
/** Optional: call to stop internal timers if you dispose this buffer. */
|
|
13512
13886
|
dispose() {
|
|
13513
13887
|
window.clearInterval(this._cleanerId);
|
|
13514
13888
|
}
|
|
13515
13889
|
get size() {
|
|
13516
|
-
return this._tiles.size +
|
|
13890
|
+
return (this._tiles.size +
|
|
13891
|
+
this._cachedTiles.size +
|
|
13892
|
+
this._galTiles.size +
|
|
13893
|
+
this._galCachedTiles.size);
|
|
13517
13894
|
}
|
|
13518
13895
|
get activeTileCount() {
|
|
13519
13896
|
return this._tiles.size + this._galTiles.size;
|
|
@@ -13572,6 +13949,7 @@ exports.TileBuffer = TileBuffer;
|
|
|
13572
13949
|
/***/ 2056
|
|
13573
13950
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
13574
13951
|
|
|
13952
|
+
"use strict";
|
|
13575
13953
|
|
|
13576
13954
|
/*
|
|
13577
13955
|
* AstroViewer
|
|
@@ -13591,11 +13969,8 @@ exports.VisibleTilesManager = void 0;
|
|
|
13591
13969
|
const Global_js_1 = __importDefault(__webpack_require__(4382));
|
|
13592
13970
|
const healpix_1 = __webpack_require__(4851);
|
|
13593
13971
|
const RayPickingUtils_js_1 = __importDefault(__webpack_require__(4639));
|
|
13594
|
-
// import { newTileBuffer } from './TileBuffer.js';
|
|
13595
13972
|
const TileBuffer_js_1 = __webpack_require__(4006);
|
|
13596
13973
|
const gl_matrix_1 = __webpack_require__(3890);
|
|
13597
|
-
// import healpixGridSingleton from '../grid/HealpixGridSingleton.js';
|
|
13598
|
-
// import {HealpixGridSingleton} from '../grid/HealpixGridSingleton.js';
|
|
13599
13974
|
const Config_js_1 = __webpack_require__(2919);
|
|
13600
13975
|
class VisibleTilesManager {
|
|
13601
13976
|
_visibleTilesByOrder;
|
|
@@ -13635,18 +14010,13 @@ class VisibleTilesManager {
|
|
|
13635
14010
|
init(insideSphere) {
|
|
13636
14011
|
this.initialised = true;
|
|
13637
14012
|
this.insideSphere = insideSphere;
|
|
13638
|
-
// this.computeVisiblePixels();
|
|
13639
|
-
// setInterval(() => this.computeVisiblePixels(), 500);
|
|
13640
14013
|
}
|
|
13641
14014
|
getVisibleOrder() {
|
|
13642
|
-
// return healpixGridSingleton.visibleorder;
|
|
13643
14015
|
return this._healpixGrid.visibleorder;
|
|
13644
14016
|
}
|
|
13645
|
-
// computeVisiblePixels(): void {
|
|
13646
14017
|
computeVisiblePixels(order, webgl, camera, pMatrix) {
|
|
13647
14018
|
if (!this.initialised)
|
|
13648
14019
|
return;
|
|
13649
|
-
// let order = healpixGridSingleton.visibleorder;
|
|
13650
14020
|
if (Global_js_1.default.insideSphere && order < 3) {
|
|
13651
14021
|
order = 3;
|
|
13652
14022
|
}
|
|
@@ -13666,8 +14036,6 @@ class VisibleTilesManager {
|
|
|
13666
14036
|
}
|
|
13667
14037
|
else {
|
|
13668
14038
|
const geomhealpix = Global_js_1.default.getHealpix(order);
|
|
13669
|
-
// const maxX = (global.gl as GL).canvas.width;
|
|
13670
|
-
// const maxY = (global.gl as GL).canvas.height;
|
|
13671
14039
|
const maxX = webgl.canvas.width;
|
|
13672
14040
|
const maxY = webgl.canvas.height;
|
|
13673
14041
|
// Sample a grid of screen points, project to the sphere, then to galactic
|
|
@@ -13687,13 +14055,11 @@ class VisibleTilesManager {
|
|
|
13687
14055
|
if (!pixels.includes(currPixNo)) {
|
|
13688
14056
|
pixels.push(currPixNo);
|
|
13689
14057
|
this._ancestorsMap.get(order).push(currPixNo);
|
|
13690
|
-
// newTileBuffer.addTile(order, currPixNo);
|
|
13691
14058
|
this._tileBuffer.addTile(order, currPixNo);
|
|
13692
14059
|
}
|
|
13693
14060
|
if (!galTiles.includes(galTileNo)) {
|
|
13694
14061
|
galTiles.push(galTileNo);
|
|
13695
14062
|
this._galAncestorsMap.get(order).push(galTileNo);
|
|
13696
|
-
// newTileBuffer.addGalTile(order, galTileNo);
|
|
13697
14063
|
this._tileBuffer.addGalTile(order, galTileNo);
|
|
13698
14064
|
}
|
|
13699
14065
|
}
|
|
@@ -13711,7 +14077,6 @@ class VisibleTilesManager {
|
|
|
13711
14077
|
const parent = pixels[p] >> (2 * o);
|
|
13712
14078
|
if (!list.includes(parent)) {
|
|
13713
14079
|
list.push(parent);
|
|
13714
|
-
// newTileBuffer.addTile(tgtOrder, parent);
|
|
13715
14080
|
this._tileBuffer.addTile(tgtOrder, parent);
|
|
13716
14081
|
}
|
|
13717
14082
|
}
|
|
@@ -13724,7 +14089,6 @@ class VisibleTilesManager {
|
|
|
13724
14089
|
const parent = galTiles[p] >> (2 * o);
|
|
13725
14090
|
if (!list.includes(parent)) {
|
|
13726
14091
|
list.push(parent);
|
|
13727
|
-
// newTileBuffer.addGalTile(tgtOrder, parent);
|
|
13728
14092
|
this._tileBuffer.addGalTile(tgtOrder, parent);
|
|
13729
14093
|
}
|
|
13730
14094
|
}
|
|
@@ -13755,6 +14119,7 @@ exports.VisibleTilesManager = VisibleTilesManager;
|
|
|
13755
14119
|
/***/ 6878
|
|
13756
14120
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
13757
14121
|
|
|
14122
|
+
"use strict";
|
|
13758
14123
|
|
|
13759
14124
|
/*
|
|
13760
14125
|
* AstroViewer
|
|
@@ -13948,6 +14313,7 @@ exports.MeshHiPS = MeshHiPS;
|
|
|
13948
14313
|
/***/ 847
|
|
13949
14314
|
(__unused_webpack_module, exports) {
|
|
13950
14315
|
|
|
14316
|
+
"use strict";
|
|
13951
14317
|
|
|
13952
14318
|
/*
|
|
13953
14319
|
* AstroViewer
|
|
@@ -14091,6 +14457,7 @@ exports.MeshHiPSDescriptor = MeshHiPSDescriptor;
|
|
|
14091
14457
|
/***/ 8170
|
|
14092
14458
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
14093
14459
|
|
|
14460
|
+
"use strict";
|
|
14094
14461
|
var __webpack_unused_export__;
|
|
14095
14462
|
|
|
14096
14463
|
/*
|
|
@@ -14251,6 +14618,7 @@ exports.MeshHiPSTile = MeshHiPSTile;
|
|
|
14251
14618
|
/***/ 4322
|
|
14252
14619
|
(__unused_webpack_module, exports) {
|
|
14253
14620
|
|
|
14621
|
+
"use strict";
|
|
14254
14622
|
var __webpack_unused_export__;
|
|
14255
14623
|
|
|
14256
14624
|
/*
|
|
@@ -14471,6 +14839,7 @@ exports.OBJMeshParser = OBJMeshParser;
|
|
|
14471
14839
|
/***/ 8022
|
|
14472
14840
|
(__unused_webpack_module, exports) {
|
|
14473
14841
|
|
|
14842
|
+
"use strict";
|
|
14474
14843
|
|
|
14475
14844
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
14476
14845
|
exports.ObservationTrackTimeline = void 0;
|
|
@@ -14715,6 +15084,7 @@ function clamp01(value) {
|
|
|
14715
15084
|
/***/ 5772
|
|
14716
15085
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
14717
15086
|
|
|
15087
|
+
"use strict";
|
|
14718
15088
|
|
|
14719
15089
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14720
15090
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -15056,6 +15426,7 @@ function createMarkerColumns() {
|
|
|
15056
15426
|
/***/ 5866
|
|
15057
15427
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15058
15428
|
|
|
15429
|
+
"use strict";
|
|
15059
15430
|
|
|
15060
15431
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
15061
15432
|
exports.ObservationTrackViewerAdapter = exports.ObservationTrackTimeline = exports.footprintToRing = exports.createObservationTrackTimeline = void 0;
|
|
@@ -15072,6 +15443,7 @@ Object.defineProperty(exports, "ObservationTrackViewerAdapter", ({ enumerable: t
|
|
|
15072
15443
|
/***/ 3603
|
|
15073
15444
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15074
15445
|
|
|
15446
|
+
"use strict";
|
|
15075
15447
|
|
|
15076
15448
|
/*
|
|
15077
15449
|
* AstroViewer
|
|
@@ -15303,6 +15675,7 @@ function normalizeLongitudeDeg(longitudeDeg) {
|
|
|
15303
15675
|
/***/ 3102
|
|
15304
15676
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15305
15677
|
|
|
15678
|
+
"use strict";
|
|
15306
15679
|
|
|
15307
15680
|
/*
|
|
15308
15681
|
* AstroViewer
|
|
@@ -15506,6 +15879,7 @@ function normalizeLongitudeDeg(longitudeDeg) {
|
|
|
15506
15879
|
/***/ 9022
|
|
15507
15880
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15508
15881
|
|
|
15882
|
+
"use strict";
|
|
15509
15883
|
|
|
15510
15884
|
/*
|
|
15511
15885
|
* AstroViewer
|
|
@@ -15573,6 +15947,7 @@ exports.TerraFootprintSetGL = TerraFootprintSetGL;
|
|
|
15573
15947
|
/***/ 5781
|
|
15574
15948
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15575
15949
|
|
|
15950
|
+
"use strict";
|
|
15576
15951
|
|
|
15577
15952
|
/*
|
|
15578
15953
|
* AstroViewer
|
|
@@ -15598,6 +15973,7 @@ exports.TerraPointSetGL = TerraPointSetGL;
|
|
|
15598
15973
|
/***/ 3665
|
|
15599
15974
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15600
15975
|
|
|
15976
|
+
"use strict";
|
|
15601
15977
|
|
|
15602
15978
|
/*
|
|
15603
15979
|
* AstroViewer
|
|
@@ -15786,6 +16162,7 @@ function normalizeLongitudeDeg(longitudeDeg) {
|
|
|
15786
16162
|
/***/ 3559
|
|
15787
16163
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15788
16164
|
|
|
16165
|
+
"use strict";
|
|
15789
16166
|
|
|
15790
16167
|
/*
|
|
15791
16168
|
* AstroViewer
|
|
@@ -15903,6 +16280,7 @@ exports.CatalogueShaderProgram = CatalogueShaderProgram;
|
|
|
15903
16280
|
/***/ 8909
|
|
15904
16281
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
15905
16282
|
|
|
16283
|
+
"use strict";
|
|
15906
16284
|
|
|
15907
16285
|
/*
|
|
15908
16286
|
* AstroViewer
|
|
@@ -16012,6 +16390,7 @@ exports.FootprintShaderProgram = FootprintShaderProgram;
|
|
|
16012
16390
|
/***/ 4707
|
|
16013
16391
|
(__unused_webpack_module, exports) {
|
|
16014
16392
|
|
|
16393
|
+
"use strict";
|
|
16015
16394
|
/*
|
|
16016
16395
|
* AstroViewer
|
|
16017
16396
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -16058,6 +16437,7 @@ exports["default"] = GridShaderManager;
|
|
|
16058
16437
|
/***/ 7786
|
|
16059
16438
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
16060
16439
|
|
|
16440
|
+
"use strict";
|
|
16061
16441
|
|
|
16062
16442
|
/*
|
|
16063
16443
|
* AstroViewer
|
|
@@ -16088,7 +16468,7 @@ class HiPSShaderProgram {
|
|
|
16088
16468
|
_UBO_colorMapVariableInfo = {
|
|
16089
16469
|
r_palette: { index: 0, offset: 0 },
|
|
16090
16470
|
g_palette: { index: 0, offset: 0 },
|
|
16091
|
-
b_palette: { index: 0, offset: 0 }
|
|
16471
|
+
b_palette: { index: 0, offset: 0 },
|
|
16092
16472
|
};
|
|
16093
16473
|
gl_uniforms;
|
|
16094
16474
|
gl_attributes;
|
|
@@ -16097,54 +16477,60 @@ class HiPSShaderProgram {
|
|
|
16097
16477
|
constructor(webgl) {
|
|
16098
16478
|
this._webgl = webgl;
|
|
16099
16479
|
this.gl_uniforms = {
|
|
16100
|
-
sampler:
|
|
16101
|
-
factor:
|
|
16102
|
-
m_perspective:
|
|
16103
|
-
m_model:
|
|
16104
|
-
m_view:
|
|
16105
|
-
colormapIdx:
|
|
16106
|
-
colormap_red:
|
|
16107
|
-
colormap_green:
|
|
16108
|
-
colormap_blue:
|
|
16480
|
+
sampler: "uSampler0",
|
|
16481
|
+
factor: "uFactor0",
|
|
16482
|
+
m_perspective: "uPMatrix",
|
|
16483
|
+
m_model: "uMMatrix",
|
|
16484
|
+
m_view: "uVMatrix",
|
|
16485
|
+
colormapIdx: "cmapIdx",
|
|
16486
|
+
colormap_red: "r",
|
|
16487
|
+
colormap_green: "g",
|
|
16488
|
+
colormap_blue: "b",
|
|
16489
|
+
textureMode: "uTextureMode",
|
|
16490
|
+
dataMin: "uDataMin",
|
|
16491
|
+
dataMax: "uDataMax",
|
|
16109
16492
|
};
|
|
16110
16493
|
this.gl_attributes = {
|
|
16111
|
-
vertex_pos:
|
|
16112
|
-
text_coords:
|
|
16494
|
+
vertex_pos: "aVertexPosition",
|
|
16495
|
+
text_coords: "aTextureCoord",
|
|
16113
16496
|
};
|
|
16114
16497
|
this.locations = {
|
|
16115
16498
|
pMatrix: null,
|
|
16116
16499
|
mMatrix: null,
|
|
16117
16500
|
vMatrix: null,
|
|
16118
|
-
|
|
16119
|
-
textureAlpha: null,
|
|
16501
|
+
samplers: new Array(8).fill(null),
|
|
16502
|
+
textureAlpha: new Array(8).fill(null),
|
|
16503
|
+
textureMode: new Array(8).fill(null),
|
|
16504
|
+
dataMin: new Array(8).fill(null),
|
|
16505
|
+
dataMax: new Array(8).fill(null),
|
|
16120
16506
|
clorMapIdx: null,
|
|
16121
16507
|
vertexPositionAttribute: -1,
|
|
16122
|
-
textureCoordAttribute: -1
|
|
16508
|
+
textureCoordAttribute: -1,
|
|
16123
16509
|
};
|
|
16124
16510
|
}
|
|
16125
16511
|
get shaderProgram() {
|
|
16126
16512
|
const gl = this._webgl;
|
|
16127
16513
|
if (!this._shaderProgram) {
|
|
16128
|
-
|
|
16129
|
-
this._shaderProgram =
|
|
16130
|
-
this.initShaders();
|
|
16514
|
+
const program = gl.createProgram();
|
|
16515
|
+
this._shaderProgram = program;
|
|
16516
|
+
this.initShaders(program);
|
|
16131
16517
|
}
|
|
16132
|
-
;
|
|
16133
16518
|
gl.useProgram(this._shaderProgram);
|
|
16134
16519
|
return this._shaderProgram;
|
|
16135
16520
|
}
|
|
16136
16521
|
setRuntimeColorMap(colorMap) {
|
|
16137
16522
|
this._runtimeColorMap = colorMap;
|
|
16138
16523
|
}
|
|
16139
|
-
initShaders() {
|
|
16140
|
-
// const gl = global.gl
|
|
16524
|
+
initShaders(program) {
|
|
16525
|
+
// const gl = global.gl
|
|
16141
16526
|
const gl = this._webgl;
|
|
16142
16527
|
const fragmentShaderStr = ShaderManager_js_1.default.hipsNativeFS();
|
|
16143
16528
|
this._fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
16144
16529
|
gl.shaderSource(this._fragmentShader, fragmentShaderStr);
|
|
16145
16530
|
gl.compileShader(this._fragmentShader);
|
|
16146
16531
|
if (!gl.getShaderParameter(this._fragmentShader, gl.COMPILE_STATUS)) {
|
|
16147
|
-
alert(gl.getShaderInfoLog(this._fragmentShader) ||
|
|
16532
|
+
alert(gl.getShaderInfoLog(this._fragmentShader) ||
|
|
16533
|
+
"Fragment shader compile error");
|
|
16148
16534
|
return;
|
|
16149
16535
|
}
|
|
16150
16536
|
const vertexShaderStr = ShaderManager_js_1.default.hipsVS();
|
|
@@ -16152,43 +16538,44 @@ class HiPSShaderProgram {
|
|
|
16152
16538
|
gl.shaderSource(this._vertexShader, vertexShaderStr);
|
|
16153
16539
|
gl.compileShader(this._vertexShader);
|
|
16154
16540
|
if (!gl.getShaderParameter(this._vertexShader, gl.COMPILE_STATUS)) {
|
|
16155
|
-
alert(gl.getShaderInfoLog(this._vertexShader) ||
|
|
16541
|
+
alert(gl.getShaderInfoLog(this._vertexShader) ||
|
|
16542
|
+
"Vertex shader compile error");
|
|
16156
16543
|
return;
|
|
16157
16544
|
}
|
|
16158
|
-
gl.attachShader(
|
|
16159
|
-
gl.attachShader(
|
|
16160
|
-
gl.linkProgram(
|
|
16161
|
-
if (!gl.getProgramParameter(
|
|
16162
|
-
alert(
|
|
16545
|
+
gl.attachShader(program, this._vertexShader);
|
|
16546
|
+
gl.attachShader(program, this._fragmentShader);
|
|
16547
|
+
gl.linkProgram(program);
|
|
16548
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
16549
|
+
alert("Could not initialise shaders");
|
|
16163
16550
|
}
|
|
16164
16551
|
}
|
|
16165
16552
|
enableProgram() {
|
|
16166
|
-
// (global.gl
|
|
16553
|
+
// (global.gl).useProgram(this._shaderProgram)
|
|
16167
16554
|
this._webgl.useProgram(this.shaderProgram);
|
|
16168
16555
|
}
|
|
16169
16556
|
setGrayscaleShader() {
|
|
16170
|
-
// const gl = global.gl
|
|
16557
|
+
// const gl = global.gl
|
|
16171
16558
|
const gl = this._webgl;
|
|
16172
16559
|
gl.detachShader(this.shaderProgram, this._fragmentShader);
|
|
16173
16560
|
const fragmentShaderStr = ShaderManager_js_1.default.hipsGrayscaleFS();
|
|
16174
16561
|
this.changeFSShader(fragmentShaderStr);
|
|
16175
16562
|
}
|
|
16176
16563
|
setNativeShader() {
|
|
16177
|
-
// const gl = global.gl
|
|
16564
|
+
// const gl = global.gl
|
|
16178
16565
|
const gl = this._webgl;
|
|
16179
16566
|
gl.detachShader(this.shaderProgram, this._fragmentShader);
|
|
16180
16567
|
const fragmentShaderStr = ShaderManager_js_1.default.hipsNativeFS();
|
|
16181
16568
|
this.changeFSShader(fragmentShaderStr);
|
|
16182
16569
|
}
|
|
16183
16570
|
setColorMapShader() {
|
|
16184
|
-
// const gl = global.gl
|
|
16571
|
+
// const gl = global.gl
|
|
16185
16572
|
const gl = this._webgl;
|
|
16186
16573
|
// Swap fragment shader
|
|
16187
16574
|
gl.detachShader(this.shaderProgram, this._fragmentShader);
|
|
16188
16575
|
const fragmentShaderStr = ShaderManager_js_1.default.hipsColorMapFS();
|
|
16189
16576
|
this.changeFSShader(fragmentShaderStr);
|
|
16190
16577
|
// UBO discovery for the "colormap" block
|
|
16191
|
-
const blockIndex = gl.getUniformBlockIndex(this.shaderProgram,
|
|
16578
|
+
const blockIndex = gl.getUniformBlockIndex(this.shaderProgram, "colormap");
|
|
16192
16579
|
// INVALID_INDEX == 0xFFFFFFFF in WebGL2
|
|
16193
16580
|
if (blockIndex === gl.INVALID_INDEX) {
|
|
16194
16581
|
console.warn('HiPSShaderProgram: uniform block "colormap" not found in hipsColorMapFS()');
|
|
@@ -16198,11 +16585,11 @@ class HiPSShaderProgram {
|
|
|
16198
16585
|
}
|
|
16199
16586
|
this._colorMapBlockIndex = blockIndex;
|
|
16200
16587
|
// const blockSize = gl.getActiveUniformBlockParameter(
|
|
16201
|
-
// this.shaderProgram
|
|
16588
|
+
// this.shaderProgram,
|
|
16202
16589
|
// blockIndex,
|
|
16203
16590
|
// gl.UNIFORM_BLOCK_DATA_SIZE
|
|
16204
16591
|
// ) as number
|
|
16205
|
-
const uboVariableNames = [
|
|
16592
|
+
const uboVariableNames = ["r_palette", "g_palette", "b_palette"];
|
|
16206
16593
|
const uboVariableIndices = gl.getUniformIndices(this.shaderProgram, uboVariableNames);
|
|
16207
16594
|
const uboVariableOffsets = gl.getActiveUniforms(this.shaderProgram, uboVariableIndices, gl.UNIFORM_OFFSET);
|
|
16208
16595
|
// Create buffer only once
|
|
@@ -16219,49 +16606,80 @@ class HiPSShaderProgram {
|
|
|
16219
16606
|
uboVariableNames.forEach((name, index) => {
|
|
16220
16607
|
this._UBO_colorMapVariableInfo[name] = {
|
|
16221
16608
|
index: uboVariableIndices[index],
|
|
16222
|
-
offset: uboVariableOffsets[index]
|
|
16609
|
+
offset: uboVariableOffsets[index],
|
|
16223
16610
|
};
|
|
16224
16611
|
});
|
|
16225
16612
|
}
|
|
16226
16613
|
changeFSShader(fragmentShaderStr) {
|
|
16227
|
-
// const gl = global.gl
|
|
16614
|
+
// const gl = global.gl
|
|
16228
16615
|
const gl = this._webgl;
|
|
16229
16616
|
this._fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
16230
16617
|
gl.shaderSource(this._fragmentShader, fragmentShaderStr);
|
|
16231
16618
|
gl.compileShader(this._fragmentShader);
|
|
16232
16619
|
if (!gl.getShaderParameter(this._fragmentShader, gl.COMPILE_STATUS)) {
|
|
16233
|
-
alert(gl.getShaderInfoLog(this._fragmentShader) ||
|
|
16620
|
+
alert(gl.getShaderInfoLog(this._fragmentShader) ||
|
|
16621
|
+
"Fragment shader compile error");
|
|
16234
16622
|
return;
|
|
16235
16623
|
}
|
|
16236
16624
|
gl.attachShader(this.shaderProgram, this._fragmentShader);
|
|
16237
16625
|
gl.linkProgram(this.shaderProgram);
|
|
16238
16626
|
if (!gl.getProgramParameter(this.shaderProgram, gl.LINK_STATUS)) {
|
|
16239
|
-
alert(
|
|
16627
|
+
alert("Could not initialise shaders");
|
|
16240
16628
|
}
|
|
16241
16629
|
gl.useProgram(this.shaderProgram);
|
|
16242
16630
|
}
|
|
16631
|
+
setTextureDataMode(samplerIndex, fits, min, max) {
|
|
16632
|
+
if (samplerIndex < 0 || samplerIndex >= 8) {
|
|
16633
|
+
throw new Error(`Invalid HiPS sampler index: ${samplerIndex}`);
|
|
16634
|
+
}
|
|
16635
|
+
const gl = this._webgl;
|
|
16636
|
+
const modeLocation = this.locations.textureMode[samplerIndex];
|
|
16637
|
+
if (modeLocation) {
|
|
16638
|
+
gl.uniform1i(modeLocation, fits ? 1 : 0);
|
|
16639
|
+
}
|
|
16640
|
+
if (!fits) {
|
|
16641
|
+
return;
|
|
16642
|
+
}
|
|
16643
|
+
if (min === undefined ||
|
|
16644
|
+
max === undefined ||
|
|
16645
|
+
!Number.isFinite(min) ||
|
|
16646
|
+
!Number.isFinite(max) ||
|
|
16647
|
+
max <= min) {
|
|
16648
|
+
throw new Error("Invalid FITS display range.");
|
|
16649
|
+
}
|
|
16650
|
+
const minLocation = this.locations.dataMin[samplerIndex];
|
|
16651
|
+
const maxLocation = this.locations.dataMax[samplerIndex];
|
|
16652
|
+
if (minLocation) {
|
|
16653
|
+
gl.uniform1f(minLocation, min);
|
|
16654
|
+
}
|
|
16655
|
+
if (maxLocation) {
|
|
16656
|
+
gl.uniform1f(maxLocation, max);
|
|
16657
|
+
}
|
|
16658
|
+
}
|
|
16243
16659
|
enableShaders(pMatrix, vMatrix, mMatrix, colorMapIdx) {
|
|
16244
|
-
// const gl = global.gl
|
|
16660
|
+
// const gl = global.gl
|
|
16245
16661
|
const gl = this._webgl;
|
|
16246
16662
|
gl.useProgram(this.shaderProgram);
|
|
16247
16663
|
this.locations.pMatrix = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.m_perspective);
|
|
16248
16664
|
this.locations.mMatrix = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.m_model);
|
|
16249
16665
|
this.locations.vMatrix = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.m_view);
|
|
16250
|
-
this.locations.sampler = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.sampler);
|
|
16251
|
-
this.locations.textureAlpha = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.factor);
|
|
16252
16666
|
this.locations.clorMapIdx = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.colormapIdx);
|
|
16253
|
-
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16257
|
-
|
|
16258
|
-
|
|
16259
|
-
|
|
16667
|
+
for (let i = 0; i < 8; i++) {
|
|
16668
|
+
this.locations.samplers[i] = gl.getUniformLocation(this.shaderProgram, `uSampler${i}`);
|
|
16669
|
+
this.locations.textureAlpha[i] = gl.getUniformLocation(this.shaderProgram, `uFactor${i}`);
|
|
16670
|
+
this.locations.textureMode[i] = gl.getUniformLocation(this.shaderProgram, `uTextureMode${i}`);
|
|
16671
|
+
this.locations.dataMin[i] = gl.getUniformLocation(this.shaderProgram, `uDataMin${i}`);
|
|
16672
|
+
this.locations.dataMax[i] = gl.getUniformLocation(this.shaderProgram, `uDataMax${i}`);
|
|
16673
|
+
if (this.locations.samplers[i]) {
|
|
16674
|
+
gl.uniform1i(this.locations.samplers[i], i);
|
|
16675
|
+
}
|
|
16260
16676
|
}
|
|
16261
|
-
|
|
16677
|
+
gl.uniform1i(this.locations.clorMapIdx, colorMapIdx);
|
|
16262
16678
|
this.locations.vertexPositionAttribute = gl.getAttribLocation(this.shaderProgram, this.gl_attributes.vertex_pos);
|
|
16263
16679
|
this.locations.textureCoordAttribute = gl.getAttribLocation(this.shaderProgram, this.gl_attributes.text_coords);
|
|
16264
|
-
if (colorMapIdx >= 2 &&
|
|
16680
|
+
if (colorMapIdx >= 2 &&
|
|
16681
|
+
this._UBO_colorMapBuffer &&
|
|
16682
|
+
this._colorMapBlockIndex !== null) {
|
|
16265
16683
|
gl.uniformBlockBinding(this.shaderProgram, this._colorMapBlockIndex, 0);
|
|
16266
16684
|
gl.bindBuffer(gl.UNIFORM_BUFFER, this._UBO_colorMapBuffer);
|
|
16267
16685
|
let currentColorMap;
|
|
@@ -16338,6 +16756,7 @@ exports.HiPSShaderProgram = HiPSShaderProgram;
|
|
|
16338
16756
|
/***/ 2257
|
|
16339
16757
|
(__unused_webpack_module, exports) {
|
|
16340
16758
|
|
|
16759
|
+
"use strict";
|
|
16341
16760
|
var __webpack_unused_export__;
|
|
16342
16761
|
|
|
16343
16762
|
/*
|
|
@@ -16454,6 +16873,7 @@ exports.MeshHiPSShaderProgram = MeshHiPSShaderProgram;
|
|
|
16454
16873
|
/***/ 5947
|
|
16455
16874
|
(__unused_webpack_module, exports) {
|
|
16456
16875
|
|
|
16876
|
+
"use strict";
|
|
16457
16877
|
|
|
16458
16878
|
/*
|
|
16459
16879
|
* AstroViewer
|
|
@@ -16634,15 +17054,6 @@ class ShaderManager {
|
|
|
16634
17054
|
|
|
16635
17055
|
in vec2 vTextureCoord;
|
|
16636
17056
|
|
|
16637
|
-
uniform sampler2D uSampler0;
|
|
16638
|
-
uniform sampler2D uSampler1;
|
|
16639
|
-
uniform sampler2D uSampler2;
|
|
16640
|
-
uniform sampler2D uSampler3;
|
|
16641
|
-
uniform sampler2D uSampler4;
|
|
16642
|
-
uniform sampler2D uSampler5;
|
|
16643
|
-
uniform sampler2D uSampler6;
|
|
16644
|
-
uniform sampler2D uSampler7;
|
|
16645
|
-
|
|
16646
17057
|
uniform float uFactor0;
|
|
16647
17058
|
uniform float uFactor1;
|
|
16648
17059
|
uniform float uFactor2;
|
|
@@ -16652,23 +17063,53 @@ class ShaderManager {
|
|
|
16652
17063
|
uniform float uFactor6;
|
|
16653
17064
|
uniform float uFactor7;
|
|
16654
17065
|
|
|
17066
|
+
${ShaderManager.hipsSamplersGLSL()}
|
|
17067
|
+
|
|
16655
17068
|
out vec4 fragColor;
|
|
16656
17069
|
|
|
16657
17070
|
void main() {
|
|
16658
17071
|
vec3 finalColor = vec3(0.0);
|
|
16659
17072
|
|
|
16660
|
-
if (uFactor0 >= 0.0){
|
|
16661
|
-
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16668
|
-
|
|
16669
|
-
|
|
16670
|
-
|
|
17073
|
+
if (uFactor0 >= 0.0) {
|
|
17074
|
+
finalColor +=
|
|
17075
|
+
sampleHiPSTexture0(vTextureCoord).rgb * uFactor0;
|
|
17076
|
+
}
|
|
17077
|
+
|
|
17078
|
+
if (uFactor1 >= 0.0) {
|
|
17079
|
+
finalColor +=
|
|
17080
|
+
sampleHiPSTexture1(vTextureCoord).rgb * uFactor1;
|
|
17081
|
+
}
|
|
17082
|
+
|
|
17083
|
+
if (uFactor2 >= 0.0) {
|
|
17084
|
+
finalColor +=
|
|
17085
|
+
sampleHiPSTexture2(vTextureCoord).rgb * uFactor2;
|
|
16671
17086
|
}
|
|
17087
|
+
|
|
17088
|
+
if (uFactor3 >= 0.0) {
|
|
17089
|
+
finalColor +=
|
|
17090
|
+
sampleHiPSTexture3(vTextureCoord).rgb * uFactor3;
|
|
17091
|
+
}
|
|
17092
|
+
|
|
17093
|
+
if (uFactor4 >= 0.0) {
|
|
17094
|
+
finalColor +=
|
|
17095
|
+
sampleHiPSTexture4(vTextureCoord).rgb * uFactor4;
|
|
17096
|
+
}
|
|
17097
|
+
|
|
17098
|
+
if (uFactor5 >= 0.0) {
|
|
17099
|
+
finalColor +=
|
|
17100
|
+
sampleHiPSTexture5(vTextureCoord).rgb * uFactor5;
|
|
17101
|
+
}
|
|
17102
|
+
|
|
17103
|
+
if (uFactor6 >= 0.0) {
|
|
17104
|
+
finalColor +=
|
|
17105
|
+
sampleHiPSTexture6(vTextureCoord).rgb * uFactor6;
|
|
17106
|
+
}
|
|
17107
|
+
|
|
17108
|
+
if (uFactor7 >= 0.0) {
|
|
17109
|
+
finalColor +=
|
|
17110
|
+
sampleHiPSTexture7(vTextureCoord).rgb * uFactor7;
|
|
17111
|
+
}
|
|
17112
|
+
|
|
16672
17113
|
fragColor = vec4(finalColor, 1.0);
|
|
16673
17114
|
}`;
|
|
16674
17115
|
}
|
|
@@ -16678,15 +17119,6 @@ class ShaderManager {
|
|
|
16678
17119
|
|
|
16679
17120
|
in vec2 vTextureCoord;
|
|
16680
17121
|
|
|
16681
|
-
uniform sampler2D uSampler0;
|
|
16682
|
-
uniform sampler2D uSampler1;
|
|
16683
|
-
uniform sampler2D uSampler2;
|
|
16684
|
-
uniform sampler2D uSampler3;
|
|
16685
|
-
uniform sampler2D uSampler4;
|
|
16686
|
-
uniform sampler2D uSampler5;
|
|
16687
|
-
uniform sampler2D uSampler6;
|
|
16688
|
-
uniform sampler2D uSampler7;
|
|
16689
|
-
|
|
16690
17122
|
uniform float uFactor0;
|
|
16691
17123
|
uniform float uFactor1;
|
|
16692
17124
|
uniform float uFactor2;
|
|
@@ -16696,76 +17128,61 @@ class ShaderManager {
|
|
|
16696
17128
|
uniform float uFactor6;
|
|
16697
17129
|
uniform float uFactor7;
|
|
16698
17130
|
|
|
17131
|
+
${ShaderManager.hipsSamplersGLSL()}
|
|
17132
|
+
|
|
16699
17133
|
out vec4 fragColor;
|
|
16700
17134
|
|
|
16701
17135
|
void main() {
|
|
16702
17136
|
vec3 finalColor = vec3(0.0);
|
|
16703
17137
|
|
|
16704
|
-
if (uFactor0 >= 0.0){
|
|
16705
|
-
|
|
16706
|
-
|
|
16707
|
-
|
|
16708
|
-
|
|
16709
|
-
|
|
16710
|
-
|
|
16711
|
-
|
|
17138
|
+
if (uFactor0 >= 0.0) {
|
|
17139
|
+
vec4 color0 = sampleHiPSTexture0(vTextureCoord);
|
|
17140
|
+
|
|
17141
|
+
float gray =
|
|
17142
|
+
0.21 * color0.r +
|
|
17143
|
+
0.71 * color0.g +
|
|
17144
|
+
0.07 * color0.b;
|
|
17145
|
+
|
|
17146
|
+
finalColor =
|
|
17147
|
+
color0.rgb * (1.0 - uFactor0) +
|
|
17148
|
+
vec3(gray) * uFactor0;
|
|
16712
17149
|
}
|
|
16713
|
-
|
|
16714
|
-
|
|
16715
|
-
|
|
16716
|
-
#else
|
|
16717
|
-
vec4 color1 = texture2D(uSampler1, vTextureCoord);
|
|
16718
|
-
#endif
|
|
17150
|
+
|
|
17151
|
+
if (uFactor1 >= 0.0) {
|
|
17152
|
+
vec4 color1 = sampleHiPSTexture1(vTextureCoord);
|
|
16719
17153
|
finalColor += color1.rgb * uFactor1;
|
|
16720
17154
|
}
|
|
16721
|
-
|
|
16722
|
-
|
|
16723
|
-
|
|
16724
|
-
#else
|
|
16725
|
-
vec4 color2 = texture2D(uSampler2, vTextureCoord);
|
|
16726
|
-
#endif
|
|
17155
|
+
|
|
17156
|
+
if (uFactor2 >= 0.0) {
|
|
17157
|
+
vec4 color2 = sampleHiPSTexture2(vTextureCoord);
|
|
16727
17158
|
finalColor += color2.rgb * uFactor2;
|
|
16728
17159
|
}
|
|
16729
|
-
|
|
16730
|
-
|
|
16731
|
-
|
|
16732
|
-
#else
|
|
16733
|
-
vec4 color3 = texture2D(uSampler3, vTextureCoord);
|
|
16734
|
-
#endif
|
|
17160
|
+
|
|
17161
|
+
if (uFactor3 >= 0.0) {
|
|
17162
|
+
vec4 color3 = sampleHiPSTexture3(vTextureCoord);
|
|
16735
17163
|
finalColor += color3.rgb * uFactor3;
|
|
16736
17164
|
}
|
|
16737
|
-
|
|
16738
|
-
|
|
16739
|
-
|
|
16740
|
-
#else
|
|
16741
|
-
vec4 color4 = texture2D(uSampler4, vTextureCoord);
|
|
16742
|
-
#endif
|
|
17165
|
+
|
|
17166
|
+
if (uFactor4 >= 0.0) {
|
|
17167
|
+
vec4 color4 = sampleHiPSTexture4(vTextureCoord);
|
|
16743
17168
|
finalColor += color4.rgb * uFactor4;
|
|
16744
17169
|
}
|
|
16745
|
-
|
|
16746
|
-
|
|
16747
|
-
|
|
16748
|
-
#else
|
|
16749
|
-
vec4 color5 = texture2D(uSampler5, vTextureCoord);
|
|
16750
|
-
#endif
|
|
17170
|
+
|
|
17171
|
+
if (uFactor5 >= 0.0) {
|
|
17172
|
+
vec4 color5 = sampleHiPSTexture5(vTextureCoord);
|
|
16751
17173
|
finalColor += color5.rgb * uFactor5;
|
|
16752
17174
|
}
|
|
16753
|
-
|
|
16754
|
-
|
|
16755
|
-
|
|
16756
|
-
#else
|
|
16757
|
-
vec4 color6 = texture2D(uSampler6, vTextureCoord);
|
|
16758
|
-
#endif
|
|
17175
|
+
|
|
17176
|
+
if (uFactor6 >= 0.0) {
|
|
17177
|
+
vec4 color6 = sampleHiPSTexture6(vTextureCoord);
|
|
16759
17178
|
finalColor += color6.rgb * uFactor6;
|
|
16760
17179
|
}
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
#else
|
|
16765
|
-
vec4 color7 = texture2D(uSampler7, vTextureCoord);
|
|
16766
|
-
#endif
|
|
17180
|
+
|
|
17181
|
+
if (uFactor7 >= 0.0) {
|
|
17182
|
+
vec4 color7 = sampleHiPSTexture7(vTextureCoord);
|
|
16767
17183
|
finalColor += color7.rgb * uFactor7;
|
|
16768
17184
|
}
|
|
17185
|
+
|
|
16769
17186
|
fragColor = vec4(finalColor, 1.0);
|
|
16770
17187
|
}`;
|
|
16771
17188
|
}
|
|
@@ -16775,38 +17192,140 @@ class ShaderManager {
|
|
|
16775
17192
|
|
|
16776
17193
|
in vec2 vTextureCoord;
|
|
16777
17194
|
|
|
16778
|
-
// UBO
|
|
16779
17195
|
layout (std140) uniform colormap {
|
|
16780
17196
|
float r_palette[256];
|
|
16781
17197
|
float g_palette[256];
|
|
16782
17198
|
float b_palette[256];
|
|
16783
17199
|
};
|
|
16784
17200
|
|
|
16785
|
-
uniform sampler2D uSampler0;
|
|
16786
17201
|
uniform float uFactor0;
|
|
17202
|
+
uniform float uFactor1;
|
|
17203
|
+
uniform float uFactor2;
|
|
17204
|
+
uniform float uFactor3;
|
|
17205
|
+
uniform float uFactor4;
|
|
17206
|
+
uniform float uFactor5;
|
|
17207
|
+
uniform float uFactor6;
|
|
17208
|
+
uniform float uFactor7;
|
|
17209
|
+
|
|
17210
|
+
${ShaderManager.hipsSamplersGLSL()}
|
|
16787
17211
|
|
|
16788
17212
|
out vec4 fragColor;
|
|
16789
17213
|
|
|
16790
|
-
|
|
16791
|
-
|
|
16792
|
-
|
|
16793
|
-
|
|
16794
|
-
vec4 color0 = texture2D(uSampler0, vTextureCoord);
|
|
16795
|
-
#endif
|
|
17214
|
+
vec3 applyColorMap(vec4 color) {
|
|
17215
|
+
int x = int(clamp(color.r, 0.0, 1.0) * 255.0);
|
|
17216
|
+
int y = int(clamp(color.g, 0.0, 1.0) * 255.0);
|
|
17217
|
+
int z = int(clamp(color.b, 0.0, 1.0) * 255.0);
|
|
16796
17218
|
|
|
16797
|
-
int x = int(color0.r * 255.0);
|
|
16798
17219
|
float px = r_palette[x] / 256.0;
|
|
16799
|
-
|
|
16800
|
-
int y = int(color0.g * 255.0);
|
|
16801
17220
|
float py = g_palette[y] / 256.0;
|
|
16802
|
-
|
|
16803
|
-
int z = int(color0.b * 255.0);
|
|
16804
17221
|
float pz = b_palette[z] / 256.0;
|
|
16805
17222
|
|
|
16806
|
-
|
|
16807
|
-
|
|
17223
|
+
return vec3(px, py, pz);
|
|
17224
|
+
}
|
|
17225
|
+
|
|
17226
|
+
void main() {
|
|
17227
|
+
vec3 finalColor = vec3(0.0);
|
|
17228
|
+
|
|
17229
|
+
if (uFactor0 >= 0.0) {
|
|
17230
|
+
finalColor +=
|
|
17231
|
+
applyColorMap(
|
|
17232
|
+
sampleHiPSTexture0(vTextureCoord)
|
|
17233
|
+
) * uFactor0;
|
|
17234
|
+
}
|
|
17235
|
+
|
|
17236
|
+
if (uFactor1 >= 0.0) {
|
|
17237
|
+
finalColor +=
|
|
17238
|
+
applyColorMap(
|
|
17239
|
+
sampleHiPSTexture1(vTextureCoord)
|
|
17240
|
+
) * uFactor1;
|
|
17241
|
+
}
|
|
17242
|
+
|
|
17243
|
+
if (uFactor2 >= 0.0) {
|
|
17244
|
+
finalColor +=
|
|
17245
|
+
applyColorMap(
|
|
17246
|
+
sampleHiPSTexture2(vTextureCoord)
|
|
17247
|
+
) * uFactor2;
|
|
17248
|
+
}
|
|
17249
|
+
|
|
17250
|
+
if (uFactor3 >= 0.0) {
|
|
17251
|
+
finalColor +=
|
|
17252
|
+
applyColorMap(
|
|
17253
|
+
sampleHiPSTexture3(vTextureCoord)
|
|
17254
|
+
) * uFactor3;
|
|
17255
|
+
}
|
|
17256
|
+
|
|
17257
|
+
if (uFactor4 >= 0.0) {
|
|
17258
|
+
finalColor +=
|
|
17259
|
+
applyColorMap(
|
|
17260
|
+
sampleHiPSTexture4(vTextureCoord)
|
|
17261
|
+
) * uFactor4;
|
|
17262
|
+
}
|
|
17263
|
+
|
|
17264
|
+
if (uFactor5 >= 0.0) {
|
|
17265
|
+
finalColor +=
|
|
17266
|
+
applyColorMap(
|
|
17267
|
+
sampleHiPSTexture5(vTextureCoord)
|
|
17268
|
+
) * uFactor5;
|
|
17269
|
+
}
|
|
17270
|
+
|
|
17271
|
+
if (uFactor6 >= 0.0) {
|
|
17272
|
+
finalColor +=
|
|
17273
|
+
applyColorMap(
|
|
17274
|
+
sampleHiPSTexture6(vTextureCoord)
|
|
17275
|
+
) * uFactor6;
|
|
17276
|
+
}
|
|
17277
|
+
|
|
17278
|
+
if (uFactor7 >= 0.0) {
|
|
17279
|
+
finalColor +=
|
|
17280
|
+
applyColorMap(
|
|
17281
|
+
sampleHiPSTexture7(vTextureCoord)
|
|
17282
|
+
) * uFactor7;
|
|
17283
|
+
}
|
|
17284
|
+
|
|
17285
|
+
fragColor = vec4(finalColor, 1.0);
|
|
16808
17286
|
}`;
|
|
16809
17287
|
}
|
|
17288
|
+
static hipsSamplerGLSL(index) {
|
|
17289
|
+
return `
|
|
17290
|
+
uniform sampler2D uSampler${index};
|
|
17291
|
+
uniform int uTextureMode${index};
|
|
17292
|
+
uniform float uDataMin${index};
|
|
17293
|
+
uniform float uDataMax${index};
|
|
17294
|
+
|
|
17295
|
+
vec4 sampleHiPSTexture${index}(vec2 uv) {
|
|
17296
|
+
vec4 color = texture(uSampler${index}, uv);
|
|
17297
|
+
|
|
17298
|
+
// JPG / PNG
|
|
17299
|
+
if (uTextureMode${index} == 0) {
|
|
17300
|
+
return color;
|
|
17301
|
+
}
|
|
17302
|
+
|
|
17303
|
+
// FITS physical value stored in red channel
|
|
17304
|
+
float value = color.r;
|
|
17305
|
+
|
|
17306
|
+
if (isnan(value)) {
|
|
17307
|
+
discard;
|
|
17308
|
+
}
|
|
17309
|
+
|
|
17310
|
+
float normalized = clamp(
|
|
17311
|
+
(value - uDataMin${index}) /
|
|
17312
|
+
(uDataMax${index} - uDataMin${index}),
|
|
17313
|
+
0.0,
|
|
17314
|
+
1.0
|
|
17315
|
+
);
|
|
17316
|
+
|
|
17317
|
+
return vec4(
|
|
17318
|
+
normalized,
|
|
17319
|
+
normalized,
|
|
17320
|
+
normalized,
|
|
17321
|
+
1.0
|
|
17322
|
+
);
|
|
17323
|
+
}
|
|
17324
|
+
`;
|
|
17325
|
+
}
|
|
17326
|
+
static hipsSamplersGLSL() {
|
|
17327
|
+
return Array.from({ length: 8 }, (_, index) => ShaderManager.hipsSamplerGLSL(index)).join("\n");
|
|
17328
|
+
}
|
|
16810
17329
|
}
|
|
16811
17330
|
exports["default"] = ShaderManager;
|
|
16812
17331
|
|
|
@@ -16816,6 +17335,7 @@ exports["default"] = ShaderManager;
|
|
|
16816
17335
|
/***/ 149
|
|
16817
17336
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
16818
17337
|
|
|
17338
|
+
"use strict";
|
|
16819
17339
|
var __webpack_unused_export__;
|
|
16820
17340
|
|
|
16821
17341
|
/*
|
|
@@ -17039,6 +17559,7 @@ exports.XYZShaderProgram = XYZShaderProgram;
|
|
|
17039
17559
|
/***/ 8145
|
|
17040
17560
|
(__unused_webpack_module, exports) {
|
|
17041
17561
|
|
|
17562
|
+
"use strict";
|
|
17042
17563
|
|
|
17043
17564
|
/*
|
|
17044
17565
|
* AstroViewer
|
|
@@ -17071,6 +17592,7 @@ var CoordsType;
|
|
|
17071
17592
|
/***/ 8083
|
|
17072
17593
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
17073
17594
|
|
|
17595
|
+
"use strict";
|
|
17074
17596
|
/*
|
|
17075
17597
|
* AstroViewer
|
|
17076
17598
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -17310,6 +17832,7 @@ exports.FoVUtils = FoVUtils;
|
|
|
17310
17832
|
/***/ 8755
|
|
17311
17833
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
17312
17834
|
|
|
17835
|
+
"use strict";
|
|
17313
17836
|
|
|
17314
17837
|
/*
|
|
17315
17838
|
* AstroViewer
|
|
@@ -17429,6 +17952,7 @@ exports["default"] = GeoJSONParser;
|
|
|
17429
17952
|
/***/ 2930
|
|
17430
17953
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
17431
17954
|
|
|
17955
|
+
"use strict";
|
|
17432
17956
|
|
|
17433
17957
|
/*
|
|
17434
17958
|
* AstroViewer
|
|
@@ -17717,6 +18241,7 @@ exports["default"] = GeomUtils;
|
|
|
17717
18241
|
/***/ 4396
|
|
17718
18242
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
17719
18243
|
|
|
18244
|
+
"use strict";
|
|
17720
18245
|
|
|
17721
18246
|
/*
|
|
17722
18247
|
* AstroViewer
|
|
@@ -17832,6 +18357,7 @@ exports["default"] = MouseHelper;
|
|
|
17832
18357
|
/***/ 9685
|
|
17833
18358
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
17834
18359
|
|
|
18360
|
+
"use strict";
|
|
17835
18361
|
var __webpack_unused_export__;
|
|
17836
18362
|
|
|
17837
18363
|
/*
|
|
@@ -17893,6 +18419,7 @@ exports.PerspectiveMatrixManager = PerspectiveMatrixManager;
|
|
|
17893
18419
|
/***/ 4639
|
|
17894
18420
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
17895
18421
|
|
|
18422
|
+
"use strict";
|
|
17896
18423
|
/*
|
|
17897
18424
|
* AstroViewer
|
|
17898
18425
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -18022,6 +18549,7 @@ exports["default"] = RayPickingUtils;
|
|
|
18022
18549
|
/***/ 9665
|
|
18023
18550
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
18024
18551
|
|
|
18552
|
+
"use strict";
|
|
18025
18553
|
|
|
18026
18554
|
/*
|
|
18027
18555
|
* AstroViewer
|
|
@@ -18145,6 +18673,7 @@ exports["default"] = STCSParser;
|
|
|
18145
18673
|
/***/ 7930
|
|
18146
18674
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
18147
18675
|
|
|
18676
|
+
"use strict";
|
|
18148
18677
|
var __webpack_unused_export__;
|
|
18149
18678
|
|
|
18150
18679
|
/*
|
|
@@ -18250,6 +18779,7 @@ function decDegToDMS(decDeg) {
|
|
|
18250
18779
|
/***/ 2166
|
|
18251
18780
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
18252
18781
|
|
|
18782
|
+
"use strict";
|
|
18253
18783
|
/*
|
|
18254
18784
|
* AstroViewer
|
|
18255
18785
|
* Copyright (C) Fabrizio Giordano
|
|
@@ -18477,11 +19007,19 @@ class XYZRayPickingUtils {
|
|
|
18477
19007
|
exports["default"] = XYZRayPickingUtils;
|
|
18478
19008
|
|
|
18479
19009
|
|
|
19010
|
+
/***/ },
|
|
19011
|
+
|
|
19012
|
+
/***/ 7223
|
|
19013
|
+
() {
|
|
19014
|
+
|
|
19015
|
+
/* (ignored) */
|
|
19016
|
+
|
|
18480
19017
|
/***/ },
|
|
18481
19018
|
|
|
18482
19019
|
/***/ 4851
|
|
18483
19020
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
18484
19021
|
|
|
19022
|
+
"use strict";
|
|
18485
19023
|
|
|
18486
19024
|
// EXPORTS
|
|
18487
19025
|
__webpack_require__.d(__webpack_exports__, {
|
|
@@ -19275,76 +19813,1887 @@ function findCircleThroughTwoPoints(points, q1, q2) {
|
|
|
19275
19813
|
|
|
19276
19814
|
|
|
19277
19815
|
|
|
19278
|
-
/***/ }
|
|
19816
|
+
/***/ },
|
|
19279
19817
|
|
|
19280
|
-
|
|
19281
|
-
|
|
19282
|
-
|
|
19283
|
-
|
|
19284
|
-
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19290
|
-
|
|
19291
|
-
|
|
19292
|
-
|
|
19293
|
-
|
|
19294
|
-
|
|
19295
|
-
|
|
19296
|
-
|
|
19297
|
-
|
|
19298
|
-
|
|
19299
|
-
|
|
19300
|
-
|
|
19301
|
-
|
|
19302
|
-
|
|
19303
|
-
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19307
|
-
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
|
|
19312
|
-
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19344
|
-
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19818
|
+
/***/ 1677
|
|
19819
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
19820
|
+
|
|
19821
|
+
"use strict";
|
|
19822
|
+
|
|
19823
|
+
// EXPORTS
|
|
19824
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
19825
|
+
FITSHeaderManager: () => (/* reexport */ FITSHeaderManager),
|
|
19826
|
+
FITSParser: () => (/* reexport */ FITSParser)
|
|
19827
|
+
});
|
|
19828
|
+
|
|
19829
|
+
// UNUSED EXPORTS: AsciiTableHDU, BinaryTableHDU, FITSFile, FITSHDU, FITSHeaderItem, FITSWriter, ImageHDU, ParseHeader, ParsePayload, PrimaryHDU
|
|
19830
|
+
|
|
19831
|
+
;// ./node_modules/jsfitsio/lib-esm/model/FITSHeaderItem.js
|
|
19832
|
+
/**
|
|
19833
|
+
* Summary. (bla bla bla)
|
|
19834
|
+
*
|
|
19835
|
+
* Description. (bla bla bla)
|
|
19836
|
+
*
|
|
19837
|
+
* @link github https://github.com/fab77/FITSParser
|
|
19838
|
+
* @author Fabrizio Giordano <fabriziogiordano77@gmail.com>
|
|
19839
|
+
*/
|
|
19840
|
+
class FITSHeaderItem {
|
|
19841
|
+
_key = "";
|
|
19842
|
+
_value = "";
|
|
19843
|
+
_comment = "";
|
|
19844
|
+
constructor(key, value, comment) {
|
|
19845
|
+
this._key = key;
|
|
19846
|
+
this._value = value;
|
|
19847
|
+
this._comment = comment;
|
|
19848
|
+
}
|
|
19849
|
+
get key() {
|
|
19850
|
+
return this._key;
|
|
19851
|
+
}
|
|
19852
|
+
get comment() {
|
|
19853
|
+
return this._comment;
|
|
19854
|
+
}
|
|
19855
|
+
get value() {
|
|
19856
|
+
return this._value;
|
|
19857
|
+
}
|
|
19858
|
+
}
|
|
19859
|
+
//# sourceMappingURL=FITSHeaderItem.js.map
|
|
19860
|
+
;// ./node_modules/jsfitsio/lib-esm/model/FITSHeaderManager.js
|
|
19861
|
+
|
|
19862
|
+
class FITSHeaderManager {
|
|
19863
|
+
static SIMPLE = "SIMPLE";
|
|
19864
|
+
static BITPIX = "BITPIX";
|
|
19865
|
+
static BZERO = "BZERO";
|
|
19866
|
+
static BSCALE = "BSCALE";
|
|
19867
|
+
static BLANK = "BLANK";
|
|
19868
|
+
static NAXIS = "NAXIS";
|
|
19869
|
+
static NAXIS1 = "NAXIS1";
|
|
19870
|
+
static NAXIS2 = "NAXIS2";
|
|
19871
|
+
static DATAMIN = "DATAMIN";
|
|
19872
|
+
static DATAMAX = "DATAMAX";
|
|
19873
|
+
static CRVAL1 = "CRVAL1";
|
|
19874
|
+
static CRVAL2 = "CRVAL2";
|
|
19875
|
+
static CTYPE1 = "CTYPE1";
|
|
19876
|
+
static CTYPE2 = "CTYPE2";
|
|
19877
|
+
static CRPIX1 = "CRPIX1";
|
|
19878
|
+
static CRPIX2 = "CRPIX2";
|
|
19879
|
+
static ORIGIN = "ORIGIN";
|
|
19880
|
+
static COMMENT = "COMMENT";
|
|
19881
|
+
static XTENSION = "XTENSION";
|
|
19882
|
+
static PCOUNT = "PCOUNT";
|
|
19883
|
+
static GCOUNT = "GCOUNT";
|
|
19884
|
+
static TFIELDS = "TFIELDS";
|
|
19885
|
+
static TFORM = "TFORM";
|
|
19886
|
+
static TTYPE = "TTYPE";
|
|
19887
|
+
static TUNIT = "TUNIT";
|
|
19888
|
+
static TSCAL = "TSCAL";
|
|
19889
|
+
static TZERO = "TZERO";
|
|
19890
|
+
static TNULL = "TNULL";
|
|
19891
|
+
static TBCOL = "TBCOL";
|
|
19892
|
+
items = [];
|
|
19893
|
+
constructor(initializeDefaults = true) {
|
|
19894
|
+
if (!initializeDefaults) {
|
|
19895
|
+
return;
|
|
19896
|
+
}
|
|
19897
|
+
this.items[0] = new FITSHeaderItem(FITSHeaderManager.SIMPLE, "T", "");
|
|
19898
|
+
this.items[1] = new FITSHeaderItem(FITSHeaderManager.BITPIX, "", "");
|
|
19899
|
+
this.items[2] = new FITSHeaderItem(FITSHeaderManager.NAXIS, 2, "");
|
|
19900
|
+
this.items[3] = new FITSHeaderItem(FITSHeaderManager.NAXIS1, "", "");
|
|
19901
|
+
this.items[4] = new FITSHeaderItem(FITSHeaderManager.NAXIS2, "", "");
|
|
19902
|
+
}
|
|
19903
|
+
// insert(item: FITSHeaderItem, position?: number): void {
|
|
19904
|
+
insert(item) {
|
|
19905
|
+
if (item.key === FITSHeaderManager.SIMPLE) {
|
|
19906
|
+
// this.items.splice(0, 0, item);
|
|
19907
|
+
this.items[0] = item;
|
|
19908
|
+
}
|
|
19909
|
+
else if (item.key === FITSHeaderManager.BITPIX) {
|
|
19910
|
+
// this.items.splice(1, 0, item);
|
|
19911
|
+
this.items[1] = item;
|
|
19912
|
+
}
|
|
19913
|
+
else if (item.key === FITSHeaderManager.NAXIS) {
|
|
19914
|
+
// this.items.splice(2, 0, item);
|
|
19915
|
+
this.items[2] = item;
|
|
19916
|
+
}
|
|
19917
|
+
else if (item.key === FITSHeaderManager.NAXIS1) {
|
|
19918
|
+
// this.items.splice(3, 0, item);
|
|
19919
|
+
this.items[3] = item;
|
|
19920
|
+
}
|
|
19921
|
+
else if (item.key === FITSHeaderManager.NAXIS2) {
|
|
19922
|
+
// this.items.splice(4, 0, item);
|
|
19923
|
+
this.items[4] = item;
|
|
19924
|
+
}
|
|
19925
|
+
else {
|
|
19926
|
+
this.items.push(item);
|
|
19927
|
+
}
|
|
19928
|
+
// if (position !== undefined && position >= 0 && position <= this.items.length) {
|
|
19929
|
+
// this.items.splice(position, 0, item);
|
|
19930
|
+
// } else {
|
|
19931
|
+
// this.items.push(item);
|
|
19932
|
+
// }
|
|
19933
|
+
}
|
|
19934
|
+
getItems() {
|
|
19935
|
+
return this.items;
|
|
19936
|
+
}
|
|
19937
|
+
remove(key) {
|
|
19938
|
+
this.items = this.items.filter((item) => item.key !== key);
|
|
19939
|
+
}
|
|
19940
|
+
findById(key) {
|
|
19941
|
+
const item = this.items.find((item) => item.key === key);
|
|
19942
|
+
if (!item) {
|
|
19943
|
+
return null;
|
|
19944
|
+
}
|
|
19945
|
+
return item;
|
|
19946
|
+
}
|
|
19947
|
+
static tableFieldKey(prefix, index) {
|
|
19948
|
+
if (!Number.isInteger(index) || index < 1) {
|
|
19949
|
+
throw new RangeError(`FITS table field index must be >= 1, received ${index}.`);
|
|
19950
|
+
}
|
|
19951
|
+
return `${prefix}${index}`;
|
|
19952
|
+
}
|
|
19953
|
+
static naxisKey(axis) {
|
|
19954
|
+
if (!Number.isInteger(axis) || axis < 1) {
|
|
19955
|
+
throw new RangeError(`FITS axis must be a positive integer, received ${axis}.`);
|
|
19956
|
+
}
|
|
19957
|
+
return `NAXIS${axis}`;
|
|
19958
|
+
}
|
|
19959
|
+
static getFITSItemStringValue(header, key) {
|
|
19960
|
+
const item = header.findById(key);
|
|
19961
|
+
if (!item) {
|
|
19962
|
+
return null;
|
|
19963
|
+
}
|
|
19964
|
+
return String(item.value).trim().replace(/^'/, "").replace(/'$/, "").trim();
|
|
19965
|
+
}
|
|
19966
|
+
}
|
|
19967
|
+
//# sourceMappingURL=FITSHeaderManager.js.map
|
|
19968
|
+
// EXTERNAL MODULE: fs (ignored)
|
|
19969
|
+
var fs_ignored_ = __webpack_require__(7223);
|
|
19970
|
+
;// ./node_modules/jsfitsio/lib-esm/FITSHeaderWriter.js
|
|
19971
|
+
class FITSHeaderWriter {
|
|
19972
|
+
static BLOCK_SIZE = 2880;
|
|
19973
|
+
static CARD_SIZE = 80;
|
|
19974
|
+
static INTEGER_KEYWORDS = new Set([
|
|
19975
|
+
"BITPIX",
|
|
19976
|
+
"NAXIS",
|
|
19977
|
+
"PCOUNT",
|
|
19978
|
+
"GCOUNT",
|
|
19979
|
+
]);
|
|
19980
|
+
static LOGICAL_KEYWORDS = new Set(["SIMPLE", "EXTEND"]);
|
|
19981
|
+
static serialize(header, primary) {
|
|
19982
|
+
const items = header.getItems();
|
|
19983
|
+
const map = new Map(items.map((item) => [item.key.toUpperCase(), item]));
|
|
19984
|
+
const cards = [];
|
|
19985
|
+
FITSHeaderWriter.appendMandatoryCards(cards, map, primary);
|
|
19986
|
+
FITSHeaderWriter.appendRemainingCards(cards, items);
|
|
19987
|
+
cards.push(FITSHeaderWriter.card80("END"));
|
|
19988
|
+
return FITSHeaderWriter.encodeAndPad(cards);
|
|
19989
|
+
}
|
|
19990
|
+
static appendMandatoryCards(cards, map, primary) {
|
|
19991
|
+
if (primary) {
|
|
19992
|
+
const simple = map.get("SIMPLE");
|
|
19993
|
+
if (!simple) {
|
|
19994
|
+
throw new Error("Missing mandatory SIMPLE card in Primary HDU");
|
|
19995
|
+
}
|
|
19996
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment("SIMPLE", simple.value, simple.comment));
|
|
19997
|
+
}
|
|
19998
|
+
else {
|
|
19999
|
+
const xtension = map.get("XTENSION");
|
|
20000
|
+
if (!xtension) {
|
|
20001
|
+
throw new Error("Missing mandatory XTENSION card in extension HDU");
|
|
20002
|
+
}
|
|
20003
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment("XTENSION", xtension.value, xtension.comment));
|
|
20004
|
+
}
|
|
20005
|
+
const bitpix = map.get("BITPIX");
|
|
20006
|
+
if (!bitpix) {
|
|
20007
|
+
throw new Error("Missing mandatory BITPIX card");
|
|
20008
|
+
}
|
|
20009
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment("BITPIX", bitpix.value, bitpix.comment));
|
|
20010
|
+
const naxis = map.get("NAXIS");
|
|
20011
|
+
if (!naxis) {
|
|
20012
|
+
throw new Error("Missing mandatory NAXIS card");
|
|
20013
|
+
}
|
|
20014
|
+
const nAxes = Number(naxis.value);
|
|
20015
|
+
if (!Number.isInteger(nAxes) || nAxes < 0) {
|
|
20016
|
+
throw new Error(`Invalid NAXIS value: ${naxis.value}`);
|
|
20017
|
+
}
|
|
20018
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment("NAXIS", nAxes, naxis.comment));
|
|
20019
|
+
for (let axis = 1; axis <= nAxes; axis++) {
|
|
20020
|
+
const key = `NAXIS${axis}`;
|
|
20021
|
+
const item = map.get(key);
|
|
20022
|
+
if (!item) {
|
|
20023
|
+
throw new Error(`Missing mandatory ${key} card`);
|
|
20024
|
+
}
|
|
20025
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment(key, item.value, item.comment));
|
|
20026
|
+
}
|
|
20027
|
+
if (!primary) {
|
|
20028
|
+
const pcount = map.get("PCOUNT");
|
|
20029
|
+
const gcount = map.get("GCOUNT");
|
|
20030
|
+
if (!pcount) {
|
|
20031
|
+
throw new Error("Missing mandatory PCOUNT card in extension HDU");
|
|
20032
|
+
}
|
|
20033
|
+
if (!gcount) {
|
|
20034
|
+
throw new Error("Missing mandatory GCOUNT card in extension HDU");
|
|
20035
|
+
}
|
|
20036
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment("PCOUNT", pcount.value, pcount.comment));
|
|
20037
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment("GCOUNT", gcount.value, gcount.comment));
|
|
20038
|
+
}
|
|
20039
|
+
if (primary) {
|
|
20040
|
+
const extend = map.get("EXTEND");
|
|
20041
|
+
if (extend) {
|
|
20042
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment("EXTEND", extend.value, extend.comment));
|
|
20043
|
+
}
|
|
20044
|
+
}
|
|
20045
|
+
}
|
|
20046
|
+
static appendRemainingCards(cards, items) {
|
|
20047
|
+
for (const item of items) {
|
|
20048
|
+
const key = item.key.toUpperCase();
|
|
20049
|
+
if (key === "SIMPLE" ||
|
|
20050
|
+
key === "XTENSION" ||
|
|
20051
|
+
key === "BITPIX" ||
|
|
20052
|
+
key === "NAXIS" ||
|
|
20053
|
+
/^NAXIS\d+$/.test(key) ||
|
|
20054
|
+
key === "PCOUNT" ||
|
|
20055
|
+
key === "GCOUNT" ||
|
|
20056
|
+
key === "EXTEND" ||
|
|
20057
|
+
key === "END") {
|
|
20058
|
+
continue;
|
|
20059
|
+
}
|
|
20060
|
+
cards.push(...FITSHeaderWriter.makeKeywordWithComment(item.key, item.value, item.comment));
|
|
20061
|
+
}
|
|
20062
|
+
}
|
|
20063
|
+
static makeKeywordWithComment(key, value, comment) {
|
|
20064
|
+
const normalized = key.toUpperCase();
|
|
20065
|
+
if (normalized === "END") {
|
|
20066
|
+
return [FITSHeaderWriter.card80("END")];
|
|
20067
|
+
}
|
|
20068
|
+
if (normalized === "COMMENT" || normalized === "HISTORY") {
|
|
20069
|
+
return FITSHeaderWriter.makeCommentCards(normalized, String(value ?? comment ?? ""));
|
|
20070
|
+
}
|
|
20071
|
+
let base = FITSHeaderWriter.keyword(normalized) +
|
|
20072
|
+
FITSHeaderWriter.valueField20(normalized, value);
|
|
20073
|
+
if (!comment || comment.length === 0) {
|
|
20074
|
+
return [FITSHeaderWriter.card80(base)];
|
|
20075
|
+
}
|
|
20076
|
+
const addition = ` / ${comment}`;
|
|
20077
|
+
const spaceLeft = FITSHeaderWriter.CARD_SIZE - base.length;
|
|
20078
|
+
if (spaceLeft <= 0) {
|
|
20079
|
+
return [
|
|
20080
|
+
FITSHeaderWriter.card80(base),
|
|
20081
|
+
...FITSHeaderWriter.makeCommentCards("COMMENT", comment),
|
|
20082
|
+
];
|
|
20083
|
+
}
|
|
20084
|
+
base += addition.slice(0, spaceLeft);
|
|
20085
|
+
const overflow = addition.slice(spaceLeft).replace(/^\s*\/\s*/, "");
|
|
20086
|
+
if (overflow.length === 0) {
|
|
20087
|
+
return [FITSHeaderWriter.card80(base)];
|
|
20088
|
+
}
|
|
20089
|
+
return [
|
|
20090
|
+
FITSHeaderWriter.card80(base),
|
|
20091
|
+
...FITSHeaderWriter.makeCommentCards("COMMENT", overflow),
|
|
20092
|
+
];
|
|
20093
|
+
}
|
|
20094
|
+
static makeCommentCards(kind, text) {
|
|
20095
|
+
const prefix = FITSHeaderWriter.keyword(kind);
|
|
20096
|
+
const width = FITSHeaderWriter.CARD_SIZE - prefix.length;
|
|
20097
|
+
const value = String(text ?? "");
|
|
20098
|
+
if (value.length === 0) {
|
|
20099
|
+
return [FITSHeaderWriter.card80(prefix)];
|
|
20100
|
+
}
|
|
20101
|
+
const cards = [];
|
|
20102
|
+
for (let offset = 0; offset < value.length; offset += width) {
|
|
20103
|
+
cards.push(FITSHeaderWriter.card80(prefix + value.slice(offset, offset + width)));
|
|
20104
|
+
}
|
|
20105
|
+
return cards;
|
|
20106
|
+
}
|
|
20107
|
+
static valueField20(key, value) {
|
|
20108
|
+
if (FITSHeaderWriter.LOGICAL_KEYWORDS.has(key)) {
|
|
20109
|
+
const logical = value === true || value === "T" || value === "t" ? "T" : "F";
|
|
20110
|
+
return `= ${logical.padStart(20, " ")}`;
|
|
20111
|
+
}
|
|
20112
|
+
if (FITSHeaderWriter.INTEGER_KEYWORDS.has(key) || /^NAXIS\d+$/.test(key)) {
|
|
20113
|
+
const number = Number(value);
|
|
20114
|
+
if (!Number.isFinite(number) || !Number.isInteger(number)) {
|
|
20115
|
+
throw new Error(`FITS header: ${key} must be an integer, got ${value}`);
|
|
20116
|
+
}
|
|
20117
|
+
return `= ${String(number).padStart(20, " ")}`;
|
|
20118
|
+
}
|
|
20119
|
+
if (typeof value === "number") {
|
|
20120
|
+
let encoded = Number.isInteger(value)
|
|
20121
|
+
? String(value)
|
|
20122
|
+
: value.toExponential(10).replace("e", "E");
|
|
20123
|
+
if (encoded.length > 20) {
|
|
20124
|
+
encoded = value.toExponential(8).replace("e", "E");
|
|
20125
|
+
}
|
|
20126
|
+
return `= ${encoded.padStart(20, " ")}`;
|
|
20127
|
+
}
|
|
20128
|
+
if (typeof value === "string") {
|
|
20129
|
+
return `= ${FITSHeaderWriter.quoteFitsString(value)}`;
|
|
20130
|
+
}
|
|
20131
|
+
return "";
|
|
20132
|
+
}
|
|
20133
|
+
static quoteFitsString(value) {
|
|
20134
|
+
const unquoted = value.replace(/^'+|'+$/g, "");
|
|
20135
|
+
const escaped = unquoted.replace(/'/g, "''");
|
|
20136
|
+
return `'${escaped}'`;
|
|
20137
|
+
}
|
|
20138
|
+
static keyword(value) {
|
|
20139
|
+
return (value ?? "").toUpperCase().padEnd(8, " ").slice(0, 8);
|
|
20140
|
+
}
|
|
20141
|
+
static card80(value) {
|
|
20142
|
+
if (value.length >= FITSHeaderWriter.CARD_SIZE) {
|
|
20143
|
+
return value.slice(0, FITSHeaderWriter.CARD_SIZE);
|
|
20144
|
+
}
|
|
20145
|
+
return value.padEnd(FITSHeaderWriter.CARD_SIZE, " ");
|
|
20146
|
+
}
|
|
20147
|
+
static encodeAndPad(cards) {
|
|
20148
|
+
let header = cards.join("");
|
|
20149
|
+
const remainder = header.length % FITSHeaderWriter.BLOCK_SIZE;
|
|
20150
|
+
if (remainder !== 0) {
|
|
20151
|
+
header += " ".repeat(FITSHeaderWriter.BLOCK_SIZE - remainder);
|
|
20152
|
+
}
|
|
20153
|
+
return new TextEncoder().encode(header);
|
|
20154
|
+
}
|
|
20155
|
+
}
|
|
20156
|
+
//# sourceMappingURL=FITSHeaderWriter.js.map
|
|
20157
|
+
;// ./node_modules/jsfitsio/lib-esm/FITSWriter.js
|
|
20158
|
+
/**
|
|
20159
|
+
* FITS serialization and file writing support.
|
|
20160
|
+
*
|
|
20161
|
+
* FITSWriter provides two serialization APIs:
|
|
20162
|
+
*
|
|
20163
|
+
* - The jsfitsio 3.x API serializes the FITSFile/HDU data model,
|
|
20164
|
+
* including PrimaryHDU, ImageHDU, BinaryTableHDU and AsciiTableHDU.
|
|
20165
|
+
*
|
|
20166
|
+
* - The legacy API serializes the former FITSParsed representation
|
|
20167
|
+
* and is retained for backward compatibility with jsfitsio 2.x
|
|
20168
|
+
* consumers.
|
|
20169
|
+
*
|
|
20170
|
+
* FITS headers are serialized according to the FITS 80-character
|
|
20171
|
+
* card format and padded to 2880-byte FITS logical blocks.
|
|
20172
|
+
* HDU payloads are likewise padded to 2880-byte boundaries.
|
|
20173
|
+
*
|
|
20174
|
+
* New code should use FITSFile together with createFITSFile() and
|
|
20175
|
+
* writeFITSFileModel().
|
|
20176
|
+
*
|
|
20177
|
+
* @see https://fits.gsfc.nasa.gov/
|
|
20178
|
+
*/
|
|
20179
|
+
|
|
20180
|
+
|
|
20181
|
+
class FITSWriter {
|
|
20182
|
+
/**
|
|
20183
|
+
* Serializes the legacy FITSParsed representation.
|
|
20184
|
+
*
|
|
20185
|
+
* @deprecated Use createFITSFile() with the FITSFile/HDU model.
|
|
20186
|
+
* This method is retained for backward compatibility with jsfitsio 2.x.
|
|
20187
|
+
*/
|
|
20188
|
+
static createFITS(fitsParsed) {
|
|
20189
|
+
const headerBytes = FITSHeaderWriter.serialize(fitsParsed.header, true);
|
|
20190
|
+
const dataBytes = this.createData(fitsParsed.data, fitsParsed.header);
|
|
20191
|
+
const fitsFile = new Uint8Array(headerBytes.length + dataBytes.length);
|
|
20192
|
+
fitsFile.set(headerBytes, 0);
|
|
20193
|
+
fitsFile.set(dataBytes, headerBytes.length);
|
|
20194
|
+
return fitsFile;
|
|
20195
|
+
}
|
|
20196
|
+
static createHDU(hdu, primary) {
|
|
20197
|
+
const headerBytes = FITSHeaderWriter.serialize(hdu.header, primary);
|
|
20198
|
+
const rawData = hdu.rawData ?? new Uint8Array(0);
|
|
20199
|
+
if (rawData.byteLength !== hdu.dataByteLength) {
|
|
20200
|
+
throw new Error(`HDU payload length mismatch: ` +
|
|
20201
|
+
`rawData contains ${rawData.byteLength} bytes, ` +
|
|
20202
|
+
`but dataByteLength=${hdu.dataByteLength}.`);
|
|
20203
|
+
}
|
|
20204
|
+
const dataBytes = FITSWriter.padData(rawData);
|
|
20205
|
+
const result = new Uint8Array(headerBytes.byteLength + dataBytes.byteLength);
|
|
20206
|
+
result.set(headerBytes, 0);
|
|
20207
|
+
result.set(dataBytes, headerBytes.byteLength);
|
|
20208
|
+
return result;
|
|
20209
|
+
}
|
|
20210
|
+
static padData(data) {
|
|
20211
|
+
const BLOCK = 2880;
|
|
20212
|
+
if (data.byteLength === 0) {
|
|
20213
|
+
return new Uint8Array(0);
|
|
20214
|
+
}
|
|
20215
|
+
const remainder = data.byteLength % BLOCK;
|
|
20216
|
+
if (remainder === 0) {
|
|
20217
|
+
return data.slice();
|
|
20218
|
+
}
|
|
20219
|
+
const padded = new Uint8Array(data.byteLength + (BLOCK - remainder));
|
|
20220
|
+
padded.set(data);
|
|
20221
|
+
return padded;
|
|
20222
|
+
}
|
|
20223
|
+
static createData(data, header) {
|
|
20224
|
+
// concat
|
|
20225
|
+
const totalLength = data.reduce((s, c) => s + c.length, 0);
|
|
20226
|
+
// OPTIONAL: verify size from BITPIX/NAXIS
|
|
20227
|
+
const bitpix = Math.abs(Number(header.findById("BITPIX")?.value ?? 0));
|
|
20228
|
+
const naxis = Number(header.findById("NAXIS")?.value ?? 0);
|
|
20229
|
+
let elems = 1;
|
|
20230
|
+
for (let k = 1; k <= naxis; k++) {
|
|
20231
|
+
elems *= Number(header.findById(`NAXIS${k}`)?.value ?? 0);
|
|
20232
|
+
}
|
|
20233
|
+
const bytesPerElem = bitpix / 8;
|
|
20234
|
+
const expectedUnpadded = naxis > 0 ? elems * bytesPerElem : 0;
|
|
20235
|
+
if (expectedUnpadded && expectedUnpadded !== totalLength) {
|
|
20236
|
+
throw new Error(`Data length ${totalLength} does not match header expectation ${expectedUnpadded} (BITPIX=${bitpix}, NAXIS=${naxis})`);
|
|
20237
|
+
}
|
|
20238
|
+
// build and pad
|
|
20239
|
+
let dataBytes = new Uint8Array(totalLength);
|
|
20240
|
+
let off = 0;
|
|
20241
|
+
for (const chunk of data) {
|
|
20242
|
+
dataBytes.set(chunk, off);
|
|
20243
|
+
off += chunk.length;
|
|
20244
|
+
}
|
|
20245
|
+
return FITSWriter.padData(dataBytes);
|
|
20246
|
+
}
|
|
20247
|
+
/**
|
|
20248
|
+
* Serializes a jsfitsio 3.x FITSFile, including all contained HDUs.
|
|
20249
|
+
*/
|
|
20250
|
+
static createFITSFile(fitsFile) {
|
|
20251
|
+
if (fitsFile.length === 0) {
|
|
20252
|
+
throw new Error("Cannot write an empty FITSFile.");
|
|
20253
|
+
}
|
|
20254
|
+
if (fitsFile.primaryHDU === null) {
|
|
20255
|
+
throw new Error("FITSFile must start with a PrimaryHDU.");
|
|
20256
|
+
}
|
|
20257
|
+
const serializedHDUs = fitsFile.hdus.map((hdu, index) => FITSWriter.createHDU(hdu, index === 0));
|
|
20258
|
+
const totalLength = serializedHDUs.reduce((sum, hdu) => sum + hdu.byteLength, 0);
|
|
20259
|
+
const result = new Uint8Array(totalLength);
|
|
20260
|
+
let offset = 0;
|
|
20261
|
+
for (const hdu of serializedHDUs) {
|
|
20262
|
+
result.set(hdu, offset);
|
|
20263
|
+
offset += hdu.byteLength;
|
|
20264
|
+
}
|
|
20265
|
+
return result;
|
|
20266
|
+
}
|
|
20267
|
+
/**
|
|
20268
|
+
* Serializes a jsfitsio 3.x FITSFile and writes it to the local filesystem.
|
|
20269
|
+
*/
|
|
20270
|
+
static writeFITSFileModel(fitsFile, filePath) {
|
|
20271
|
+
const data = FITSWriter.createFITSFile(fitsFile);
|
|
20272
|
+
fs_ignored_.writeFileSync(filePath, data);
|
|
20273
|
+
}
|
|
20274
|
+
/**
|
|
20275
|
+
* Writes the legacy FITSParsed representation to a local file.
|
|
20276
|
+
*
|
|
20277
|
+
* @deprecated Use writeFITSFileModel() with FITSFile instead.
|
|
20278
|
+
* This method is retained for backward compatibility with jsfitsio 2.x.
|
|
20279
|
+
*/
|
|
20280
|
+
static writeFITSFile(fitsParsed, filePath) {
|
|
20281
|
+
const fitsFile = FITSWriter.createFITS(fitsParsed);
|
|
20282
|
+
fs_ignored_.writeFileSync(filePath, fitsFile);
|
|
20283
|
+
}
|
|
20284
|
+
}
|
|
20285
|
+
//# sourceMappingURL=FITSWriter.js.map
|
|
20286
|
+
;// ./node_modules/jsfitsio/lib-esm/ParseHeader.js
|
|
20287
|
+
// import { FITSHeader } from "./model/FITSHeader.js";
|
|
20288
|
+
|
|
20289
|
+
|
|
20290
|
+
/**
|
|
20291
|
+
* Summary. (bla bla bla)
|
|
20292
|
+
*
|
|
20293
|
+
* Description. (bla bla bla)
|
|
20294
|
+
*
|
|
20295
|
+
* @link github https://github.com/fab77/FITSParser
|
|
20296
|
+
* @author Fabrizio Giordano <fabriziogiordano77@gmail.com>
|
|
20297
|
+
*/
|
|
20298
|
+
class ParseHeader {
|
|
20299
|
+
static CARD_SIZE = 80;
|
|
20300
|
+
static BLOCK_SIZE = 2880;
|
|
20301
|
+
static getFITSItemStringValue(header, key) {
|
|
20302
|
+
const item = header.findById(key);
|
|
20303
|
+
if (!item) {
|
|
20304
|
+
return null;
|
|
20305
|
+
}
|
|
20306
|
+
return String(item.value).trim().replace(/^'/, "").replace(/'$/, "").trim();
|
|
20307
|
+
}
|
|
20308
|
+
static getFITSItemValue(header, key) {
|
|
20309
|
+
const item = header.findById(key);
|
|
20310
|
+
if (!item) {
|
|
20311
|
+
return null;
|
|
20312
|
+
}
|
|
20313
|
+
const value = Number(item.value);
|
|
20314
|
+
return Number.isNaN(value) ? null : value;
|
|
20315
|
+
}
|
|
20316
|
+
/**
|
|
20317
|
+
* Returns the complete FITS header size, including padding
|
|
20318
|
+
* up to the next 2880-byte boundary.
|
|
20319
|
+
*/
|
|
20320
|
+
static getHeaderByteLength(rawData, startOffset = 0) {
|
|
20321
|
+
const decoder = new TextDecoder("ascii");
|
|
20322
|
+
for (let offset = startOffset; offset + ParseHeader.CARD_SIZE <= rawData.byteLength; offset += ParseHeader.CARD_SIZE) {
|
|
20323
|
+
const key = decoder.decode(rawData.subarray(offset, offset + 8)).trim();
|
|
20324
|
+
if (key === "END") {
|
|
20325
|
+
const consumed = offset + ParseHeader.CARD_SIZE - startOffset;
|
|
20326
|
+
return (Math.ceil(consumed / ParseHeader.BLOCK_SIZE) * ParseHeader.BLOCK_SIZE);
|
|
20327
|
+
}
|
|
20328
|
+
}
|
|
20329
|
+
throw new Error("Invalid FITS header: END card not found.");
|
|
20330
|
+
}
|
|
20331
|
+
static parse(rawData, startOffset = 0) {
|
|
20332
|
+
const decoder = new TextDecoder("ascii");
|
|
20333
|
+
const headerLength = ParseHeader.getHeaderByteLength(rawData, startOffset);
|
|
20334
|
+
const header = new FITSHeaderManager(false);
|
|
20335
|
+
for (let offset = startOffset; offset < startOffset + headerLength; offset += ParseHeader.CARD_SIZE) {
|
|
20336
|
+
const line = decoder.decode(rawData.subarray(offset, offset + ParseHeader.CARD_SIZE));
|
|
20337
|
+
const key = line.slice(0, 8).trim();
|
|
20338
|
+
if (key === "END") {
|
|
20339
|
+
break;
|
|
20340
|
+
}
|
|
20341
|
+
if (!key) {
|
|
20342
|
+
continue;
|
|
20343
|
+
}
|
|
20344
|
+
let value;
|
|
20345
|
+
let comment = "";
|
|
20346
|
+
const rawValue = line.slice(10).trim().split("/")[0].trim();
|
|
20347
|
+
if (Number.isNaN(Number(rawValue))) {
|
|
20348
|
+
value = rawValue;
|
|
20349
|
+
}
|
|
20350
|
+
else {
|
|
20351
|
+
value = Number(rawValue);
|
|
20352
|
+
}
|
|
20353
|
+
if (line.includes("/")) {
|
|
20354
|
+
comment = line.slice(10).trim().split("/")[1]?.trim() ?? "";
|
|
20355
|
+
}
|
|
20356
|
+
header.insert(new FITSHeaderItem(key, value, comment));
|
|
20357
|
+
}
|
|
20358
|
+
return header;
|
|
20359
|
+
}
|
|
20360
|
+
}
|
|
20361
|
+
//# sourceMappingURL=ParseHeader.js.map
|
|
20362
|
+
;// ./node_modules/jsfitsio/lib-esm/FITSImageUtils.js
|
|
20363
|
+
|
|
20364
|
+
|
|
20365
|
+
class FITSImageUtils {
|
|
20366
|
+
static getShape(header) {
|
|
20367
|
+
const naxis = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS);
|
|
20368
|
+
if (naxis === null) {
|
|
20369
|
+
throw new Error("NAXIS not defined.");
|
|
20370
|
+
}
|
|
20371
|
+
if (!Number.isInteger(naxis) || naxis < 0) {
|
|
20372
|
+
throw new Error(`Invalid FITS NAXIS value: ${naxis}`);
|
|
20373
|
+
}
|
|
20374
|
+
const shape = [];
|
|
20375
|
+
for (let axis = 1; axis <= naxis; axis++) {
|
|
20376
|
+
const size = ParseHeader.getFITSItemValue(header, FITSHeaderManager.naxisKey(axis));
|
|
20377
|
+
if (size === null) {
|
|
20378
|
+
throw new Error(`NAXIS${axis} not defined.`);
|
|
20379
|
+
}
|
|
20380
|
+
shape.push(size);
|
|
20381
|
+
}
|
|
20382
|
+
return shape;
|
|
20383
|
+
}
|
|
20384
|
+
static getElementCount(shape) {
|
|
20385
|
+
if (shape.length === 0) {
|
|
20386
|
+
return 0;
|
|
20387
|
+
}
|
|
20388
|
+
return shape.reduce((total, dimension) => total * dimension, 1);
|
|
20389
|
+
}
|
|
20390
|
+
}
|
|
20391
|
+
//# sourceMappingURL=FITSImageUtils.js.map
|
|
20392
|
+
;// ./node_modules/jsfitsio/lib-esm/ParsePayload.js
|
|
20393
|
+
// "use strict";
|
|
20394
|
+
/**
|
|
20395
|
+
* Summary. (bla bla bla)
|
|
20396
|
+
*
|
|
20397
|
+
* Description. (bla bla bla)
|
|
20398
|
+
*
|
|
20399
|
+
* @link github https://github.com/fab77/FITSParser
|
|
20400
|
+
* @author Fabrizio Giordano <fabriziogiordano77@gmail.com>
|
|
20401
|
+
*/
|
|
20402
|
+
|
|
20403
|
+
|
|
20404
|
+
|
|
20405
|
+
|
|
20406
|
+
class ParsePayload {
|
|
20407
|
+
static SUPPORTED_BITPIX = new Set([8, 16, 32, 64, -32, -64]);
|
|
20408
|
+
static assertSupportedBITPIX(bitpix) {
|
|
20409
|
+
if (!ParsePayload.SUPPORTED_BITPIX.has(bitpix)) {
|
|
20410
|
+
throw new Error(`Unsupported FITS BITPIX value: ${bitpix}`);
|
|
20411
|
+
}
|
|
20412
|
+
}
|
|
20413
|
+
static extractPixelFromView(view, offset, bitpix) {
|
|
20414
|
+
switch (bitpix) {
|
|
20415
|
+
case 8:
|
|
20416
|
+
return view.getUint8(offset);
|
|
20417
|
+
case 16:
|
|
20418
|
+
return view.getInt16(offset, false);
|
|
20419
|
+
case 32:
|
|
20420
|
+
return view.getInt32(offset, false);
|
|
20421
|
+
case -32:
|
|
20422
|
+
return view.getFloat32(offset, false);
|
|
20423
|
+
case -64:
|
|
20424
|
+
return view.getFloat64(offset, false);
|
|
20425
|
+
case 64: {
|
|
20426
|
+
const value = view.getBigInt64(offset, false);
|
|
20427
|
+
const numeric = Number(value);
|
|
20428
|
+
if (!Number.isSafeInteger(numeric)) {
|
|
20429
|
+
throw new RangeError(`BITPIX=64 value ${value} cannot be represented ` +
|
|
20430
|
+
`exactly as a JavaScript number.`);
|
|
20431
|
+
}
|
|
20432
|
+
return numeric;
|
|
20433
|
+
}
|
|
20434
|
+
default:
|
|
20435
|
+
throw new Error(`Unsupported FITS BITPIX value: ${bitpix}`);
|
|
20436
|
+
}
|
|
20437
|
+
}
|
|
20438
|
+
static computePhysicalMinAndMax(header, payload) {
|
|
20439
|
+
const bitpix = ParseHeader.getFITSItemValue(header, FITSHeaderManager.BITPIX);
|
|
20440
|
+
if (bitpix === null) {
|
|
20441
|
+
return null;
|
|
20442
|
+
}
|
|
20443
|
+
ParsePayload.assertSupportedBITPIX(bitpix);
|
|
20444
|
+
const shape = FITSImageUtils.getShape(header);
|
|
20445
|
+
/*
|
|
20446
|
+
* NAXIS=0 is a valid FITS HDU.
|
|
20447
|
+
*/
|
|
20448
|
+
if (shape.length === 0 || payload.byteLength === 0) {
|
|
20449
|
+
return header;
|
|
20450
|
+
}
|
|
20451
|
+
const dataMinItem = header.findById(FITSHeaderManager.DATAMIN);
|
|
20452
|
+
const dataMaxItem = header.findById(FITSHeaderManager.DATAMAX);
|
|
20453
|
+
if (dataMinItem === null || dataMaxItem === null) {
|
|
20454
|
+
try {
|
|
20455
|
+
const [min, max] = ParsePayload.computePhysicalValues(payload, header);
|
|
20456
|
+
if (dataMinItem === null && min !== null) {
|
|
20457
|
+
header.insert(new FITSHeaderItem(FITSHeaderManager.DATAMIN, min, "computed by jsfitsio"));
|
|
20458
|
+
}
|
|
20459
|
+
if (dataMaxItem === null && max !== null) {
|
|
20460
|
+
header.insert(new FITSHeaderItem(FITSHeaderManager.DATAMAX, max, "computed by jsfitsio"));
|
|
20461
|
+
}
|
|
20462
|
+
}
|
|
20463
|
+
catch (error) {
|
|
20464
|
+
if (bitpix === 64 && error instanceof RangeError) {
|
|
20465
|
+
return header;
|
|
20466
|
+
}
|
|
20467
|
+
throw error;
|
|
20468
|
+
}
|
|
20469
|
+
}
|
|
20470
|
+
return header;
|
|
20471
|
+
}
|
|
20472
|
+
static createTypedArray(rawData, bitpix) {
|
|
20473
|
+
ParsePayload.assertSupportedBITPIX(bitpix);
|
|
20474
|
+
const bytesPerElement = Math.abs(bitpix) / 8;
|
|
20475
|
+
if (rawData.byteLength % bytesPerElement !== 0) {
|
|
20476
|
+
throw new Error(`Payload byte length ${rawData.byteLength} ` +
|
|
20477
|
+
`is not aligned with BITPIX=${bitpix}.`);
|
|
20478
|
+
}
|
|
20479
|
+
const count = rawData.byteLength / bytesPerElement;
|
|
20480
|
+
const view = new DataView(rawData.buffer, rawData.byteOffset, rawData.byteLength);
|
|
20481
|
+
switch (bitpix) {
|
|
20482
|
+
case 8: {
|
|
20483
|
+
/*
|
|
20484
|
+
* For 8-bit FITS, byte order is irrelevant.
|
|
20485
|
+
*
|
|
20486
|
+
* Use slice() so typedData has its own correctly
|
|
20487
|
+
* sized backing store.
|
|
20488
|
+
*/
|
|
20489
|
+
return rawData.slice();
|
|
20490
|
+
}
|
|
20491
|
+
case 16: {
|
|
20492
|
+
const result = new Int16Array(count);
|
|
20493
|
+
for (let i = 0; i < count; i++) {
|
|
20494
|
+
result[i] = view.getInt16(i * 2, false);
|
|
20495
|
+
}
|
|
20496
|
+
return result;
|
|
20497
|
+
}
|
|
20498
|
+
case 32: {
|
|
20499
|
+
const result = new Int32Array(count);
|
|
20500
|
+
for (let i = 0; i < count; i++) {
|
|
20501
|
+
result[i] = view.getInt32(i * 4, false);
|
|
20502
|
+
}
|
|
20503
|
+
return result;
|
|
20504
|
+
}
|
|
20505
|
+
case 64: {
|
|
20506
|
+
const result = new BigInt64Array(count);
|
|
20507
|
+
for (let i = 0; i < count; i++) {
|
|
20508
|
+
result[i] = view.getBigInt64(i * 8, false);
|
|
20509
|
+
}
|
|
20510
|
+
return result;
|
|
20511
|
+
}
|
|
20512
|
+
case -32: {
|
|
20513
|
+
const result = new Float32Array(count);
|
|
20514
|
+
for (let i = 0; i < count; i++) {
|
|
20515
|
+
result[i] = view.getFloat32(i * 4, false);
|
|
20516
|
+
}
|
|
20517
|
+
return result;
|
|
20518
|
+
}
|
|
20519
|
+
case -64: {
|
|
20520
|
+
const result = new Float64Array(count);
|
|
20521
|
+
for (let i = 0; i < count; i++) {
|
|
20522
|
+
result[i] = view.getFloat64(i * 8, false);
|
|
20523
|
+
}
|
|
20524
|
+
return result;
|
|
20525
|
+
}
|
|
20526
|
+
default:
|
|
20527
|
+
throw new Error(`Unsupported FITS BITPIX value: ${bitpix}`);
|
|
20528
|
+
}
|
|
20529
|
+
}
|
|
20530
|
+
static computePhysicalValues(rawData, header) {
|
|
20531
|
+
const bitpix = ParseHeader.getFITSItemValue(header, FITSHeaderManager.BITPIX);
|
|
20532
|
+
if (bitpix === null) {
|
|
20533
|
+
return [null, null];
|
|
20534
|
+
}
|
|
20535
|
+
ParsePayload.assertSupportedBITPIX(bitpix);
|
|
20536
|
+
const shape = FITSImageUtils.getShape(header);
|
|
20537
|
+
const pixelCount = FITSImageUtils.getElementCount(shape);
|
|
20538
|
+
if (pixelCount === 0) {
|
|
20539
|
+
return [null, null];
|
|
20540
|
+
}
|
|
20541
|
+
const blank = ParseHeader.getFITSItemValue(header, FITSHeaderManager.BLANK);
|
|
20542
|
+
const bzero = ParseHeader.getFITSItemValue(header, FITSHeaderManager.BZERO) ?? 0;
|
|
20543
|
+
const bscale = ParseHeader.getFITSItemValue(header, FITSHeaderManager.BSCALE) ?? 1;
|
|
20544
|
+
const bytesPerElement = Math.abs(bitpix) / 8;
|
|
20545
|
+
const requiredBytes = pixelCount * bytesPerElement;
|
|
20546
|
+
if (rawData.byteLength < requiredBytes) {
|
|
20547
|
+
throw new Error(`FITS payload is too short: expected ${requiredBytes} bytes, ` +
|
|
20548
|
+
`received ${rawData.byteLength}.`);
|
|
20549
|
+
}
|
|
20550
|
+
const view = new DataView(rawData.buffer, rawData.byteOffset, rawData.byteLength);
|
|
20551
|
+
let min = null;
|
|
20552
|
+
let max = null;
|
|
20553
|
+
for (let i = 0; i < pixelCount; i++) {
|
|
20554
|
+
const rawValue = ParsePayload.extractPixelFromView(view, i * bytesPerElement, bitpix);
|
|
20555
|
+
// BLANK applies to integer FITS image data.
|
|
20556
|
+
if (bitpix > 0 && blank !== null && rawValue === blank) {
|
|
20557
|
+
continue;
|
|
20558
|
+
}
|
|
20559
|
+
const physicalValue = ParsePayload.pixel2physicalValue(rawValue, bscale, bzero);
|
|
20560
|
+
// Floating-point FITS images may contain NaN.
|
|
20561
|
+
if (Number.isNaN(physicalValue)) {
|
|
20562
|
+
continue;
|
|
20563
|
+
}
|
|
20564
|
+
if (min === null || physicalValue < min) {
|
|
20565
|
+
min = physicalValue;
|
|
20566
|
+
}
|
|
20567
|
+
if (max === null || physicalValue > max) {
|
|
20568
|
+
max = physicalValue;
|
|
20569
|
+
}
|
|
20570
|
+
}
|
|
20571
|
+
return [min, max];
|
|
20572
|
+
}
|
|
20573
|
+
static pixel2physicalValue(pxval, BSCALE, BZERO) {
|
|
20574
|
+
if (BZERO === null || BSCALE === null) {
|
|
20575
|
+
throw new Error("Either BZERO or BSCALE is null");
|
|
20576
|
+
}
|
|
20577
|
+
return BZERO + BSCALE * pxval;
|
|
20578
|
+
}
|
|
20579
|
+
static extractPixelValue(rawData, offset, bitpix) {
|
|
20580
|
+
ParsePayload.assertSupportedBITPIX(bitpix);
|
|
20581
|
+
const view = new DataView(rawData.buffer, rawData.byteOffset, rawData.byteLength);
|
|
20582
|
+
return ParsePayload.extractPixelFromView(view, offset, bitpix);
|
|
20583
|
+
}
|
|
20584
|
+
}
|
|
20585
|
+
//# sourceMappingURL=ParsePayload.js.map
|
|
20586
|
+
;// ./node_modules/jsfitsio/lib-esm/model/FITSHDU.js
|
|
20587
|
+
class FITSHDU {
|
|
20588
|
+
header;
|
|
20589
|
+
rawData;
|
|
20590
|
+
dataOffset;
|
|
20591
|
+
dataByteLength;
|
|
20592
|
+
constructor(header, rawData, dataOffset, dataByteLength) {
|
|
20593
|
+
this.header = header;
|
|
20594
|
+
this.rawData = rawData;
|
|
20595
|
+
this.dataOffset = dataOffset;
|
|
20596
|
+
this.dataByteLength = dataByteLength;
|
|
20597
|
+
}
|
|
20598
|
+
}
|
|
20599
|
+
//# sourceMappingURL=FITSHDU.js.map
|
|
20600
|
+
;// ./node_modules/jsfitsio/lib-esm/model/ImageHDU.js
|
|
20601
|
+
|
|
20602
|
+
class ImageHDU extends FITSHDU {
|
|
20603
|
+
bitpix;
|
|
20604
|
+
shape;
|
|
20605
|
+
typedData;
|
|
20606
|
+
type = "IMAGE";
|
|
20607
|
+
constructor(header, rawData, dataOffset, dataByteLength, bitpix, shape, typedData) {
|
|
20608
|
+
super(header, rawData, dataOffset, dataByteLength);
|
|
20609
|
+
this.bitpix = bitpix;
|
|
20610
|
+
this.shape = shape;
|
|
20611
|
+
this.typedData = typedData;
|
|
20612
|
+
}
|
|
20613
|
+
get naxis() {
|
|
20614
|
+
return this.shape.length;
|
|
20615
|
+
}
|
|
20616
|
+
get elementCount() {
|
|
20617
|
+
if (this.shape.length === 0) {
|
|
20618
|
+
return 0;
|
|
20619
|
+
}
|
|
20620
|
+
return this.shape.reduce((accumulator, dimension) => accumulator * dimension, 1);
|
|
20621
|
+
}
|
|
20622
|
+
}
|
|
20623
|
+
//# sourceMappingURL=ImageHDU.js.map
|
|
20624
|
+
;// ./node_modules/jsfitsio/lib-esm/model/PrimaryHDU.js
|
|
20625
|
+
|
|
20626
|
+
class PrimaryHDU extends ImageHDU {
|
|
20627
|
+
type = "PRIMARY";
|
|
20628
|
+
constructor(header, rawData, dataOffset, dataByteLength, bitpix, shape, typedData) {
|
|
20629
|
+
super(header, rawData, dataOffset, dataByteLength, bitpix, shape, typedData);
|
|
20630
|
+
}
|
|
20631
|
+
}
|
|
20632
|
+
//# sourceMappingURL=PrimaryHDU.js.map
|
|
20633
|
+
;// ./node_modules/jsfitsio/lib-esm/model/FITSFile.js
|
|
20634
|
+
|
|
20635
|
+
class FITSFile {
|
|
20636
|
+
_hdus;
|
|
20637
|
+
constructor(hdus = []) {
|
|
20638
|
+
this._hdus = [...hdus];
|
|
20639
|
+
}
|
|
20640
|
+
get hdus() {
|
|
20641
|
+
return this._hdus;
|
|
20642
|
+
}
|
|
20643
|
+
get length() {
|
|
20644
|
+
return this._hdus.length;
|
|
20645
|
+
}
|
|
20646
|
+
get primaryHDU() {
|
|
20647
|
+
const hdu = this._hdus[0];
|
|
20648
|
+
if (hdu instanceof PrimaryHDU) {
|
|
20649
|
+
return hdu;
|
|
20650
|
+
}
|
|
20651
|
+
return null;
|
|
20652
|
+
}
|
|
20653
|
+
getHDU(index) {
|
|
20654
|
+
return this._hdus[index] ?? null;
|
|
20655
|
+
}
|
|
20656
|
+
addHDU(hdu) {
|
|
20657
|
+
this._hdus.push(hdu);
|
|
20658
|
+
}
|
|
20659
|
+
}
|
|
20660
|
+
//# sourceMappingURL=FITSFile.js.map
|
|
20661
|
+
;// ./node_modules/jsfitsio/lib-esm/model/BinaryTableHDU.js
|
|
20662
|
+
|
|
20663
|
+
class BinaryTableHDU extends FITSHDU {
|
|
20664
|
+
rowByteLength;
|
|
20665
|
+
rowCount;
|
|
20666
|
+
columns;
|
|
20667
|
+
type = "BINTABLE";
|
|
20668
|
+
constructor(header, rawData, dataOffset, dataByteLength, rowByteLength, rowCount, columns) {
|
|
20669
|
+
super(header, rawData, dataOffset, dataByteLength);
|
|
20670
|
+
this.rowByteLength = rowByteLength;
|
|
20671
|
+
this.rowCount = rowCount;
|
|
20672
|
+
this.columns = columns;
|
|
20673
|
+
}
|
|
20674
|
+
get columnCount() {
|
|
20675
|
+
return this.columns.length;
|
|
20676
|
+
}
|
|
20677
|
+
getRowView(rowIndex) {
|
|
20678
|
+
if (rowIndex < 0 || rowIndex >= this.rowCount) {
|
|
20679
|
+
throw new RangeError(`Invalid row index ${rowIndex}.`);
|
|
20680
|
+
}
|
|
20681
|
+
const offset = rowIndex * this.rowByteLength;
|
|
20682
|
+
return new DataView(this.rawData.buffer, this.rawData.byteOffset + offset, this.rowByteLength);
|
|
20683
|
+
}
|
|
20684
|
+
getRow(rowIndex) {
|
|
20685
|
+
return this.columns.map((_, columnIndex) => this.getCell(rowIndex, columnIndex));
|
|
20686
|
+
}
|
|
20687
|
+
getCell(rowIndex, column) {
|
|
20688
|
+
const columnDefinition = this.resolveColumn(column);
|
|
20689
|
+
const row = this.getRowView(rowIndex);
|
|
20690
|
+
const offset = columnDefinition.byteOffset;
|
|
20691
|
+
const repeat = columnDefinition.repeat;
|
|
20692
|
+
switch (columnDefinition.type) {
|
|
20693
|
+
case "CHAR": {
|
|
20694
|
+
const bytes = new Uint8Array(row.buffer, row.byteOffset + offset, columnDefinition.byteWidth);
|
|
20695
|
+
return new TextDecoder("ascii").decode(bytes).replace(/\s+$/, "");
|
|
20696
|
+
}
|
|
20697
|
+
case "LOGICAL": {
|
|
20698
|
+
const values = [];
|
|
20699
|
+
for (let i = 0; i < repeat; i++) {
|
|
20700
|
+
const value = String.fromCharCode(row.getUint8(offset + i));
|
|
20701
|
+
values.push(value === "T");
|
|
20702
|
+
}
|
|
20703
|
+
return repeat === 1 ? values[0] : values;
|
|
20704
|
+
}
|
|
20705
|
+
case "UINT8": {
|
|
20706
|
+
const values = [];
|
|
20707
|
+
for (let i = 0; i < repeat; i++) {
|
|
20708
|
+
const raw = row.getUint8(offset + i);
|
|
20709
|
+
values.push(this.applyNumericScaling(raw, columnDefinition.scale, columnDefinition.zero));
|
|
20710
|
+
}
|
|
20711
|
+
return repeat === 1 ? values[0] : values;
|
|
20712
|
+
}
|
|
20713
|
+
case "INT16":
|
|
20714
|
+
return this.readNumericColumn(row, offset, repeat, 2, (view, position) => view.getInt16(position, false), columnDefinition.scale, columnDefinition.zero, columnDefinition.nullValue);
|
|
20715
|
+
case "INT32":
|
|
20716
|
+
return this.readNumericColumn(row, offset, repeat, 4, (view, position) => view.getInt32(position, false), columnDefinition.scale, columnDefinition.zero, columnDefinition.nullValue);
|
|
20717
|
+
case "INT64": {
|
|
20718
|
+
const values = [];
|
|
20719
|
+
for (let i = 0; i < repeat; i++) {
|
|
20720
|
+
const raw = row.getBigInt64(offset + i * 8, false);
|
|
20721
|
+
/*
|
|
20722
|
+
* Preserve exact 64-bit integers.
|
|
20723
|
+
*
|
|
20724
|
+
* Do not silently convert bigint to number.
|
|
20725
|
+
*/
|
|
20726
|
+
values.push(raw);
|
|
20727
|
+
}
|
|
20728
|
+
return repeat === 1 ? values[0] : values;
|
|
20729
|
+
}
|
|
20730
|
+
case "FLOAT32":
|
|
20731
|
+
return this.readNumericColumn(row, offset, repeat, 4, (view, position) => view.getFloat32(position, false), columnDefinition.scale, columnDefinition.zero, null);
|
|
20732
|
+
case "FLOAT64":
|
|
20733
|
+
return this.readNumericColumn(row, offset, repeat, 8, (view, position) => view.getFloat64(position, false), columnDefinition.scale, columnDefinition.zero, null);
|
|
20734
|
+
case "COMPLEX64": {
|
|
20735
|
+
const values = [];
|
|
20736
|
+
for (let i = 0; i < repeat; i++) {
|
|
20737
|
+
const position = offset + i * 8;
|
|
20738
|
+
values.push({
|
|
20739
|
+
real: row.getFloat32(position, false),
|
|
20740
|
+
imaginary: row.getFloat32(position + 4, false),
|
|
20741
|
+
});
|
|
20742
|
+
}
|
|
20743
|
+
return repeat === 1 ? values[0] : values;
|
|
20744
|
+
}
|
|
20745
|
+
case "COMPLEX128": {
|
|
20746
|
+
const values = [];
|
|
20747
|
+
for (let i = 0; i < repeat; i++) {
|
|
20748
|
+
const position = offset + i * 16;
|
|
20749
|
+
values.push({
|
|
20750
|
+
real: row.getFloat64(position, false),
|
|
20751
|
+
imaginary: row.getFloat64(position + 8, false),
|
|
20752
|
+
});
|
|
20753
|
+
}
|
|
20754
|
+
return repeat === 1 ? values[0] : values;
|
|
20755
|
+
}
|
|
20756
|
+
case "BIT":
|
|
20757
|
+
/*
|
|
20758
|
+
* I'd defer bit-array decoding for the moment.
|
|
20759
|
+
* The raw bytes remain available.
|
|
20760
|
+
*/
|
|
20761
|
+
return new Uint8Array(row.buffer, row.byteOffset + offset, columnDefinition.byteWidth).slice();
|
|
20762
|
+
default:
|
|
20763
|
+
throw new Error(`Unsupported BINTABLE column type: ${columnDefinition.type}`);
|
|
20764
|
+
}
|
|
20765
|
+
}
|
|
20766
|
+
readNumericColumn(view, offset, repeat, bytesPerElement, reader, scale, zero, nullValue) {
|
|
20767
|
+
const values = [];
|
|
20768
|
+
for (let i = 0; i < repeat; i++) {
|
|
20769
|
+
const raw = reader(view, offset + i * bytesPerElement);
|
|
20770
|
+
if (nullValue !== null && raw === nullValue) {
|
|
20771
|
+
values.push(null);
|
|
20772
|
+
continue;
|
|
20773
|
+
}
|
|
20774
|
+
values.push(this.applyNumericScaling(raw, scale, zero));
|
|
20775
|
+
}
|
|
20776
|
+
if (repeat === 1) {
|
|
20777
|
+
return values[0];
|
|
20778
|
+
}
|
|
20779
|
+
/*
|
|
20780
|
+
* Because repeated integer fields may contain NULL,
|
|
20781
|
+
* we cannot represent every case as number[].
|
|
20782
|
+
*
|
|
20783
|
+
* For now return a generic value array.
|
|
20784
|
+
*/
|
|
20785
|
+
return values;
|
|
20786
|
+
}
|
|
20787
|
+
applyNumericScaling(raw, scale, zero) {
|
|
20788
|
+
return zero + scale * raw;
|
|
20789
|
+
}
|
|
20790
|
+
resolveColumn(column) {
|
|
20791
|
+
if (typeof column === "number") {
|
|
20792
|
+
if (!Number.isInteger(column) ||
|
|
20793
|
+
column < 0 ||
|
|
20794
|
+
column >= this.columns.length) {
|
|
20795
|
+
throw new RangeError(`Invalid column index ${column}.`);
|
|
20796
|
+
}
|
|
20797
|
+
return this.columns[column];
|
|
20798
|
+
}
|
|
20799
|
+
const found = this.columns.find((candidate) => candidate.name === column);
|
|
20800
|
+
if (!found) {
|
|
20801
|
+
throw new Error(`BINTABLE column '${column}' not found.`);
|
|
20802
|
+
}
|
|
20803
|
+
return found;
|
|
20804
|
+
}
|
|
20805
|
+
}
|
|
20806
|
+
//# sourceMappingURL=BinaryTableHDU.js.map
|
|
20807
|
+
;// ./node_modules/jsfitsio/lib-esm/FITSBinaryTableUtils.js
|
|
20808
|
+
class FITSBinaryTableUtils {
|
|
20809
|
+
static parseTFORM(format) {
|
|
20810
|
+
const normalized = format
|
|
20811
|
+
.trim()
|
|
20812
|
+
.replace(/^'/, "")
|
|
20813
|
+
.replace(/'$/, "")
|
|
20814
|
+
.trim()
|
|
20815
|
+
.toUpperCase();
|
|
20816
|
+
const match = normalized.match(/^(\d*)([LXBIJKAEDCM])$/);
|
|
20817
|
+
if (!match) {
|
|
20818
|
+
throw new Error(`Unsupported FITS TFORM value: ${format}`);
|
|
20819
|
+
}
|
|
20820
|
+
const repeat = match[1] ? Number(match[1]) : 1;
|
|
20821
|
+
const code = match[2];
|
|
20822
|
+
const bytesPerElement = FITSBinaryTableUtils.bytesPerType(code);
|
|
20823
|
+
return {
|
|
20824
|
+
repeat,
|
|
20825
|
+
code,
|
|
20826
|
+
byteWidth: code === "X" ? Math.ceil(repeat / 8) : repeat * bytesPerElement,
|
|
20827
|
+
};
|
|
20828
|
+
}
|
|
20829
|
+
static bytesPerType(code) {
|
|
20830
|
+
switch (code) {
|
|
20831
|
+
case "L":
|
|
20832
|
+
case "B":
|
|
20833
|
+
case "A":
|
|
20834
|
+
return 1;
|
|
20835
|
+
case "I":
|
|
20836
|
+
return 2;
|
|
20837
|
+
case "J":
|
|
20838
|
+
case "E":
|
|
20839
|
+
return 4;
|
|
20840
|
+
case "K":
|
|
20841
|
+
case "D":
|
|
20842
|
+
return 8;
|
|
20843
|
+
case "C":
|
|
20844
|
+
return 8;
|
|
20845
|
+
case "M":
|
|
20846
|
+
return 16;
|
|
20847
|
+
case "X":
|
|
20848
|
+
return 0;
|
|
20849
|
+
default:
|
|
20850
|
+
throw new Error(`Unsupported FITS binary table type: ${code}`);
|
|
20851
|
+
}
|
|
20852
|
+
}
|
|
20853
|
+
}
|
|
20854
|
+
//# sourceMappingURL=FITSBinaryTableUtils.js.map
|
|
20855
|
+
;// ./node_modules/jsfitsio/lib-esm/model/AsciiTableHDU.js
|
|
20856
|
+
|
|
20857
|
+
class AsciiTableHDU extends FITSHDU {
|
|
20858
|
+
rowByteLength;
|
|
20859
|
+
rowCount;
|
|
20860
|
+
columns;
|
|
20861
|
+
type = "TABLE";
|
|
20862
|
+
constructor(header, rawData, dataOffset, dataByteLength, rowByteLength, rowCount, columns) {
|
|
20863
|
+
super(header, rawData, dataOffset, dataByteLength);
|
|
20864
|
+
this.rowByteLength = rowByteLength;
|
|
20865
|
+
this.rowCount = rowCount;
|
|
20866
|
+
this.columns = columns;
|
|
20867
|
+
}
|
|
20868
|
+
get columnCount() {
|
|
20869
|
+
return this.columns.length;
|
|
20870
|
+
}
|
|
20871
|
+
getRowView(rowIndex) {
|
|
20872
|
+
if (!Number.isInteger(rowIndex) ||
|
|
20873
|
+
rowIndex < 0 ||
|
|
20874
|
+
rowIndex >= this.rowCount) {
|
|
20875
|
+
throw new RangeError(`Invalid row index ${rowIndex}.`);
|
|
20876
|
+
}
|
|
20877
|
+
const start = rowIndex * this.rowByteLength;
|
|
20878
|
+
return this.rawData.subarray(start, start + this.rowByteLength);
|
|
20879
|
+
}
|
|
20880
|
+
getRowText(rowIndex) {
|
|
20881
|
+
return new TextDecoder("ascii").decode(this.getRowView(rowIndex));
|
|
20882
|
+
}
|
|
20883
|
+
resolveColumn(column) {
|
|
20884
|
+
if (typeof column === "number") {
|
|
20885
|
+
if (!Number.isInteger(column) ||
|
|
20886
|
+
column < 0 ||
|
|
20887
|
+
column >= this.columns.length) {
|
|
20888
|
+
throw new RangeError(`Invalid column index ${column}.`);
|
|
20889
|
+
}
|
|
20890
|
+
return this.columns[column];
|
|
20891
|
+
}
|
|
20892
|
+
const found = this.columns.find((candidate) => candidate.name === column);
|
|
20893
|
+
if (!found) {
|
|
20894
|
+
throw new Error(`ASCII TABLE column '${column}' not found.`);
|
|
20895
|
+
}
|
|
20896
|
+
return found;
|
|
20897
|
+
}
|
|
20898
|
+
getCell(rowIndex, column) {
|
|
20899
|
+
const definition = this.resolveColumn(column);
|
|
20900
|
+
const row = this.getRowView(rowIndex);
|
|
20901
|
+
const bytes = row.subarray(definition.byteOffset, definition.byteOffset + definition.width);
|
|
20902
|
+
const raw = new TextDecoder("ascii").decode(bytes);
|
|
20903
|
+
const trimmed = raw.trim();
|
|
20904
|
+
/*
|
|
20905
|
+
* Blank numeric fields are treated as null.
|
|
20906
|
+
*/
|
|
20907
|
+
if (trimmed.length === 0) {
|
|
20908
|
+
return definition.type === "CHAR" ? "" : null;
|
|
20909
|
+
}
|
|
20910
|
+
switch (definition.type) {
|
|
20911
|
+
case "CHAR":
|
|
20912
|
+
return raw.replace(/\s+$/, "");
|
|
20913
|
+
case "INTEGER": {
|
|
20914
|
+
const value = Number.parseInt(trimmed, 10);
|
|
20915
|
+
if (Number.isNaN(value)) {
|
|
20916
|
+
return null;
|
|
20917
|
+
}
|
|
20918
|
+
return value;
|
|
20919
|
+
}
|
|
20920
|
+
case "FLOAT":
|
|
20921
|
+
case "EXPONENTIAL":
|
|
20922
|
+
case "DOUBLE": {
|
|
20923
|
+
/*
|
|
20924
|
+
* FITS ASCII tables may use D exponent notation.
|
|
20925
|
+
* JavaScript expects E.
|
|
20926
|
+
*/
|
|
20927
|
+
const normalized = trimmed.replace(/[dD]/, "E");
|
|
20928
|
+
const value = Number.parseFloat(normalized);
|
|
20929
|
+
if (Number.isNaN(value)) {
|
|
20930
|
+
return null;
|
|
20931
|
+
}
|
|
20932
|
+
return value;
|
|
20933
|
+
}
|
|
20934
|
+
default:
|
|
20935
|
+
throw new Error(`Unsupported ASCII TABLE column type: ${definition.type}`);
|
|
20936
|
+
}
|
|
20937
|
+
}
|
|
20938
|
+
getRow(rowIndex) {
|
|
20939
|
+
return this.columns.map((_, columnIndex) => this.getCell(rowIndex, columnIndex));
|
|
20940
|
+
}
|
|
20941
|
+
}
|
|
20942
|
+
//# sourceMappingURL=AsciiTableHDU.js.map
|
|
20943
|
+
;// ./node_modules/jsfitsio/lib-esm/FITSAsciiTableUtils.js
|
|
20944
|
+
class FITSAsciiTableUtils {
|
|
20945
|
+
static parseTFORM(format) {
|
|
20946
|
+
const normalized = format
|
|
20947
|
+
.trim()
|
|
20948
|
+
.replace(/^'/, "")
|
|
20949
|
+
.replace(/'$/, "")
|
|
20950
|
+
.trim()
|
|
20951
|
+
.toUpperCase();
|
|
20952
|
+
/*
|
|
20953
|
+
* FITS ASCII table formats:
|
|
20954
|
+
*
|
|
20955
|
+
* Aw
|
|
20956
|
+
* Iw
|
|
20957
|
+
* Fw.d
|
|
20958
|
+
* Ew.d
|
|
20959
|
+
* Dw.d
|
|
20960
|
+
*/
|
|
20961
|
+
const match = normalized.match(/^([AIFED])(\d+)(?:\.(\d+))?$/);
|
|
20962
|
+
if (!match) {
|
|
20963
|
+
throw new Error(`Unsupported FITS ASCII table TFORM value: ${format}`);
|
|
20964
|
+
}
|
|
20965
|
+
const code = match[1];
|
|
20966
|
+
const width = Number(match[2]);
|
|
20967
|
+
const decimals = match[3] !== undefined
|
|
20968
|
+
? Number(match[3])
|
|
20969
|
+
: null;
|
|
20970
|
+
if (!Number.isInteger(width) ||
|
|
20971
|
+
width <= 0) {
|
|
20972
|
+
throw new Error(`Invalid FITS ASCII table field width: ${width}`);
|
|
20973
|
+
}
|
|
20974
|
+
if (code === "A" ||
|
|
20975
|
+
code === "I") {
|
|
20976
|
+
if (decimals !== null) {
|
|
20977
|
+
throw new Error(`TFORM ${format} must not specify decimal places.`);
|
|
20978
|
+
}
|
|
20979
|
+
}
|
|
20980
|
+
else if (decimals === null) {
|
|
20981
|
+
throw new Error(`TFORM ${format} requires decimal places.`);
|
|
20982
|
+
}
|
|
20983
|
+
return {
|
|
20984
|
+
code,
|
|
20985
|
+
width,
|
|
20986
|
+
decimals,
|
|
20987
|
+
};
|
|
20988
|
+
}
|
|
20989
|
+
}
|
|
20990
|
+
//# sourceMappingURL=FITSAsciiTableUtils.js.map
|
|
20991
|
+
;// ./node_modules/jsfitsio/lib-esm/FITSParser.js
|
|
20992
|
+
|
|
20993
|
+
|
|
20994
|
+
|
|
20995
|
+
|
|
20996
|
+
|
|
20997
|
+
|
|
20998
|
+
|
|
20999
|
+
|
|
21000
|
+
|
|
21001
|
+
|
|
21002
|
+
|
|
21003
|
+
|
|
21004
|
+
class FITSParser {
|
|
21005
|
+
/**
|
|
21006
|
+
* @deprecated Use loadFITSFile() instead.
|
|
21007
|
+
*
|
|
21008
|
+
* This legacy API supports only 2-dimensional image FITS files
|
|
21009
|
+
* and returns the former FITSParsed structure.
|
|
21010
|
+
*/
|
|
21011
|
+
static async loadFITS(path, options = {}) {
|
|
21012
|
+
const fitsFile = await FITSParser.loadFITSFile(path, options);
|
|
21013
|
+
if (fitsFile === null) {
|
|
21014
|
+
return null;
|
|
21015
|
+
}
|
|
21016
|
+
const primary = fitsFile.primaryHDU;
|
|
21017
|
+
if (primary === null || primary.rawData === null) {
|
|
21018
|
+
return null;
|
|
21019
|
+
}
|
|
21020
|
+
const shape = FITSImageUtils.getShape(primary.header);
|
|
21021
|
+
if (shape.length !== 2) {
|
|
21022
|
+
throw new Error("Legacy loadFITS() supports only 2D FITS images. " +
|
|
21023
|
+
"Use loadFITSFile() for N-dimensional images.");
|
|
21024
|
+
}
|
|
21025
|
+
return {
|
|
21026
|
+
header: primary.header,
|
|
21027
|
+
data: FITSParser.createMatrix(primary.rawData, primary.header),
|
|
21028
|
+
};
|
|
21029
|
+
}
|
|
21030
|
+
static async loadFITSFile(path, options = {}) {
|
|
21031
|
+
const rawData = await FITSParser.getFile(path);
|
|
21032
|
+
if (rawData.byteLength === 0) {
|
|
21033
|
+
return null;
|
|
21034
|
+
}
|
|
21035
|
+
return FITSParser.processFITSFile(rawData, options);
|
|
21036
|
+
}
|
|
21037
|
+
static processFITSFile(rawData, options) {
|
|
21038
|
+
const fitsFile = new FITSFile();
|
|
21039
|
+
let offset = 0;
|
|
21040
|
+
let hduIndex = 0;
|
|
21041
|
+
while (offset < rawData.byteLength) {
|
|
21042
|
+
/*
|
|
21043
|
+
* Ignore trailing zero/space padding.
|
|
21044
|
+
*/
|
|
21045
|
+
if (FITSParser.isPaddingOnly(rawData, offset)) {
|
|
21046
|
+
break;
|
|
21047
|
+
}
|
|
21048
|
+
const header = ParseHeader.parse(rawData, offset);
|
|
21049
|
+
const headerByteLength = ParseHeader.getHeaderByteLength(rawData, offset);
|
|
21050
|
+
const dataOffset = offset + headerByteLength;
|
|
21051
|
+
const hduType = FITSParser.getHDUType(header, hduIndex);
|
|
21052
|
+
switch (hduType) {
|
|
21053
|
+
case "PRIMARY":
|
|
21054
|
+
case "IMAGE": {
|
|
21055
|
+
const dataByteLength = FITSParser.getImagePayloadByteLength(header);
|
|
21056
|
+
if (dataOffset + dataByteLength > rawData.byteLength) {
|
|
21057
|
+
throw new Error(`Invalid FITS HDU ${hduIndex}: ` +
|
|
21058
|
+
`expected ${dataByteLength} payload bytes ` +
|
|
21059
|
+
`at offset ${dataOffset}, but only ` +
|
|
21060
|
+
`${rawData.byteLength - dataOffset} remain.`);
|
|
21061
|
+
}
|
|
21062
|
+
const rawPayload = rawData.subarray(dataOffset, dataOffset + dataByteLength);
|
|
21063
|
+
const hdu = FITSParser.createImageHDU(header, rawPayload, dataOffset, dataByteLength, hduIndex === 0, options);
|
|
21064
|
+
fitsFile.addHDU(hdu);
|
|
21065
|
+
const paddedPayloadLength = FITSParser.getPaddedByteLength(dataByteLength);
|
|
21066
|
+
offset = dataOffset + paddedPayloadLength;
|
|
21067
|
+
break;
|
|
21068
|
+
}
|
|
21069
|
+
case "BINTABLE": {
|
|
21070
|
+
const dataByteLength = FITSParser.getBinaryTablePayloadByteLength(header);
|
|
21071
|
+
if (dataOffset + dataByteLength > rawData.byteLength) {
|
|
21072
|
+
throw new Error(`Invalid BINTABLE HDU ${hduIndex}.`);
|
|
21073
|
+
}
|
|
21074
|
+
const rawPayload = rawData.subarray(dataOffset, dataOffset + dataByteLength);
|
|
21075
|
+
const hdu = FITSParser.createBinaryTableHDU(header, rawPayload, dataOffset, dataByteLength);
|
|
21076
|
+
fitsFile.addHDU(hdu);
|
|
21077
|
+
offset = dataOffset + FITSParser.getPaddedByteLength(dataByteLength);
|
|
21078
|
+
break;
|
|
21079
|
+
}
|
|
21080
|
+
case "TABLE": {
|
|
21081
|
+
const dataByteLength = FITSParser.getAsciiTablePayloadByteLength(header);
|
|
21082
|
+
if (dataOffset + dataByteLength > rawData.byteLength) {
|
|
21083
|
+
throw new Error(`Invalid ASCII TABLE HDU ${hduIndex}: ` +
|
|
21084
|
+
`expected ${dataByteLength} payload bytes ` +
|
|
21085
|
+
`at offset ${dataOffset}, but only ` +
|
|
21086
|
+
`${rawData.byteLength - dataOffset} remain.`);
|
|
21087
|
+
}
|
|
21088
|
+
const rawPayload = rawData.subarray(dataOffset, dataOffset + dataByteLength);
|
|
21089
|
+
const hdu = FITSParser.createAsciiTableHDU(header, rawPayload, dataOffset, dataByteLength);
|
|
21090
|
+
fitsFile.addHDU(hdu);
|
|
21091
|
+
offset = dataOffset + FITSParser.getPaddedByteLength(dataByteLength);
|
|
21092
|
+
break;
|
|
21093
|
+
}
|
|
21094
|
+
default:
|
|
21095
|
+
throw new Error(`Unsupported FITS HDU type at index ${hduIndex}.`);
|
|
21096
|
+
}
|
|
21097
|
+
hduIndex++;
|
|
21098
|
+
}
|
|
21099
|
+
return fitsFile;
|
|
21100
|
+
}
|
|
21101
|
+
static getPaddedByteLength(byteLength) {
|
|
21102
|
+
if (byteLength === 0) {
|
|
21103
|
+
return 0;
|
|
21104
|
+
}
|
|
21105
|
+
return (Math.ceil(byteLength / ParseHeader.BLOCK_SIZE) * ParseHeader.BLOCK_SIZE);
|
|
21106
|
+
}
|
|
21107
|
+
static isPaddingOnly(rawData, offset) {
|
|
21108
|
+
for (let i = offset; i < rawData.byteLength; i++) {
|
|
21109
|
+
const value = rawData[i];
|
|
21110
|
+
if (value !== 0x00 && value !== 0x20) {
|
|
21111
|
+
return false;
|
|
21112
|
+
}
|
|
21113
|
+
}
|
|
21114
|
+
return true;
|
|
21115
|
+
}
|
|
21116
|
+
static getHDUType(header, index) {
|
|
21117
|
+
if (index === 0) {
|
|
21118
|
+
return "PRIMARY";
|
|
21119
|
+
}
|
|
21120
|
+
const xtension = ParseHeader.getFITSItemStringValue(header, FITSHeaderManager.XTENSION);
|
|
21121
|
+
if (xtension === null) {
|
|
21122
|
+
return "UNKNOWN";
|
|
21123
|
+
}
|
|
21124
|
+
switch (xtension.toUpperCase()) {
|
|
21125
|
+
case "IMAGE":
|
|
21126
|
+
return "IMAGE";
|
|
21127
|
+
case "BINTABLE":
|
|
21128
|
+
return "BINTABLE";
|
|
21129
|
+
case "TABLE":
|
|
21130
|
+
return "TABLE";
|
|
21131
|
+
default:
|
|
21132
|
+
return "UNKNOWN";
|
|
21133
|
+
}
|
|
21134
|
+
}
|
|
21135
|
+
static createImageHDU(header, rawPayload, dataOffset, dataByteLength, primary, options) {
|
|
21136
|
+
const finalHeader = options.computeDataMinMax
|
|
21137
|
+
? (ParsePayload.computePhysicalMinAndMax(header, rawPayload) ?? header)
|
|
21138
|
+
: header;
|
|
21139
|
+
const bitpix = ParseHeader.getFITSItemValue(finalHeader, FITSHeaderManager.BITPIX);
|
|
21140
|
+
if (bitpix === null) {
|
|
21141
|
+
throw new Error("BITPIX not defined.");
|
|
21142
|
+
}
|
|
21143
|
+
const shape = FITSImageUtils.getShape(finalHeader);
|
|
21144
|
+
const typedData = ParsePayload.createTypedArray(rawPayload, bitpix);
|
|
21145
|
+
if (primary) {
|
|
21146
|
+
return new PrimaryHDU(finalHeader, rawPayload, dataOffset, dataByteLength, bitpix, shape, typedData);
|
|
21147
|
+
}
|
|
21148
|
+
return new ImageHDU(finalHeader, rawPayload, dataOffset, dataByteLength, bitpix, shape, typedData);
|
|
21149
|
+
}
|
|
21150
|
+
static getImagePayloadByteLength(header) {
|
|
21151
|
+
const bitpix = ParseHeader.getFITSItemValue(header, FITSHeaderManager.BITPIX);
|
|
21152
|
+
if (bitpix === null) {
|
|
21153
|
+
throw new Error("BITPIX not defined.");
|
|
21154
|
+
}
|
|
21155
|
+
ParsePayload.assertSupportedBITPIX(bitpix);
|
|
21156
|
+
const shape = FITSImageUtils.getShape(header);
|
|
21157
|
+
if (shape.length === 0) {
|
|
21158
|
+
return 0;
|
|
21159
|
+
}
|
|
21160
|
+
const elementCount = shape.reduce((total, dimension) => total * dimension, 1);
|
|
21161
|
+
const bytesPerElement = Math.abs(bitpix) / 8;
|
|
21162
|
+
return elementCount * bytesPerElement;
|
|
21163
|
+
}
|
|
21164
|
+
static getBinaryTablePayloadByteLength(header) {
|
|
21165
|
+
const rowByteLength = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS1);
|
|
21166
|
+
const rowCount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS2);
|
|
21167
|
+
const pcount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.PCOUNT) ?? 0;
|
|
21168
|
+
if (rowByteLength === null || rowCount === null) {
|
|
21169
|
+
throw new Error("BINTABLE requires NAXIS1 and NAXIS2.");
|
|
21170
|
+
}
|
|
21171
|
+
return rowByteLength * rowCount + pcount;
|
|
21172
|
+
}
|
|
21173
|
+
static getBinaryTableColumns(header) {
|
|
21174
|
+
const fieldCount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.TFIELDS);
|
|
21175
|
+
if (fieldCount === null) {
|
|
21176
|
+
throw new Error("BINTABLE requires TFIELDS.");
|
|
21177
|
+
}
|
|
21178
|
+
const columns = [];
|
|
21179
|
+
let byteOffset = 0;
|
|
21180
|
+
for (let index = 1; index <= fieldCount; index++) {
|
|
21181
|
+
const tform = ParseHeader.getFITSItemStringValue(header, FITSHeaderManager.tableFieldKey("TFORM", index));
|
|
21182
|
+
if (tform === null) {
|
|
21183
|
+
throw new Error(`Missing TFORM${index}.`);
|
|
21184
|
+
}
|
|
21185
|
+
const parsed = FITSBinaryTableUtils.parseTFORM(tform);
|
|
21186
|
+
const name = ParseHeader.getFITSItemStringValue(header, FITSHeaderManager.tableFieldKey("TTYPE", index));
|
|
21187
|
+
const unit = ParseHeader.getFITSItemStringValue(header, FITSHeaderManager.tableFieldKey("TUNIT", index));
|
|
21188
|
+
columns.push({
|
|
21189
|
+
index,
|
|
21190
|
+
name,
|
|
21191
|
+
format: tform,
|
|
21192
|
+
type: FITSParser.mapBinaryType(parsed.code),
|
|
21193
|
+
repeat: parsed.repeat,
|
|
21194
|
+
byteOffset,
|
|
21195
|
+
byteWidth: parsed.byteWidth,
|
|
21196
|
+
unit,
|
|
21197
|
+
scale: ParseHeader.getFITSItemValue(header, FITSHeaderManager.tableFieldKey("TSCAL", index)) ?? 1,
|
|
21198
|
+
zero: ParseHeader.getFITSItemValue(header, FITSHeaderManager.tableFieldKey("TZERO", index)) ?? 0,
|
|
21199
|
+
nullValue: ParseHeader.getFITSItemValue(header, FITSHeaderManager.tableFieldKey("TNULL", index)),
|
|
21200
|
+
});
|
|
21201
|
+
byteOffset += parsed.byteWidth;
|
|
21202
|
+
}
|
|
21203
|
+
return columns;
|
|
21204
|
+
}
|
|
21205
|
+
static mapBinaryType(code) {
|
|
21206
|
+
switch (code.toUpperCase()) {
|
|
21207
|
+
case "L":
|
|
21208
|
+
return "LOGICAL";
|
|
21209
|
+
case "X":
|
|
21210
|
+
return "BIT";
|
|
21211
|
+
case "B":
|
|
21212
|
+
return "UINT8";
|
|
21213
|
+
case "I":
|
|
21214
|
+
return "INT16";
|
|
21215
|
+
case "J":
|
|
21216
|
+
return "INT32";
|
|
21217
|
+
case "K":
|
|
21218
|
+
return "INT64";
|
|
21219
|
+
case "A":
|
|
21220
|
+
return "CHAR";
|
|
21221
|
+
case "E":
|
|
21222
|
+
return "FLOAT32";
|
|
21223
|
+
case "D":
|
|
21224
|
+
return "FLOAT64";
|
|
21225
|
+
case "C":
|
|
21226
|
+
return "COMPLEX64";
|
|
21227
|
+
case "M":
|
|
21228
|
+
return "COMPLEX128";
|
|
21229
|
+
default:
|
|
21230
|
+
return "UNKNOWN";
|
|
21231
|
+
}
|
|
21232
|
+
}
|
|
21233
|
+
static createBinaryTableHDU(header, rawPayload, dataOffset, dataByteLength) {
|
|
21234
|
+
const rowByteLength = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS1);
|
|
21235
|
+
const rowCount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS2);
|
|
21236
|
+
if (rowByteLength === null || rowCount === null) {
|
|
21237
|
+
throw new Error("Invalid BINTABLE header.");
|
|
21238
|
+
}
|
|
21239
|
+
const columns = FITSParser.getBinaryTableColumns(header);
|
|
21240
|
+
const columnsByteWidth = columns.reduce((sum, column) => sum + column.byteWidth, 0);
|
|
21241
|
+
if (columnsByteWidth !== rowByteLength) {
|
|
21242
|
+
throw new Error(`BINTABLE columns occupy ${columnsByteWidth} bytes per row, ` +
|
|
21243
|
+
`but NAXIS1=${rowByteLength}.`);
|
|
21244
|
+
}
|
|
21245
|
+
return new BinaryTableHDU(header, rawPayload, dataOffset, dataByteLength, rowByteLength, rowCount, columns);
|
|
21246
|
+
}
|
|
21247
|
+
static getAsciiTablePayloadByteLength(header) {
|
|
21248
|
+
const rowByteLength = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS1);
|
|
21249
|
+
const rowCount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS2);
|
|
21250
|
+
if (rowByteLength === null || rowCount === null) {
|
|
21251
|
+
throw new Error("ASCII TABLE requires NAXIS1 and NAXIS2.");
|
|
21252
|
+
}
|
|
21253
|
+
if (!Number.isInteger(rowByteLength) || rowByteLength < 0) {
|
|
21254
|
+
throw new Error(`Invalid ASCII TABLE NAXIS1=${rowByteLength}.`);
|
|
21255
|
+
}
|
|
21256
|
+
if (!Number.isInteger(rowCount) || rowCount < 0) {
|
|
21257
|
+
throw new Error(`Invalid ASCII TABLE NAXIS2=${rowCount}.`);
|
|
21258
|
+
}
|
|
21259
|
+
const pcount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.PCOUNT) ?? 0;
|
|
21260
|
+
if (pcount !== 0) {
|
|
21261
|
+
throw new Error(`ASCII TABLE requires PCOUNT=0, received ${pcount}.`);
|
|
21262
|
+
}
|
|
21263
|
+
return rowByteLength * rowCount;
|
|
21264
|
+
}
|
|
21265
|
+
static mapAsciiType(code) {
|
|
21266
|
+
switch (code.toUpperCase()) {
|
|
21267
|
+
case "A":
|
|
21268
|
+
return "CHAR";
|
|
21269
|
+
case "I":
|
|
21270
|
+
return "INTEGER";
|
|
21271
|
+
case "F":
|
|
21272
|
+
return "FLOAT";
|
|
21273
|
+
case "E":
|
|
21274
|
+
return "EXPONENTIAL";
|
|
21275
|
+
case "D":
|
|
21276
|
+
return "DOUBLE";
|
|
21277
|
+
default:
|
|
21278
|
+
return "UNKNOWN";
|
|
21279
|
+
}
|
|
21280
|
+
}
|
|
21281
|
+
static getAsciiTableColumns(header) {
|
|
21282
|
+
const fieldCount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.TFIELDS);
|
|
21283
|
+
if (fieldCount === null) {
|
|
21284
|
+
throw new Error("ASCII TABLE requires TFIELDS.");
|
|
21285
|
+
}
|
|
21286
|
+
if (!Number.isInteger(fieldCount) || fieldCount < 0) {
|
|
21287
|
+
throw new Error(`Invalid ASCII TABLE TFIELDS=${fieldCount}.`);
|
|
21288
|
+
}
|
|
21289
|
+
const columns = [];
|
|
21290
|
+
for (let index = 1; index <= fieldCount; index++) {
|
|
21291
|
+
const tform = ParseHeader.getFITSItemStringValue(header, FITSHeaderManager.tableFieldKey("TFORM", index));
|
|
21292
|
+
if (tform === null) {
|
|
21293
|
+
throw new Error(`Missing TFORM${index}.`);
|
|
21294
|
+
}
|
|
21295
|
+
const tbcol = ParseHeader.getFITSItemValue(header, FITSHeaderManager.tableFieldKey("TBCOL", index));
|
|
21296
|
+
if (tbcol === null) {
|
|
21297
|
+
throw new Error(`Missing TBCOL${index}.`);
|
|
21298
|
+
}
|
|
21299
|
+
if (!Number.isInteger(tbcol) || tbcol < 1) {
|
|
21300
|
+
throw new Error(`Invalid TBCOL${index}=${tbcol}.`);
|
|
21301
|
+
}
|
|
21302
|
+
const parsed = FITSAsciiTableUtils.parseTFORM(tform);
|
|
21303
|
+
const name = ParseHeader.getFITSItemStringValue(header, FITSHeaderManager.tableFieldKey("TTYPE", index));
|
|
21304
|
+
const unit = ParseHeader.getFITSItemStringValue(header, FITSHeaderManager.tableFieldKey("TUNIT", index));
|
|
21305
|
+
columns.push({
|
|
21306
|
+
index,
|
|
21307
|
+
name,
|
|
21308
|
+
format: tform,
|
|
21309
|
+
type: FITSParser.mapAsciiType(parsed.code),
|
|
21310
|
+
startColumn: tbcol,
|
|
21311
|
+
/*
|
|
21312
|
+
* FITS TBCOL is 1-based.
|
|
21313
|
+
* JavaScript offsets are 0-based.
|
|
21314
|
+
*/
|
|
21315
|
+
byteOffset: tbcol - 1,
|
|
21316
|
+
width: parsed.width,
|
|
21317
|
+
decimals: parsed.decimals,
|
|
21318
|
+
unit,
|
|
21319
|
+
});
|
|
21320
|
+
}
|
|
21321
|
+
return columns;
|
|
21322
|
+
}
|
|
21323
|
+
static validateAsciiTableColumns(columns, rowByteLength) {
|
|
21324
|
+
for (const column of columns) {
|
|
21325
|
+
const endOffset = column.byteOffset + column.width;
|
|
21326
|
+
if (endOffset > rowByteLength) {
|
|
21327
|
+
throw new Error(`ASCII TABLE column ${column.index} ` +
|
|
21328
|
+
`extends to byte ${endOffset}, ` +
|
|
21329
|
+
`but NAXIS1=${rowByteLength}.`);
|
|
21330
|
+
}
|
|
21331
|
+
}
|
|
21332
|
+
}
|
|
21333
|
+
static createAsciiTableHDU(header, rawPayload, dataOffset, dataByteLength) {
|
|
21334
|
+
const rowByteLength = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS1);
|
|
21335
|
+
const rowCount = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS2);
|
|
21336
|
+
if (rowByteLength === null || rowCount === null) {
|
|
21337
|
+
throw new Error("Invalid ASCII TABLE header.");
|
|
21338
|
+
}
|
|
21339
|
+
const columns = FITSParser.getAsciiTableColumns(header);
|
|
21340
|
+
FITSParser.validateAsciiTableColumns(columns, rowByteLength);
|
|
21341
|
+
return new AsciiTableHDU(header, rawPayload, dataOffset, dataByteLength, rowByteLength, rowCount, columns);
|
|
21342
|
+
}
|
|
21343
|
+
static createMatrix(payload, header) {
|
|
21344
|
+
const NAXIS1 = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS1);
|
|
21345
|
+
if (NAXIS1 === null) {
|
|
21346
|
+
throw new Error("NAXIS1 not defined.");
|
|
21347
|
+
}
|
|
21348
|
+
const NAXIS2 = ParseHeader.getFITSItemValue(header, FITSHeaderManager.NAXIS2);
|
|
21349
|
+
if (NAXIS2 === null) {
|
|
21350
|
+
throw new Error("NAXIS2 not defined.");
|
|
21351
|
+
}
|
|
21352
|
+
const BITPIX = ParseHeader.getFITSItemValue(header, FITSHeaderManager.BITPIX);
|
|
21353
|
+
if (BITPIX === null) {
|
|
21354
|
+
throw new Error("BITPIX not defined.");
|
|
21355
|
+
}
|
|
21356
|
+
const bytesXelem = Math.abs(BITPIX / 8);
|
|
21357
|
+
// if (payload.length !== NAXIS1 * NAXIS2 * bytesXelem) {
|
|
21358
|
+
// throw new Error("Payload size does not match the expected matrix dimensions.");
|
|
21359
|
+
// }
|
|
21360
|
+
// const matrix: Array<Uint8Array> = [];
|
|
21361
|
+
const matrix = [];
|
|
21362
|
+
for (let i = 0; i < NAXIS2; i++) {
|
|
21363
|
+
matrix.push(payload.slice(i * NAXIS1 * bytesXelem, (i + 1) * NAXIS1 * bytesXelem));
|
|
21364
|
+
}
|
|
21365
|
+
return matrix;
|
|
21366
|
+
}
|
|
21367
|
+
/**
|
|
21368
|
+
* @deprecated Legacy FITSParsed writer API.
|
|
21369
|
+
*/
|
|
21370
|
+
static saveFITSLocally(fitsParsed, path) {
|
|
21371
|
+
return FITSWriter.writeFITSFile(fitsParsed, path);
|
|
21372
|
+
}
|
|
21373
|
+
static async getFile(uri) {
|
|
21374
|
+
if (!uri.substring(0, 5).toLowerCase().includes("http")) {
|
|
21375
|
+
const p = await __webpack_require__.e(/* import() */ 64).then(__webpack_require__.bind(__webpack_require__, 7064));
|
|
21376
|
+
const rawData = await p.getLocalFile(uri);
|
|
21377
|
+
if (rawData?.length) {
|
|
21378
|
+
const uint8 = new Uint8Array(rawData);
|
|
21379
|
+
return uint8;
|
|
21380
|
+
}
|
|
21381
|
+
return new Uint8Array(0);
|
|
21382
|
+
}
|
|
21383
|
+
else {
|
|
21384
|
+
const p = await __webpack_require__.e(/* import() */ 911).then(__webpack_require__.bind(__webpack_require__, 1911));
|
|
21385
|
+
const rawData = await p.getFile(uri);
|
|
21386
|
+
if (rawData?.byteLength) {
|
|
21387
|
+
const uint8 = new Uint8Array(rawData);
|
|
21388
|
+
return uint8;
|
|
21389
|
+
}
|
|
21390
|
+
return new Uint8Array(0);
|
|
21391
|
+
}
|
|
21392
|
+
}
|
|
21393
|
+
}
|
|
21394
|
+
// const url = "http://skies.esac.esa.int/Herschel/normalized/PACS_hips160//Norder8/Dir40000/Npix47180.fits"
|
|
21395
|
+
// FITSParser.loadFITS(url).then((fits) => {
|
|
21396
|
+
// if (fits == null) {
|
|
21397
|
+
// return null
|
|
21398
|
+
// }
|
|
21399
|
+
// const path = "./fitsTest1.fits"
|
|
21400
|
+
// console.log(fits.header)
|
|
21401
|
+
// FITSParser.saveFITSLocally(fits, path)
|
|
21402
|
+
// console.log("finished")
|
|
21403
|
+
// })
|
|
21404
|
+
// // const file = "/Users/fabriziogiordano/Desktop/PhD/code/new/FITSParser/tests/inputs/empty.fits"
|
|
21405
|
+
// const file = "/Users/fabriziogiordano/Desktop/PhD/code/new/FITSParser/tests/inputs/Npix43348.fits"
|
|
21406
|
+
// FITSParser.loadFITS(file).then((fits) => {
|
|
21407
|
+
// if (fits == null) {
|
|
21408
|
+
// return null
|
|
21409
|
+
// }
|
|
21410
|
+
// const path = "./fitsTest2.fits"
|
|
21411
|
+
// console.log(fits.header)
|
|
21412
|
+
// FITSParser.saveFITSLocally(fits, path)
|
|
21413
|
+
// console.log("finished")
|
|
21414
|
+
// })
|
|
21415
|
+
//# sourceMappingURL=FITSParser.js.map
|
|
21416
|
+
;// ./node_modules/jsfitsio/lib-esm/index.js
|
|
21417
|
+
|
|
21418
|
+
|
|
21419
|
+
|
|
21420
|
+
|
|
21421
|
+
|
|
21422
|
+
|
|
21423
|
+
|
|
21424
|
+
|
|
21425
|
+
|
|
21426
|
+
|
|
21427
|
+
|
|
21428
|
+
|
|
21429
|
+
//# sourceMappingURL=index.js.map
|
|
21430
|
+
|
|
21431
|
+
/***/ }
|
|
21432
|
+
|
|
21433
|
+
/******/ });
|
|
21434
|
+
/************************************************************************/
|
|
21435
|
+
/******/ // The module cache
|
|
21436
|
+
/******/ const __webpack_module_cache__ = {};
|
|
21437
|
+
/******/
|
|
21438
|
+
/******/ // The require function
|
|
21439
|
+
/******/ function __webpack_require__(moduleId) {
|
|
21440
|
+
/******/ // Check if module is in cache
|
|
21441
|
+
/******/ const cachedModule = __webpack_module_cache__[moduleId];
|
|
21442
|
+
/******/ if (cachedModule !== undefined) {
|
|
21443
|
+
/******/ return cachedModule.exports;
|
|
21444
|
+
/******/ }
|
|
21445
|
+
/******/ // Create a new module (and put it into the cache)
|
|
21446
|
+
/******/ const module = __webpack_module_cache__[moduleId] = {
|
|
21447
|
+
/******/ // no module.id needed
|
|
21448
|
+
/******/ // no module.loaded needed
|
|
21449
|
+
/******/ exports: {}
|
|
21450
|
+
/******/ };
|
|
21451
|
+
/******/
|
|
21452
|
+
/******/ // Execute the module function
|
|
21453
|
+
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
21454
|
+
/******/
|
|
21455
|
+
/******/ // Return the exports of the module
|
|
21456
|
+
/******/ return module.exports;
|
|
21457
|
+
/******/ }
|
|
21458
|
+
/******/
|
|
21459
|
+
/******/ // expose the modules object (__webpack_modules__)
|
|
21460
|
+
/******/ __webpack_require__.m = __webpack_modules__;
|
|
21461
|
+
/******/
|
|
21462
|
+
/************************************************************************/
|
|
21463
|
+
/******/ /* webpack/runtime/define property getters */
|
|
21464
|
+
/******/ (() => {
|
|
21465
|
+
/******/ // define getter/value functions for harmony exports
|
|
21466
|
+
/******/ __webpack_require__.d = (exports, definition) => {
|
|
21467
|
+
/******/ if(Array.isArray(definition)) {
|
|
21468
|
+
/******/ var i = 0;
|
|
21469
|
+
/******/ while(i < definition.length) {
|
|
21470
|
+
/******/ var key = definition[i++];
|
|
21471
|
+
/******/ var binding = definition[i++];
|
|
21472
|
+
/******/ if(!__webpack_require__.o(exports, key)) {
|
|
21473
|
+
/******/ if(binding === 0) {
|
|
21474
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
|
|
21475
|
+
/******/ } else {
|
|
21476
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
|
|
21477
|
+
/******/ }
|
|
21478
|
+
/******/ } else if(binding === 0) { i++; }
|
|
21479
|
+
/******/ }
|
|
21480
|
+
/******/ } else {
|
|
21481
|
+
/******/ for(var key in definition) {
|
|
21482
|
+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
21483
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
21484
|
+
/******/ }
|
|
21485
|
+
/******/ }
|
|
21486
|
+
/******/ }
|
|
21487
|
+
/******/ };
|
|
21488
|
+
/******/ })();
|
|
21489
|
+
/******/
|
|
21490
|
+
/******/ /* webpack/runtime/ensure chunk */
|
|
21491
|
+
/******/ (() => {
|
|
21492
|
+
/******/ __webpack_require__.f = {};
|
|
21493
|
+
/******/ // This file contains only the entry chunk.
|
|
21494
|
+
/******/ // The chunk loading function for additional chunks
|
|
21495
|
+
/******/ __webpack_require__.e = (chunkId) => {
|
|
21496
|
+
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
|
|
21497
|
+
/******/ __webpack_require__.f[key](chunkId, promises);
|
|
21498
|
+
/******/ return promises;
|
|
21499
|
+
/******/ }, []));
|
|
21500
|
+
/******/ };
|
|
21501
|
+
/******/ })();
|
|
21502
|
+
/******/
|
|
21503
|
+
/******/ /* webpack/runtime/get javascript chunk filename */
|
|
21504
|
+
/******/ (() => {
|
|
21505
|
+
/******/ // This function allow to reference async chunks
|
|
21506
|
+
/******/ __webpack_require__.u = (chunkId) => {
|
|
21507
|
+
/******/ // return url for filenames based on template
|
|
21508
|
+
/******/ return "" + chunkId + ".astroviewer.js";
|
|
21509
|
+
/******/ };
|
|
21510
|
+
/******/ })();
|
|
21511
|
+
/******/
|
|
21512
|
+
/******/ /* webpack/runtime/global */
|
|
21513
|
+
/******/ (() => {
|
|
21514
|
+
/******/ __webpack_require__.g = (function() {
|
|
21515
|
+
/******/ if (typeof globalThis === 'object') return globalThis;
|
|
21516
|
+
/******/ try {
|
|
21517
|
+
/******/ return this || new Function('return this')();
|
|
21518
|
+
/******/ } catch (e) {
|
|
21519
|
+
/******/ if (typeof window === 'object') return window;
|
|
21520
|
+
/******/ }
|
|
21521
|
+
/******/ })();
|
|
21522
|
+
/******/ })();
|
|
21523
|
+
/******/
|
|
21524
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
21525
|
+
/******/ (() => {
|
|
21526
|
+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
21527
|
+
/******/ })();
|
|
21528
|
+
/******/
|
|
21529
|
+
/******/ /* webpack/runtime/load script */
|
|
21530
|
+
/******/ (() => {
|
|
21531
|
+
/******/ const inProgress = {};
|
|
21532
|
+
/******/ const dataWebpackPrefix = "astroviewer:";
|
|
21533
|
+
/******/ // loadScript function to load a script via script tag
|
|
21534
|
+
/******/ __webpack_require__.l = (url, done, key, chunkId) => {
|
|
21535
|
+
/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
|
|
21536
|
+
/******/ let script, needAttach;
|
|
21537
|
+
/******/ if(key !== undefined) {
|
|
21538
|
+
/******/ const scripts = document.getElementsByTagName("script");
|
|
21539
|
+
/******/ for(var i = 0; i < scripts.length; i++) {
|
|
21540
|
+
/******/ const s = scripts[i];
|
|
21541
|
+
/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }
|
|
21542
|
+
/******/ }
|
|
21543
|
+
/******/ }
|
|
21544
|
+
/******/ if(!script) {
|
|
21545
|
+
/******/ needAttach = true;
|
|
21546
|
+
/******/ script = document.createElement('script');
|
|
21547
|
+
/******/
|
|
21548
|
+
/******/ script.charset = 'utf-8';
|
|
21549
|
+
/******/ if (__webpack_require__.nc) {
|
|
21550
|
+
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
|
21551
|
+
/******/ }
|
|
21552
|
+
/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key);
|
|
21553
|
+
/******/
|
|
21554
|
+
/******/ script.src = url;
|
|
21555
|
+
/******/ }
|
|
21556
|
+
/******/ inProgress[url] = [done];
|
|
21557
|
+
/******/ const onScriptComplete = (prev, event) => {
|
|
21558
|
+
/******/ // avoid mem leaks in IE.
|
|
21559
|
+
/******/ script.onerror = script.onload = null;
|
|
21560
|
+
/******/ clearTimeout(timeout);
|
|
21561
|
+
/******/ const doneFns = inProgress[url];
|
|
21562
|
+
/******/ delete inProgress[url];
|
|
21563
|
+
/******/ script.parentNode?.removeChild(script);
|
|
21564
|
+
/******/ doneFns?.forEach((fn) => (fn(event)));
|
|
21565
|
+
/******/ if(prev) return prev(event);
|
|
21566
|
+
/******/ }
|
|
21567
|
+
/******/ const timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
|
|
21568
|
+
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
|
|
21569
|
+
/******/ script.onload = onScriptComplete.bind(null, script.onload);
|
|
21570
|
+
/******/ needAttach && document.head.appendChild(script);
|
|
21571
|
+
/******/ };
|
|
21572
|
+
/******/ })();
|
|
21573
|
+
/******/
|
|
21574
|
+
/******/ /* webpack/runtime/make namespace object */
|
|
21575
|
+
/******/ (() => {
|
|
21576
|
+
/******/ // define __esModule on exports
|
|
21577
|
+
/******/ __webpack_require__.r = (exports) => {
|
|
21578
|
+
/******/ if(Symbol.toStringTag) {
|
|
21579
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
21580
|
+
/******/ }
|
|
21581
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
21582
|
+
/******/ };
|
|
21583
|
+
/******/ })();
|
|
21584
|
+
/******/
|
|
21585
|
+
/******/ /* webpack/runtime/publicPath */
|
|
21586
|
+
/******/ (() => {
|
|
21587
|
+
/******/ let scriptUrl;
|
|
21588
|
+
/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
|
|
21589
|
+
/******/ const document = __webpack_require__.g.document;
|
|
21590
|
+
/******/ if (!scriptUrl && document) {
|
|
21591
|
+
/******/ if (document.currentScript?.tagName.toUpperCase() === 'SCRIPT')
|
|
21592
|
+
/******/ scriptUrl = document.currentScript.src;
|
|
21593
|
+
/******/ if (!scriptUrl) {
|
|
21594
|
+
/******/ const scripts = document.getElementsByTagName("script");
|
|
21595
|
+
/******/ if(scripts.length) {
|
|
21596
|
+
/******/ let i = scripts.length - 1;
|
|
21597
|
+
/******/ while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;
|
|
21598
|
+
/******/ }
|
|
21599
|
+
/******/ }
|
|
21600
|
+
/******/ }
|
|
21601
|
+
/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
|
|
21602
|
+
/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
|
|
21603
|
+
/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
|
|
21604
|
+
/******/ scriptUrl = scriptUrl.replace(/^blob:/, "").replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
|
|
21605
|
+
/******/ __webpack_require__.p = scriptUrl;
|
|
21606
|
+
/******/ })();
|
|
21607
|
+
/******/
|
|
21608
|
+
/******/ /* webpack/runtime/jsonp chunk loading */
|
|
21609
|
+
/******/ (() => {
|
|
21610
|
+
/******/ // no baseURI
|
|
21611
|
+
/******/
|
|
21612
|
+
/******/ // object to store loaded and loading chunks
|
|
21613
|
+
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
|
21614
|
+
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
|
21615
|
+
/******/ const installedChunks = {
|
|
21616
|
+
/******/ 792: 0
|
|
21617
|
+
/******/ };
|
|
21618
|
+
/******/
|
|
21619
|
+
/******/ __webpack_require__.f.j = (chunkId, promises) => {
|
|
21620
|
+
/******/ // JSONP chunk loading for javascript
|
|
21621
|
+
/******/ let installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
|
|
21622
|
+
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
|
|
21623
|
+
/******/
|
|
21624
|
+
/******/ // a Promise means "currently loading".
|
|
21625
|
+
/******/ if(installedChunkData) {
|
|
21626
|
+
/******/ promises.push(installedChunkData[2]);
|
|
21627
|
+
/******/ } else {
|
|
21628
|
+
/******/ if(true) { // all chunks have JS
|
|
21629
|
+
/******/ // setup Promise in chunk cache
|
|
21630
|
+
/******/ const promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
|
|
21631
|
+
/******/ promises.push(installedChunkData[2] = promise);
|
|
21632
|
+
/******/
|
|
21633
|
+
/******/ // start chunk loading
|
|
21634
|
+
/******/ const url = __webpack_require__.p + __webpack_require__.u(chunkId);
|
|
21635
|
+
/******/ // create error before stack unwound to get useful stacktrace later
|
|
21636
|
+
/******/ const error = new Error();
|
|
21637
|
+
/******/ const loadingEnded = (event) => {
|
|
21638
|
+
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
|
|
21639
|
+
/******/ installedChunkData = installedChunks[chunkId];
|
|
21640
|
+
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
|
|
21641
|
+
/******/ if(installedChunkData) {
|
|
21642
|
+
/******/ const errorType = event && (event.type === 'load' ? 'missing' : event.type);
|
|
21643
|
+
/******/ const realSrc = event && event.target && event.target.src;
|
|
21644
|
+
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
|
|
21645
|
+
/******/ error.name = 'ChunkLoadError';
|
|
21646
|
+
/******/ error.type = errorType;
|
|
21647
|
+
/******/ error.request = realSrc;
|
|
21648
|
+
/******/ error.event = event;
|
|
21649
|
+
/******/ installedChunkData[1](error);
|
|
21650
|
+
/******/ }
|
|
21651
|
+
/******/ }
|
|
21652
|
+
/******/ };
|
|
21653
|
+
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
|
|
21654
|
+
/******/ }
|
|
21655
|
+
/******/ }
|
|
21656
|
+
/******/ }
|
|
21657
|
+
/******/ };
|
|
21658
|
+
/******/
|
|
21659
|
+
/******/ // no prefetching
|
|
21660
|
+
/******/
|
|
21661
|
+
/******/ // no preloaded
|
|
21662
|
+
/******/
|
|
21663
|
+
/******/ // no HMR
|
|
21664
|
+
/******/
|
|
21665
|
+
/******/ // no HMR manifest
|
|
21666
|
+
/******/
|
|
21667
|
+
/******/ // no on chunks loaded
|
|
21668
|
+
/******/
|
|
21669
|
+
/******/ // install a JSONP callback for chunk loading
|
|
21670
|
+
/******/ const webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
|
|
21671
|
+
/******/ let [chunkIds, moreModules, runtime] = data;
|
|
21672
|
+
/******/ // add "moreModules" to the modules object,
|
|
21673
|
+
/******/ // then flag all "chunkIds" as loaded and fire callback
|
|
21674
|
+
/******/ var moduleId, chunkId, i = 0;
|
|
21675
|
+
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
|
|
21676
|
+
/******/ for(moduleId in moreModules) {
|
|
21677
|
+
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
|
21678
|
+
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
|
21679
|
+
/******/ }
|
|
21680
|
+
/******/ }
|
|
21681
|
+
/******/ if(runtime) var result = runtime(__webpack_require__);
|
|
21682
|
+
/******/ }
|
|
21683
|
+
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
|
|
21684
|
+
/******/ for(;i < chunkIds.length; i++) {
|
|
21685
|
+
/******/ chunkId = chunkIds[i];
|
|
21686
|
+
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
|
|
21687
|
+
/******/ installedChunks[chunkId][0]();
|
|
21688
|
+
/******/ }
|
|
21689
|
+
/******/ installedChunks[chunkId] = 0;
|
|
21690
|
+
/******/ }
|
|
21691
|
+
/******/
|
|
21692
|
+
/******/ }
|
|
21693
|
+
/******/
|
|
21694
|
+
/******/ const chunkLoadingGlobal = self["webpackChunkastroviewer"] = self["webpackChunkastroviewer"] || [];
|
|
21695
|
+
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
|
|
21696
|
+
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
|
|
19348
21697
|
/******/ })();
|
|
19349
21698
|
/******/
|
|
19350
21699
|
/************************************************************************/
|