Compare commits
16 Commits
feat-keep-
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
645bab7cd9 | ||
|
|
62f9e61978 | ||
|
|
addbd555c1 | ||
|
|
db70a6b9cd | ||
|
|
258781d078 | ||
|
|
7418ed822d | ||
|
|
ba728c23c7 | ||
|
|
89f760c1db | ||
|
|
c5d0875265 | ||
|
|
4a8d3bfa65 | ||
|
|
bde5a37b51 | ||
|
|
fbdc7e2e76 | ||
|
|
312b9844d1 | ||
|
|
0e740454bd | ||
|
|
18e98e9f5f | ||
|
|
c938a58cbc |
@@ -8,8 +8,8 @@
|
||||
"dateModified": "2023-01-31",
|
||||
"issueTracker": "https://github.com/cds-astro/aladin-lite/issues",
|
||||
"name": "Aladin Lite",
|
||||
"version": "3.6.4",
|
||||
"softwareVersion": "3.6.4",
|
||||
"version": "3.6.5",
|
||||
"softwareVersion": "3.6.5",
|
||||
"description": "An astronomical HiPS visualizer in the browser.",
|
||||
"identifier": "10.5281/zenodo.7638833",
|
||||
"applicationCategory": "Astronomy, Visualization",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 256px;"></div>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px;"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
@@ -13,12 +13,14 @@
|
||||
var aladin = A.aladin(
|
||||
'#aladin-lite-div',
|
||||
{
|
||||
survey: 'https://alasky.cds.unistra.fr/Pan-STARRS/DR1/color-z-zg-g/', // set initial image survey
|
||||
survey: 'data/hips/wcs', // set initial image survey
|
||||
projection: 'SIN', // set a projection
|
||||
fov: 114.19, // initial field of view in degrees
|
||||
target: '19 24 51.556 +45 16 44.36', // initial target
|
||||
cooFrame: 'equatorial', // set galactic frame
|
||||
showCooGrid: true, // set the grid
|
||||
fov: 80.0, // initial field of view in degrees
|
||||
target: '96.5279427 -88.0037230', // initial target
|
||||
cooFrame: 'galactic', // set galactic frame
|
||||
showCooGrid: true, // set the grid,
|
||||
fullScreen: true,
|
||||
showSettingsControl: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
// Start up Aladin Lite
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'M 1', fov: 0.2, showContextMenu: true, fullScreen: true});
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'M 1', fov: 0.2, showContextMenu: true, fullScreen: true});
|
||||
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 3, lineDash: [2, 2]});
|
||||
/*aladin.addOverlay(overlay);
|
||||
aladin.addOverlay(overlay);
|
||||
overlay.addFootprints([
|
||||
A.polygon([[83.64287, 22.01713], [83.59872, 22.01692], [83.59852, 21.97629], [83.64295, 21.97629]], {hoverColor: 'green'}),
|
||||
A.polygon([[83.62807, 22.06330], [83.58397, 22.02280], [83.62792, 22.02258]]),
|
||||
@@ -21,7 +21,7 @@
|
||||
]);
|
||||
overlay.add(A.circle(83.66067, 22.03081, 0.04, {color: 'cyan'})); // radius in degrees
|
||||
overlay.add(A.vector(83.66067, 22.03081, 0.04, {color: 'cyan'})); // radius in degrees
|
||||
*/
|
||||
|
||||
aladin.on("footprintClicked", (footprint, xyMouseCoords) => {
|
||||
console.log("footprint clicked catched: ", footprint, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
|
||||
})
|
||||
@@ -35,8 +35,8 @@
|
||||
console.log("Object hovered stopped: ", object, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
|
||||
})
|
||||
|
||||
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 10, {onClick: 'showTable', selectionColor: "orange", hoverColor: 'red', limit: 10000});
|
||||
aladin.addCatalog(cat);
|
||||
//const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 10, {onClick: 'showTable', selectionColor: "orange", hoverColor: 'red', limit: 10000});
|
||||
//aladin.addCatalog(cat);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 30, survey: "CDS/P/DSS2/color", target: "280 +0", projection: "AIT", showShareControl:true, showSettingsControl: true, showContextMenu:true});
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 30, target: "280 +0", projection: "AIT", showShareControl:true, showSettingsControl: true, showContextMenu:true});
|
||||
|
||||
aladin.setOverlayImageLayer(A.image(
|
||||
"https://www.virtualastronomy.org/images/sig05-013.jpg",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
showCooGrid: true,
|
||||
fullScreen: true,
|
||||
samp: true,
|
||||
realFullscreen: true,
|
||||
lockNorthUp: true,
|
||||
}
|
||||
);
|
||||
|
||||
BIN
examples/data/hips/wcs/Norder0/Dir0/Npix10.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/data/hips/wcs/Norder0/Dir0/Npix11.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/data/hips/wcs/Norder0/Dir0/Npix4.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
examples/data/hips/wcs/Norder0/Dir0/Npix8.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
examples/data/hips/wcs/Norder0/Dir0/Npix9.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
examples/data/hips/wcs/Norder1/Dir0/Npix16.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
examples/data/hips/wcs/Norder1/Dir0/Npix32.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
examples/data/hips/wcs/Norder1/Dir0/Npix34.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/data/hips/wcs/Norder1/Dir0/Npix36.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
examples/data/hips/wcs/Norder1/Dir0/Npix40.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
examples/data/hips/wcs/Norder1/Dir0/Npix44.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/data/hips/wcs/Norder2/Dir0/Npix128.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
examples/data/hips/wcs/Norder2/Dir0/Npix139.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
examples/data/hips/wcs/Norder2/Dir0/Npix144.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
examples/data/hips/wcs/Norder2/Dir0/Npix160.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
examples/data/hips/wcs/Norder2/Dir0/Npix176.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
examples/data/hips/wcs/Norder2/Dir0/Npix64.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/data/hips/wcs/Norder2/Dir0/Npix65.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
examples/data/hips/wcs/Norder3/Allsky.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix257.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix260.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix512.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix513.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix558.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix576.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix578.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix640.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
examples/data/hips/wcs/Norder3/Dir0/Npix704.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix1029.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix1031.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix1040.png
Normal file
|
After Width: | Height: | Size: 153 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix1041.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2048.png
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2049.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2050.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2052.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2234.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2235.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2304.png
Normal file
|
After Width: | Height: | Size: 195 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2305.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2306.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2312.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2560.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
examples/data/hips/wcs/Norder4/Dir0/Npix2816.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix4119.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix4125.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix4160.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix4161.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix4162.png
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix4163.png
Normal file
|
After Width: | Height: | Size: 231 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix4164.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8192.png
Normal file
|
After Width: | Height: | Size: 226 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8193.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8194.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8195.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8196.png
Normal file
|
After Width: | Height: | Size: 208 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8197.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8198.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8200.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8208.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8939.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix8942.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9216.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9217.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9218.png
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9219.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9222.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9224.png
Normal file
|
After Width: | Height: | Size: 209 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9225.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9226.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir0/Npix9248.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir10000/Npix10240.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir10000/Npix10242.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
examples/data/hips/wcs/Norder5/Dir10000/Npix11264.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
33
examples/data/hips/wcs/properties
Normal file
@@ -0,0 +1,33 @@
|
||||
creator_did = ivo://UNK.AUTH/P/474-2244-wcs
|
||||
obs_title = 474-2244-wcs.fits
|
||||
hips_builder = Aladin/HipsGen v12.135
|
||||
hips_version = 1.4
|
||||
hips_frame = galactic
|
||||
hips_order = 10
|
||||
hips_order_min = 0
|
||||
hips_tile_width = 512
|
||||
hips_status = public master clonableOnce
|
||||
hips_tile_format = png
|
||||
hips_pixel_bitpix = -32
|
||||
hips_pixel_cut = -670.2 64044
|
||||
hips_data_range = -38085 98627
|
||||
hips_initial_ra = 11.66767
|
||||
hips_initial_dec = -24.86479
|
||||
hips_initial_fov = 5.90651
|
||||
hips_pixel_scale = 1.118E-4
|
||||
s_pixel_scale = 1.222E-4
|
||||
dataproduct_type = image
|
||||
hipsgen_date = 2024-11-13T17:07Z
|
||||
hipsgen_params = in=NAROO/474-2244-wcs.fits out=/var/www/tmp/HiPS/474-2244-wcs id=474-2244-wcs maxThread=20
|
||||
data_pixel_bitpix = -32
|
||||
hips_sampling = bilinear
|
||||
hips_overlay = overlayMean mergeOverwrite treeMean
|
||||
hips_release_date = 2024-11-13T18:33Z
|
||||
hips_data_minmax = -21385 73221
|
||||
moc_sky_fraction = 0.001074
|
||||
hipsgen_date_1 = 2024-11-13T18:25Z
|
||||
hipsgen_params_1 = in=NAROO/474-2244-wcs.fits out=/var/www/tmp/HiPS/474-2244-wcs id=474-2244-wcs maxThread=20
|
||||
hips_creation_date = 2024-11-13T18:25Z
|
||||
hips_estsize = 24116525
|
||||
hips_nb_tiles = 36636
|
||||
hips_check_code = png:735272809
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "al-api"
|
||||
version = "3.6.4"
|
||||
version = "3.6.5"
|
||||
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "al-core"
|
||||
version = "3.6.4"
|
||||
version = "3.6.5"
|
||||
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -185,14 +185,24 @@ impl From<query::Allsky> for AllskyRequest {
|
||||
.collect())
|
||||
}
|
||||
InMemData::F32(data) => {
|
||||
let data = unsafe { std::slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * 4) };
|
||||
let data = unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
data.as_ptr() as *const u8,
|
||||
data.len() * 4,
|
||||
)
|
||||
};
|
||||
Ok(handle_allsky_fits(&data, tile_size, texture_size)?
|
||||
.map(|image| ImageType::RawRgba8u { image })
|
||||
.collect())
|
||||
}
|
||||
InMemData::F64(data) => {
|
||||
let data = data.iter().map(|v| *v as f32).collect::<Vec<_>>();
|
||||
let data = unsafe { std::slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * 4) };
|
||||
let data = unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
data.as_ptr() as *const u8,
|
||||
data.len() * 4,
|
||||
)
|
||||
};
|
||||
|
||||
Ok(handle_allsky_fits(&data, tile_size, texture_size)?
|
||||
.map(|image| ImageType::RawRgba8u { image })
|
||||
@@ -228,71 +238,77 @@ fn handle_allsky_file<F: ImageFormat>(
|
||||
let num_allsky_tiles_per_tile = (tile_size / allsky_tile_size) * (tile_size / allsky_tile_size);
|
||||
|
||||
let mut src_idx = 0;
|
||||
let tiles = (0..num_tiles)
|
||||
.map(move |_| {
|
||||
let mut base_tile =
|
||||
let tiles = (0..num_tiles).map(move |_| {
|
||||
let mut base_tile =
|
||||
ImageBuffer::<F>::allocate(&<F as ImageFormat>::P::BLACK, tile_size, tile_size);
|
||||
for idx_tile in 0..num_allsky_tiles_per_tile {
|
||||
let (x, y) = crate::utils::unmortonize(idx_tile as u64);
|
||||
let dx = x * (allsky_tile_size as u32);
|
||||
let dy = y * (allsky_tile_size as u32);
|
||||
for idx_tile in 0..num_allsky_tiles_per_tile {
|
||||
let (x, y) = crate::utils::unmortonize(idx_tile as u64);
|
||||
let dx = x * (allsky_tile_size as u32);
|
||||
let dy = y * (allsky_tile_size as u32);
|
||||
|
||||
let sx = (src_idx % 27) * allsky_tile_size;
|
||||
let sy = (src_idx / 27) * allsky_tile_size;
|
||||
let s = ImageBufferView {
|
||||
x: sx as i32,
|
||||
y: sy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
let d = ImageBufferView {
|
||||
x: dx as i32,
|
||||
y: dy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
let sx = (src_idx % 27) * allsky_tile_size;
|
||||
let sy = (src_idx / 27) * allsky_tile_size;
|
||||
let s = ImageBufferView {
|
||||
x: sx as i32,
|
||||
y: sy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
let d = ImageBufferView {
|
||||
x: dx as i32,
|
||||
y: dy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
|
||||
base_tile.tex_sub(&allsky, &s, &d);
|
||||
base_tile.tex_sub(&allsky, &s, &d);
|
||||
|
||||
src_idx += 1;
|
||||
}
|
||||
src_idx += 1;
|
||||
}
|
||||
|
||||
base_tile
|
||||
});
|
||||
base_tile
|
||||
});
|
||||
|
||||
Ok(tiles)
|
||||
}
|
||||
|
||||
fn handle_allsky_fits<F: ImageFormat>(
|
||||
allsky_data: &[<<F as ImageFormat>::P as Pixel>::Item],
|
||||
|
||||
tile_size: i32,
|
||||
texture_size: i32,
|
||||
) -> Result<impl Iterator<Item=ImageBuffer<F>>, JsValue> {
|
||||
) -> Result<impl Iterator<Item = ImageBuffer<F>>, JsValue> {
|
||||
let allsky_tile_size = std::cmp::min(tile_size, 64);
|
||||
let width_allsky_px = 27 * allsky_tile_size;
|
||||
let height_allsky_px = 29 * allsky_tile_size;
|
||||
// The fits image layout stores rows in reverse
|
||||
let reversed_rows_data = allsky_data
|
||||
.chunks(width_allsky_px as usize)
|
||||
.chunks(width_allsky_px as usize * F::NUM_CHANNELS)
|
||||
.rev()
|
||||
.flatten()
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let allsky = ImageBuffer::<F>::new(reversed_rows_data, width_allsky_px, height_allsky_px);
|
||||
|
||||
let allsky_tiles_iter = handle_allsky_file::<F>(allsky, allsky_tile_size, texture_size, tile_size)?
|
||||
.map(move |image| {
|
||||
// The GPU does a specific transformation on the UV
|
||||
// for FITS tiles
|
||||
// We must revert this to be compatible with this GPU transformation
|
||||
let mut new_image_data = Vec::with_capacity(tile_size as usize);
|
||||
for c in image.get_data().chunks((tile_size * tile_size) as usize) {
|
||||
new_image_data.extend(c.chunks(tile_size as usize).rev().flatten());
|
||||
}
|
||||
let allsky_tiles_iter =
|
||||
handle_allsky_file::<F>(allsky, allsky_tile_size, texture_size, tile_size)?.map(
|
||||
move |image| {
|
||||
// The GPU does a specific transformation on the UV for FITS tiles
|
||||
// We must revert this to be compatible with this GPU transformation
|
||||
let new_image_data = image
|
||||
.get_data()
|
||||
.chunks((tile_size * tile_size) as usize * F::NUM_CHANNELS)
|
||||
.flat_map(|c| {
|
||||
c.chunks(tile_size as usize * F::NUM_CHANNELS)
|
||||
.rev()
|
||||
.flatten()
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
ImageBuffer::<F>::new(new_image_data, tile_size, tile_size)
|
||||
});
|
||||
ImageBuffer::<F>::new(new_image_data, tile_size, tile_size)
|
||||
},
|
||||
);
|
||||
|
||||
Ok(allsky_tiles_iter)
|
||||
}
|
||||
|
||||
@@ -76,15 +76,20 @@ impl HEALPixCell {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn idx(&self) -> u64 {
|
||||
pub(crate) const fn idx(&self) -> u64 {
|
||||
self.1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn depth(&self) -> u8 {
|
||||
pub(crate) const fn depth(&self) -> u8 {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn nside(&self) -> u64 {
|
||||
1 << self.depth()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_root(&self) -> bool {
|
||||
self.depth() == 0
|
||||
@@ -168,6 +173,19 @@ impl HEALPixCell {
|
||||
HEALPixTilesIter::new(depth_children, first_idx..last_idx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) const fn subdivide(&self) -> [HEALPixCell; 4] {
|
||||
let children_depth = self.depth() + 1;
|
||||
let children_idx = self.idx() << 2;
|
||||
|
||||
[
|
||||
HEALPixCell(children_depth, children_idx),
|
||||
HEALPixCell(children_depth, children_idx + 1),
|
||||
HEALPixCell(children_depth, children_idx + 2),
|
||||
HEALPixCell(children_depth, children_idx + 3),
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn allsky(depth: u8) -> impl Iterator<Item = HEALPixCell> {
|
||||
let npix = 12 << ((depth as usize) << 1);
|
||||
@@ -193,7 +211,7 @@ impl HEALPixCell {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_on_pole(&self) -> bool {
|
||||
pub(crate) fn is_on_pole(&self) -> bool {
|
||||
let HEALPixCell(depth, idx) = *self;
|
||||
|
||||
let two_times_depth = 2 * depth;
|
||||
@@ -207,6 +225,40 @@ impl HEALPixCell {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn has_7_neigh(&self) -> bool {
|
||||
let base_cell = self.ancestor(self.depth());
|
||||
let nside_minus_one = (self.nside() - 1) as u32;
|
||||
|
||||
let (x, y) = self.offset_in_parent(&base_cell);
|
||||
|
||||
match base_cell.idx() {
|
||||
0..=3 => (x == 0 && y == nside_minus_one) || (y == 0 && x == nside_minus_one),
|
||||
4..=7 => (x == 0 && y == 0) || (x == nside_minus_one && y == nside_minus_one),
|
||||
8..=11 => (x == 0 && y == nside_minus_one) || (y == 0 && x == nside_minus_one),
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn is_on_base_cell_edges(&self) -> bool {
|
||||
let base_cell = self.ancestor(self.depth());
|
||||
|
||||
let nside_minus_one = (self.nside() - 1) as u32;
|
||||
|
||||
let (x, y) = self.offset_in_parent(&base_cell);
|
||||
|
||||
if x == 0 || x == nside_minus_one {
|
||||
return true;
|
||||
}
|
||||
|
||||
if y == 0 || y == nside_minus_one {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
// Given in ICRS
|
||||
#[inline]
|
||||
pub fn new(depth: u8, theta: f64, delta: f64) -> Self {
|
||||
|
||||
@@ -10,6 +10,7 @@ use al_core::colormap::Colormaps;
|
||||
use al_core::image::format::ChannelType;
|
||||
use cgmath::Vector3;
|
||||
|
||||
use crate::math::angle::ToAngle;
|
||||
use crate::downloader::query;
|
||||
|
||||
use al_core::image::Image;
|
||||
@@ -31,10 +32,7 @@ use crate::{math::lonlat::LonLatT, utils};
|
||||
|
||||
use crate::downloader::request::allsky::Allsky;
|
||||
use crate::healpix::{cell::HEALPixCell, coverage::HEALPixCoverage};
|
||||
use crate::renderable::utils::index_patch::DefaultPatchIndexIter;
|
||||
use crate::time::Time;
|
||||
use crate::math::angle::ToAngle;
|
||||
|
||||
|
||||
use super::config::HiPSConfig;
|
||||
use std::collections::HashSet;
|
||||
@@ -451,7 +449,15 @@ impl HiPS2D {
|
||||
|
||||
// Retrieve the model and inverse model matrix
|
||||
let mut off_indices = 0;
|
||||
// Define a global level of subdivisions for all the healpix tile cells in the view
|
||||
// This should prevent seeing many holes
|
||||
// We compute it from the first cell in the view but it might be an under/over estimate for the other cells in the view
|
||||
let num_sub = self.hpx_cells_in_view.iter()
|
||||
.map(|cell| super::subdivide::num_hpx_subdivision(cell, camera, projection))
|
||||
.max().unwrap();
|
||||
|
||||
//let num_sub =
|
||||
// super::subdivide::num_hpx_subdivision(&self.hpx_cells_in_view[0], camera, projection);
|
||||
for cell in &self.hpx_cells_in_view {
|
||||
// filter textures that are not in the moc
|
||||
let cell_in_cov = if let Some(moc) = self.footprint_moc.as_ref() {
|
||||
@@ -559,64 +565,70 @@ impl HiPS2D {
|
||||
let d01e = uv_1[TileCorner::BottomRight].x - uv_1[TileCorner::BottomLeft].x;
|
||||
let d02e = uv_1[TileCorner::TopLeft].y - uv_1[TileCorner::BottomLeft].y;
|
||||
|
||||
let sub_cells =
|
||||
super::subdivide::subdivide_hpx_cell(cell, num_sub, camera);
|
||||
|
||||
let num_subdivision =
|
||||
super::subdivide::num_hpxcell_subdivision(cell, camera, projection);
|
||||
let mut pos = Vec::with_capacity(sub_cells.len() * 4);
|
||||
|
||||
let n_segments_by_side: usize = 1 << (num_subdivision as usize);
|
||||
let n_segments_by_side_f32 = n_segments_by_side as f32;
|
||||
let mut idx = 0;
|
||||
|
||||
let n_vertices_per_segment = n_segments_by_side + 1;
|
||||
for sub_cell in sub_cells {
|
||||
let (i, j) = sub_cell.offset_in_parent(cell);
|
||||
let nside = (1 << (sub_cell.depth() - cell.depth())) as f32;
|
||||
|
||||
let mut pos = Vec::with_capacity((n_segments_by_side + 1) * 4);
|
||||
for ((lon, lat), (di, dj)) in
|
||||
sub_cell
|
||||
.vertices()
|
||||
.iter()
|
||||
.zip([(0, 0), (1, 0), (1, 1), (0, 1)])
|
||||
{
|
||||
let hj0 = ((j + dj) as f32) / nside;
|
||||
let hi0 = ((i + di) as f32) / nside;
|
||||
|
||||
let grid_lonlat =
|
||||
healpix::nested::grid(cell.depth(), cell.idx(), n_segments_by_side as u16);
|
||||
let grid_lonlat_iter = grid_lonlat.iter();
|
||||
let uv_start = [
|
||||
uv_0[TileCorner::BottomLeft].x + hj0 * d01s,
|
||||
uv_0[TileCorner::BottomLeft].y + hi0 * d02s,
|
||||
uv_0[TileCorner::BottomLeft].z,
|
||||
];
|
||||
|
||||
for (idx, &(lon, lat)) in grid_lonlat_iter.enumerate() {
|
||||
let i: usize = idx / n_vertices_per_segment;
|
||||
let j: usize = idx % n_vertices_per_segment;
|
||||
let uv_end = [
|
||||
uv_1[TileCorner::BottomLeft].x + hj0 * d01e,
|
||||
uv_1[TileCorner::BottomLeft].y + hi0 * d02e,
|
||||
uv_1[TileCorner::BottomLeft].z,
|
||||
];
|
||||
|
||||
let hj0 = (j as f32) / n_segments_by_side_f32;
|
||||
let hi0 = (i as f32) / n_segments_by_side_f32;
|
||||
self.uv_start.extend(uv_start);
|
||||
self.uv_end.extend(uv_end);
|
||||
self.time_tile_received.push(start_time);
|
||||
|
||||
let uv_start = [
|
||||
uv_0[TileCorner::BottomLeft].x + hj0 * d01s,
|
||||
uv_0[TileCorner::BottomLeft].y + hi0 * d02s,
|
||||
uv_0[TileCorner::BottomLeft].z,
|
||||
];
|
||||
let xyz = crate::math::lonlat::radec_to_xyz(lon.to_angle(), lat.to_angle());
|
||||
pos.push([xyz.x as f32, xyz.y as f32, xyz.z as f32]);
|
||||
}
|
||||
|
||||
let uv_end = [
|
||||
uv_1[TileCorner::BottomLeft].x + hj0 * d01e,
|
||||
uv_1[TileCorner::BottomLeft].y + hi0 * d02e,
|
||||
uv_1[TileCorner::BottomLeft].z,
|
||||
];
|
||||
// GL TRIANGLES
|
||||
self.idx_vertices.extend([
|
||||
idx + off_indices,
|
||||
idx + 1 + off_indices,
|
||||
idx + 2 + off_indices,
|
||||
idx + off_indices,
|
||||
idx + 2 + off_indices,
|
||||
idx + 3 + off_indices,
|
||||
]);
|
||||
// GL LINES
|
||||
/*self.idx_vertices.extend([
|
||||
idx + off_indices,
|
||||
idx + 1 + off_indices,
|
||||
idx + 1 + off_indices,
|
||||
idx + 2 + off_indices,
|
||||
idx + 2 + off_indices,
|
||||
idx + 3 + off_indices,
|
||||
idx + 3 + off_indices,
|
||||
idx + off_indices,
|
||||
]);*/
|
||||
|
||||
self.uv_start.extend(uv_start);
|
||||
self.uv_end.extend(uv_end);
|
||||
self.time_tile_received.push(start_time);
|
||||
|
||||
let xyz = crate::math::lonlat::radec_to_xyz(lon.to_angle(), lat.to_angle());
|
||||
pos.push([xyz.x as f32, xyz.y as f32, xyz.z as f32]);
|
||||
idx += 4;
|
||||
}
|
||||
|
||||
let patch_indices_iter = DefaultPatchIndexIter::new(
|
||||
&(0..=n_segments_by_side),
|
||||
&(0..=n_segments_by_side),
|
||||
n_vertices_per_segment,
|
||||
)
|
||||
.flatten()
|
||||
.map(|indices| {
|
||||
[
|
||||
indices.0 + off_indices,
|
||||
indices.1 + off_indices,
|
||||
indices.2 + off_indices,
|
||||
]
|
||||
})
|
||||
.flatten();
|
||||
self.idx_vertices.extend(patch_indices_iter);
|
||||
|
||||
off_indices += pos.len() as u16;
|
||||
|
||||
// Replace options with an arbitrary vertex
|
||||
@@ -773,6 +785,7 @@ impl HiPS2D {
|
||||
.bind_vertex_array_object_ref(&self.vao)
|
||||
.draw_elements_with_i32(
|
||||
WebGl2RenderingContext::TRIANGLES,
|
||||
//WebGl2RenderingContext::LINES,
|
||||
Some(self.num_idx as i32),
|
||||
WebGl2RenderingContext::UNSIGNED_SHORT,
|
||||
0,
|
||||
|
||||
@@ -28,7 +28,6 @@ use crate::math::lonlat::LonLatT;
|
||||
|
||||
use crate::downloader::request::allsky::Allsky;
|
||||
use crate::healpix::{cell::HEALPixCell, coverage::HEALPixCoverage};
|
||||
use crate::renderable::utils::index_patch::DefaultPatchIndexIter;
|
||||
use crate::time::Time;
|
||||
|
||||
use super::config::HiPSConfig;
|
||||
@@ -94,47 +93,6 @@ pub fn get_raster_shader<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn get_raytracer_shader<'a>(
|
||||
cmap: &Colormap,
|
||||
gl: &WebGlContext,
|
||||
shaders: &'a mut ShaderManager,
|
||||
config: &HiPSConfig,
|
||||
) -> Result<&'a Shader, JsValue> {
|
||||
//let colored_hips = config.is_colored();
|
||||
if config.get_format().is_colored() && cmap.label() == "native" {
|
||||
crate::shader::get_shader(
|
||||
gl,
|
||||
shaders,
|
||||
"hips_raytracer_raytracer.vert",
|
||||
"hips_raytracer_color.frag",
|
||||
)
|
||||
} else {
|
||||
if config.tex_storing_unsigned_int {
|
||||
crate::shader::get_shader(
|
||||
gl,
|
||||
shaders,
|
||||
"hips_raytracer_raytracer.vert",
|
||||
"hips_raytracer_grayscale_to_colormap_u.frag",
|
||||
)
|
||||
} else if config.tex_storing_integers {
|
||||
crate::shader::get_shader(
|
||||
gl,
|
||||
shaders,
|
||||
"hips_raytracer_raytracer.vert",
|
||||
"hips_raytracer_grayscale_to_colormap_i.frag",
|
||||
)
|
||||
} else {
|
||||
crate::shader::get_shader(
|
||||
gl,
|
||||
shaders,
|
||||
"hips_raytracer_raytracer.vert",
|
||||
"hips_raytracer_grayscale_to_colormap.frag",
|
||||
)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
pub struct HiPS3D {
|
||||
//color: Color,
|
||||
// The image survey texture buffer
|
||||
@@ -355,6 +313,15 @@ impl HiPS3D {
|
||||
|
||||
let channel = self.get_config().get_format().get_channel();
|
||||
|
||||
// Define a global level of subdivisions for all the healpix tile cells in the view
|
||||
// This should prevent seeing many holes
|
||||
// We compute it from the first cell in the view but it might be an under/over estimate for the other cells in the view
|
||||
//let num_sub = super::subdivide::num_hpx_subdivision(&self.hpx_cells_in_view[0], camera, proj);
|
||||
|
||||
let num_sub = self.hpx_cells_in_view.iter()
|
||||
.map(|cell| super::subdivide::num_hpx_subdivision(cell, camera, proj))
|
||||
.max().unwrap();
|
||||
|
||||
for cell in &self.hpx_cells_in_view {
|
||||
// filter textures that are not in the moc
|
||||
let cell = if let Some(moc) = self.footprint_moc.as_ref() {
|
||||
@@ -405,62 +372,68 @@ impl HiPS3D {
|
||||
let d01e = uv_1[TileCorner::BottomRight].x - uv_1[TileCorner::BottomLeft].x;
|
||||
let d02e = uv_1[TileCorner::TopLeft].y - uv_1[TileCorner::BottomLeft].y;
|
||||
|
||||
let num_subdivision =
|
||||
super::subdivide::num_hpxcell_subdivision(cell, camera, proj);
|
||||
let sub_cells = super::subdivide::subdivide_hpx_cell(cell, num_sub, camera);
|
||||
|
||||
let n_segments_by_side: usize = 1 << (num_subdivision as usize);
|
||||
let n_segments_by_side_f32 = n_segments_by_side as f32;
|
||||
let mut pos = Vec::with_capacity(sub_cells.len() * 4);
|
||||
|
||||
let n_vertices_per_segment = n_segments_by_side + 1;
|
||||
let mut idx = 0;
|
||||
|
||||
let mut pos = Vec::with_capacity((n_segments_by_side + 1) * 4);
|
||||
let tmp = self.idx_vertices.len();
|
||||
|
||||
let grid_lonlat =
|
||||
healpix::nested::grid(cell.depth(), cell.idx(), n_segments_by_side as u16);
|
||||
let grid_lonlat_iter = grid_lonlat.iter();
|
||||
for sub_cell in sub_cells {
|
||||
let (i, j) = sub_cell.offset_in_parent(cell);
|
||||
let nside = (1 << (sub_cell.depth() - cell.depth())) as f32;
|
||||
|
||||
for (idx, &(lon, lat)) in grid_lonlat_iter.enumerate() {
|
||||
let i: usize = idx / n_vertices_per_segment;
|
||||
let j: usize = idx % n_vertices_per_segment;
|
||||
for ((lon, lat), (di, dj)) in sub_cell.vertices().iter().zip([(0, 0), (1, 0), (1, 1), (0, 1)]) {
|
||||
let hj0 = ((j + dj) as f32) / nside;
|
||||
let hi0 = ((i + di) as f32) / nside;
|
||||
|
||||
let hj0 = (j as f32) / n_segments_by_side_f32;
|
||||
let hi0 = (i as f32) / n_segments_by_side_f32;
|
||||
let uv_end = [
|
||||
uv_1[TileCorner::BottomLeft].x + hj0 * d01e,
|
||||
uv_1[TileCorner::BottomLeft].y + hi0 * d02e,
|
||||
uv_1[TileCorner::BottomLeft].z,
|
||||
];
|
||||
|
||||
let uv_end = [
|
||||
uv_1[TileCorner::BottomLeft].x + hj0 * d01e,
|
||||
uv_1[TileCorner::BottomLeft].y + hi0 * d02e,
|
||||
uv_1[TileCorner::BottomLeft].z,
|
||||
];
|
||||
self.uv.extend(uv_end);
|
||||
|
||||
self.uv.extend(uv_end);
|
||||
pos.push([*lon as f32, *lat as f32]);
|
||||
}
|
||||
|
||||
pos.push([lon as f32, lat as f32]);
|
||||
// GL TRIANGLES
|
||||
self.idx_vertices.extend([
|
||||
idx + off_indices,
|
||||
idx + 2 + off_indices,
|
||||
idx + 1 + off_indices,
|
||||
|
||||
idx + off_indices,
|
||||
idx + 3 + off_indices,
|
||||
idx + 2 + off_indices,
|
||||
]);
|
||||
// GL LINES
|
||||
/*self.idx_vertices.extend([
|
||||
idx + off_indices,
|
||||
idx + 1 + off_indices,
|
||||
|
||||
idx + 1 + off_indices,
|
||||
idx + 2 + off_indices,
|
||||
|
||||
idx + 2 + off_indices,
|
||||
idx + 3 + off_indices,
|
||||
|
||||
idx + 3 + off_indices,
|
||||
idx + off_indices,
|
||||
]);*/
|
||||
|
||||
idx += 4;
|
||||
}
|
||||
|
||||
let patch_indices_iter = DefaultPatchIndexIter::new(
|
||||
&(0..=n_segments_by_side),
|
||||
&(0..=n_segments_by_side),
|
||||
n_vertices_per_segment,
|
||||
)
|
||||
.flatten()
|
||||
.map(|indices| {
|
||||
[
|
||||
indices.0 + off_indices,
|
||||
indices.1 + off_indices,
|
||||
indices.2 + off_indices,
|
||||
]
|
||||
})
|
||||
.flatten();
|
||||
let tmp = self.idx_vertices.len();
|
||||
self.idx_vertices.extend(patch_indices_iter);
|
||||
off_indices += pos.len() as u16;
|
||||
|
||||
self.num_indices.push(self.idx_vertices.len() - tmp);
|
||||
off_indices += pos.len() as u16;
|
||||
|
||||
// Replace options with an arbitrary vertex
|
||||
let position_iter = pos
|
||||
.into_iter()
|
||||
//.map(|ndc| ndc.unwrap_or([0.0, 0.0]))
|
||||
.flatten();
|
||||
self.position.extend(position_iter);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ use crate::math::projection::ProjectionType;
|
||||
use crate::math::vector::dist2;
|
||||
use crate::HEALPixCell;
|
||||
use crate::math::angle::ToAngle;
|
||||
const M: f64 = 280.0 * 280.0;
|
||||
const N: f64 = 150.0 * 150.0;
|
||||
const RAP: f64 = 0.7;
|
||||
|
||||
const M: f64 = 220.0 * 220.0;
|
||||
|
||||
fn is_too_large(cell: &HEALPixCell, camera: &CameraViewPort, projection: &ProjectionType) -> bool {
|
||||
let vertices = cell
|
||||
.vertices()
|
||||
@@ -21,47 +21,128 @@ fn is_too_large(cell: &HEALPixCell, camera: &CameraViewPort, projection: &Projec
|
||||
} else {
|
||||
let d1 = dist2(vertices[0].as_ref(), &vertices[2].as_ref());
|
||||
let d2 = dist2(vertices[1].as_ref(), &vertices[3].as_ref());
|
||||
if d1 > M || d2 > M {
|
||||
true
|
||||
} else if d1 < N && d2 < N {
|
||||
false
|
||||
} else {
|
||||
let rap = if d2 > d1 { d1 / d2 } else { d2 / d1 };
|
||||
|
||||
rap < RAP
|
||||
}
|
||||
d1 > M || d2 > M
|
||||
}
|
||||
}
|
||||
|
||||
pub fn num_hpxcell_subdivision(
|
||||
pub(crate) fn num_hpx_subdivision(
|
||||
cell: &HEALPixCell,
|
||||
camera: &CameraViewPort,
|
||||
projection: &ProjectionType,
|
||||
) -> u8 {
|
||||
let d = cell.depth();
|
||||
// Subdivide all cells at least one time.
|
||||
// TODO: use a single subdivision number computed from the current cells inside the view
|
||||
// i.e. subdivide all cells in the view with the cell that has to be the most subdivided
|
||||
let mut num_sub = 1;
|
||||
if d < 2 {
|
||||
num_sub = 2 - d;
|
||||
let d0 = cell.depth();
|
||||
|
||||
let num_sub = num_hpx_subdivision_rec(cell, d0, camera, projection);
|
||||
|
||||
// Ensure that the HEALPix cells wireframe is at least composed of order 3 cells
|
||||
let sub_cells_depth = d0 + num_sub;
|
||||
|
||||
if sub_cells_depth < 3 {
|
||||
num_sub + (3 - sub_cells_depth)
|
||||
} else {
|
||||
num_sub
|
||||
}
|
||||
|
||||
// Largest deformation cell among the cells of a specific depth
|
||||
let largest_center_to_vertex_dist =
|
||||
healpix::largest_center_to_vertex_distance(d, 0.0, healpix::TRANSITION_LATITUDE);
|
||||
let smallest_center_to_vertex_dist =
|
||||
healpix::largest_center_to_vertex_distance(d, 0.0, healpix::LAT_OF_SQUARE_CELL);
|
||||
|
||||
let (lon, lat) = cell.center();
|
||||
let center_to_vertex_dist = healpix::largest_center_to_vertex_distance(d, lon, lat);
|
||||
|
||||
let skewed_factor = (center_to_vertex_dist - smallest_center_to_vertex_dist)
|
||||
/ (largest_center_to_vertex_dist - smallest_center_to_vertex_dist);
|
||||
|
||||
if skewed_factor > 0.25 || is_too_large(cell, camera, projection) || cell.is_on_pole() {
|
||||
num_sub += 1;
|
||||
}
|
||||
|
||||
num_sub
|
||||
}
|
||||
|
||||
fn num_hpx_subdivision_rec(
|
||||
cell: &HEALPixCell,
|
||||
d0: u8,
|
||||
camera: &CameraViewPort,
|
||||
projection: &ProjectionType,
|
||||
) -> u8 {
|
||||
if (cell.depth() - d0) < MAX_HPX_CELL_SUBDIVISION
|
||||
&& cell.depth() < 29
|
||||
&& is_too_large(cell, camera, projection)
|
||||
{
|
||||
let sub_cells = cell.subdivide();
|
||||
|
||||
1 + [
|
||||
num_hpx_subdivision_rec(&sub_cells[0], d0, camera, projection),
|
||||
num_hpx_subdivision_rec(&sub_cells[1], d0, camera, projection),
|
||||
num_hpx_subdivision_rec(&sub_cells[2], d0, camera, projection),
|
||||
num_hpx_subdivision_rec(&sub_cells[3], d0, camera, projection),
|
||||
]
|
||||
.iter()
|
||||
.max()
|
||||
.unwrap()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_HPX_CELL_SUBDIVISION: u8 = 4;
|
||||
/// Subdivide a HEALPix cell that is directly mapped to a tile image in many sub cells
|
||||
/// taking into account the distortion occuring when projecting its vertices into the screen pixel space
|
||||
pub(crate) fn subdivide_hpx_cell(
|
||||
cell: &HEALPixCell,
|
||||
num_subdivisions: u8,
|
||||
camera: &CameraViewPort,
|
||||
) -> Box<[HEALPixCell]> {
|
||||
cell.get_children_cells(num_subdivisions)
|
||||
.map(|child_cell| {
|
||||
/*let cell_depth = child_cell.depth();
|
||||
|
||||
// Largest deformation cell among the cells of a specific depth
|
||||
let largest_center_to_vertex_dist = healpix::largest_center_to_vertex_distance(
|
||||
cell_depth,
|
||||
0.0,
|
||||
healpix::TRANSITION_LATITUDE,
|
||||
);
|
||||
let smallest_center_to_vertex_dist = healpix::largest_center_to_vertex_distance(
|
||||
cell_depth,
|
||||
0.0,
|
||||
healpix::LAT_OF_SQUARE_CELL,
|
||||
);
|
||||
|
||||
let (lon, lat) = child_cell.center();
|
||||
let center_to_vertex_dist =
|
||||
healpix::largest_center_to_vertex_distance(cell_depth, lon, lat);
|
||||
|
||||
let skewed_factor = (center_to_vertex_dist - smallest_center_to_vertex_dist)
|
||||
/ (largest_center_to_vertex_dist - smallest_center_to_vertex_dist);*/
|
||||
|
||||
let lat = child_cell.center().1;
|
||||
|
||||
|
||||
let c0 = child_cell.ancestor(child_cell.depth()).idx();
|
||||
|
||||
let c3 = child_cell.ancestor(child_cell.depth() - 3);
|
||||
let (x3i, y3i) = c3.get_offset_in_texture_cell(c3.depth());
|
||||
let nside3i = c3.nside() as u32;
|
||||
let c3_s = (x3i, y3i) == (0, nside3i - 1) || (x3i, y3i) == (nside3i - 1, 0);
|
||||
|
||||
let (x, y) = child_cell.get_offset_in_texture_cell(child_cell.depth());
|
||||
let nside = child_cell.nside() as u32;
|
||||
|
||||
let collignon_equatorial_frontier = ((0..=3).contains(&c0) || (8..=11).contains(&c0)) && ((x + y) as i32 - (nside as i32) + 1).abs() <= 1;
|
||||
|
||||
// A HEALPix cell would be distorted if
|
||||
let hpx_num_sub = if camera.get_aperture() >= 15.0_f64.to_radians() &&
|
||||
// cells at the frontier between collignon and equatorial HEALpix zones
|
||||
((0..=3).contains(&c0) || (8..=11).contains(&c0)) &&
|
||||
// neighbors of cells having only 7 neighbors (the most distorted ones)
|
||||
c3_s
|
||||
{
|
||||
// more specific cells needing a subdivision
|
||||
2
|
||||
} else if collignon_equatorial_frontier && c3_s {
|
||||
// on the collignon/equatorial fence and part of a 3 order cell having only 7 neighbors
|
||||
1
|
||||
} else if child_cell.is_on_pole() {
|
||||
// it lies on a pole
|
||||
1
|
||||
} else if child_cell.is_on_base_cell_edges() && lat.abs() >= healpix::TRANSITION_LATITUDE {
|
||||
// it lies on a frontier between base cells and at a high absolute latitude
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
// Subdivide one more time if the HEALPix cell is distorted
|
||||
child_cell.get_children_cells(hpx_num_sub)
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<_>>()
|
||||
.into_boxed_slice()
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ use crate::downloader::{query, Downloader};
|
||||
use crate::time::{DeltaTime, Time};
|
||||
use crate::Abort;
|
||||
|
||||
use al_api::moc::MOCOptions;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::rc::Rc;
|
||||
use al_api::moc::MOCOptions;
|
||||
|
||||
const MAX_NUM_TILE_FETCHING: usize = 8;
|
||||
const MAX_QUERY_QUEUE_LENGTH: usize = 100;
|
||||
@@ -214,7 +214,7 @@ impl TileFetcherQueue {
|
||||
|
||||
let tile_size = cfg.get_tile_size();
|
||||
//Request the allsky for the small tile size or if base tiles are not available
|
||||
if tile_size <= 128 || cfg.get_min_depth_tile() > 0 {
|
||||
if tile_size <= 256 || cfg.get_min_depth_tile() > 0 {
|
||||
// Request the allsky
|
||||
downloader.borrow_mut().fetch(query::Allsky::new(
|
||||
cfg,
|
||||
|
||||
@@ -413,6 +413,8 @@ export let Aladin = (function () {
|
||||
// Merge what is already in the cache for that HiPS with new properties
|
||||
// coming from the MOCServer
|
||||
this.hipsFavorites.push(hipsObj);
|
||||
// Favorites are also directly pushed to the cache
|
||||
this.hipsCache.append(hipsObj.id, hipsObj)
|
||||
}
|
||||
|
||||
this._setupUI(options);
|
||||
@@ -432,11 +434,7 @@ export let Aladin = (function () {
|
||||
});
|
||||
} else if (options.survey === HiPS.DEFAULT_SURVEY_ID) {
|
||||
// DSS is cached inside HiPS class, no need to provide any further information
|
||||
const survey = this.createImageSurvey(
|
||||
HiPS.DEFAULT_SURVEY_ID
|
||||
);
|
||||
|
||||
this.setBaseImageLayer(survey);
|
||||
this.setBaseImageLayer(HiPS.DEFAULT_SURVEY_ID);
|
||||
} else {
|
||||
this.setBaseImageLayer(options.survey);
|
||||
}
|
||||
@@ -472,22 +470,24 @@ export let Aladin = (function () {
|
||||
// maximize control
|
||||
if (options.showFullscreenControl) {
|
||||
// react to fullscreenchange event to restore initial width/height (if user pressed ESC to go back from full screen)
|
||||
// This event is only triggered with realFullscreen on
|
||||
Utils.on(
|
||||
document,
|
||||
"fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange",
|
||||
function (e) {
|
||||
() => {
|
||||
var fullscreenElt =
|
||||
document.fullscreenElement ||
|
||||
document.webkitFullscreenElement ||
|
||||
document.mozFullScreenElement ||
|
||||
document.msFullscreenElement;
|
||||
if (fullscreenElt === null || fullscreenElt === undefined) {
|
||||
self.toggleFullscreen(options.realFullscreen);
|
||||
|
||||
var fullScreenToggledFn =
|
||||
self.callbacksByEventName["fullScreenToggled"];
|
||||
typeof fullScreenToggledFn === "function" &&
|
||||
fullScreenToggledFn(self.isInFullscreen);
|
||||
// fix: Only toggle off the screen once because in case of closing the real fullscreen from the ui button, this could be called 2 times
|
||||
// * one toggleFullscreen from the button itself
|
||||
// * one toggleFullscreen from the fullscreenchange event
|
||||
// => resulting in closing and opening the fullscreen again.
|
||||
if (self.isInFullscreen) {
|
||||
self.toggleFullscreen(options.realFullscreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -709,7 +709,6 @@ export let Aladin = (function () {
|
||||
Aladin.prototype.toggleFullscreen = function (realFullscreen) {
|
||||
let self = this;
|
||||
|
||||
realFullscreen = Boolean(realFullscreen);
|
||||
self.isInFullscreen = !self.isInFullscreen;
|
||||
|
||||
ContextMenu.hideAll();
|
||||
@@ -720,13 +719,7 @@ export let Aladin = (function () {
|
||||
ui.toggle();
|
||||
}
|
||||
})
|
||||
|
||||
if (this.aladinDiv.classList.contains("aladin-fullscreen")) {
|
||||
this.aladinDiv.classList.remove("aladin-fullscreen");
|
||||
} else {
|
||||
this.aladinDiv.classList.add("aladin-fullscreen");
|
||||
}
|
||||
|
||||
|
||||
if (realFullscreen) {
|
||||
// go to "real" full screen mode
|
||||
if (self.isInFullscreen) {
|
||||
@@ -757,6 +750,8 @@ export let Aladin = (function () {
|
||||
}
|
||||
}
|
||||
|
||||
this.aladinDiv.classList.toggle("aladin-fullscreen");
|
||||
|
||||
// Delay the fixLayoutDimensions layout for firefox
|
||||
/*setTimeout(function () {
|
||||
self.view.fixLayoutDimensions();
|
||||
@@ -1579,10 +1574,8 @@ export let Aladin = (function () {
|
||||
let hipsOptions = { id, name, maxOrder, url, cooFrame, ...options };
|
||||
let hips = new HiPS(id, url || id, hipsOptions)
|
||||
|
||||
// This allows to retrieve the survey's options when it will be
|
||||
// added later to the view.
|
||||
if (this instanceof Aladin && !this.hipsCache.contains(hips.id)) {
|
||||
// Add it to the cache as soon as possible if we have a reference to the aladin object
|
||||
// A HiPS can be refered by its unique ID thus we add it to the cache (cf excample/al-cfht.html that refers to HiPS object just by their unique ID)
|
||||
if (this instanceof Aladin) {
|
||||
this.hipsCache.append(hips.id, hipsOptions)
|
||||
}
|
||||
|
||||
@@ -1939,12 +1932,14 @@ export let Aladin = (function () {
|
||||
let imageLayer;
|
||||
|
||||
let hipsCache = this.hipsCache;
|
||||
|
||||
// 1. User gives an ID
|
||||
if (typeof urlOrHiPSOrFITS === "string") {
|
||||
const idOrUrl = urlOrHiPSOrFITS;
|
||||
// many cases here
|
||||
// 1/ It has been already added to the cache
|
||||
let cachedOptions = hipsCache.get(idOrUrl)
|
||||
|
||||
if (cachedOptions) {
|
||||
imageLayer = A.HiPS(idOrUrl, cachedOptions);
|
||||
} else {
|
||||
@@ -1964,7 +1959,7 @@ export let Aladin = (function () {
|
||||
if (!cachedLayerOptions) {
|
||||
hipsCache.append(imageLayer.id, imageLayer.options)
|
||||
} else {
|
||||
// set the options from what is in the cache
|
||||
// Set the options from what is in the cache
|
||||
imageLayer.setOptions(cachedLayerOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +613,6 @@ export let Catalog = (function () {
|
||||
// Set the same color of the shape than the catalog.
|
||||
// FIXME: the color/shape could be a parameter at the source level, allowing the user single catalogs handling different shapes
|
||||
shape.setColor(this.color)
|
||||
|
||||
shape.setSelectionColor(this.selectionColor);
|
||||
shape.setHoverColor(this.hoverColor);
|
||||
}
|
||||
|
||||
@@ -640,6 +640,7 @@ export let View = (function () {
|
||||
var footprintClickedFunction = view.aladin.callbacksByEventName['footprintClicked'];
|
||||
|
||||
let objsByCats = {};
|
||||
let shapes = [];
|
||||
for (let o of objs) {
|
||||
// classify the different objects by catalog
|
||||
let cat = o.getCatalog && o.getCatalog();
|
||||
@@ -658,11 +659,22 @@ export let View = (function () {
|
||||
footprintClickedFunction(o, xy);
|
||||
}
|
||||
}
|
||||
|
||||
// If this shape has a catalog then it will be selected from its source
|
||||
// so we will not add it
|
||||
if (!cat) {
|
||||
shapes.push(o);
|
||||
}
|
||||
}
|
||||
|
||||
// rewrite objs
|
||||
// Rewrite objs
|
||||
objs = Array.from(Object.values(objsByCats));
|
||||
// Add the external shapes (i.e. which are not associated with catalog sources e.g. those from GraphicOverlay)
|
||||
if (shapes.length > 0) {
|
||||
objs.push(shapes)
|
||||
}
|
||||
view.selectObjects(objs);
|
||||
|
||||
view.lastClickedObject = objs;
|
||||
|
||||
} else {
|
||||
@@ -1209,7 +1221,7 @@ export let View = (function () {
|
||||
switch (e.keyCode) {
|
||||
// escape
|
||||
case 27:
|
||||
// if there is a selection occuring
|
||||
// Called when realfullscreen is false. Escaping from real fullscreen does not seem to trigger the keydown event
|
||||
if (view.aladin.isInFullscreen) {
|
||||
view.aladin.toggleFullscreen(view.aladin.options.realFullscreen);
|
||||
}
|
||||
@@ -2101,26 +2113,21 @@ export let View = (function () {
|
||||
}
|
||||
|
||||
let closests = [];
|
||||
const fLineWidth = (footprints && footprints[0] && footprints[0].getLineWidth()) || 1;
|
||||
let lw = fLineWidth + 3;
|
||||
//for (var lw = startLw + 1; lw <= startLw + 3; lw++) {
|
||||
footprints.forEach((footprint) => {
|
||||
if (!footprint.source || !footprint.source.tooSmallFootprint) {
|
||||
// Hidden footprints are not considered
|
||||
//let originLineWidth = footprint.getLineWidth();
|
||||
|
||||
footprint.setLineWidth(lw);
|
||||
if (footprint.isShowing && footprint.isInStroke(ctx, this, x * window.devicePixelRatio, y * window.devicePixelRatio)) {
|
||||
closests.push(footprint);
|
||||
}
|
||||
footprint.setLineWidth(fLineWidth);
|
||||
}
|
||||
})
|
||||
|
||||
/* if (closests.length > 0) {
|
||||
break;
|
||||
footprints.forEach((footprint) => {
|
||||
if (!footprint.source || !footprint.source.tooSmallFootprint) {
|
||||
const originLineWidth = footprint.getLineWidth();
|
||||
let spreadedLineWidth = (originLineWidth || 1) + 3;
|
||||
|
||||
footprint.setLineWidth(spreadedLineWidth);
|
||||
if (footprint.isShowing && footprint.isInStroke(ctx, this, x * window.devicePixelRatio, y * window.devicePixelRatio)) {
|
||||
closests.push(footprint);
|
||||
}
|
||||
|
||||
footprint.setLineWidth(originLineWidth);
|
||||
}
|
||||
}*/
|
||||
})
|
||||
|
||||
|
||||
return closests;
|
||||
};
|
||||
@@ -2132,13 +2139,11 @@ export let View = (function () {
|
||||
var canvas = this.catalogCanvas;
|
||||
var ctx = canvas.getContext("2d");
|
||||
// this makes footprint selection easier as the catch-zone is larger
|
||||
//let pastLineWidth = ctx.lineWidth;
|
||||
|
||||
let closests = [];
|
||||
if (this.overlays) {
|
||||
for (var k = 0; k < this.overlays.length; k++) {
|
||||
overlay = this.overlays[k];
|
||||
|
||||
closests = closests.concat(this.closestFootprints(overlay.overlayItems, ctx, x, y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,15 +528,7 @@ export class OverlayStackBox extends Box {
|
||||
position: self.position,
|
||||
});*/
|
||||
self.aladin.addNewImageLayer(
|
||||
A.imageHiPS('P/DSS2/color', {
|
||||
errorCallback: (e) => {
|
||||
aladin.addStatusBarMessage({
|
||||
duration: 2000,
|
||||
type: 'info',
|
||||
message: 'DSS2 colored HiPS could not plot',
|
||||
})
|
||||
}
|
||||
})
|
||||
'P/DSS2/color'
|
||||
);
|
||||
},
|
||||
},
|
||||
@@ -940,6 +932,7 @@ export class OverlayStackBox extends Box {
|
||||
options.push(value)
|
||||
}
|
||||
|
||||
|
||||
let HiPSSelector = Input.select({
|
||||
value,
|
||||
options,
|
||||
|
||||
@@ -57,8 +57,8 @@ export class FullScreenActionButton extends ActionButton {
|
||||
if (aladin.statusBar) {
|
||||
aladin.statusBar.removeMessage('tooltip')
|
||||
}
|
||||
|
||||
aladin.toggleFullscreen(aladin.options.realFullscreen);
|
||||
|
||||
aladin.toggleFullscreen(aladin.options.realFullscreen);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ export let Circle = (function() {
|
||||
|
||||
this.color = options['color'] || undefined;
|
||||
this.fillColor = options['fillColor'] || undefined;
|
||||
this.lineWidth = options["lineWidth"] || 2;
|
||||
this.lineWidth = options["lineWidth"] || undefined;
|
||||
this.selectionColor = options["selectionColor"] || '#00ff00';
|
||||
this.hoverColor = options["hoverColor"] || undefined;
|
||||
this.opacity = options['opacity'] || 1;
|
||||
@@ -297,6 +297,10 @@ export let Circle = (function() {
|
||||
ctx.strokeStyle = baseColor;
|
||||
}
|
||||
|
||||
if (!this.lineWidth) {
|
||||
this.lineWidth = (this.overlay && this.overlay.lineWidth) || 2;
|
||||
}
|
||||
|
||||
ctx.lineWidth = this.lineWidth;
|
||||
ctx.globalAlpha = this.opacity;
|
||||
ctx.beginPath();
|
||||
|
||||
@@ -51,7 +51,7 @@ export let Ellipse = (function() {
|
||||
|
||||
this.color = options['color'] || undefined;
|
||||
this.fillColor = options['fillColor'] || undefined;
|
||||
this.lineWidth = options["lineWidth"] || 2;
|
||||
this.lineWidth = options["lineWidth"] || undefined;
|
||||
this.selectionColor = options["selectionColor"] || '#00ff00';
|
||||
this.hoverColor = options["hoverColor"] || undefined;
|
||||
this.opacity = options['opacity'] || 1;
|
||||
@@ -283,6 +283,10 @@ export let Ellipse = (function() {
|
||||
ctx.strokeStyle = baseColor;
|
||||
}
|
||||
|
||||
if (!this.lineWidth) {
|
||||
this.lineWidth = (this.overlay && this.overlay.lineWidth) || 2;
|
||||
}
|
||||
|
||||
ctx.lineWidth = this.lineWidth;
|
||||
ctx.globalAlpha = this.opacity;
|
||||
ctx.beginPath();
|
||||
|
||||