Compare commits

..

17 Commits

Author SHA1 Message Date
Matthieu Baumann
60339e529a make rust test pass 2024-09-11 17:40:52 +02:00
Matthieu Baumann
9bccdefcc5 expose in the doc the api of coo class 2024-09-11 16:40:51 +02:00
Matthieu Baumann
16f978810f remove rust warning, fix rust compilation 2024-09-11 16:06:43 +02:00
Matthieu Baumann
424c3cebba fix css browser text input width so that user can redefine css 2024-09-11 11:35:19 +02:00
Matthieu Baumann
66326b59e4 fix default allwise hips stored 2024-09-11 10:18:35 +02:00
Matthieu Baumann
7b80efa324 add new tests. configure playwright to be less subject to timeouts by avoiding doing requests and using mocked data (gw local fits files, image fits files, local hips jpg tiles) 2024-09-11 10:11:04 +02:00
Matthieu Baumann
fd9a7b0de2 add gw to playwright tests 2024-09-10 23:50:43 +02:00
Matthieu Baumann
72d7e4e6bb fix playwright snapshots 2024-09-10 23:23:38 +02:00
Matthieu Baumann
186e634a86 rename ImageHiPS in HiPS, factorize Image/HiPS, zoom for trackpad refined 2024-09-10 18:32:47 +02:00
Matthieu Baumann
5fd6bedeb9 wip have a default hips url on allsky for the default hips list to begin to query while waiting for the mocserver response 2024-09-10 18:32:46 +02:00
Matthieu Baumann
6dd8ee2b85 fasten a little bit the starting by disabling the download of less precised tiles and thus it will only blend the good resolued tiles with less precised ones. 2024-09-10 18:31:05 +02:00
Matthieu Baumann
a8c07137a4 fix issue #179: onClick can be associated to user defined function 2024-09-10 18:31:05 +02:00
Matthieu Baumann
7dc4a737ac WIP: try to enhance starting 2024-09-10 18:31:05 +02:00
Matthieu Baumann
a1b7b255bd avoid computing the full unprojected texturefor the raytracing step. Hope it's gonna fasten the starting of aladin lite 2024-09-10 18:31:05 +02:00
Matthieu Baumann
1c3d6e90c9 add possibility to associate an Image or HTMLCanvasElement to a specific source in the shape function 2024-09-10 18:31:05 +02:00
Matthieu Baumann
ebb2172833 add error ellipse example for 2mass 2024-09-10 18:31:03 +02:00
Matthieu Baumann
256e440ac5 first commit hips cube impl 2024-09-10 18:30:09 +02:00
26 changed files with 204 additions and 629 deletions

View File

