astro-viewer 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/astroviewer.cjs +3082 -1410
  2. package/dist/astroviewer.js +1 -1
  3. package/dist/astroviewer.min.js +1 -1
  4. package/lib-esm/AstroSphere.d.ts +40 -16
  5. package/lib-esm/AstroSphere.js +359 -93
  6. package/lib-esm/AstroViewer.d.ts +20 -5
  7. package/lib-esm/AstroViewer.js +50 -0
  8. package/lib-esm/Camera.js +28 -14
  9. package/lib-esm/Config.d.ts +2 -0
  10. package/lib-esm/Config.js +15 -1
  11. package/lib-esm/Global.js +12 -0
  12. package/lib-esm/index.d.ts +8 -4
  13. package/lib-esm/index.js +17 -3
  14. package/lib-esm/model/AbstractSkyEntity.d.ts +1 -0
  15. package/lib-esm/model/AbstractSkyEntity.js +12 -0
  16. package/lib-esm/model/AstroGL.js +12 -0
  17. package/lib-esm/model/ColorMaps.js +12 -0
  18. package/lib-esm/model/MetadataColumn.js +12 -0
  19. package/lib-esm/model/MetadataManager.d.ts +1 -0
  20. package/lib-esm/model/MetadataManager.js +16 -1
  21. package/lib-esm/model/Point.d.ts +9 -1
  22. package/lib-esm/model/Point.js +30 -0
  23. package/lib-esm/model/Point2D.js +12 -0
  24. package/lib-esm/model/Source.js +12 -0
  25. package/lib-esm/model/SphereFoV.d.ts +30 -0
  26. package/lib-esm/model/SphereFoV.js +196 -0
  27. package/lib-esm/model/catalogues/CatalogueGL.js +12 -0
  28. package/lib-esm/model/catalogues/CatalogueProps.js +13 -1
  29. package/lib-esm/model/earth/{wmts/WMTSAdapter.d.ts → WMTSAdapter.d.ts} +2 -1
  30. package/lib-esm/model/earth/{wmts/WMTSAdapter.js → WMTSAdapter.js} +12 -0
  31. package/lib-esm/model/earth/XYZAnchestorTile.d.ts +17 -0
  32. package/lib-esm/model/earth/XYZAnchestorTile.js +87 -0
  33. package/lib-esm/model/earth/{types.d.ts → XYZConfig.d.ts} +6 -17
  34. package/lib-esm/model/earth/XYZConfig.js +13 -0
  35. package/lib-esm/model/earth/XYZFoVHelper.d.ts +12 -0
  36. package/lib-esm/model/earth/XYZFoVHelper.js +138 -0
  37. package/lib-esm/model/earth/XYZMap.d.ts +31 -0
  38. package/lib-esm/model/earth/XYZMap.js +208 -0
  39. package/lib-esm/model/earth/XYZMapDescriptor.d.ts +29 -0
  40. package/lib-esm/model/earth/XYZMapDescriptor.js +77 -0
  41. package/lib-esm/model/earth/XYZMeshBuilder.d.ts +1 -1
  42. package/lib-esm/model/earth/XYZMeshBuilder.js +13 -2
  43. package/lib-esm/model/earth/XYZTile.d.ts +20 -21
  44. package/lib-esm/model/earth/XYZTile.js +82 -102
  45. package/lib-esm/model/earth/XYZTileBuffer.d.ts +24 -26
  46. package/lib-esm/model/earth/XYZTileBuffer.js +60 -70
  47. package/lib-esm/model/earth/XYZTileRequestScheduler.d.ts +1 -1
  48. package/lib-esm/model/earth/XYZTileRequestScheduler.js +13 -2
  49. package/lib-esm/model/earth/XYZTypes.d.ts +24 -0
  50. package/lib-esm/model/earth/XYZTypes.js +13 -0
  51. package/lib-esm/model/earth/XYZVisibleTilesManager.d.ts +16 -27
  52. package/lib-esm/model/earth/XYZVisibleTilesManager.js +61 -192
  53. package/lib-esm/model/footprints/Footprint.d.ts +4 -1
  54. package/lib-esm/model/footprints/Footprint.js +30 -2
  55. package/lib-esm/model/footprints/FootprintProps.js +13 -1
  56. package/lib-esm/model/footprints/FootprintSetGL.d.ts +4 -2
  57. package/lib-esm/model/footprints/FootprintSetGL.js +21 -6
  58. package/lib-esm/model/grid/EquatorialGrid.d.ts +2 -1
  59. package/lib-esm/model/grid/EquatorialGrid.js +30 -12
  60. package/lib-esm/model/grid/GridTextHelper.d.ts +10 -19
  61. package/lib-esm/model/grid/GridTextHelper.js +70 -67
  62. package/lib-esm/model/grid/HealpixGrid.d.ts +4 -4
  63. package/lib-esm/model/grid/HealpixGrid.js +24 -8
  64. package/lib-esm/model/grid/LonLatGrid.d.ts +43 -0
  65. package/lib-esm/model/grid/LonLatGrid.js +309 -0
  66. package/lib-esm/model/hips/AllSky.js +12 -0
  67. package/lib-esm/model/hips/AncestorTile.js +12 -0
  68. package/lib-esm/model/hips/FoVHelper.d.ts +5 -2
  69. package/lib-esm/model/hips/FoVHelper.js +52 -3
  70. package/lib-esm/model/hips/HiPS.d.ts +2 -0
  71. package/lib-esm/model/hips/HiPS.js +38 -14
  72. package/lib-esm/model/hips/HiPSConfig.d.ts +13 -0
  73. package/lib-esm/model/hips/HiPSDescriptor.js +12 -0
  74. package/lib-esm/model/hips/Tile.d.ts +1 -0
  75. package/lib-esm/model/hips/Tile.js +15 -0
  76. package/lib-esm/model/hips/TileBuffer.d.ts +5 -0
  77. package/lib-esm/model/hips/TileBuffer.js +61 -0
  78. package/lib-esm/model/hips/VisibleTilesManager.js +12 -0
  79. package/lib-esm/model/tap/TapMetadata.js +12 -0
  80. package/lib-esm/model/tap/TapMetadataList.js +12 -0
  81. package/lib-esm/model/tap/TapRepo.js +12 -0
  82. package/lib-esm/model/terra/TerraFootprintSetGL.d.ts +6 -0
  83. package/lib-esm/model/terra/TerraFootprintSetGL.js +54 -0
  84. package/lib-esm/model/terra/TerraPointSetGL.js +12 -0
  85. package/lib-esm/services/SesameService.js +11 -3
  86. package/lib-esm/services/helpers.js +12 -0
  87. package/lib-esm/services/hipsNodeService.js +12 -0
  88. package/lib-esm/services/parse-hipslist.js +12 -0
  89. package/lib-esm/services/queryCatalogueByFoV.js +13 -1
  90. package/lib-esm/services/queryFootprintSetByFov.js +13 -1
  91. package/lib-esm/services/tapRepoService.js +13 -1
  92. package/lib-esm/services/types.js +12 -0
  93. package/lib-esm/shader/CatalogueShaderProgram.js +12 -0
  94. package/lib-esm/shader/FootprintShaderProgram.js +12 -0
  95. package/lib-esm/shader/GridShaderManager.js +12 -0
  96. package/lib-esm/shader/HiPSShaderProgram.js +12 -0
  97. package/lib-esm/shader/ShaderManager.js +12 -1
  98. package/lib-esm/shader/ShaderManagerMutliHiPS.js +12 -1
  99. package/lib-esm/shader/XYZShaderProgram.d.ts +14 -1
  100. package/lib-esm/shader/XYZShaderProgram.js +127 -2
  101. package/lib-esm/utils/CoordsType.d.ts +2 -1
  102. package/lib-esm/utils/CoordsType.js +13 -0
  103. package/lib-esm/utils/FoVUtils.js +12 -0
  104. package/lib-esm/utils/GeoJSONParser.d.ts +19 -0
  105. package/lib-esm/utils/GeoJSONParser.js +112 -0
  106. package/lib-esm/utils/GeomUtils.js +12 -0
  107. package/lib-esm/utils/MouseHelper.js +12 -0
  108. package/lib-esm/utils/PerspectiveMatrixManager.js +16 -1
  109. package/lib-esm/utils/RayPickingUtils.js +12 -0
  110. package/lib-esm/utils/STCSParser.d.ts +7 -3
  111. package/lib-esm/utils/STCSParser.js +27 -9
  112. package/lib-esm/utils/ShaderUtility.js +13 -1
  113. package/lib-esm/utils/Utils.js +12 -0
  114. package/lib-esm/utils/XYZRayPickingUtils.d.ts +27 -0
  115. package/lib-esm/utils/XYZRayPickingUtils.js +226 -0
  116. package/package.json +2 -2
  117. package/lib-esm/model/FoV.d.ts +0 -62
  118. package/lib-esm/model/FoV.js +0 -274
  119. package/lib-esm/model/earth/XYZAncestorMeshCache.d.ts +0 -10
  120. package/lib-esm/model/earth/XYZAncestorMeshCache.js +0 -31
  121. package/lib-esm/model/earth/XYZLayer.d.ts +0 -31
  122. package/lib-esm/model/earth/XYZLayer.js +0 -231
  123. package/lib-esm/model/earth/XYZTileProvider.d.ts +0 -29
  124. package/lib-esm/model/earth/XYZTileProvider.js +0 -187
  125. package/lib-esm/model/earth/wmts/types.d.ts +0 -1
  126. package/lib-esm/model/earth/wmts/types.js +0 -1
  127. /package/lib-esm/model/{earth/types.js → hips/HiPSConfig.js} +0 -0
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { SelectionObj } from '../../utils/GeomUtils.js';
5
5
  import { Point } from '../Point.js';
