mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2026-01-12 13:15:22 -08:00
242 lines
7.0 KiB
Rust
242 lines
7.0 KiB
Rust
use crate::{coosys, healpix::cell::HEALPixCell, math};
|
|
use std::collections::HashMap;
|
|
|
|
|
|
/*
|
|
use crate::math::angle::Angle;
|
|
use crate::Projection;
|
|
use cgmath::Vector2;
|
|
pub fn project_vertices<P: Projection>(cell: &HEALPixCell, camera: &CameraViewPort) -> [Vector2<f64>; 4] {
|
|
let project_vertex = |(lon, lat): (f64, f64)| -> Vector2<f64> {
|
|
let vertex = crate::math::lonlat::radec_to_xyzw(Angle(lon), Angle(lat));
|
|
P::view_to_screen_space(&vertex, camera).unwrap()
|
|
};
|
|
|
|
let vertices = cell.vertices();
|
|
|
|
[
|
|
project_vertex(vertices[0]),
|
|
project_vertex(vertices[1]),
|
|
project_vertex(vertices[2]),
|
|
project_vertex(vertices[3])
|
|
]
|
|
}*/
|
|
|
|
// Compute a depth from a number of pixels on screen
|
|
pub fn depth_from_pixels_on_screen(camera: &CameraViewPort, num_pixels: i32) -> u8 {
|
|
let width = camera.get_screen_size().x;
|
|
let aperture = camera.get_aperture().0 as f32;
|
|
|
|
let angle_per_pixel = aperture / width;
|
|
|
|
let two_power_two_times_depth_pixel =
|
|
std::f32::consts::PI / (3.0 * angle_per_pixel * angle_per_pixel);
|
|
let depth_pixel = (two_power_two_times_depth_pixel.log2() / 2.0).round() as u32;
|
|
|
|
//let survey_max_depth = conf.get_max_depth();
|
|
// The depth of the texture
|
|
// A texture of 512x512 pixels will have a depth of 9
|
|
let depth_offset_texture = math::utils::log_2_unchecked(num_pixels);
|
|
// The depth of the texture corresponds to the depth of a pixel
|
|
// minus the offset depth of the texture
|
|
if depth_offset_texture > depth_pixel {
|
|
0_u8
|
|
} else {
|
|
(depth_pixel - depth_offset_texture) as u8
|
|
}
|
|
|
|
/*let mut depth = 0;
|
|
let mut d1 = std::f64::MAX;
|
|
let mut d2 = std::f64::MAX;
|
|
|
|
while d1 > 512.0*512.0 && d2 > 512.0*512.0 {
|
|
|
|
let (lon, lat) = crate::math::lonlat::xyzw_to_radec(camera.get_center());
|
|
let lonlat = math::lonlat::LonLatT(lon, lat);
|
|
|
|
let (ipix, _, _) = crate::healpix::utils::hash_with_dxdy(depth, &lonlat);
|
|
let vertices = project_vertices::<P>(&HEALPixCell(depth, ipix), camera);
|
|
|
|
d1 = crate::math::vector::dist2(&vertices[0], &vertices[2]);
|
|
d2 = crate::math::vector::dist2(&vertices[1], &vertices[3]);
|
|
|
|
depth += 1;
|
|
}
|
|
al_core::info!(depth);
|
|
if depth > 0 {
|
|
depth - 1
|
|
} else {
|
|
0
|
|
}*/
|
|
}
|
|
|
|
use healpix::coverage::HEALPixCoverage;
|
|
pub fn compute_view_coverage(camera: &CameraViewPort, depth: u8, dst_frame: &CooSystem) -> HEALPixCoverage {
|
|
if depth <= 1 {
|
|
HEALPixCoverage::allsky(depth)
|
|
} else {
|
|
if let Some(vertices) = camera.get_vertices() {
|
|
// The vertices coming from the camera are in a specific coo sys
|
|
// but cdshealpix accepts them to be given in ICRSJ2000 coo sys
|
|
let camera_frame = camera.get_system();
|
|
let vertices = vertices
|
|
.iter()
|
|
.map(|v| coosys::apply_coo_system(camera_frame, dst_frame, v))
|
|
.collect::<Vec<_>>();
|
|
|
|
let inside_vertex = camera.get_center();
|
|
let inside_vertex = coosys::apply_coo_system(camera_frame, &dst_frame, &inside_vertex);
|
|
|
|
// Prefer to query from_polygon with depth >= 2
|
|
HEALPixCoverage::new(
|
|
depth,
|
|
&vertices[..],
|
|
&inside_vertex.truncate(),
|
|
)
|
|
} else {
|
|
HEALPixCoverage::allsky(depth)
|
|
}
|
|
}
|
|
}
|
|
|
|
use crate::healpix;
|
|
use al_api::coo_system::CooSystem;
|
|
pub fn get_tile_cells_in_camera(
|
|
depth_tile: u8,
|
|
camera: &CameraViewPort,
|
|
hips_frame: &CooSystem,
|
|
) -> (HEALPixCoverage, Vec<HEALPixCell>) {
|
|
let moc = compute_view_coverage(camera, depth_tile, &hips_frame);
|
|
let cells = moc.flatten_to_fixed_depth_cells()
|
|
.map(|idx| {
|
|
HEALPixCell(depth_tile, idx)
|
|
})
|
|
.collect();
|
|
|
|
(moc, cells)
|
|
}
|
|
|
|
// Contains the cells being in the FOV for a specific
|
|
pub struct HEALPixCellsInView {
|
|
// The set of cells being in the current view for a
|
|
// specific image survey
|
|
pub depth: u8,
|
|
prev_depth: u8,
|
|
view_unchanged: bool,
|
|
frame: CooSystem,
|
|
|
|
// flags associating true to cells that
|
|
// are new in the fov
|
|
cells: HashMap<HEALPixCell, bool>,
|
|
// A flag telling whether there has been
|
|
// new cells added from the last frame
|
|
is_new_cells_added: bool,
|
|
|
|
coverage: HEALPixCoverage,
|
|
}
|
|
|
|
use crate::camera::CameraViewPort;
|
|
impl HEALPixCellsInView {
|
|
pub fn new() -> Self {
|
|
let cells = HashMap::new();
|
|
let coverage = HEALPixCoverage::allsky(0);
|
|
|
|
let view_unchanged = false;
|
|
let frame = CooSystem::ICRSJ2000;
|
|
Self {
|
|
cells,
|
|
prev_depth: 0,
|
|
depth: 0,
|
|
is_new_cells_added: false,
|
|
view_unchanged,
|
|
frame,
|
|
coverage,
|
|
}
|
|
}
|
|
|
|
pub fn reset_frame(&mut self) {
|
|
self.is_new_cells_added = false;
|
|
self.view_unchanged = false;
|
|
self.prev_depth = self.get_depth();
|
|
}
|
|
|
|
// This method is called whenever the user does an action
|
|
// that moves the camera.
|
|
// Everytime the user moves or zoom, the views must be updated
|
|
// The new cells obtained are used for sending new requests
|
|
pub fn refresh(&mut self, new_depth: u8, hips_frame: CooSystem, camera: &CameraViewPort) {
|
|
self.depth = new_depth;
|
|
self.frame = hips_frame;
|
|
|
|
// Get the cells of that depth in the current field of view
|
|
let (coverage, tile_cells) = get_tile_cells_in_camera(self.depth, camera, &self.frame);
|
|
self.coverage = coverage;
|
|
|
|
// Update cells in the fov
|
|
self.update_cells_in_fov(&tile_cells);
|
|
}
|
|
|
|
fn update_cells_in_fov(&mut self, cells_in_fov: &[HEALPixCell]) {
|
|
let new_cells = cells_in_fov
|
|
.iter()
|
|
.map(|cell| {
|
|
let new = !self.cells.contains_key(cell);
|
|
self.is_new_cells_added |= new;
|
|
|
|
(*cell, new)
|
|
})
|
|
.collect::<HashMap<_, _>>();
|
|
|
|
// If no new cells have been added
|
|
self.view_unchanged = !self.is_new_cells_added && new_cells.len() == self.cells.len();
|
|
self.cells = new_cells;
|
|
}
|
|
|
|
// Accessors
|
|
#[inline]
|
|
pub fn get_cells(&self) -> impl Iterator<Item = &HEALPixCell> {
|
|
self.cells.keys()
|
|
}
|
|
|
|
#[inline]
|
|
pub fn num_of_cells(&self) -> usize {
|
|
self.cells.len()
|
|
}
|
|
|
|
#[inline]
|
|
pub fn get_depth(&self) -> u8 {
|
|
self.depth
|
|
}
|
|
|
|
#[inline]
|
|
pub fn get_frame(&self) -> &CooSystem {
|
|
&self.frame
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_new(&self, cell: &HEALPixCell) -> bool {
|
|
if let Some(&is_cell_new) = self.cells.get(cell) {
|
|
is_cell_new
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn get_coverage(&self) -> &HEALPixCoverage {
|
|
&self.coverage
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_there_new_cells_added(&self) -> bool {
|
|
//self.new_cells.is_there_new_cells_added()
|
|
self.is_new_cells_added
|
|
}
|
|
|
|
#[inline]
|
|
pub fn has_view_changed(&self) -> bool {
|
|
//self.new_cells.is_there_new_cells_added()
|
|
!self.view_unchanged
|
|
}
|
|
}
|