@@ -1,14 +1,11 @@
# Changelogs
## 3.5.1-beta
## [Unreleased]
* [feat] Add support for name removing in `removeOverlay` method
* [test] Add support of playwright. Instructions in the readme for running the test matching snapshots [PR #176]
* [fix] Order of overlays in the stack now matches the addMOC/addCatalog/addOverlay calls ordering
* [fixed] Order of overlays in the stack now matches the addMOC/addCatalog/addOverlay calls ordering
* [doc] Expose the API of Coo class
* [fix] Insert aladin css inside the aladin lite so that it should be compliant with the use of shadow DOMs [cds-astro/ipyaladin#113], [marimo-team/marimo#2106]
* [feat] Add possibility of giving a local JS FileList to load a locally-stored HiPS without starting an HTTP server [cds-astro/aladin-lite#103]
* [fix] removeOverlayByName
## 3.5.0-beta

View File

@@ -8,8 +8,8 @@
"dateModified": "2023-01-31",
"issueTracker": "https://github.com/cds-astro/aladin-lite/issues",
"name": "Aladin Lite",
"version": "3.5.1-beta",
"softwareVersion": "3.5.1-beta",
"version": "3.5.0-beta",
"softwareVersion": "3.5.0-beta",
"description": "An astronomical HiPS visualizer in the browser.",
"identifier": "10.5281/zenodo.7638833",
"applicationCategory": "Astronomy, Visualization",

View File

@@ -1,32 +0,0 @@
<!doctype html>
<html>
<head>
</head>
<body>
<div class="shadow-host"></div>
<script type="text/javascript" src="./../dist/aladin.umd.cjs" charset="utf-8"></script>
<script type="text/javascript">
const shadowEl = document.querySelector(".shadow-host");
const shadow = shadowEl.attachShadow({mode: 'open'});
let aladinLiteEl = document.createElement('div');
aladinLiteEl.id = "aladin-lite-div"
aladinLiteEl.style = "width: 768px; height: 512px";
shadow.appendChild(aladinLiteEl)
A.init.then(() => {
let aladin = A.aladin(
aladinLiteEl,
{
survey: 'P/allWISE/color', // set initial image survey
projection: 'AIT', // set a projection
fov: 1.5, // initial field of view in degrees
target: 'orion', // initial target
}
);
});
</script>
</body>
</html>

View File

@@ -13,7 +13,6 @@
aladin = A.aladin(
'#aladin-lite-div',
{
showSimbadPointerControl: true,
survey: 'P/allWISE/color', // set initial image survey
projection: 'AIT', // set a projection
fov: 1.5, // initial field of view in degrees
@@ -31,14 +30,7 @@
}
);
/*let id;
aladin.on("zoomChanged", () => {
if (id)
clearTimeout(id);
id = setTimeout(() => {
console.log("wheel stopped, new cone search here")
}, 500);
})*/
//aladin.removeHiPSFromFavorites('CDS/P/allWISE/color')
});
</script>
<style>

View File

@@ -11,17 +11,10 @@
A.init.then(() => {
let vertices = A.Utils.HEALPix.vertices(Math.pow(2, 3), BigInt(276))
let lonlat = A.Utils.HEALPix.pix2ang(8, 0n)
let ipix = A.Utils.HEALPix.ang2pix(8, 0.1, 0.4)
console.log("vertices", vertices, lonlat, ipix)
A.Utils.Sesame.resolveAstronomicalName("M101", (o) => {
console.log("object found", o)
},
(err) => {
console.error("errr", err)
}
)
//let lonlat = A.Utils.HEALPix.pix2ang(8, 0n)
//let ipix = A.Utils.HEALPix.ang2pix(8, 0.1, 0.4)
//console.log("vertices", vertices, lonlat, ipix)
console.log(vertices)
})
</script>

View File

@@ -9,7 +9,9 @@
"module": "./dist/aladin.js",
"main": "./dist/aladin.js",
"files": [
"dist/aladin.js"
"dist/aladin.js",
"dist/aladin.umd.cjs",
"dist/index.html"
],
"exports": {
".": {
@@ -34,8 +36,8 @@
"wasm:dbg": "wasm-pack build --dev ./src/core --target web --out-name core -- --features=webgl2,dbg -Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort ",
"predeploy": "npm run build && rm -rf aladin-lite*.tgz && npm pack",
"deploy": "python3 deploy/deploy.py",
"build": "npm run wasm && vite build",
"build:dbg": "npm run wasm:dbg && vite build",
"build": "npm run wasm && vite build && cp examples/index.html dist/index.html",
"build:dbg": "npm run wasm:dbg && vite build && cp examples/index.html dist/index.html",
"dev": "npm run build && vite",
"dev:dbg": "npm run build:dbg && vite",
"serve": "npm run dev",
@@ -51,6 +53,7 @@
"@playwright/test": "^1.47.0",
"jsdoc": "^4.0.2",
"vite": "^4.3.8",
"vite-plugin-css-injected-by-js": "^3.1.1",
"vite-plugin-glsl": "^1.1.2",
"vite-plugin-top-level-await": "^1.4.1",
"vite-plugin-wasm": "^3.2.2",

View File

@@ -3,7 +3,7 @@ name = "aladin-lite"
description = "Aladin Lite v3 introduces a new graphical engine written in Rust with the use of WebGL"
license = "BSD-3-Clause"
repository = "https://github.com/cds-astro/aladin-lite"
version = "3.5.1-beta"
version = "3.5.0-beta"
authors = [ "baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr",]
edition = "2018"
@@ -70,7 +70,7 @@ path = "./al-api"
[dependencies.web-sys]
version = "*"
features = [ "console", "CssStyleDeclaration", "Document", "Element", "HtmlCollection", "HtmlElement", "HtmlImageElement", "HtmlCanvasElement", "Blob", "ImageBitmap", "ImageData", "CanvasRenderingContext2d", "WebGlBuffer", "WebGlContextAttributes", "WebGlFramebuffer", "WebGlProgram", "WebGlShader", "WebGlUniformLocation", "WebGlTexture", "WebGlActiveInfo", "Headers", "Window", "Request", "RequestInit", "RequestMode", "Response", "XmlHttpRequest", "XmlHttpRequestResponseType", "PerformanceTiming", "Performance", "Url", "ReadableStream", "File", "FileList",]
features = [ "console", "CssStyleDeclaration", "Document", "Element", "HtmlCollection", "HtmlElement", "HtmlImageElement", "HtmlCanvasElement", "Blob", "ImageBitmap", "ImageData", "CanvasRenderingContext2d", "WebGlBuffer", "WebGlContextAttributes", "WebGlFramebuffer", "WebGlProgram", "WebGlShader", "WebGlUniformLocation", "WebGlTexture", "WebGlActiveInfo", "Headers", "Window", "Request", "RequestInit", "RequestMode", "Response", "XmlHttpRequest", "XmlHttpRequestResponseType", "PerformanceTiming", "Performance", "Url", "ReadableStream",]
[dev-dependencies.image-decoder]
package = "image"

View File

@@ -61,8 +61,6 @@ features = [
'PerformanceTiming',
'Performance',
'Url',
'File',
'FileList'
]
[profile.dev]

View File

@@ -73,8 +73,6 @@ features = [
'PerformanceTiming',
'Performance',
'Url',
'File',
'FileList'
]
[profile.dev]

View File

@@ -1,5 +1,4 @@
use crate::renderable::ImageLayer;
use crate::tile_fetcher::HiPSLocalFiles;
use crate::{
//async_task::{BuildCatalogIndex, ParseTableTask, TaskExecutor, TaskResult, TaskType},
camera::CameraViewPort,
@@ -303,6 +302,16 @@ impl App {
ancestors.insert(ancestor_tile_cell);
}
}
//let ancestor_next_tile_cell = next_tile_cell.ancestor(3);
//if !survey.contains_tile(&ancestor_tile_cell) {
//self.tile_fetcher.append(
// query::Tile::new(&ancestor_tile_cell, hips_url.clone(), format),
// &mut self.downloader,
//);
//}
//if ancestor_tile_cell != ancestor_next_tile_cell {
//}
}
}
// Request for ancestor
@@ -796,12 +805,8 @@ impl App {
// Check for async retrieval
if let Ok(img) = self.img_recv.try_recv() {
let params = img.get_params();
self.layers.add_image(
img,
&mut self.camera,
&self.projection,
&mut self.tile_fetcher,
)?;
self.layers
.add_image(img, &mut self.camera, &self.projection)?;
self.request_redraw = true;
// Send the ack to the js promise so that she finished
@@ -953,12 +958,8 @@ impl App {
}
pub(crate) fn remove_layer(&mut self, layer: &str) -> Result<(), JsValue> {
self.layers.remove_layer(
layer,
&mut self.camera,
&self.projection,
&mut self.tile_fetcher,
)?;
self.layers
.remove_layer(layer, &mut self.camera, &self.projection)?;
self.request_redraw = true;
@@ -981,31 +982,17 @@ impl App {
Ok(())
}
pub(crate) fn add_image_hips(
&mut self,
hips_cfg: HiPSCfg,
local_files: Option<HiPSLocalFiles>,
) -> Result<(), JsValue> {
let cdid = hips_cfg.properties.get_creator_did().to_string();
let hips = self.layers.add_image_hips(
&self.gl,
hips_cfg,
&mut self.camera,
&self.projection,
&mut self.tile_fetcher,
)?;
if let Some(local_files) = local_files {
self.tile_fetcher.insert_hips_local_files(cdid, local_files);
}
pub(crate) fn add_image_hips(&mut self, hips_cfg: HiPSCfg) -> Result<(), JsValue> {
let hips =
self.layers
.add_image_hips(&self.gl, hips_cfg, &mut self.camera, &self.projection)?;
self.tile_fetcher
.launch_starting_hips_requests(hips, self.downloader.clone());
// Once its added, request the tiles in the view (unless the viewer is at depth 0)
self.request_for_new_tiles = true;
self.request_redraw = true;
//self.grid.update(&self.camera, &self.projection);
Ok(())
}

View File

@@ -87,7 +87,6 @@ use math::projection::*;
use moclib::moc::RangeMOCIntoIterator;
//use votable::votable::VOTableWrapper;
use crate::tile_fetcher::HiPSLocalFiles;
use wasm_bindgen::prelude::*;
use web_sys::HtmlElement;
@@ -161,7 +160,11 @@ impl WebClient {
/// * `shaders` - The list of shader objects containing the GLSL code source
/// * `resources` - Image resource files
#[wasm_bindgen(constructor)]
pub fn new(aladin_div: &HtmlElement, resources: JsValue) -> Result<WebClient, JsValue> {
pub fn new(
aladin_div: &HtmlElement,
//_shaders: JsValue,
resources: JsValue,
) -> Result<WebClient, JsValue> {
#[cfg(feature = "dbg")]
panic::set_hook(Box::new(console_error_panic_hook::hook));
@@ -368,14 +371,10 @@ impl WebClient {
/// of WebGL2 texture units on some architectures, the total number of surveys rendered is
/// limited to 4.
#[wasm_bindgen(js_name = addHiPS)]
pub fn add_image_hips(
&mut self,
hips: JsValue,
files: Option<HiPSLocalFiles>,
) -> Result<(), JsValue> {
pub fn add_image_hips(&mut self, hips: JsValue) -> Result<(), JsValue> {
// Deserialize the survey objects that compose the survey
let hips = serde_wasm_bindgen::from_value(hips)?;
self.app.add_image_hips(hips, files)?;
self.app.add_image_hips(hips)?;
Ok(())
}
@@ -1033,7 +1032,7 @@ impl WebClient {
Ok(())
}
#[wasm_bindgen(js_name = addFITSMOC)]
#[wasm_bindgen(js_name = addFITSMoc)]
pub fn add_fits_moc(&mut self, params: &al_api::moc::MOC, data: &[u8]) -> Result<(), JsValue> {
//let bytes = js_sys::Uint8Array::new(array_buffer).to_vec();
let moc = match fits::from_fits_ivoa_custom(Cursor::new(&data[..]), false)

View File

@@ -10,7 +10,6 @@ pub mod text;
pub mod utils;
use crate::renderable::image::Image;
use crate::tile_fetcher::TileFetcherQueue;
use al_core::image::format::ChannelType;
@@ -317,7 +316,6 @@ impl Layers {
layer: &str,
camera: &mut CameraViewPort,
proj: &ProjectionType,
tile_fetcher: &mut TileFetcherQueue,
) -> Result<usize, JsValue> {
let err_layer_not_found = JsValue::from_str(&format!(
"Layer {:?} not found, so cannot be removed.",
@@ -353,9 +351,6 @@ impl Layers {
// remove the frame
camera.unregister_view_frame(hips_frame, proj);
// remove the local files access from the tile fetcher
tile_fetcher.delete_hips_local_files(s.get_config().get_creator_did());
Ok(id_layer)
} else if let Some(_) = self.images.remove(&id) {
// A FITS image has been found and removed
@@ -423,7 +418,6 @@ impl Layers {
hips: HiPSCfg,
camera: &mut CameraViewPort,
proj: &ProjectionType,
tile_fetcher: &mut TileFetcherQueue,
) -> Result<&HiPS, JsValue> {
let HiPSCfg {
layer,
@@ -437,7 +431,7 @@ impl Layers {
let layer_already_found = self.layers.iter().any(|l| l == &layer);
let idx = if layer_already_found {
let idx = self.remove_layer(&layer, camera, proj, tile_fetcher)?;
let idx = self.remove_layer(&layer, camera, proj)?;
idx
} else {
self.layers.len()
@@ -498,7 +492,6 @@ impl Layers {
image: ImageLayer,
camera: &mut CameraViewPort,
proj: &ProjectionType,
tile_fetcher: &mut TileFetcherQueue,
) -> Result<&[Image], JsValue> {
let ImageLayer {
layer,
@@ -511,7 +504,7 @@ impl Layers {
let layer_already_found = self.layers.iter().any(|s| s == &layer);
let idx = if layer_already_found {
let idx = self.remove_layer(&layer, camera, proj, tile_fetcher)?;
let idx = self.remove_layer(&layer, camera, proj)?;
idx
} else {
self.layers.len()

View File

@@ -27,7 +27,6 @@ impl<const N: usize> BitVector<N> {
}
}
#[cfg(test)]
mod tests {
use super::BitVector;

View File

@@ -4,7 +4,7 @@ use crate::time::{DeltaTime, Time};
use crate::Abort;
use std::cell::RefCell;
use std::collections::{HashMap, VecDeque};
use std::collections::VecDeque;
use std::rc::Rc;
const MAX_NUM_TILE_FETCHING: usize = 8;
@@ -16,68 +16,25 @@ pub struct TileFetcherQueue {
base_tile_queries: Vec<query::Tile>,
tiles_fetched_time: Time,
num_tiles_fetched: usize,
hips_local_files: HashMap<CreatorDid, HiPSLocalFiles>,
}
#[derive(Debug)]
#[wasm_bindgen]
pub struct HiPSLocalFiles {
paths: Box<[HashMap<u64, web_sys::File>]>,
}
use crate::tile_fetcher::query::Tile;
use crate::HEALPixCell;
use wasm_bindgen::prelude::wasm_bindgen;
use wasm_bindgen::JsValue;
#[wasm_bindgen]
impl HiPSLocalFiles {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
let paths = vec![HashMap::new(); 30].into_boxed_slice();
Self { paths }
}
pub fn insert(&mut self, depth: u8, ipix: u64, file: web_sys::File) {
self.paths[depth as usize].insert(ipix, file);
}
fn get(&self, cell: &HEALPixCell) -> Option<&web_sys::File> {
let d = cell.depth() as usize;
let i = cell.idx();
return self.paths[d].get(&i);
}
}
use crate::renderable::CreatorDid;
impl TileFetcherQueue {
pub fn new() -> Self {
let queries = VecDeque::new();
let base_tile_queries = Vec::new();
let tiles_fetched_time = Time::now();
let num_tiles_fetched = 0;
Self {
queries,
base_tile_queries,
tiles_fetched_time,
num_tiles_fetched,
hips_local_files: HashMap::new(),
}
}
pub fn insert_hips_local_files(&mut self, id: CreatorDid, local_files: HiPSLocalFiles) {
self.hips_local_files.insert(id, local_files);
}
pub fn delete_hips_local_files(&mut self, id: &str) {
self.hips_local_files.remove(id);
}
pub fn clear(&mut self) {
self.queries.clear();
//self.query_set.clear();
}
pub fn append(&mut self, query: query::Tile) {
@@ -115,41 +72,23 @@ impl TileFetcherQueue {
self.num_tiles_fetched
}
fn check_in_file_list(&self, mut query: Tile) -> Result<Tile, JsValue> {
if let Some(files) = self.hips_local_files.get(&query.hips_cdid) {
if let Some(file) = files.get(&query.cell) {
if let Ok(url) = web_sys::Url::create_object_url_with_blob(file.as_ref()) {
// rewrite the url
query.url = url;
Ok(query)
} else {
Err(JsValue::from_str("could not create an url from the tile"))
}
} else {
Ok(query)
}
} else {
Ok(query)
}
}
fn fetch(&mut self, downloader: Rc<RefCell<Downloader>>) {
// Fetch the base tiles with higher priority
while let Some(query) = self.base_tile_queries.pop() {
if let Ok(query) = self.check_in_file_list(query) {
downloader.borrow_mut().fetch(query);
}
//if downloader.fetch(query) {
// The fetch has succeded
//self.num_tiles_fetched += 1;
//}
downloader.borrow_mut().fetch(query);
}
let mut num_fetched_tile = 0;
while num_fetched_tile < MAX_NUM_TILE_FETCHING && !self.queries.is_empty() {
let query = self.queries.pop_back().unwrap_abort();
if let Ok(query) = self.check_in_file_list(query) {
if downloader.borrow_mut().fetch(query) {
// The fetch has succeded
num_fetched_tile += 1;
}
if downloader.borrow_mut().fetch(query) {
// The fetch has succeded
num_fetched_tile += 1;
}
}
@@ -185,23 +124,20 @@ impl TileFetcherQueue {
let hips_fmt = cfg.get_format();
let min_order = cfg.get_min_depth_texture();
for tile_cell in crate::healpix::cell::ALLSKY_HPX_CELLS_D0 {
if let Ok(query) = self.check_in_file_list(query::Tile::new(
tile_cell,
hips_cdid.clone(),
hips_url.clone(),
hips_fmt,
)) {
let dl = downloader.clone();
crate::utils::set_timeout(
move || {
dl.borrow_mut().fetch(query);
},
2_000,
);
}
}
let dl = downloader.clone();
crate::utils::set_timeout(
move || {
for tile_cell in crate::healpix::cell::ALLSKY_HPX_CELLS_D0 {
dl.borrow_mut().fetch(query::Tile::new(
tile_cell,
hips_cdid.clone(),
hips_url.clone(),
hips_fmt,
));
}
},
2_000,
);
}
}
}

View File

@@ -51,7 +51,8 @@ import { Sesame } from "./Sesame.js";
import init, * as module from './../core/pkg';
// Import aladin css inside the project
import aladinCSS from './../css/aladin.css?inline';
import './../css/aladin.css';
///////////////////////////////
/////// Aladin Lite API ///////
@@ -96,32 +97,17 @@ A.aladin = function (divSelector, options) {
} else {
divElement = divSelector;
}
// Associate the CSS inside the div
var cssStyleSheet = document.createElement('style')
cssStyleSheet.classList.add("aladin-css");
cssStyleSheet.innerHTML = aladinCSS;
divElement.appendChild(cssStyleSheet)
return new Aladin(divElement, options);
};
/**
* Creates a HiPS image object
*
* @function
* @name A.HiPS
* @name A.imageHiPS
* @memberof A
* @param {string|FileList|Object} id - Can be: <br/>
* - an http url <br/>
* - a relative path to your HiPS <br/>
* - a special ID pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here} <br/>
* - a dict storing a local HiPS files. This object contains a tile file: hips[order][ipix] = File and refers to the properties file like so: hips["properties"] = File. <br/>
* A javascript FileList pointing to the opened webkit directory is also accepted.
* @param {HiPSOptions} [options] - Options describing the survey
* @returns {HiPS} - A HiPS image object
* @deprecated
* Old method name, use {@link A.HiPS} instead.
*/
A.HiPS = function (id, options) {
A.imageHiPS = function (id, options) {
let url = id;
return Aladin.createImageSurvey(
id,
@@ -134,13 +120,17 @@ A.HiPS = function (id, options) {
}
/**
* Creates a HiPS image object
*
* @function
* @name A.imageHiPS
* @name A.HiPS
* @memberof A
* @deprecated
* Old method name, use {@link A.HiPS} instead.
* @param {string} id - Can be either an `url` that refers to a HiPS.
* Or it can be a "CDS ID" pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}.
* @param {HiPSOptions} [options] - Options describing the survey
* @returns {HiPS} - A HiPS image object
*/
A.imageHiPS = A.HiPS;
A.HiPS = A.imageHiPS;
/**
* Creates a celestial source object with the given coordinates.
@@ -453,19 +443,17 @@ A.MOCFromURL = function (url, options, successCallback, errorCallback) {
* @returns {MOC} Returns a new MOC object
*
* @example
* var json = {
* "3": [517],
* "4": [2065,2066,2067,2112,2344,2346,2432],
* "5": [8221,8257,8258,8259,8293,8304,8305,8307,8308,8452,8456,9346,9352,9354,9736],
* "6": [32861,32862,32863,32881,32882,32883,32892,32893,33025,33026,33027,33157,33168,33169,33171,
* var json = {"3":[517],
* "4":[2065,2066,2067,2112,2344,2346,2432],
* "5":[8221,8257,8258,8259,8293,8304,8305,8307,8308,8452,8456,9346,9352,9354,9736],
* "6":[32861,32862,32863,32881,32882,32883,32892,32893,33025,33026,33027,33157,33168,33169,33171,
* 33181,33224,33225,33227,33236,33240,33812,33816,33828,33832,37377,37378,37379,37382,37388,
* 37390,37412,37414,37420,37422,37562,38928,38930,38936,38948,38952],
* "7": [131423,131439,131443,131523,131556,131557,131580,131581,132099,132612,132613,132624,132625,132627,132637,
* "7":[131423,131439,131443,131523,131556,131557,131580,131581,132099,132612,132613,132624,132625,132627,132637,
* 132680,132681,132683,132709,132720,132721,132904,132905,132948,132952,132964,132968,133008,133009,133012,135252,135256,135268,135316,135320,135332,135336,148143,148152,148154,149507,149520
* ,149522,149523,149652,149654,149660,149662,149684,149686,149692,149694,149695,150120,150122,150208,150210,150216,150218,150240,150242,150243,155748,155752,155796,155800,155812,155816]
* };
* ,149522,149523,149652,149654,149660,149662,149684,149686,149692,149694,149695,150120,150122,150208,150210,150216,150218,150240,150242,150243,155748,155752,155796,155800,155812,155816]};
* var moc = A.MOCFromJSON(json, {opacity: 0.25, color: 'magenta', lineWidth: 3});
* aladin.addMOC(moc);
* aladin.addMOC(moc);
*/
A.MOCFromJSON = function (jsonMOC, options, successCallback, errorCallback) {
var moc = new MOC(options);
@@ -824,7 +812,6 @@ A.catalogFromSKAORucio = function (target, radiusDegrees, options, successCallba
*
* @example
* const cat = A.catalogFromVizieR('I/311/hip2', 'M 45', 5, {onClick: 'showTable'});
* const cat2 = A.catalogFromVizieR('I/311/hip2', '12 +9', 5, {onClick: 'showTable'});
*/
A.catalogFromVizieR = function (vizCatId, target, radius, options, successCallback, errorCallback) {
options = options || {};
@@ -992,7 +979,7 @@ A.box = function(options) {
}
/**
* Returns Utils object.
* Returns utils object
*
* This contains utilitary methods such as HEALPix basic or projection methods.
*

View File

@@ -1462,7 +1462,7 @@ export let Aladin = (function () {
* @memberof Aladin
*/
Aladin.prototype.removeOverlays = function () {
this.view.removeOverlays();
this.view.removeLayers();
};
/**
@@ -1471,10 +1471,10 @@ export let Aladin = (function () {
* @memberof Aladin
*/
Aladin.prototype.removeLayers = Aladin.prototype.removeOverlays;
/**
* @typedef {MOC|Catalog|ProgressiveCat|GraphicOverlay} Overlay
* @description Possible overlays
*/
/**
* @typedef {MOC|Catalog|ProgressiveCat|GraphicOverlay} Overlay
* @description Possible overlays
*/
/**
* Remove an overlay by its layer name
*
@@ -1482,11 +1482,10 @@ export let Aladin = (function () {
* @param {string|Overlay} overlay - The name of the overlay to remove or the overlay object itself
*/
Aladin.prototype.removeOverlay = function (overlay) {
if(typeof overlay === 'string' || overlay instanceof String) {
if(overlay instanceof String)
this.view.removeOverlayByName(overlay);
} else {
else
this.view.removeOverlay(overlay);
}
};
/**
@@ -1497,6 +1496,10 @@ export let Aladin = (function () {
Aladin.prototype.removeLayer = Aladin.prototype.removeOverlay;
/**
* @deprecated
* Creates and return an image survey (HiPS) object
* Please use {@link A.hiPS} instead for creating a new survey image
*
* @memberof Aladin
* @param {string} id - Mandatory unique identifier for the survey.
* @param {string} [name] - A convinient name for the survey, optional
@@ -1529,6 +1532,10 @@ export let Aladin = (function () {
};
/**
* @deprecated
* Creates and return an image survey (HiPS) object.
* Please use {@link A.hiPS} instead for creating a new survey image
*
* @function createImageSurvey
* @memberof Aladin
* @static
@@ -1647,6 +1654,7 @@ export let Aladin = (function () {
* Please use {@link A.hiPS} instead for creating a new survey image
*
* @memberof Aladin
* @static
* @param {string} id - Can be:
* <ul>
* <li>1. An url that refers to a HiPS.</li>
@@ -1659,8 +1667,7 @@ export let Aladin = (function () {
*/
Aladin.prototype.newImageSurvey = function (id, options) {
// a wrapper on createImageSurvey that aggregates all params in an options object
return this.createImageSurvey(
id,
return this.createImageSurvey(id,
options && options.name,
id,
options && options.cooFrame,
@@ -1741,29 +1748,11 @@ export let Aladin = (function () {
return this.backgroundColor;
};
/**
* Remove an image layer/overlay from the instance
*
* @memberof Aladin
* @param {string|Overlay} item - the overlay object or image layer name to remove
*/
Aladin.prototype.remove = function (item) {
const layers = this.getStackLayers()
let idxToDelete = layers.findIndex(l => l === item);
if (idxToDelete >= 0) {
this.view.removeImageLayer(item);
return;
}
// must be an overlay
this.view.removeOverlay(item)
};
/**
* Remove a specific layer
*
* @memberof Aladin
* @param {string} layer - The name of the layer to remove or the HiPS/Image object
* @param {string} layer - The name of the layer to remove
*/
Aladin.prototype.removeImageLayer = function (layer) {
this.view.removeImageLayer(layer);
@@ -1804,7 +1793,7 @@ export let Aladin = (function () {
* <li>1. An url that refers to a HiPS.</li>
* <li>2. Or it can be a CDS ID that refers to a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}</li>
* <li>3. A {@link HiPS} HiPS object created from {@link A.HiPS}</li>
* <li>4. A {@link Image} FITS/jpeg/png image</li>
* <li>4. A {@link Image} FITS/jped/png image</li>
* </ul>
* @param {string} [layer="overlay"] - A layer name. By default 'overlay' is chosen and it is destined to be plot
* on top the 'base' layer. If the layer is already present in the view, it will be replaced by the new HiPS/FITS image given here.

View File

@@ -28,7 +28,6 @@
*
*****************************************************************************/
import { Aladin } from "./Aladin";
import { Sesame } from "./Sesame";
/**
* @namespace AladinUtils
@@ -146,28 +145,6 @@ export let AladinUtils = {
}
},
/**
* @namespace Sesame
* @memberof AladinUtils
* @description Namespace for Sesame related service.
*/
Sesame: {
/**
* find RA, DEC for any target (object name or position) <br/>
* if successful, callback is called with an object {ra: ra-value, dec: dec-value} <br/>
* if not successful, errorCallback is called
*
* @function
* @memberof AladinUtils.Sesame
* @name resolveAstronomicalName
*
* @param {string} target - object name or position
* @param {Function} callback - if successful, callback is called with an object {ra: <ra-value>, dec: <dec-value>}
* @param {Function} errorCallback - if not successful, errorCallback is called
*/
resolveAstronomicalName: Sesame.getTargetRADec
},
/**
* @deprecated
*

View File

@@ -47,7 +47,7 @@ import { Footprint } from "./Footprint.js";
* @property {string} [name="catalog"] - The name of the catalog.
* @property {string} [color] - The color associated with the catalog.
* @property {number} [sourceSize=8] - The size of the sources in the catalog.
* @property {string|Function|Image|HTMLCanvasElement|HTMLImageElement} [shape="square"] - The shape of the sources (can be, "square", "circle", "plus", "cross", "rhomb", "triangle").
* @property {string|function|Image|HTMLCanvasElement} [shape="square"] - The shape of the sources (can be, "square", "circle", "plus", "cross", "rhomb", "triangle").
* @property {number} [limit] - The maximum number of sources to display.
* @property {string|Function} [onClick] - Whether the source data appears as a table row or a in popup. Can be 'showTable' string, 'showPopup' string or a custom user defined function that handles the click.
* @property {boolean} [readOnly=false] - Whether the catalog is read-only.
@@ -79,9 +79,7 @@ export let Catalog = (function () {
* markerSize: 15,
* shape: "circle",
* limit: 1000,
* onClick: (source) => {
* // handle sources
* },
* onClick: (source) => { /* handle source click * },
* readOnly: true,
* raField: "ra",
* decField: "dec",
@@ -481,17 +479,7 @@ export let Catalog = (function () {
);
};
/**
* Set the shape of the sources
*
* @memberof Catalog
*
* @param {Object} [options] - shape options
* @param {string} [options.color] - the color of the shape
* @param {number} [options.sourceSize] - size of the shape
* @param {string|Function|HTMLImageCanvas|HTMLImageElement} [options.shape="square"] - the type of the shape. Can be square, rhomb, plus, cross, triangle, circle.
* A callback function can also be called that return an HTMLImageElement in function of the source object. A canvas or an image can also be given.
*/
// API
Catalog.prototype.updateShape = function (options) {
options = options || {};
this.color = options.color || this.color || Color.getNextColor();
@@ -536,13 +524,7 @@ export let Catalog = (function () {
this.reportChange();
};
/**
* Add sources to the catalog
*
* @memberof Catalog
*
* @param {Source[]} sources - An array of sources or only one source to add
*/
// API
Catalog.prototype.addSources = function (sources) {
// make sure we have an array and not an individual source
sources = [].concat(sources);
@@ -577,6 +559,17 @@ export let Catalog = (function () {
this.reportChange();
};
/*Catalog.prototype.addFootprints = function(footprintsToAdd) {
footprintsToAdd = [].concat(footprintsToAdd); // make sure we have an array and not an individual footprints
this.footprints = this.footprints.concat(footprintsToAdd);
footprintsToAdd.forEach(f => {
f.setCatalog(this);
})
this.reportChange();
};*/
Catalog.prototype.computeFootprints = function (sources) {
let footprints = [];
@@ -626,14 +619,12 @@ export let Catalog = (function () {
this.showFieldCallback[field] = callback;
};
/**
* Create sources from a 2d array and add them to the catalog
*
* @memberof Catalog
*
* @param {String[]} columnNames - array with names of the columns
* @param {String[][]|number[][]} array - 2D-array, each item being a 1d-array with the same number of items as columnNames
*/
// API
//
// create sources from a 2d array and add them to the catalog
//
// @param columnNames: array with names of the columns
// @array: 2D-array, each item being a 1d-array with the same number of items as columnNames
Catalog.prototype.addSourcesAsArray = function (columnNames, array) {
var fields = [];
for (var colIdx = 0; colIdx < columnNames.length; colIdx++) {
@@ -675,13 +666,7 @@ export let Catalog = (function () {
this.addSources(newSources);
};
/**
* Get all the sources
*
* @memberof Catalog
*
* @returns {Source[]} - an array of all the sources in the catalog object
*/
// return the current list of Source objects
Catalog.prototype.getSources = function () {
return this.sources;
};
@@ -690,11 +675,7 @@ export let Catalog = (function () {
return this.footprints;
};
/**
* Select all the source catalog
*
* @memberof Catalog
*/
// TODO : fonction générique traversant la liste des sources
Catalog.prototype.selectAll = function () {
if (!this.sources) {
return;
@@ -705,11 +686,6 @@ export let Catalog = (function () {
}
};
/**
* Unselect all the source of the catalog
*
* @memberof Catalog
*/
Catalog.prototype.deselectAll = function () {
if (!this.sources) {
return;
@@ -720,15 +696,7 @@ export let Catalog = (function () {
}
};
/**
* Get one source by its index in the catalog
*
* @memberof Catalog
*
* @param {number} idx - the index of the source in the catalog sources
*
* @returns {Source} - the source at the index
*/
// return a source by index
Catalog.prototype.getSource = function (idx) {
if (idx < this.sources.length) {
return this.sources[idx];
@@ -746,86 +714,37 @@ export let Catalog = (function () {
this.reportChange();
};
/**
* Set the color of the catalog
*
* @memberof Catalog
*
* @param {String} - the new color
*/
Catalog.prototype.setColor = function (color) {
this.color = color;
this.updateShape();
};
/**
* Set the color of selected sources
*
* @memberof Catalog
*
* @param {String} - the new color
*/
Catalog.prototype.setSelectionColor = function (color) {
this.selectionColor = color;
this.updateShape();
};
/**
* Set the color of hovered sources
*
* @memberof Catalog
*
* @param {String} - the new color
*/
Catalog.prototype.setHoverColor = function (color) {
this.hoverColor = color;
this.updateShape();
};
/**
* Set the size of the catalog sources
*
* @memberof Catalog
*
* @param {number} - the new size
*/
Catalog.prototype.setSourceSize = function (sourceSize) {
// will be discarded in updateShape if the shape is an Image
this.sourceSize = sourceSize;
this.updateShape();
};
/**
* Set the color of the catalog
*
* @memberof Catalog
*
* @param {string|Function|HTMLImageCanvas|HTMLImageElement} [shape="square"] - the type of the shape. Can be square, rhomb, plus, cross, triangle, circle.
* A callback function can also be called that return an HTMLImageElement in function of the source object. A canvas or an image can also be given.
*/
Catalog.prototype.setShape = function (shape) {
this.shape = shape;
this.updateShape();
};
/**
* Get the size of the catalog sources
*
* @memberof Catalog
*
* @returns {number} - the size of the sources
*/
Catalog.prototype.getSourceSize = function () {
return this.sourceSize;
};
/**
* Remove a specific source from the catalog
*
* @memberof Catalog
*
* @param {Source} - the source to remove
*/
// remove a source
Catalog.prototype.remove = function (source) {
var idx = this.sources.indexOf(source);
if (idx < 0) {
@@ -843,19 +762,12 @@ export let Catalog = (function () {
this.reportChange();
};
/**
* Clear all the sources from the catalog
*
* @memberof Catalog
*/
Catalog.prototype.removeAll = Catalog.prototype.clear = function () {
// TODO : RAZ de l'index
this.sources = [];
this.ra = [];
this.dec = [];
this.footprints = [];
this.reportChange();
};
Catalog.prototype.draw = function (ctx, width, height) {
@@ -1001,11 +913,6 @@ export let Catalog = (function () {
this.view && this.view.requestRedraw();
};
/**
* Show the catalog
*
* @memberof Catalog
*/
Catalog.prototype.show = function () {
if (this.isShowing) {
return;
@@ -1019,11 +926,6 @@ export let Catalog = (function () {
this.reportChange();
};
/**
* Hide the catalog
*
* @memberof Catalog
*/
Catalog.prototype.hide = function () {
if (!this.isShowing) {
return;

View File

@@ -28,7 +28,7 @@
import { ALEvent } from "./events/ALEvent.js";
import { ColorCfg } from "./ColorCfg.js";
import { HiPSProperties } from "./HiPSProperties.js";
import { Aladin } from "./Aladin.js";
let PropertyParser = {};
// Utilitary functions for parsing the properties and giving default values
/// Mandatory tileSize property
@@ -153,12 +153,6 @@ PropertyParser.isPlanetaryBody = function (properties) {
* @property {number} [brightness=0.0] - The brightness value for the color configuration.
* @property {number} [contrast=0.0] - The contrast value for the color configuration.
*/
/**
* @typedef {Object} FileList
*
* JS {@link https://developer.mozilla.org/fr/docs/Web/API/FileList| FileList} API type
*/
export let HiPS = (function () {
/**
* The object describing an image survey
@@ -167,12 +161,10 @@ export let HiPS = (function () {
* @constructs HiPS
*
* @param {string} id - Mandatory unique identifier for the layer. Can be an arbitrary name
* @param {string|FileList|Object} location - Can be:
* @param {string} location - Can be:
* - an http url <br/>
* - a relative path to your HiPS <br/>
* - a special ID pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here} <br/>
* - a dict storing a local HiPS. This object contains a tile file: hips[order][ipix] = File and refers to the properties file like so: hips["properties"] = File. <br/>
* A javascript FileList pointing to the opened webkit directory is also accepted.
* - a special ID pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}
* @param {HiPSOptions} [options] - The option for the survey
*
* @description Giving a CDS ID will do a query to the MOCServer first to retrieve metadata. Then it will also check for the presence of faster HiPS nodes to choose a faster url to query to tiles from.
@@ -186,30 +178,6 @@ export let HiPS = (function () {
this.name = (options && options.name) || undefined;
this.startUrl = options.startUrl;
if (location instanceof FileList) {
let files = {};
for (var file of location) {
let path = file.webkitRelativePath;
if (path.includes("Norder") && path.includes("Npix")) {
const order = +path.substring(path.indexOf("Norder") + 6).split("/")[0];
if (!files[order]) {
files[order] = {}
}
const ipix = +path.substring(path.indexOf("Npix") + 4).split(".")[0];
files[order][ipix] = file;
}
if (path.includes("properties")) {
files['properties'] = file;
}
}
this.files = files;
} else if (location instanceof Object) {
this.files = location;
}
this.url = location;
this.maxOrder = options.maxOrder;
this.minOrder = options.minOrder || 0;
@@ -434,30 +402,11 @@ export let HiPS = (function () {
}
this.view = view;
if (this.files) {
// Fetch the properties file
self.query = (async () => {
// look for the properties file
await HiPSProperties.fetchFromFile(self.files["properties"])
.then((p) => {
self._parseProperties(p);
self.url = "local";
delete self.files["properties"]
})
return self;
})();
return;
}
let isIncompleteOptions = true;
// This is very dirty but it allows me to differentiate the location from whether it is an ID or a plain url
// This is very dirty but it allows me to differentiate the location from
// whether an ID or a plain url
let isID = this.url.includes("P/") || this.url.includes("C/")
if (this.imgFormat === "fits") {
// a fits is given
isIncompleteOptions = !(
@@ -479,6 +428,7 @@ export let HiPS = (function () {
}
self.query = (async () => {
if (isIncompleteOptions) {
// ID typed url
if (self.startUrl && isID) {
@@ -509,6 +459,8 @@ export let HiPS = (function () {
},
1000
);
} catch (e) {
throw e;
}
@@ -847,7 +799,7 @@ export let HiPS = (function () {
this.layer = layer;
let self = this;
const config = {
this.view.wasm.addHiPS({
layer,
properties: {
creatorDid: self.creatorDid,
@@ -869,24 +821,8 @@ export let HiPS = (function () {
...this.colorCfg.get(),
longitudeReversed: this.longitudeReversed,
imgFormat: this.imgFormat,
}
};
let localFiles;
if (this.files) {
localFiles = new Aladin.wasmLibs.core.HiPSLocalFiles();
for (var order in this.files) {
for (var ipix in this.files[order]) {
const file = this.files[order][ipix];
localFiles.insert(+order, BigInt(+ipix), file)
}
}
}
this.view.wasm.addHiPS(
config,
localFiles
);
},
});
return Promise.resolve(this)
.then((hips) => {

View File

@@ -70,8 +70,6 @@ HiPSProperties.fetchFromID = async function(ID) {
}
HiPSProperties.fetchFromUrl = async function(urlOrId) {
let url;
try {
urlOrId = new URL(urlOrId);
} catch (e) {
@@ -87,7 +85,7 @@ HiPSProperties.fetchFromUrl = async function(urlOrId) {
// Fetch the properties of the survey
const HiPSServiceUrl = urlOrId.toString();
url = HiPSServiceUrl;
let url = HiPSServiceUrl;
// Use the url for retrieving the HiPS properties
// remove final slash
if (url.slice(-1) === '/') {
@@ -100,7 +98,6 @@ HiPSProperties.fetchFromUrl = async function(urlOrId) {
// fix for HTTPS support --> will work for all HiPS served by CDS
url = Utils.fixURLForHTTPS(url)
let init = {};
if (Utils.requestCORSIfNotSameOrigin(url)) {
init = { mode: 'cors' };
@@ -124,9 +121,7 @@ HiPSProperties.fetchFromUrl = async function(urlOrId) {
if (!metadata.hips_frame || !metadata.hips_order) {
reject('Bad properties: do not contain the mandatory frame or order info')
} else {
if (!("hips_service_url" in metadata)) {
metadata.hips_service_url = HiPSServiceUrl;
}
metadata.hips_service_url = HiPSServiceUrl;
resolve(metadata);
}
} else {
@@ -138,27 +133,6 @@ HiPSProperties.fetchFromUrl = async function(urlOrId) {
return result;
}
HiPSProperties.fetchFromFile = function(file) {
let url = URL.createObjectURL(file);
return fetch(url)
.then((response) => response.text())
.then(
(response) => new Promise((resolve, reject) => {
// We get the property here
let metadata = HiPSDefinition.parseHiPSProperties(response);
URL.revokeObjectURL(url)
// 1. Ensure there is exactly one survey matching
if (metadata && Object.keys(metadata).length > 0) {
resolve(metadata)
} else {
reject('No surveys matching at this url: ' + rootURL);
}
})
);
}
HiPSProperties.getFasterMirrorUrl = function (metadata) {
const pingHiPSServiceUrl = async (baseUrl) => {
baseUrl = Utils.fixURLForHTTPS(baseUrl);

View File

@@ -134,7 +134,7 @@ export let MOC = (function() {
if (data instanceof ArrayBuffer) {
// from an url
const buf = data;
self.view.wasm.addFITSMOC(self.mocParams, new Uint8Array(buf));
self.view.wasm.addFITSMoc(self.mocParams, new Uint8Array(buf));
} else if(data.ra && data.dec && data.radius) {
// circle
const c = data;

View File

@@ -62,18 +62,16 @@ export let Sesame = (function() {
// ask resolution by Sesame
else {
Sesame.resolve(target,
function(data) { // success callback
callback({
ra: data.coo.jradeg,
dec: data.coo.jdedeg
});
},
function(data) { // success callback
callback({ra: data.Target.Resolver.jradeg,
dec: data.Target.Resolver.jdedeg});
},
function(data) { // error callback
if (errorCallback) {
errorCallback(data);
}
}
function(data) { // error callback
if (errorCallback) {
errorCallback();
}
}
);
}
};

View File

@@ -126,7 +126,7 @@ export let View = (function () {
this.aladinDiv.ondragover = Utils.dragOverHandler;
this.throttledPositionChanged = Utils.throttle(
(dragging) => {
() => {
var posChangedFn = this.aladin.callbacksByEventName && this.aladin.callbacksByEventName['positionChanged'];
if (typeof posChangedFn === 'function') {
var pos = this.aladin.pix2world(this.width / 2, this.height / 2, 'icrs');
@@ -135,7 +135,7 @@ export let View = (function () {
posChangedFn({
ra: pos[0],
dec: pos[1],
dragging: dragging
dragging: true
});
} catch(e) {
console.error(e)
@@ -841,9 +841,6 @@ export let View = (function () {
if (wasDragging) {
view.realDragging = false;
// call the positionChanged once more with a dragging = false
view.throttledPositionChanged(false);
}
} // end of "if (view.dragging) ... "
@@ -1012,6 +1009,11 @@ export let View = (function () {
view.updateObjectsLookup();
}
/*if (!view.dragging || Utils.hasTouchScreen()) {
// update location box
view.updateLocation({mouseX: xymouse.x, mouseY: xymouse.y});
}*/
if (!view.dragging && !view.moving && view.mode === View.PAN) {
// call listener of 'mouseMove' event
var onMouseMoveFunction = view.aladin.callbacksByEventName['mouseMove'];
@@ -1125,7 +1127,7 @@ export let View = (function () {
ALEvent.POSITION_CHANGED.dispatchedTo(view.aladin.aladinDiv, view.viewCenter);
// Apply position changed callback after the move
view.throttledPositionChanged(true);
view.throttledPositionChanged();
}
}); //// endof mousemove ////
@@ -1148,6 +1150,7 @@ export let View = (function () {
view.zoom.stopAnimation();
}, 100);
const xymouse = Utils.relMouseCoords(e);
view.xy = xymouse
ALEvent.CANVAS_EVENT.dispatchedTo(view.aladinDiv, {
@@ -1291,25 +1294,33 @@ export let View = (function () {
const now = performance.now();
const elapsedTime = now - this.then;
this.dt = elapsedTime;
// If enough time has elapsed, draw the next frame
//if (elapsedTime >= View.FPS_INTERVAL) {
// Get ready for next frame by setting then=now, but also adjust for your
// specified fpsInterval not being a multiple of RAF's interval (16.7ms)
//if (this.dt > 10)
// console.log(this.dt)
// Drawing code
//try {
this.moving = this.wasm.update(elapsedTime);
// inertia run throttled position
if (this.moving && this.aladin.callbacksByEventName && this.aladin.callbacksByEventName['positionChanged'] && this.wasm.isInerting()) {
// run the trottled position
this.throttledPositionChanged();
}
this.moving = this.wasm.update(elapsedTime);
// inertia run throttled position
if (this.moving && this.aladin.callbacksByEventName && this.aladin.callbacksByEventName['positionChanged'] && this.wasm.isInerting()) {
// run the trottled position
this.throttledPositionChanged(false);
}
////// 2. Draw catalogues////////
const isViewRendering = this.wasm.isRendering();
if (isViewRendering || this.needRedraw) {
this.drawAllOverlays();
}
this.needRedraw = false;
////// 2. Draw catalogues////////
const isViewRendering = this.wasm.isRendering();
if (isViewRendering || this.needRedraw) {
this.drawAllOverlays();
}
this.needRedraw = false;
this.then = now;
//this.then = now % View.FPS_INTERVAL;
requestAnimFrame(this.redrawClbk);
this.then = now;
//this.then = now % View.FPS_INTERVAL;
requestAnimFrame(this.redrawClbk);
//}
};
View.prototype.drawAllOverlays = function () {
@@ -2009,7 +2020,7 @@ export let View = (function () {
var self = this;
setTimeout(function () { self.refreshProgressiveCats(); }, 1000);
// Apply position changed callback after the move
self.throttledPositionChanged(false);
self.throttledPositionChanged();
// hide the popup if it is open
this.aladin.hidePopup();
@@ -2036,7 +2047,7 @@ export let View = (function () {
return false;
};
View.prototype.removeOverlays = function () {
View.prototype.removeLayers = function () {
this.catalogs = [];
this.overlays = [];
this.mocs = [];
@@ -2052,11 +2063,6 @@ export let View = (function () {
View.prototype.removeOverlay = function (overlay) {
let indexToDelete = this.allOverlayLayers.indexOf(overlay);
if (indexToDelete === -1) {
// overlay not found
return;
}
this.allOverlayLayers.splice(indexToDelete, 1);
if (overlay.type == 'catalog' || overlay.type == 'progressivecat') {
@@ -2085,12 +2091,12 @@ export let View = (function () {
};
View.prototype.removeOverlayByName = function (overlayName) {
let overlay = this.allOverlayLayers.find(o => o.name === overlayName);
if (!overlay) {
console.error(`Overlay "${overlayName}" not found.`);
let layer = this.allOverlayLayers.find(l => l.name === overlayName);
if (!layer) {
console.error(`Layer with name "${overlayName}" not found.`);
return;
}
this.removeOverlay(overlay);
this.removeOverlay(layer);
};
View.prototype.add = function(overlay) {

View File

@@ -580,8 +580,7 @@ export class OverlayStackBox extends Box {
// Center the view around the new fits object
self.aladin.gotoRaDec(ra, dec);
self.aladin.setFoV(fov * 1.1);
URL.revokeObjectURL(url);
//self.aladin.selectLayer(image.layer);
}
);
@@ -591,31 +590,6 @@ export class OverlayStackBox extends Box {
);
},
}),
ContextMenu.webkitDir({
label: "Load local HiPS",
action(files) {
let id = files[0].webkitRelativePath.split("/")[0];
let name = id;
let hips = self.aladin.createImageSurvey(
id,
name,
files,
null,
null,
{
errorCallback: (e) => {
aladin.addStatusBarMessage({
duration: 2000,
type: 'info',
message: 'Could not add the local HiPS',
})
}
}
)
self.aladin.addNewImageLayer(hips);
},
}),
],
tooltip: {
content: "Add a HiPS or an FITS image",
@@ -794,7 +768,7 @@ export class OverlayStackBox extends Box {
);
layout = layout.concat(this._createSurveysList());
return Layout.vertical({ layout });
return Layout.vertical({ layout, classList: ["content"] });
}
_createOverlaysList() {

View File

@@ -407,36 +407,4 @@ export class ContextMenu extends DOMElement {
}
}
}
static webkitDir(itemOptions) {
return {
...itemOptions,
label: {
icon: {
monochrome: true,
tooltip: {content: 'Load a local file from your computer.<br \>Accept ' + itemOptions.accept + ' files'},
url: uploadIconUrl,
cssStyle: {
cursor: 'help',
}
},
content: itemOptions.label
},
action(e) {
let webkitDirLoader = document.createElement('input');
webkitDirLoader.type = 'file';
webkitDirLoader.webkitdirectory = true;
webkitDirLoader.multiple = true;
// Case: The user is loading a FITS file
webkitDirLoader.addEventListener("change", (e) => {
if (itemOptions.action) {
itemOptions.action(e.target.files)
}
});
webkitDirLoader.click();
}
}
}
}

View File

@@ -10,7 +10,7 @@ import wasmPack from 'vite-plugin-wasm-pack';
// To include and minify glsl into the bundle
import glsl from 'vite-plugin-glsl';
// To include css into the bundle
//import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
export default defineConfig({
build: {
@@ -38,6 +38,7 @@ export default defineConfig({
glsl({
compress: true,
}),
cssInjectedByJsPlugin(),
],
resolve: {
alias: [