6
+ import { CoordsType } from '../../utils/CoordsType.js';
6
7
  export interface FootprintDetail {
7
8
  key: string;
8
9
  value: string | number;
@@ -19,6 +20,7 @@ export declare class Footprint {
19
20
  private _totConvexPoints;
20
21
  private _npix256?;
21
22
  private _footprintsPointsOrder?;
23
+ private _coordsType;
22
24
  private _selectionObj;
23
25
  private _identifier?;
24
26
  private _center?;
@@ -27,7 +29,8 @@ export declare class Footprint {
27
29
  * @param in_details optional metadata
28
30
  * @param footprintsPointsOrder 1-> clockwise, -1 counter clockwise
29
31
  */
30
- constructor(in_stcs?: string, in_details?: FootprintDetail[], footprintsPointsOrder?: 1 | -1);
32
+ constructor(in_stcs?: string, in_details?: FootprintDetail[], footprintsPointsOrder?: 1 | -1, coordsType?: CoordsType.ASTRO | CoordsType.GEOGRAPHIC);
33
+ static fromPolygons(polygons: Point[][], details?: FootprintDetail[], coordsType?: CoordsType.ASTRO | CoordsType.GEOGRAPHIC): Footprint;
31
34
  private computeSelectionObject;
32
35
  private computePoints;
33
36
  get valid(): boolean;
@@ -1,3 +1,15 @@
1
+ /*
2
+ * AstroViewer
3
+ * Copyright (C) Fabrizio Giordano
4
+ * SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
5
+ *
6
+ * This file is part of AstroViewer.
7
+ * AstroViewer is distributed under a dual-license model.
8
+ * Commercial use requires a separate commercial license.
9
+ * Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
10
+ *
11
+ * See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
12
+ */
1
13
  'use strict';
2
14
  /**
3
15
  * @author Fabrizio Giordano (Fab)
@@ -7,6 +19,7 @@
7
19
  import GeomUtils from '../../utils/GeomUtils.js';
8
20
  // import global from '../../Global.js';
9
21
  import STCSParser from '../../utils/STCSParser.js';
22
+ import { CoordsType } from '../../utils/CoordsType.js';
10
23
  // export interface ParsedSTCS {
11
24
  // polygons: Point[][]; // array of polygons (each polygon is array of Point objects)
12
25
  // totpoints: number;
@@ -21,6 +34,7 @@ export class Footprint {
21
34
  _totConvexPoints = 0;
22
35
  _npix256;
23
36
  _footprintsPointsOrder;
37
+ _coordsType;
24
38
  _selectionObj;
25
39
  _identifier;
26
40
  _center; // could be typed if you have a Point type
@@ -29,7 +43,8 @@ export class Footprint {
29
43
  * @param in_details optional metadata
30
44
  * @param footprintsPointsOrder 1-> clockwise, -1 counter clockwise
31
45
  */
32
- constructor(in_stcs, in_details = [], footprintsPointsOrder) {
46
+ constructor(in_stcs, in_details = [], footprintsPointsOrder, coordsType = CoordsType.ASTRO) {
47
+ this._coordsType = coordsType;
33
48
  if (in_stcs) {
34
49
  this._stcs = in_stcs.toUpperCase();
35
50
  this._details = in_details;
@@ -44,6 +59,17 @@ export class Footprint {
44
59
  this._details = [];
45
60
  }
46
61
  }
62
+ static fromPolygons(polygons, details = [], coordsType = CoordsType.ASTRO) {
63
+ const footprint = new Footprint(undefined, [], undefined, coordsType);
64
+ footprint._polygons = polygons;
65
+ footprint._details = details;
66
+ footprint._totPoints = polygons.reduce((total, polygon) => total + polygon.length, 0);
67
+ footprint._totConvexPoints = 0;
68
+ footprint._coordsType = coordsType;
69
+ footprint._selectionObj = footprint.computeSelectionObject();
70
+ footprint._valid = footprint._totPoints > 0;
71
+ return footprint;
72
+ }
47
73
  computeSelectionObject() {
48
74
  return GeomUtils.computeSelectionObject(this._polygons);
49
75
  }
@@ -66,7 +92,9 @@ export class Footprint {
66
92
  // return Array.from(rangeSet.r);
67
93
  // }
68
94
  computePoints() {
69
- const res = STCSParser.parseSTCS(this._stcs);
95
+ const res = STCSParser.parseSTCS(this._stcs, {
96
+ coordsType: this._coordsType,
97
+ });
70
98
  this._polygons = res.polygons;
71
99
  this._totPoints = res.totpoints;
72
100
  }
@@ -1,6 +1,18 @@
1
+ /*
2
+ * AstroViewer
3
+ * Copyright (C) Fabrizio Giordano
4
+ * SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
5
+ *
6
+ * This file is part of AstroViewer.
7
+ * AstroViewer is distributed under a dual-license model.
8
+ * Commercial use requires a separate commercial license.
9
+ * Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
10
+ *
11
+ * See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
12
+ */
13
+ export {};
1
14
  // import {Metadata} from '../tap/TapMetadata.js';
2
15
  // import {TapMetadataList} from '../tap/TapMetadataList.js';
3
- export {};
4
16
  // export default class FootprintProps {
5
17
  // // resolved columns
6
18
  // pgSphereColumn?: Metadata;
@@ -1,5 +1,6 @@
1
1
  import { Footprint } from "./Footprint.js";
2
2
  import MouseHelper from "../../utils/MouseHelper.js";
3
+ import { CoordsType } from "../../utils/CoordsType.js";
3
4
  import { MetadataManager } from "../MetadataManager.js";
4
5
  import { MetadataColumn } from "../MetadataColumn.js";
5
6
  import { VisibleTilesManager } from "../hips/VisibleTilesManager.js";
@@ -58,10 +59,11 @@ export declare class FootprintSetGL {
58
59
  totSelectedPoints: number;
59
60
  nSlectedPrimitiveFlags: number;
60
61
  _shapeColor: string;
61
- private _bufferInitialised;
62
+ protected _coordsType: CoordsType.ASTRO | CoordsType.GEOGRAPHIC;
63
+ protected _bufferInitialised: boolean;
62
64
  private _webgl;
63
65
  _isVisible: boolean;
64
- private _metadataManager;
66
+ protected _metadataManager: MetadataManager;
65
67
  _providerUrl: string;
66
68
  private _footprintShaderProgram;
67
69
  private _visibleTilesManager;
@@ -1,3 +1,15 @@
1
+ /*
2
+ * AstroViewer
3
+ * Copyright (C) Fabrizio Giordano
4
+ * SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
5
+ *
6
+ * This file is part of AstroViewer.
7
+ * AstroViewer is distributed under a dual-license model.
8
+ * Commercial use requires a separate commercial license.
9
+ * Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
10
+ *
11
+ * See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
12
+ */
1
13
  import { Footprint } from "./Footprint.js";
2
14
  import { colorHex2RGB } from "../../utils/Utils.js";
3
15
  import { FootprintShaderProgram } from "../../shader/FootprintShaderProgram.js";
@@ -46,6 +58,7 @@ export class FootprintSetGL {
46
58
  totSelectedPoints;
47
59
  nSlectedPrimitiveFlags = 0;
48
60
  _shapeColor = "#00fff2ff";
61
+ _coordsType = CoordsType.ASTRO;
49
62
  _bufferInitialised = false;
50
63
  _webgl;
51
64
  _isVisible = true;
@@ -127,7 +140,7 @@ export class FootprintSetGL {
127
140
  }
128
141
  for (let j = 0; j < in_data.length; j++) {
129
142
  if (in_data[j][geomDataIndex] !== null) {
130
- const footprint = new Footprint(in_data[j][geomDataIndex], in_data[j]);
143
+ const footprint = new Footprint(in_data[j][geomDataIndex], in_data[j], undefined, this._coordsType);
131
144
  if (footprint._valid) {
132
145
  this.addFootprint(footprint);
133
146
  this.totPoints += footprint.totPoints;
@@ -181,6 +194,11 @@ export class FootprintSetGL {
181
194
  }
182
195
  }
183
196
  this.indexes[this.indexes.length - 1] = MAX_UNSIGNED_INT;
197
+ this._webgl.bindBuffer(this._webgl.ARRAY_BUFFER, this.vertexCataloguePositionBuffer);
198
+ this._webgl.bufferData(this._webgl.ARRAY_BUFFER, this.vertexCataloguePosition, this._webgl.STATIC_DRAW);
199
+ this._webgl.bindBuffer(this._webgl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
200
+ this._webgl.bufferData(this._webgl.ELEMENT_ARRAY_BUFFER, this.indexes, this._webgl.STATIC_DRAW);
201
+ this._bufferInitialised = true;
184
202
  console.log("Buffer initialized");
185
203
  }
186
204
  checkSelection(mouseHelper) {
@@ -200,9 +218,8 @@ export class FootprintSetGL {
200
218
  const details = [...footprint.details];
201
219
  // const geomDataIndex = this.footprintsetProps.geomColumn?.index
202
220
  const geomDataIndex = this._metadataManager.selectedOutlineColumn?.index ?? -1;
203
- if (geomDataIndex < 0)
204
- continue;
205
- details.splice(geomDataIndex, 1);
221
+ if (geomDataIndex >= 0)
222
+ details.splice(geomDataIndex, 1);
206
223
  this._hoveredFootprints.push(footprint);
207
224
  this.totHoveredPoints += footprint.totPoints;
208
225
  }
@@ -574,11 +591,9 @@ export class FootprintSetGL {
574
591
  this._webgl.drawElements(this._webgl.LINE_LOOP, this.selectedVertexPosition.length / 3 + this.nSlectedPrimitiveFlags, this._webgl.UNSIGNED_INT, 0);
575
592
  }
576
593
  this._webgl.bindBuffer(this._webgl.ARRAY_BUFFER, this.vertexCataloguePositionBuffer);
577
- this._webgl.bufferData(this._webgl.ARRAY_BUFFER, this.vertexCataloguePosition, this._webgl.STATIC_DRAW);
578
594
  this._webgl.vertexAttribPointer(this._footprintShaderProgram.locations.position, FootprintSetGL.ELEM_SIZE, this._webgl.FLOAT, false, FootprintSetGL.BYTES_X_ELEM * FootprintSetGL.ELEM_SIZE, 0);
579
595
  this._webgl.enableVertexAttribArray(this._footprintShaderProgram.locations.position);
580
596
  this._webgl.bindBuffer(this._webgl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
581
- this._webgl.bufferData(this._webgl.ELEMENT_ARRAY_BUFFER, this.indexes, this._webgl.STATIC_DRAW);
582
597
  // const shapeColor = [...colorHex2RGB(this.footprintsetProps.shapeColor), 1.0] as [number, number, number, number]
583
598
  const shapeColor = [...colorHex2RGB(this._shapeColor), 1.0];
584
599
  this._webgl.uniform4f(this._footprintShaderProgram.locations.color, ...shapeColor);
@@ -20,6 +20,7 @@ export declare class EquatorialGrid extends AbstractSkyEntity {
20
20
  private _thetaStepRad;
21
21
  private _phiArray;
22
22
  private _thetaArray;
23
+ private _bufferKey;
23
24
  private _dec4Labels;
24
25
  private _ra4Labels;
25
26
  private _healpixGrid;
@@ -34,7 +35,7 @@ export declare class EquatorialGrid extends AbstractSkyEntity {
34
35
  /** Build RA/Dec line vertex arrays based on FoV step helper */
35
36
  private initBuffers;
36
37
  /** Update buffers when FoV (in degrees) changes */
37
- refresh(fovDeg: number): void;
38
+ refresh(fovDeg: number, coarse?: boolean): void;
38
39
  private vectorDistance;
39
40
  private enableShader;
40
41
  isVisible(): boolean;
@@ -1,3 +1,15 @@
1
+ /*
2
+ * AstroViewer
3
+ * Copyright (C) Fabrizio Giordano
4
+ * SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
5
+ *
6
+ * This file is part of AstroViewer.
7
+ * AstroViewer is distributed under a dual-license model.
8
+ * Commercial use requires a separate commercial license.
9
+ * Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
10
+ *
11
+ * See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
12
+ */
1
13
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
14
  import { vec4, mat4 } from 'gl-matrix';
3
15
  import { fovHelper } from '../hips/FoVHelper.js';
@@ -19,7 +31,7 @@ export class EquatorialGrid extends AbstractSkyEntity {
19
31
  _vertexShader;
20
32
  _fragmentShader;
21
33
  defaultColor = '#41d421';
22
- gridText = new GridTextHelper();
34
+ gridText = new GridTextHelper('equatorial');
23
35
  _attribLocations = {
24
36
  position: 0,
25
37
  selected: 1,
@@ -36,6 +48,7 @@ export class EquatorialGrid extends AbstractSkyEntity {
36
48
  _thetaStepRad = 0;
37
49
  _phiArray = [];
38
50
  _thetaArray = [];
51
+ _bufferKey = '';
39
52
  // For placing text labels near current view center:
40
53
  // - _dec4Labels: key = RA(deg), value = points along that RA ring (for Dec labels)
41
54
  // - _ra4Labels : key = Dec(deg), value = points along that Dec ring (for RA labels)
@@ -96,9 +109,9 @@ export class EquatorialGrid extends AbstractSkyEntity {
96
109
  super.webgl.useProgram(this._shaderProgram);
97
110
  }
98
111
  /** Build RA/Dec line vertex arrays based on FoV step helper */
99
- initBuffers(fovDeg) {
112
+ initBuffers(fovDeg, coarse = false) {
100
113
  const R = 1.0;
101
- const steps = fovHelper.getRADegSteps(fovDeg);
114
+ const steps = fovHelper.getRADegSteps(fovDeg, coarse);
102
115
  const phiStep = steps.raStep; // RA step (deg)
103
116
  const thetaStep = steps.decStep; // Dec step (deg)
104
117
  this._phiStep = phiStep;
@@ -150,11 +163,14 @@ export class EquatorialGrid extends AbstractSkyEntity {
150
163
  }
151
164
  }
152
165
  /** Update buffers when FoV (in degrees) changes */
153
- refresh(fovDeg) {
166
+ refresh(fovDeg, coarse = false) {
154
167
  // const fovDeg = healpixGridSingleton.getMinFoV()
155
- if (this._fov !== fovDeg) {
168
+ const steps = fovHelper.getRADegSteps(fovDeg, coarse);
169
+ const bufferKey = `${coarse ? 'coarse' : 'settled'}:${steps.raStep}:${steps.decStep}`;
170
+ if (this._bufferKey !== bufferKey) {
156
171
  this._fov = fovDeg;
157
- this.initBuffers(this._fov);
172
+ this._bufferKey = bufferKey;
173
+ this.initBuffers(this._fov, coarse);
158
174
  }
159
175
  }
160
176
  vectorDistance(p1, p2) {
@@ -214,7 +230,7 @@ export class EquatorialGrid extends AbstractSkyEntity {
214
230
  return;
215
231
  if (this._thetaArray.length === 0)
216
232
  return;
217
- this.refresh(fovDeg);
233
+ this.refresh(fovDeg, !!input.cameraMoving);
218
234
  if (!this.showGrid) {
219
235
  // gridTextHelper.resetDivSets();
220
236
  this.gridText.resetDivSets();
@@ -260,9 +276,10 @@ export class EquatorialGrid extends AbstractSkyEntity {
260
276
  // perspective divide
261
277
  clipspace[0] /= clipspace[3];
262
278
  clipspace[1] /= clipspace[3];
263
- // clip->pixel
264
- const pixelX = (clipspace[0] * 0.5 + 0.5) * super.webgl.canvas.width;
265
- const pixelY = (clipspace[1] * -0.5 + 0.5) * super.webgl.canvas.height;
279
+ // clip -> CSS pixels
280
+ const canvasRect = super.webgl.canvas.getBoundingClientRect();
281
+ const pixelX = canvasRect.left + (clipspace[0] * 0.5 + 0.5) * canvasRect.width;
282
+ const pixelY = canvasRect.top + (clipspace[1] * -0.5 + 0.5) * canvasRect.height;
266
283
  this.gridText.addEqDivSet(decDeg.toFixed(2), pixelX, pixelY, 'dec');
267
284
  // gridTextHelper.addEqDivSet(decDeg.toFixed(2), pixelX, pixelY, 'dec');
268
285
  }
@@ -283,8 +300,9 @@ export class EquatorialGrid extends AbstractSkyEntity {
283
300
  vec4.transformMat4(clipspace, phiPoint, mvpMatrix);
284
301
  clipspace[0] /= clipspace[3];
285
302
  clipspace[1] /= clipspace[3];
286
- const pixelX = (clipspace[0] * 0.5 + 0.5) * super.webgl.canvas.width;
287
- const pixelY = (clipspace[1] * -0.5 + 0.5) * super.webgl.canvas.height;
303
+ const canvasRect = super.webgl.canvas.getBoundingClientRect();
304
+ const pixelX = canvasRect.left + (clipspace[0] * 0.5 + 0.5) * canvasRect.width;
305
+ const pixelY = canvasRect.top + (clipspace[1] * -0.5 + 0.5) * canvasRect.height;
288
306
  // gridTextHelper.addEqDivSet(raDeg.toFixed(2), pixelX, pixelY, 'ra');
289
307
  this.gridText.addEqDivSet(raDeg.toFixed(2), pixelX, pixelY, 'ra');
290
308
  }
@@ -1,25 +1,16 @@
1
- /**
2
- * @author Fabrizio Giordano (Fab)
3
- * @param in_radius - number
4
- * @param in_gl - GL context
5
- * @param in_position - array of double e.g. [0.0, 0.0, 0.0]
6
- */
1
+ type GridLabelLayer = 'healpix' | 'equatorial' | 'lonlat';
7
2
  declare class GridTextHelper {
8
- private _divEqContainerElement;
9
- private _divHPXContainerElement;
10
- private _divSets;
11
- private _divSetNdx;
12
- constructor();
3
+ private static layers;
4
+ private layer;
5
+ constructor(layer?: GridLabelLayer);
13
6
  initHtml(): void;
14
- resetDivSets(): void;
15
- /**
16
- * Add / reuse a floating label for HPX coordinates
17
- */
7
+ resetDivSets(layer?: GridLabelLayer): void;
18
8
  addHPXDivSet(msg: string, x: number, y: number): void;
19
- /**
20
- * Add / reuse a floating label for Equatorial coords
21
- * @param type 'ra' or 'dec'
22
- */
23
9
  addEqDivSet(msg: string, x: number, y: number, type: 'ra' | 'dec'): void;
10
+ addLonLatDivSet(msg: string, x: number, y: number, type: 'lon' | 'lat'): void;
11
+ private addLabel;
12
+ private classNameForKind;
13
+ private static getLayerState;
14
+ private static resolveContainer;
24
15
  }
25
16
  export default GridTextHelper;
@@ -1,91 +1,94 @@
1
- /**
2
- * @author Fabrizio Giordano (Fab)
3
- * @param in_radius - number
4
- * @param in_gl - GL context
5
- * @param in_position - array of double e.g. [0.0, 0.0, 0.0]
1
+ /*
2
+ * AstroViewer
3
+ * Copyright (C) Fabrizio Giordano
4
+ * SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
5
+ *
6
+ * This file is part of AstroViewer.
7
+ * AstroViewer is distributed under a dual-license model.
8
+ * Commercial use requires a separate commercial license.
9
+ * Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
10
+ *
11
+ * See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
6
12
  */
7
13
  class GridTextHelper {
8
- _divEqContainerElement;
9
- _divHPXContainerElement;
10
- _divSets;
11
- _divSetNdx;
12
- constructor() {
13
- this._divEqContainerElement = document.querySelector('#gridcoords');
14
- this._divHPXContainerElement = document.querySelector('#gridhpx');
15
- this._divSetNdx = 0;
16
- this._divSets = [];
14
+ static layers = new Map();
15
+ layer;
16
+ constructor(layer = 'equatorial') {
17
+ this.layer = layer;
18
+ GridTextHelper.getLayerState(layer);
17
19
  }
18
20
  initHtml() {
19
- // Kept for API parity; nothing required here with current logic.
21
+ GridTextHelper.getLayerState(this.layer);
20
22
  }
21
- resetDivSets() {
22
- // Hide remaining divs and reset index
23
- for (; this._divSetNdx < this._divSets.length; ++this._divSetNdx) {
24
- this._divSets[this._divSetNdx].style.display = 'none';
23
+ resetDivSets(layer = this.layer) {
24
+ const state = GridTextHelper.getLayerState(layer);
25
+ for (; state.divSetNdx < state.divSets.length; ++state.divSetNdx) {
26
+ state.divSets[state.divSetNdx].style.display = 'none';
25
27
  }
26
- this._divSetNdx = 0;
28
+ state.divSetNdx = 0;
27
29
  }
28
- /**
29
- * Add / reuse a floating label for HPX coordinates
30
- */
31
30
  addHPXDivSet(msg, x, y) {
32
- let divSet = this._divSets[this._divSetNdx++];
33
- // Create on demand
31
+ this.addLabel('healpix', msg, x + 25, y, 'hpx');
32
+ }
33
+ addEqDivSet(msg, x, y, type) {
34
+ this.addLabel('equatorial', msg, type === 'ra' ? x + 25 : x, type === 'ra' ? y : y + 25, type);
35
+ }
36
+ addLonLatDivSet(msg, x, y, type) {
37
+ this.addLabel('lonlat', msg, type === 'lon' ? x + 25 : x, type === 'lon' ? y : y + 25, type);
38
+ }
39
+ addLabel(layer, msg, x, y, kind) {
40
+ const state = GridTextHelper.getLayerState(layer);
41
+ if (!state.container)
42
+ return;
43
+ let divSet = state.divSets[state.divSetNdx++];
34
44
  if (!divSet) {
35
45
  const div = document.createElement('div');
36
46
  const textNode = document.createTextNode('');
37
- div.className = 'floating-div-ra'; // style like RA tags
38
47
  div.appendChild(textNode);
39
- if (!this._divHPXContainerElement) {
40
- this._divHPXContainerElement = document.querySelector('#gridhpx');
41
- }
42
- if (!this._divHPXContainerElement) {
43
- // If container is still missing, abort gracefully
44
- return;
45
- }
46
- this._divHPXContainerElement.appendChild(div);
48
+ state.container.appendChild(div);
47
49
  divSet = { div, textNode, style: div.style };
48
- this._divSets.push(divSet);
50
+ state.divSets.push(divSet);
49
51
  }
50
- // Show & position
52
+ divSet.div.className = this.classNameForKind(kind);
51
53
  divSet.style.display = 'block';
52
- divSet.style.left = `${Math.floor(x + 25)}px`;
54
+ divSet.style.left = `${Math.floor(x)}px`;
53
55
  divSet.style.top = `${Math.floor(y)}px`;
54
56
  divSet.textNode.nodeValue = msg;
55
57
  }
56
- /**
57
- * Add / reuse a floating label for Equatorial coords
58
- * @param type 'ra' or 'dec'
59
- */
60
- addEqDivSet(msg, x, y, type) {
61
- let divSet = this._divSets[this._divSetNdx++];
62
- if (!divSet) {
63
- const div = document.createElement('div');
64
- const textNode = document.createTextNode('');
65
- div.className = type === 'ra' ? 'floating-div-ra' : 'floating-div-dec';
66
- div.appendChild(textNode);
67
- if (!this._divEqContainerElement) {
68
- this._divEqContainerElement = document.querySelector('#gridcoords');
69
- }
70
- if (!this._divEqContainerElement) {
71
- // If container is still missing, abort gracefully
72
- return;
73
- }
74
- this._divEqContainerElement.appendChild(div);
75
- divSet = { div, textNode, style: div.style };
76
- this._divSets.push(divSet);
58
+ classNameForKind(kind) {
59
+ switch (kind) {
60
+ case 'dec':
61
+ return 'floating-div-dec';
62
+ case 'lat':
63
+ return 'floating-div-lat';
64
+ case 'lon':
65
+ return 'floating-div-lon';
66
+ case 'hpx':
67
+ case 'ra':
68
+ default:
69
+ return 'floating-div-ra';
77
70
  }
78
- divSet.style.display = 'block';
79
- if (type === 'ra') {
80
- divSet.style.left = `${Math.floor(x + 25)}px`;
81
- divSet.style.top = `${Math.floor(y)}px`;
71
+ }
72
+ static getLayerState(layer) {
73
+ const current = GridTextHelper.layers.get(layer);
74
+ if (current) {
75
+ if (!current.container)
76
+ current.container = GridTextHelper.resolveContainer(layer);
77
+ return current;
82
78
  }
83
- else {
84
- divSet.style.left = `${Math.floor(x)}px`;
85
- divSet.style.top = `${Math.floor(y + 25)}px`;
79
+ const state = {
80
+ container: GridTextHelper.resolveContainer(layer),
81
+ divSets: [],
82
+ divSetNdx: 0,
83
+ };
84
+ GridTextHelper.layers.set(layer, state);
85
+ return state;
86
+ }
87
+ static resolveContainer(layer) {
88
+ if (layer === 'healpix') {
89
+ return document.querySelector('#gridhpx');
86
90
  }
87
- divSet.textNode.nodeValue = msg;
91
+ return document.querySelector('#gridcoords');
88
92
  }
89
93
  }
90
- // export const gridTextHelper = new GridTextHelper();
91
94
  export default GridTextHelper;
@@ -1,6 +1,6 @@
1
1
  import { AbstractSkyEntity, SkyEntityDrawInput } from '../AbstractSkyEntity.js';
2
2
  import { ReadonlyMat4 } from 'gl-matrix';
3
- import { FoV } from '../FoV.js';
3
+ import { SphereFoV } from '../SphereFoV.js';
4
4
  import { VisibleTilesManager } from '../hips/VisibleTilesManager.js';
5
5
  import Camera from '../../Camera.js';
6
6
  export declare class HealpixGrid extends AbstractSkyEntity {
@@ -28,13 +28,13 @@ export declare class HealpixGrid extends AbstractSkyEntity {
28
28
  private _visibleTilesManager;
29
29
  constructor(webgl: WebGL2RenderingContext);
30
30
  init(): void;
31
- get fovObj(): FoV;
31
+ get fovObj(): SphereFoV;
32
32
  get RADIUS(): number;
33
33
  get INITIAL_POSITION(): [number, number, number];
34
34
  get INITIAL_PhiRad(): number;
35
35
  get INITIAL_ThetaRad(): number;
36
- refreshFoV(camera: Camera, pMatrix: ReadonlyMat4): FoV;
37
- getFoV(): FoV;
36
+ refreshFoV(camera: Camera, pMatrix: ReadonlyMat4): SphereFoV;
37
+ getFoV(): SphereFoV;
38
38
  getMinFoV(): number;
39
39
  private initShaders;
40
40
  initBuffers(pixels: number[], order: number): void;
@@ -1,10 +1,22 @@
1
+ /*
2
+ * AstroViewer
3
+ * Copyright (C) Fabrizio Giordano
4
+ * SPDX-License-Identifier: LicenseRef-AstroViewer-Dual-License
5
+ *
6
+ * This file is part of AstroViewer.
7
+ * AstroViewer is distributed under a dual-license model.
8
+ * Commercial use requires a separate commercial license.
9
+ * Non-commercial use is governed by LICENSE-NONCOMMERCIAL.md.
10
+ *
11
+ * See LICENSE.md, LICENSE-COMMERCIAL.md, and LICENSE-NONCOMMERCIAL.md for details.
12
+ */
1
13
  'use strict';
2
14
  import { AbstractSkyEntity } from '../AbstractSkyEntity.js';
3
15
  import global from '../../Global.js';
4
16
  import { mat4, vec4 } from 'gl-matrix';
5
17
  import { fovHelper } from '../hips/FoVHelper.js';
6
18
  import { FoVUtils } from '../../utils/FoVUtils.js';
7
- import { FoV } from '../FoV.js';
19
+ import { SphereFoV } from '../SphereFoV.js';
8
20
  import { CoordsType } from '../../utils/CoordsType.js';
9
21
  import { Point } from '../Point.js';
10
22
  import GridShaderManager from '../../shader/GridShaderManager.js';
@@ -22,7 +34,7 @@ export class HealpixGrid extends AbstractSkyEntity {
22
34
  fragmentShader;
23
35
  vertexShader;
24
36
  defaultColor = '#ec0acaff';
25
- gridText = new GridTextHelper();
37
+ gridText = new GridTextHelper('healpix');
26
38
  // private _hipsShaderProgram: HiPSShaderProgram
27
39
  _attribLocations = {
28
40
  position: 0,
@@ -59,7 +71,7 @@ export class HealpixGrid extends AbstractSkyEntity {
59
71
  this._vertexCataloguePositionBuffer = super.webgl.createBuffer();
60
72
  this._indexBuffer = super.webgl.createBuffer();
61
73
  this._vertexCataloguePosition = new Float32Array(0);
62
- this._fovObj = new FoV(super.webgl);
74
+ this._fovObj = new SphereFoV(super.webgl);
63
75
  }
64
76
  get fovObj() {
65
77
  return this._fovObj;
@@ -199,7 +211,7 @@ export class HealpixGrid extends AbstractSkyEntity {
199
211
  // (global as any).hipsFoV = fov;
200
212
  // global.order = fovHelper.getHiPSNorder(fov);
201
213
  // this._visibleorder = global.order;
202
- this._visibleorder = fovHelper.getHiPSNorder(fov);
214
+ this._visibleorder = fovHelper.getHiPSNorder(fov, this._visibleorder);
203
215
  }
204
216
  enableShader(in_mMatrix, pMatrix, vMatrix) {
205
217
  const gl = super.webgl;
@@ -243,7 +255,10 @@ export class HealpixGrid extends AbstractSkyEntity {
243
255
  const pMatrix = input.pMatrix;
244
256
  if (!pMatrix)
245
257
  return;
246
- this.refresh(camera, pMatrix);
258
+ // this.refresh(camera, pMatrix);
259
+ const rawFov = input.fovDeg ?? this.getMinFoV();
260
+ const fov = Number.isFinite(rawFov) && rawFov > 0 ? rawFov : 1e-6;
261
+ this._visibleorder = fovHelper.getHiPSNorder(fov, this._visibleorder);
247
262
  if (!this.showGrid) {
248
263
  // gridTextHelper.resetDivSets();
249
264
  this.gridText.resetDivSets();
@@ -288,9 +303,10 @@ export class HealpixGrid extends AbstractSkyEntity {
288
303
  // NDC divide
289
304
  clipspace[0] /= clipspace[3];
290
305
  clipspace[1] /= clipspace[3];
291
- // clip pixels
292
- const pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
293
- const pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;
306
+ // clip -> CSS pixels
307
+ const canvasRect = gl.canvas.getBoundingClientRect();
308
+ const pixelX = canvasRect.left + (clipspace[0] * 0.5 + 0.5) * canvasRect.width;
309
+ const pixelY = canvasRect.top + (clipspace[1] * -0.5 + 0.5) * canvasRect.height;
294
310
  this.gridText.addHPXDivSet(this._visibleorder + '/' + pixels[p], pixelX, pixelY);
295
311
  // gridTextHelper.addHPXDivSet(this._visibleorder + '/' + pixels[p], pixelX, pixelY);
296
312
  }
@@ -0,0 +1,43 @@
1
+ import { AbstractSkyEntity, SkyEntityDrawInput } from '../AbstractSkyEntity.js';
2
+ import { SphereFoV } from '../SphereFoV.js';
3
+ export declare class LatLonGrid extends AbstractSkyEntity {
4
+ static ELEM_SIZE: number;
5
+ static BYTES_X_ELEM: number;
6
+ private _shaderProgram;
7
+ private _vertexShader;
8
+ private _fragmentShader;
9
+ private _attribLocations;
10
+ private _lonVertexPositionBuffer;
11
+ private _latVertexPositionBuffer;
12
+ private _lonStep;
13
+ private _latStep;
14
+ private _segmentStep;
15
+ private _fovObj;
16
+ private _fovDeg;
17
+ private _showGrid;
18
+ private _lonArray;
19
+ private _latArray;
20
+ private _bufferKey;
21
+ private defaultColor;
22
+ private gridText;
23
+ constructor(radius: number, position: [number, number, number], xrad: number, yrad: number, name: string, webgl: WebGL2RenderingContext);
24
+ init(): void;
25
+ private initShaders;
26
+ private initBuffers;
27
+ private buildLonRange;
28
+ private buildLatRange;
29
+ private lonLatToCartesian;
30
+ private refresh;
31
+ refreshFoV(input: SkyEntityDrawInput): number;
32
+ getMinFoVDeg(): number;
33
+ getFoV(): SphereFoV;
34
+ isVisible(): boolean;
35
+ toggleShowGrid(): boolean;
36
+ setShowGrid(showGrid: boolean): void;
37
+ private enableShader;
38
+ draw(input: SkyEntityDrawInput): void;
39
+ private drawLabels;
40
+ private projectPointToScreen;
41
+ private roundToStep;
42
+ private normalizeLon;
43
+ }