Subdivision tuning

Cells are all subdivided at the same level.
One subdivision is added if:
* the cell is on a pole
* the cell is at a frontier of a base cells (and in collignon zona)
This commit is contained in:
Matthieu Baumann
2025-04-01 14:31:57 +02:00
parent 62f9e61978
commit 645bab7cd9
81 changed files with 330 additions and 181 deletions

View File

@@ -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,
}
);
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View 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

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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()
}

View File

@@ -658,11 +658,6 @@ export let View = (function () {
if (typeof footprintClickedFunction === 'function') {
footprintClickedFunction(o, xy);
}
// If this footprint has a catalog then it will be selected from its source
// so we will not add it
if (!cat) {
footprints.push(o);
}
}
// If this shape has a catalog then it will be selected from its source