mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-12 07:40:26 -08:00
Refac and fix UI and cooFrame problems, add API doc too
This commit is contained in:
@@ -2,6 +2,14 @@
|
||||
|
||||
## 3.3.0
|
||||
|
||||
* [fixed] A.on('select') (debugged from ipyaladin)
|
||||
* [fixed] Simbad pointer in galactical frame, cone search of simbad/vizier cats/other cone search services in galactical frame and MOC creation from selection in galactical frame => there is now a new `frame` optional param to Aladin.pix2world. If not given, the coo returned are in the frame of the view.
|
||||
* [doc] Add doc for image survey definition
|
||||
* [deprecation] A.createImageSurvey/A.newImageSurvey are now deprecated (but still in the API). Please use `A.imageHiPS` instead by providing a valid url or CDS ID conformed to <https://aladin.cds.unistra.fr/hips/list>
|
||||
* [refac] Simplify the instanciation of an imageHiPS/ imageFITS. Add a `A.imageHiPS` method for defining a HiPS object
|
||||
* [fixed] At initialisation, giving a fov > 180 was clamped back to 180 even if we specify allsky projection (i.e. accepting fov > 180). This is now fixed.
|
||||
* [fixed] MeasurementTable now display the full cell values (no ellipsis anymore)
|
||||
* [fixed] aladin.on('select') has been implemented. Callback is triggered on a circle and rect selections for not on polygonal selection.
|
||||
* [fixed] the cooFrame UI selector is updated if the user calls `aladin.setFrame`
|
||||
* [fixed] `reticleColor` and `reticleSize` options in the public API
|
||||
* Restore setFoVRange
|
||||
|
||||
@@ -11,6 +11,7 @@ Aladin Lite is built to be easily embeddable in any web page. It powers astronom
|
||||
More details on [Aladin Lite documentation page](http://aladin.u-strasbg.fr/AladinLite/doc/).
|
||||
|
||||
[](https://github.com/cds-astro/aladin-lite/actions/workflows/test.yml)
|
||||
[](https://cds-astro.github.io/aladin-lite)
|
||||
|
||||
# How to test it ?
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
A.init.then(() => {
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 70,projection: "AIT"});
|
||||
|
||||
//let hsc = aladin.newImageSurvey("P/HSC/DR2/deep/g", {colormap:"Purples", imgFormat: "fits"});
|
||||
//aladin.setBaseImageLayer(hsc);
|
||||
let hsc = aladin.newImageSurvey("P/HSC/DR2/deep/g", {colormap:"Purples", imgFormat: "fits"});
|
||||
aladin.setBaseImageLayer(hsc);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -252,13 +252,13 @@
|
||||
aladin.addCatalog(hipsCats['constellations-boundaries']);
|
||||
aladin.addCatalog(hipsCats['gaia']);
|
||||
|
||||
|
||||
var coronelliStars = {
|
||||
'coronelli-stars-white': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/white.xml", {name: 'Coronelli white', color: '#ffffff', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-yellow': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/yellow.xml", {name: 'Coronelli yellow', color: '#f6f874', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-red': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/red.xml", {name: 'Coronelli red', color: '#ff5555', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-blue': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/blue.xml", {name: 'Coronelli blue', color: '#1ca5ec', shape: 'rhomb', sourceSize: 10})
|
||||
'coronelli-stars-white': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/white.xml", {name: 'Coronelli white', color: '#ffffff', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-yellow': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/yellow.xml", {name: 'Coronelli yellow', color: '#f6f874', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-red': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/red.xml", {name: 'Coronelli red', color: '#ff5555', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-blue': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/blue.xml", {name: 'Coronelli blue', color: '#1ca5ec', shape: 'rhomb', sourceSize: 20})
|
||||
};
|
||||
|
||||
coronelliStars['coronelli-stars-white'].hide();
|
||||
coronelliStars['coronelli-stars-yellow'].hide();
|
||||
coronelliStars['coronelli-stars-red'].hide();
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
aladin.addStatusBarMessage({
|
||||
duration: 10000,
|
||||
type: 'info',
|
||||
message: 'Aladin Lite v3.3 is out. New features available:<ul><li>New Button, Box objects</li><li>Polygonal, circular selection</li></ul>'
|
||||
message: 'Aladin Lite v3.3 is out. New features available:<ul><li>New Button, Box <b>objects</b></li><li>Polygonal, circular selection</li></ul>'
|
||||
})
|
||||
});
|
||||
</script>
|
||||
@@ -94,6 +94,11 @@
|
||||
|
||||
background-color: pink;
|
||||
}
|
||||
|
||||
.aladin-cooFrame {
|
||||
position: absolute;
|
||||
top: 10rem;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
}, // no optional params
|
||||
(ra, dec, fov, image) => {
|
||||
// ra, dec and fov are centered around the fits image
|
||||
console.log("jjj", image)
|
||||
image.setColormap("magma", {stretch: "asinh"});
|
||||
|
||||
aladin.gotoRaDec(ra, dec);
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
showContextMenu: true,
|
||||
fullScreen: true,
|
||||
showSimbadPointerControl: true,
|
||||
showSimbadPointerControl: false,
|
||||
showShareControl: true,
|
||||
showSettingsControl: true,
|
||||
showStackLayerControl: true,
|
||||
samp: true,
|
||||
});
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: 'http://alasky.cds.unistra.fr/ancillary/GaiaDR2/hips-density-map/', showProjectionControl: true, showContextMenu: true, showStatusBar: true, fullScreen: true, target: 'galactic center'});
|
||||
|
||||
const fluxMap = aladin.createImageSurvey('gdr3-color-flux-map', 'Gaia DR3 flux map', 'https://alasky.u-strasbg.fr/ancillary/GaiaEDR3/color-Rp-G-Bp-flux-map', 'equatorial', 7);
|
||||
const densityMap = aladin.createImageSurvey('gdr3-density-map', 'Gaia DR3 density map', 'sdfsg', 'equatorial', 7, {imgFormat: 'fits'});
|
||||
const decaps = aladin.createImageSurvey("decaps", "DECaPS DR1", "http://alasky.u-strasbg.fr/DECaPS/DR1/color/", "equatorial", 11, {imgFormat: 'png'});
|
||||
const panstarrs = aladin.createImageSurvey("panstarrs", "PanSTARRS", "http://alasky.u-strasbg.fr/Pan-STARRS/DR1/color-i-r-g/", "equatorial", 11, {imgFormat: 'jpg'});
|
||||
const densityMap = aladin.createImageSurvey('gdr3-density-map', 'Gaia DR3 density map', 'sdfsg', 'equatorial', 7, {formats: ['fits']});
|
||||
const decaps = aladin.createImageSurvey("decaps", "DECaPS DR1", "http://alasky.u-strasbg.fr/DECaPS/DR1/color/", "equatorial", 11, {formats: ['png'], tileSize: 512});
|
||||
const panstarrs = aladin.createImageSurvey("panstarrs", "PanSTARRS", "http://alasky.u-strasbg.fr/Pan-STARRS/DR1/color-i-r-g/", "equatorial", 11, {formats: ['jpg']});
|
||||
|
||||
aladin.setOverlayImageLayer(fluxMap)
|
||||
aladin.setOverlayImageLayer(densityMap, "density")
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
var aladin;
|
||||
console.log("jkjkjk")
|
||||
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin(
|
||||
'#aladin-lite-div',
|
||||
@@ -29,7 +31,7 @@
|
||||
showZoomControl: true,
|
||||
showContextMenu: true,
|
||||
showCooGridControl: true,
|
||||
showSimbadPointerControl: true,
|
||||
//showSimbadPointerControl: true,
|
||||
showFullscreenControl: true,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<script>var aladin;</script>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {fullScreen: true, survey: ['P/DM/vizMine', 'P/HST/GOODS/color', 'P/MATLAS/g'], target: '0 0', showProjectionControl: true, showCooGrid: true, fov: 180});
|
||||
aladin = A.aladin('#aladin-lite-div', {projection: 'MOL', fullScreen: true, fov: 360, survey: ['P/DM/vizMine', 'P/HST/GOODS/color', 'P/MATLAS/g'], target: '0 0', showProjectionControl: true, showSettingsControl: true, showCooGrid: true});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
27
examples/al-no-properties.html
Normal file
27
examples/al-no-properties.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 70,projection: "AIT"});
|
||||
|
||||
aladin.setOverlayImageLayer(A.imageHiPS(
|
||||
'Fermi',
|
||||
"https://alasky.cds.unistra.fr/Fermi/Color",
|
||||
{
|
||||
name: "Fermi color",
|
||||
maxOrder: 3,
|
||||
imgFormat: 'jpeg',
|
||||
tileSize: 512,
|
||||
cooFrame: 'equatorial'
|
||||
}
|
||||
));
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -43,10 +43,9 @@ pub struct HiPSProperties {
|
||||
// Associated with the HiPS
|
||||
url: String,
|
||||
max_order: u8,
|
||||
frame: CooSystem,
|
||||
coo_frame: CooSystem,
|
||||
tile_size: i32,
|
||||
formats: Vec<ImageExt>,
|
||||
dataproduct_subtype: Option<Vec<String>>,
|
||||
|
||||
is_planetary_body: Option<bool>,
|
||||
|
||||
@@ -103,7 +102,7 @@ impl HiPSProperties {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_frame(&self) -> CooSystem {
|
||||
self.frame
|
||||
self.coo_frame
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -125,11 +124,6 @@ impl HiPSProperties {
|
||||
pub fn get_initial_dec(&self) -> Option<f64> {
|
||||
self.hips_initial_dec
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_dataproduct_subtype(&self) -> &Option<Vec<String>> {
|
||||
&self.dataproduct_subtype
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
||||
@@ -4,10 +4,10 @@ pub mod uv;
|
||||
|
||||
use al_api::hips::ImageExt;
|
||||
use al_api::hips::ImageMetadata;
|
||||
|
||||
use al_core::colormap::Colormap;
|
||||
use al_core::colormap::Colormaps;
|
||||
use al_core::image::format::ChannelType;
|
||||
use al_core::image::format::ImageFormatType;
|
||||
use al_core::image::Image;
|
||||
use al_core::log::console_log;
|
||||
use al_core::shader::Shader;
|
||||
@@ -282,9 +282,7 @@ pub fn get_raster_shader<'a>(
|
||||
shaders: &'a mut ShaderManager,
|
||||
config: &HiPSConfig,
|
||||
) -> Result<&'a Shader, JsValue> {
|
||||
let colored_hips = config.is_colored();
|
||||
|
||||
if colored_hips && cmap.label() == "native" {
|
||||
if config.get_format().is_colored() && cmap.label() == "native" {
|
||||
crate::shader::get_shader(gl, shaders, "RasterizerVS", "RasterizerColorFS")
|
||||
} else {
|
||||
if config.tex_storing_unsigned_int {
|
||||
@@ -318,8 +316,8 @@ pub fn get_raytracer_shader<'a>(
|
||||
shaders: &'a mut ShaderManager,
|
||||
config: &HiPSConfig,
|
||||
) -> Result<&'a Shader, JsValue> {
|
||||
let colored_hips = config.is_colored();
|
||||
if colored_hips && cmap.label() == "native" {
|
||||
//let colored_hips = config.is_colored();
|
||||
if config.get_format().is_colored() && cmap.label() == "native" {
|
||||
crate::shader::get_shader(gl, shaders, "RayTracerVS", "RayTracerColorFS")
|
||||
} else {
|
||||
if config.tex_storing_unsigned_int {
|
||||
|
||||
@@ -168,8 +168,8 @@ pub struct HiPSConfig {
|
||||
pub frame: CooSystem,
|
||||
pub bitpix: Option<i32>,
|
||||
format: ImageFormatType,
|
||||
dataproduct_subtype: Option<Vec<String>>,
|
||||
colored: bool,
|
||||
//dataproduct_subtype: Option<Vec<String>>,
|
||||
//colored: bool,
|
||||
pub creator_did: String,
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ impl HiPSConfig {
|
||||
}),
|
||||
}?;
|
||||
|
||||
let dataproduct_subtype = properties.get_dataproduct_subtype().clone();
|
||||
/*let dataproduct_subtype = properties.get_dataproduct_subtype().clone();
|
||||
let colored = if tex_storing_fits {
|
||||
false
|
||||
} else {
|
||||
@@ -281,7 +281,7 @@ impl HiPSConfig {
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
};*/
|
||||
|
||||
let empty_image = EmptyTileImage::new(tile_size, format.get_channel());
|
||||
|
||||
@@ -341,8 +341,8 @@ impl HiPSConfig {
|
||||
bitpix,
|
||||
format,
|
||||
tile_size,
|
||||
dataproduct_subtype,
|
||||
colored,
|
||||
//dataproduct_subtype,
|
||||
//colored,
|
||||
};
|
||||
|
||||
Ok(hips_config)
|
||||
@@ -421,7 +421,7 @@ impl HiPSConfig {
|
||||
self.empty_image = EmptyTileImage::new(self.tile_size, self.format.get_channel());
|
||||
|
||||
// Recompute if the survey will be colored or not
|
||||
self.colored = if self.tex_storing_fits {
|
||||
/*self.colored = if self.tex_storing_fits {
|
||||
false
|
||||
} else {
|
||||
if let Some(subtypes) = &self.dataproduct_subtype {
|
||||
@@ -429,7 +429,7 @@ impl HiPSConfig {
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
};*/
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -528,7 +528,7 @@ impl HiPSConfig {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_colored(&self) -> bool {
|
||||
self.colored
|
||||
self.format.is_colored()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
||||
@@ -80,7 +80,7 @@ body { overscroll-behavior: contain; }
|
||||
|
||||
display: block;
|
||||
|
||||
max-height: 33vh;
|
||||
max-height: 30vh;
|
||||
max-width: 100%;
|
||||
-ms-overflow-style: none;
|
||||
overscroll-behavior-x: none;
|
||||
@@ -150,8 +150,8 @@ body { overscroll-behavior: contain; }
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
max-width: 150px;
|
||||
text-overflow: ellipsis;
|
||||
/*max-width: 150px;
|
||||
text-overflow: ellipsis;*/
|
||||
}
|
||||
|
||||
.aladin-measurement-div table td.aladin-text-td-container {
|
||||
@@ -159,8 +159,8 @@ body { overscroll-behavior: contain; }
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
max-width: 150px;
|
||||
text-overflow: ellipsis;
|
||||
/*max-width: 150px;
|
||||
text-overflow: ellipsis;*/
|
||||
}
|
||||
|
||||
.aladin-measurement-div table td.aladin-href-td-container:hover {
|
||||
@@ -464,10 +464,12 @@ canvas {
|
||||
}
|
||||
|
||||
.aladin-input-text.search.aladin-unknownObject {
|
||||
-webkit-box-shadow:inset 0px 0px 0px 3px #f00;
|
||||
-moz-box-shadow:inset 0px 0px 0px 3px #f00;
|
||||
box-shadow:inset 0px 0px 0px 3px #f00;
|
||||
}
|
||||
-webkit-box-shadow:inset 0px 0px 0px 1px #f00;
|
||||
-moz-box-shadow:inset 0px 0px 0px 1px #f00;
|
||||
box-shadow:inset 0px 0px 0px 1px #f00;
|
||||
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.aladin-dark-theme {
|
||||
color: white;
|
||||
@@ -654,10 +656,14 @@ canvas {
|
||||
.aladin-status-bar-message {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
max-width: 300px;
|
||||
text-wrap: nowrap;
|
||||
-ms-overflow-style: none;
|
||||
overscroll-behavior-x: none;
|
||||
overflow-y: scroll;
|
||||
scrollbar-width: none;
|
||||
|
||||
max-width: 30rem;
|
||||
|
||||
font-size: 1rem;
|
||||
}
|
||||
@@ -988,6 +994,7 @@ canvas {
|
||||
border-radius: 2px;
|
||||
|
||||
top:0%;
|
||||
left:0%;
|
||||
|
||||
z-index: 100;
|
||||
|
||||
|
||||
40
src/js/A.js
40
src/js/A.js
@@ -87,6 +87,7 @@ let A = {};
|
||||
*/
|
||||
A.aladin = function (divSelector, options) {
|
||||
let divElement;
|
||||
|
||||
if (!(divSelector instanceof HTMLElement)) {
|
||||
divElement = document.querySelector(divSelector)
|
||||
} else {
|
||||
@@ -95,6 +96,45 @@ A.aladin = function (divSelector, options) {
|
||||
return new Aladin(divElement, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a HiPS image object
|
||||
*
|
||||
* @function
|
||||
* @name A.imageHiPS
|
||||
* @memberof A
|
||||
* @param {string} id - Mandatory unique identifier for the layer.
|
||||
* @param {string} url - Can be 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 {ImageSurveyOptions} [options] - Options describing the survey
|
||||
* @returns {ImageSurvey} - A HiPS image object
|
||||
*/
|
||||
A.imageHiPS = function (id, url, options) {
|
||||
return Aladin.createImageSurvey(
|
||||
id,
|
||||
options && options.name,
|
||||
url,
|
||||
options && options.cooFrame,
|
||||
options && options.maxOrder,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a celestial source object with the given coordinates.
|
||||
*
|
||||
* @function
|
||||
* @name A.imageFITS
|
||||
* @memberof A
|
||||
* @param {string} url - Options describing the fits file. An url is mandatory
|
||||
* @param {ImageFITSOptions} [options] - Options describing the fits file. An url is mandatory
|
||||
* @returns {ImageSurvey} - A HiPS image object
|
||||
* @example
|
||||
* const sourceObj = A.source(180.0, 30.0, data, options);
|
||||
*/
|
||||
A.imageFITS = function (url, options) {
|
||||
return Aladin.createImageFITS(url, options.name, options, options.successCallback, options.errorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a celestial source object with the given coordinates.
|
||||
*
|
||||
|
||||
215
src/js/Aladin.js
215
src/js/Aladin.js
@@ -56,14 +56,11 @@ import { Location } from "./gui/Location.js";
|
||||
import { FoV } from "./gui/FoV.js";
|
||||
import { ShareActionButton } from "./gui/Button/ShareView.js";
|
||||
import { ContextMenu } from "./gui/Widgets/ContextMenu.js";
|
||||
import { Input } from "./gui/Widgets/Input.js";
|
||||
import { Popup } from "./Popup.js";
|
||||
import A from "./A.js";
|
||||
import { StatusBarBox } from "./gui/Box/StatusBarBox.js";
|
||||
import { FullScreenActionButton } from "./gui/Button/FullScreen.js";
|
||||
import { ProjectionActionButton } from "./gui/Button/Projection.js";
|
||||
import { Toolbar } from './gui/Widgets/Toolbar';
|
||||
import { ImageLayer } from './ImageLayer';
|
||||
|
||||
// features
|
||||
import { SettingsButton } from "./gui/Button/Settings";
|
||||
@@ -80,7 +77,7 @@ import { CooFrame } from './gui/Input/CooFrame';
|
||||
* @property {string[]} [surveyUrl=["https://alaskybis.unistra.fr/DSS/DSSColor", "https://alasky.unistra.fr/DSS/DSSColor"]]
|
||||
* Array of URLs for the survey images. This replaces the survey parameter.
|
||||
* @property {string} [target="0 +0"] - Target coordinates for the initial view.
|
||||
* @property {string} [cooFrame="J2000"] - Coordinate frame.
|
||||
* @property {CooFrame} [cooFrame="J2000"] - Coordinate frame.
|
||||
* @property {number} [fov=60] - Field of view in degrees.
|
||||
* @property {string} [backgroundColor="rgb(60, 60, 60)"] - Background color in RGB format.
|
||||
*
|
||||
@@ -130,13 +127,18 @@ import { CooFrame } from './gui/Input/CooFrame';
|
||||
* @property {boolean} [gridOptions.showLabels=true] - Whether the grid has labels.
|
||||
* @property {number} [gridOptions.labelSize=15] - The font size of the labels.
|
||||
*
|
||||
* @property {string} [projection="SIN"] - Projection type.
|
||||
* @property {string} [projection="SIN"] - Projection type. Can be 'SIN' for orthographic, 'MOL' for mollweide, 'AIT' for hammer-aitoff, 'ZEA' for zenital equal-area or 'MER' for mercator
|
||||
* @property {boolean} [log=true] - Whether to log events.
|
||||
* @property {boolean} [samp=false] - Whether to enable SAMP (Simple Application Messaging Protocol).
|
||||
* @property {boolean} [realFullscreen=false] - Whether to use real fullscreen mode.
|
||||
* @property {boolean} [pixelateCanvas=true] - Whether to pixelate the canvas.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {string} CooFrame
|
||||
* String with possible values: 'equatorial', 'ICRS', 'ICRSd', 'j2000', 'gal, 'galactic'
|
||||
*/
|
||||
|
||||
export let Aladin = (function () {
|
||||
/**
|
||||
* Creates an instance of the Aladin interactive sky atlas.
|
||||
@@ -214,11 +216,9 @@ export let Aladin = (function () {
|
||||
// parent div
|
||||
aladinDiv.classList.add("aladin-container");
|
||||
|
||||
// measurement table
|
||||
// Init the measurement table
|
||||
this.measurementTable = new MeasurementTable(this);
|
||||
|
||||
//var location = new Location(locationDiv.find('.aladin-location-text'));
|
||||
|
||||
// set different options
|
||||
// Reticle
|
||||
this.view = new View(this);
|
||||
@@ -229,7 +229,6 @@ export let Aladin = (function () {
|
||||
this.reticle = new Reticle(this.options, this);
|
||||
this.popup = new Popup(this.aladinDiv, this.view);
|
||||
|
||||
this.cacheSurveys = new Map();
|
||||
this.ui = [];
|
||||
|
||||
// Background color
|
||||
@@ -249,10 +248,6 @@ export let Aladin = (function () {
|
||||
}
|
||||
this.setCooGrid(gridOptions);
|
||||
|
||||
// Set the projection
|
||||
let projection = (options && options.projection) || 'SIN';
|
||||
this.setProjection(projection)
|
||||
|
||||
this.gotoObject(options.target, undefined);
|
||||
|
||||
if (options.log) {
|
||||
@@ -279,12 +274,14 @@ export let Aladin = (function () {
|
||||
i++;
|
||||
});
|
||||
} else if (options.survey === ImageSurvey.DEFAULT_SURVEY_ID) {
|
||||
const survey = ImageSurvey.fromLayerOptions(this, ImageLayer.DEFAULT_SURVEY);
|
||||
// DSS is cached inside ImageSurvey class, no need to provide any further information
|
||||
const survey = this.createImageSurvey(ImageSurvey.DEFAULT_SURVEY_ID);
|
||||
|
||||
this.setBaseImageLayer(survey);
|
||||
} else {
|
||||
this.setBaseImageLayer(options.survey)
|
||||
}
|
||||
} else if (options.surveyUrl) {
|
||||
} else {
|
||||
// Add the image layers
|
||||
// For that we check the survey key of options
|
||||
// It can be given as a single string or an array of strings
|
||||
@@ -301,9 +298,6 @@ export let Aladin = (function () {
|
||||
}
|
||||
|
||||
this.setBaseImageLayer(url);
|
||||
} else {
|
||||
// This case should not happen because if there is no survey given
|
||||
// then the surveyUrl pointing to the DSS is given.
|
||||
}
|
||||
|
||||
this.view.showCatalog(options.showCatalog);
|
||||
@@ -348,11 +342,7 @@ export let Aladin = (function () {
|
||||
|
||||
// Status bar
|
||||
if (options.showStatusBar) {
|
||||
let statusBarOptions = {};
|
||||
if (typeof options.showStatusBar === "object") {
|
||||
statusBarOptions = options.showStatusBar;
|
||||
}
|
||||
this.statusBar = new StatusBarBox(this, statusBarOptions);
|
||||
this.statusBar = new StatusBarBox(this);
|
||||
this.addUI(this.statusBar)
|
||||
}
|
||||
|
||||
@@ -853,7 +843,7 @@ export let Aladin = (function () {
|
||||
}
|
||||
// planetary case
|
||||
else {
|
||||
const body = baseImageLayer.properties.hipsBody;
|
||||
const body = baseImageLayer.hipsBody;
|
||||
PlanetaryFeaturesNameResolver.resolve(targetName, body,
|
||||
function (data) { // success callback
|
||||
self.view.pointTo(data.lon, data.lat);
|
||||
@@ -1179,29 +1169,51 @@ export let Aladin = (function () {
|
||||
this.view.removeLayer(layer);
|
||||
};
|
||||
|
||||
// @oldAPI
|
||||
Aladin.prototype.createImageSurvey = function(id, name, rootUrl, cooFrame, maxOrder, options = {}) {
|
||||
let cfg = this.cacheSurveys.get(id);
|
||||
if (!cfg) {
|
||||
// Add the cooFrame and maxOrder given by the user
|
||||
// to the list of options passed to the ImageSurvey constructor
|
||||
if (cooFrame) {
|
||||
options.cooFrame = cooFrame;
|
||||
}
|
||||
/**
|
||||
* @deprecated
|
||||
* Creates and return an image survey (HiPS) object
|
||||
*
|
||||
* @memberof Aladin
|
||||
* @param {string} id - Mandatory unique identifier for the layer.
|
||||
* @param {string} [name] - A convinient name for the survey, optional
|
||||
* @param {string} url - Can be 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 {string} [cooFrame] - Values accepted: 'equatorial', 'icrs', 'icrsd', 'j2000', 'gal', 'galactic'
|
||||
* @param {number} [maxOrder] - The maximum HEALPix order of the HiPS, i.e the HEALPix order of the most refined tile images of the HiPS.
|
||||
* @param {ImageSurveyOptions} [options] - Options describing the survey
|
||||
* @returns {ImageSurvey} A HiPS image object.
|
||||
*/
|
||||
Aladin.prototype.createImageSurvey = function(id, name, url, cooFrame, maxOrder, options) {
|
||||
let surveyOptions = ImageSurvey.cache[id];
|
||||
|
||||
if (maxOrder) {
|
||||
options.maxOrder = maxOrder;
|
||||
}
|
||||
|
||||
cfg = {id, name, rootUrl, options};
|
||||
this.cacheSurveys.set(id, cfg);
|
||||
} else {
|
||||
cfg = Utils.clone(cfg)
|
||||
if (!surveyOptions) {
|
||||
surveyOptions = {url, name, maxOrder, cooFrame, ...options};
|
||||
ImageSurvey.cache[id] = surveyOptions;
|
||||
}
|
||||
return new ImageSurvey(cfg.id, cfg.name, cfg.rootUrl, cfg.options, this.view);
|
||||
|
||||
return new ImageSurvey(id, surveyOptions.url, surveyOptions);
|
||||
};
|
||||
|
||||
Aladin.prototype.createImageFITS = function(url, name, options = {}, successCallback = undefined, errorCallback = undefined) {
|
||||
/**
|
||||
* @deprecated
|
||||
* Creates and return an image survey (HiPS) object
|
||||
*
|
||||
* @function createImageSurvey
|
||||
* @memberof Aladin
|
||||
* @static
|
||||
* @param {string} id - Mandatory unique identifier for the layer.
|
||||
* @param {string} [name] - A convinient name for the survey, optional
|
||||
* @param {string} url - Can be 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 {string} [cooFrame] - Values accepted: 'equatorial', 'icrs', 'icrsd', 'j2000', 'gal', 'galactic'
|
||||
* @param {number} [maxOrder] - The maximum HEALPix order of the HiPS, i.e the HEALPix order of the most refined tile images of the HiPS.
|
||||
* @param {ImageSurveyOptions} [options] - Options describing the survey
|
||||
* @returns {ImageSurvey} A HiPS image object.
|
||||
*/
|
||||
Aladin.createImageSurvey = Aladin.prototype.createImageSurvey;
|
||||
|
||||
|
||||
Aladin.prototype.createImageFITS = function(url, name, options, successCallback, errorCallback) {
|
||||
try {
|
||||
url = new URL(url);
|
||||
} catch(e) {
|
||||
@@ -1213,30 +1225,53 @@ export let Aladin = (function () {
|
||||
// Do not use proxy with CORS headers until we solve that: https://github.com/MattiasBuelens/wasm-streams/issues/20
|
||||
//url = Utils.handleCORSNotSameOrigin(url);
|
||||
|
||||
let cfg = this.cacheSurveys.get(url);
|
||||
if (!cfg) {
|
||||
cfg = {url, name, options, successCallback, errorCallback}
|
||||
this.cacheSurveys.set(url, cfg);
|
||||
} else {
|
||||
cfg = Utils.clone(cfg)
|
||||
let image = ImageFITS.cache[url];
|
||||
if (!image) {
|
||||
image = new ImageFITS(url, name, options, successCallback, errorCallback)
|
||||
ImageFITS.cache[url] = image;
|
||||
}
|
||||
|
||||
return new ImageFITS(cfg.url, cfg.name, this.view, cfg.options, cfg.successCallback, cfg.errorCallback);
|
||||
return image;
|
||||
};
|
||||
|
||||
Aladin.prototype.newImageSurvey = function(rootUrlOrId, options) {
|
||||
const idOrUrl = rootUrlOrId;
|
||||
// Check if the survey has already been added
|
||||
// Create a new ImageSurvey
|
||||
const name = idOrUrl;
|
||||
/**
|
||||
* Creates a FITS image object
|
||||
*
|
||||
* @function createImageFITS
|
||||
* @memberof Aladin
|
||||
* @static
|
||||
* @param {string} url - The url of the fits.
|
||||
* @param {string} [name] - The url of the fits.
|
||||
* @param {ImageSurveyOptions} [options] - Options for rendering the image
|
||||
* @param {function} [success] - A success callback
|
||||
* @param {function} [error] - A success callback
|
||||
* @returns {ImageSurvey} A FITS image object.
|
||||
*/
|
||||
Aladin.createImageFITS = Aladin.prototype.createImageFITS;
|
||||
|
||||
return this.createImageSurvey(idOrUrl, name, idOrUrl, null, null, options);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Create a new layer from an url or CDS ID.
|
||||
*
|
||||
* @memberof Aladin
|
||||
* @static
|
||||
* @param {string} url - Can be 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 {ImageSurveyOptions} [options] - Options for rendering the image
|
||||
* @param {function} [success] - A success callback
|
||||
* @param {function} [error] - A success callback
|
||||
* @returns {ImageSurvey} A FITS image object.
|
||||
*/
|
||||
Aladin.prototype.newImageSurvey = function(url, options) {
|
||||
const id = url;
|
||||
return A.imageHiPS(id, url, options);
|
||||
}
|
||||
|
||||
Aladin.prototype.addNewImageLayer = function() {
|
||||
let layerName = Utils.uuidv4();
|
||||
// A HIPS_LAYER_ADDED will be called after the hips is added to the view
|
||||
this.setOverlayImageLayer('CDS/P/DSS2/color', layerName);
|
||||
this.setOverlayImageLayer(ImageSurvey.DEFAULT_SURVEY_ID, layerName);
|
||||
}
|
||||
|
||||
// @param imageSurvey : ImageSurvey object or image survey identifier
|
||||
@@ -1273,8 +1308,8 @@ export let Aladin = (function () {
|
||||
};
|
||||
|
||||
|
||||
Aladin.prototype.setBaseImageLayer = function(idOrSurvey) {
|
||||
return this.setOverlayImageLayer(idOrSurvey, "base");
|
||||
Aladin.prototype.setBaseImageLayer = function(idOrUrlOrImageLayer) {
|
||||
return this.setOverlayImageLayer(idOrUrlOrImageLayer, "base");
|
||||
};
|
||||
|
||||
// @api
|
||||
@@ -1288,26 +1323,9 @@ export let Aladin = (function () {
|
||||
// 1. User gives an ID
|
||||
if (typeof idOrUrlOrImageLayer === "string") {
|
||||
const idOrUrl = idOrUrlOrImageLayer;
|
||||
// Check if the survey has already been added
|
||||
// Create a new ImageSurvey
|
||||
/*let isUrl = false;
|
||||
if (idOrUrl.includes("http")) {
|
||||
isUrl = true;
|
||||
}
|
||||
const name = idOrUrl;
|
||||
|
||||
if (isUrl) {
|
||||
const url = idOrUrl;
|
||||
const id = url;
|
||||
// Url
|
||||
imageLayer = this.createImageSurvey(idOrUrl, name, idOrUrl, null, null);
|
||||
} else {
|
||||
const id = idOrUrl;
|
||||
// ID
|
||||
imageLayer = this.createImageSurvey(idOrUrl, name, idOrUrl, null, null);
|
||||
}*/
|
||||
const name = idOrUrl;
|
||||
imageLayer = this.createImageSurvey(idOrUrl, name, idOrUrl, null, null);
|
||||
imageLayer = A.imageHiPS(idOrUrl, idOrUrl);
|
||||
|
||||
// 2. User gives a non resolved promise
|
||||
} else {
|
||||
imageLayer = idOrUrlOrImageLayer;
|
||||
@@ -1457,11 +1475,6 @@ export let Aladin = (function () {
|
||||
Aladin.prototype.select = async function (mode = 'rect', callback) {
|
||||
await this.reticle.loaded;
|
||||
|
||||
// Default callback selects objects
|
||||
callback = callback || ((selection) => {
|
||||
this.view.selectObjects(selection);
|
||||
});
|
||||
|
||||
this.fire('selectstart', {mode, callback});
|
||||
};
|
||||
|
||||
@@ -1635,7 +1648,7 @@ export let Aladin = (function () {
|
||||
let radecsys;
|
||||
|
||||
if (this.getBaseImageLayer().isPlanetaryBody()) {
|
||||
const body = this.getBaseImageLayer().properties.hipsBody
|
||||
const body = this.getBaseImageLayer().hipsBody
|
||||
if (body in solarSystemObjects) {
|
||||
cooType1 = `${solarSystemObjects[body]}LN-`;
|
||||
cooType2 = `${solarSystemObjects[body]}LT-`;
|
||||
@@ -1715,13 +1728,29 @@ export let Aladin = (function () {
|
||||
* @memberof Aladin
|
||||
* @param {number} x - The x-coordinate in pixel coordinates.
|
||||
* @param {number} y - The y-coordinate in pixel coordinates.
|
||||
* @param {CooFrame} [frame] - The frame in which we want to retrieve the coordinates.
|
||||
* If not given, the frame chosen is the one from the view
|
||||
*
|
||||
* @returns {number[]} - An array representing the [Right Ascension, Declination] coordinates in degrees.
|
||||
* @returns {number[]} - An array representing the [Right Ascension, Declination] coordinates in degrees in the `frame`.
|
||||
* If not specified, returns the coo in the frame of the current view.
|
||||
*
|
||||
* @throws {Error} Throws an error if an issue occurs during the transformation.
|
||||
*/
|
||||
Aladin.prototype.pix2world = function (x, y) {
|
||||
const [ra, dec] = this.view.wasm.screenToWorld(x, y);
|
||||
Aladin.prototype.pix2world = function (x, y, frame) {
|
||||
let radec = this.view.wasm.screenToWorld(x, y);
|
||||
|
||||
frame = frame || this.view.cooFrame.label;
|
||||
frame = CooFrameEnum.fromString(frame, CooFrameEnum.J2000);
|
||||
|
||||
if (frame !== this.view.cooFrame) {
|
||||
if (frame.label === 'Galactic') {
|
||||
console.warn('Conversion from icrs to galactic not yet impl')
|
||||
} else {
|
||||
radec = this.view.wasm.viewToICRSCooSys(radec[0], radec[1]);
|
||||
}
|
||||
}
|
||||
|
||||
let [ra, dec] = radec;
|
||||
|
||||
if (ra < 0) {
|
||||
return [ra + 360.0, dec];
|
||||
@@ -1734,8 +1763,8 @@ export let Aladin = (function () {
|
||||
* Transform world coordinates to pixel coordinates in the view.
|
||||
*
|
||||
* @memberof Aladin
|
||||
* @param {number} ra - The Right Ascension (RA) coordinate in degrees.
|
||||
* @param {number} dec - The Declination (Dec) coordinate in degrees.
|
||||
* @param {number} ra - The Right Ascension (RA) coordinate in degrees. Frame considered is the current view frame
|
||||
* @param {number} dec - The Declination (Dec) coordinate in degrees. Frame considered is the current view frame
|
||||
*
|
||||
* @returns {number[]} - An array representing the [x, y] coordinates in pixel coordinates in the view.
|
||||
*
|
||||
@@ -1753,14 +1782,16 @@ export let Aladin = (function () {
|
||||
* @param {number} y1 - The y-coordinate of the first pixel coordinates.
|
||||
* @param {number} x2 - The x-coordinate of the second pixel coordinates.
|
||||
* @param {number} y2 - The y-coordinate of the second pixel coordinates.
|
||||
* @param {CooFrame} [frame] - The frame in which we want to retrieve the coordinates.
|
||||
* If not given, the frame chosen is the one from the view
|
||||
*
|
||||
* @returns {number} - The angular distance between the two pixel coordinates in degrees
|
||||
*
|
||||
* @throws {Error} Throws an error if an issue occurs during the transformation.
|
||||
*/
|
||||
Aladin.prototype.angularDist = function (x1, y1, x2, y2) {
|
||||
const [ra1, dec1] = this.pix2world(x1, y1);
|
||||
const [ra2, dec2] = this.pix2world(x2, y2);
|
||||
Aladin.prototype.angularDist = function (x1, y1, x2, y2, frame) {
|
||||
const [ra1, dec1] = this.pix2world(x1, y1, frame);
|
||||
const [ra2, dec2] = this.pix2world(x2, y2, frame);
|
||||
|
||||
return this.wasm.angularDist(ra1, dec1, ra2, dec2);
|
||||
};
|
||||
|
||||
@@ -55,7 +55,6 @@ export let Catalog = (function() {
|
||||
* @param {string} [options.name="catalog"] - The name of the catalog.
|
||||
* @param {string} [options.color] - The color associated with the catalog.
|
||||
* @param {number} [options.sourceSize=8] - The size of the sources in the catalog.
|
||||
* @param {number} [options.markerSize=12] - The size of the markers associated with sources.
|
||||
* @param {string} [options.shape="square"] - The shape of the sources (can be, "square", "circle", "plus", "cross", "rhomb", "triangle").
|
||||
* @param {number} [options.limit] - The maximum number of sources to display.
|
||||
* @param {function} [options.onClick] - The callback function to execute on a source click.
|
||||
|
||||
@@ -222,7 +222,31 @@
|
||||
return [this.minCut, this.maxCut];
|
||||
};
|
||||
|
||||
ColorCfg.COLORMAPS = [];
|
||||
ColorCfg.COLORMAPS = [
|
||||
"blues",
|
||||
"cividis",
|
||||
"cubehelix",
|
||||
"eosb",
|
||||
"grayscale",
|
||||
"inferno",
|
||||
"magma",
|
||||
"native",
|
||||
"parula",
|
||||
"plasma",
|
||||
"rainbow",
|
||||
"rdbu",
|
||||
"rdylbu",
|
||||
"redtemperature",
|
||||
"sinebow",
|
||||
"spectral",
|
||||
"summer",
|
||||
"viridis",
|
||||
"ylgnbu",
|
||||
"ylorbr",
|
||||
"red",
|
||||
"green",
|
||||
"blue"
|
||||
];
|
||||
|
||||
return ColorCfg;
|
||||
})();
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
// Copyright 2013 - UDS/CNRS
|
||||
// The Aladin Lite program is distributed under the terms
|
||||
// of the GNU General Public License version 3.
|
||||
//
|
||||
// This file is part of Aladin Lite.
|
||||
//
|
||||
// Aladin Lite is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 3 of the License.
|
||||
//
|
||||
// Aladin Lite is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// The GNU General Public License is available in COPYING file
|
||||
// along with Aladin Lite.
|
||||
//
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Aladin Lite project
|
||||
*
|
||||
* File ColorMap.js
|
||||
*
|
||||
* Author: Thomas Boch[CDS]
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
import { AladinUtils } from "./AladinUtils.js";
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.0
|
||||
*/
|
||||
export let ColorMap = (function() {
|
||||
|
||||
|
||||
// constructor
|
||||
let ColorMap = function(view) {
|
||||
this.view = view;
|
||||
this.reversed = false;
|
||||
this.mapName = 'native';
|
||||
this.sig = this.signature();
|
||||
};
|
||||
|
||||
ColorMap.MAPS = {};
|
||||
|
||||
ColorMap.MAPS['eosb'] = {
|
||||
name: 'Eos B',
|
||||
r: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,9,18,27,36,45,49,57,72,81,91,100,109,118,127,
|
||||
136,131,139,163,173,182,191,200,209,218,227,213,221,255,255,255,255,255,
|
||||
255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,
|
||||
255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,
|
||||
255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,
|
||||
229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,
|
||||
255,229,229,255,255,255,255,255,255,255,255,229,229,255,253,251,249,247,
|
||||
245,243,241,215,214,235,234,232,230,228,226,224,222,198,196,216,215,213,
|
||||
211,209,207,205,203,181,179,197,196,194,192,190,188,186,184,164,162,178,
|
||||
176,175,173,171,169,167,165,147,145,159,157,156,154,152,150,148,146,130,
|
||||
128,140,138,137,135,133,131,129,127,113,111,121,119,117,117],
|
||||
g: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,15,23,31,39,47,55,57,64,79,87,95,
|
||||
103,111,119,127,135,129,136,159,167,175,183,191,199,207,215,200,207,239,
|
||||
247,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,
|
||||
229,255,255,255,255,255,255,255,255,229,229,255,250,246,242,238,233,229,
|
||||
225,198,195,212,208,204,199,195,191,187,182,160,156,169,165,161,157,153,
|
||||
148,144,140,122,118,127,125,123,121,119,116,114,112,99,97,106,104,102,
|
||||
99,97,95,93,91,80,78,84,82,80,78,76,74,72,70,61,59,63,61,59,57,55,53,50,
|
||||
48,42,40,42,40,38,36,33,31,29,27,22,21,21,19,16,14,12,13,8,6,3,1,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
b: [116,121,127,131,136,140,144,148,153,
|
||||
157,145,149,170,174,178,182,187,191,195,199,183,187,212,216,221,225,229,
|
||||
233,238,242,221,225,255,247,239,231,223,215,207,199,172,164,175,167,159,
|
||||
151,143,135,127,119,100,93,95,87,79,71,63,55,47,39,28,21,15,7,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0]
|
||||
};
|
||||
ColorMap.MAPS['rainbow'] = {
|
||||
name: 'Rainbow',
|
||||
r: [0,4,9,13,18,22,27,31,36,40,45,50,54,
|
||||
58,61,64,68,69,72,74,77,79,80,82,83,85,84,86,87,88,86,87,87,87,85,84,84,
|
||||
84,83,79,78,77,76,71,70,68,66,60,58,55,53,46,43,40,36,33,25,21,16,12,4,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,12,21,25,29,33,42,
|
||||
46,51,55,63,67,72,76,80,89,93,97,101,110,114,119,123,131,135,140,144,153,
|
||||
157,161,165,169,178,182,187,191,199,203,208,212,221,225,229,233,242,246,
|
||||
250,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255],
|
||||
g: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,4,8,16,21,25,29,38,42,46,51,55,63,67,72,76,84,89,93,97,
|
||||
106,110,114,119,127,131,135,140,144,152,157,161,165,174,178,182,187,195,
|
||||
199,203,208,216,220,225,229,233,242,246,250,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,250,242,238,233,229,221,216,212,208,199,195,191,187,178,174,170,165,
|
||||
161,153,148,144,140,131,127,123,119,110,106,102,97,89,85,80,76,72,63,59,
|
||||
55,51,42,38,34,29,21,17,12,8,0],
|
||||
b: [0,3,7,10,14,19,23,28,32,38,43,48,53,
|
||||
59,63,68,72,77,81,86,91,95,100,104,109,113,118,122,127,132,136,141,145,
|
||||
150,154,159,163,168,173,177,182,186,191,195,200,204,209,214,218,223,227,
|
||||
232,236,241,245,250,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,246,242,238,233,225,220,216,212,203,199,195,191,
|
||||
187,178,174,170,165,157,152,148,144,135,131,127,123,114,110,106,102,97,
|
||||
89,84,80,76,67,63,59,55,46,42,38,34,25,21,16,12,8,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
||||
};
|
||||
ColorMap.MAPS['cubehelix'] = {
|
||||
name: 'Cubehelix',
|
||||
r: [0,1,3,4,6,8,9,10,12,13,14,15,17,18,
|
||||
19,20,20,21,22,23,23,24,24,25,25,25,26,26,26,26,26,26,26,26,26,26,26,25,
|
||||
25,25,25,24,24,24,23,23,23,23,22,22,22,21,21,21,21,21,21,20,20,20,21,21,
|
||||
21,21,21,22,22,22,23,23,24,25,26,27,27,28,30,31,32,33,35,36,38,39,41,43,
|
||||
45,47,49,51,53,55,57,60,62,65,67,70,72,75,78,81,83,86,89,92,95,98,101,104,
|
||||
107,110,113,116,120,123,126,129,132,135,138,141,144,147,150,153,155,158,
|
||||
161,164,166,169,171,174,176,178,181,183,185,187,189,191,193,194,196,198,
|
||||
199,201,202,203,204,205,206,207,208,209,209,210,211,211,211,212,212,212,
|
||||
212,212,212,212,212,211,211,211,210,210,210,209,208,208,207,207,206,205,
|
||||
205,204,203,203,202,201,201,200,199,199,198,197,197,196,196,195,195,194,
|
||||
194,194,193,193,193,193,193,193,193,193,193,193,194,194,195,195,196,196,
|
||||
197,198,199,200,200,202,203,204,205,206,208,209,210,212,213,215,217,218,
|
||||
220,222,223,225,227,229,231,232,234,236,238,240,242,244,245,247,249,251,
|
||||
253,255],
|
||||
g: [0,0,1,1,2,2,3,4,4,5,6,6,7,8,9,10,
|
||||
11,11,12,13,14,15,17,18,19,20,21,22,24,25,26,28,29,31,32,34,35,37,38,40,
|
||||
41,43,45,46,48,50,52,53,55,57,58,60,62,64,66,67,69,71,73,74,76,78,79,81,
|
||||
83,84,86,88,89,91,92,94,95,97,98,99,101,102,103,104,106,107,108,109,110,
|
||||
111,112,113,114,114,115,116,116,117,118,118,119,119,120,120,120,121,121,
|
||||
121,121,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,121,
|
||||
121,121,121,121,121,121,121,121,120,120,120,120,120,120,120,120,120,120,
|
||||
121,121,121,121,121,122,122,122,123,123,124,124,125,125,126,127,127,128,
|
||||
129,130,131,131,132,133,135,136,137,138,139,140,142,143,144,146,147,149,
|
||||
150,152,154,155,157,158,160,162,164,165,167,169,171,172,174,176,178,180,
|
||||
182,183,185,187,189,191,193,194,196,198,200,202,203,205,207,208,210,212,
|
||||
213,215,216,218,219,221,222,224,225,226,228,229,230,231,232,233,235,236,
|
||||
237,238,239,240,240,241,242,243,244,244,245,246,247,247,248,248,249,250,
|
||||
250,251,251,252,252,253,253,254,255],
|
||||
b: [0,1,3,4,6,8,9,11,13,15,17,19,21,23,
|
||||
25,27,29,31,33,35,37,39,41,43,45,47,48,50,52,54,56,57,59,60,62,63,65,66,
|
||||
67,69,70,71,72,73,74,74,75,76,76,77,77,77,78,78,78,78,78,78,78,77,77,77,
|
||||
76,76,75,75,74,73,73,72,71,70,69,68,67,66,66,65,64,63,61,60,59,58,58,57,
|
||||
56,55,54,53,52,51,51,50,49,49,48,48,47,47,47,46,46,46,46,46,47,47,47,48,
|
||||
48,49,50,50,51,52,53,55,56,57,59,60,62,64,65,67,69,71,74,76,78,81,83,86,
|
||||
88,91,94,96,99,102,105,108,111,114,117,120,124,127,130,133,136,140,143,
|
||||
146,149,153,156,159,162,165,169,172,175,178,181,184,186,189,192,195,197,
|
||||
200,203,205,207,210,212,214,216,218,220,222,224,226,227,229,230,231,233,
|
||||
234,235,236,237,238,239,239,240,241,241,242,242,242,243,243,243,243,243,
|
||||
243,243,243,243,243,242,242,242,242,241,241,241,241,240,240,240,239,239,
|
||||
239,239,239,238,238,238,238,238,238,238,238,239,239,239,240,240,240,241,
|
||||
242,242,243,244,245,246,247,248,249,250,252,253,255]
|
||||
};
|
||||
|
||||
|
||||
|
||||
ColorMap.MAPS_CUSTOM = ['cubehelix', 'eosb', 'rainbow'];
|
||||
ColorMap.MAPS_NAMES = ['native', 'grayscale'].concat(ColorMap.MAPS_CUSTOM);
|
||||
|
||||
ColorMap.prototype.reverse = function(val) {
|
||||
if (val) {
|
||||
this.reversed = val;
|
||||
}
|
||||
else {
|
||||
this.reversed = ! this.reversed;
|
||||
}
|
||||
this.sig = this.signature();
|
||||
this.view.requestRedraw();
|
||||
};
|
||||
|
||||
|
||||
ColorMap.prototype.signature = function() {
|
||||
var s = this.mapName;
|
||||
|
||||
if (this.reversed) {
|
||||
s += ' reversed';
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
|
||||
ColorMap.prototype.update = function(mapName) {
|
||||
this.mapName = mapName;
|
||||
this.sig = this.signature();
|
||||
this.view.requestRedraw();
|
||||
};
|
||||
|
||||
ColorMap.prototype.apply = function(img) {
|
||||
if ( this.sig=='native' ) {
|
||||
return img;
|
||||
}
|
||||
|
||||
if (img.cmSig==this.sig) {
|
||||
return img.cmImg; // return cached pixels
|
||||
}
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
var pixelData = imageData.data;
|
||||
var length = pixelData.length;
|
||||
var a, b, c;
|
||||
var switchCase = 3;
|
||||
if (this.mapName=='grayscale') {
|
||||
switchCase = 1;
|
||||
}
|
||||
else if (ColorMap.MAPS_CUSTOM.indexOf(this.mapName)>=0) {
|
||||
switchCase = 2;
|
||||
}
|
||||
for (var i = 0; i < length; i+= 4) {
|
||||
switch(switchCase) {
|
||||
case 1:
|
||||
a = b = c = AladinUtils.myRound((pixelData[i]+pixelData[i+1]+pixelData[i+2])/3);
|
||||
break;
|
||||
case 2:
|
||||
if (this.reversed) {
|
||||
a = ColorMap.MAPS[this.mapName].r[255-pixelData[i]];
|
||||
b = ColorMap.MAPS[this.mapName].g[255-pixelData[i+1]];
|
||||
c = ColorMap.MAPS[this.mapName].b[255-pixelData[i+2]];
|
||||
}
|
||||
else {
|
||||
a = ColorMap.MAPS[this.mapName].r[pixelData[i]];
|
||||
b = ColorMap.MAPS[this.mapName].g[pixelData[i+1]];
|
||||
c = ColorMap.MAPS[this.mapName].b[pixelData[i+2]];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
a = pixelData[i];
|
||||
b = pixelData[i + 1];
|
||||
c = pixelData[i + 2];
|
||||
|
||||
}
|
||||
if (switchCase!=2 && this.reversed) {
|
||||
a = 255-a;
|
||||
b = 255-b;
|
||||
c = 255-c;
|
||||
|
||||
}
|
||||
pixelData[i] = a;
|
||||
pixelData[i + 1] = b;
|
||||
pixelData[i + 2] = c;
|
||||
|
||||
}
|
||||
//imageData.data = pixelData; // not needed, and create an error in strict mode !
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
// cache image with color map applied
|
||||
img.cmSig = this.sig;
|
||||
img.cmImg = canvas;
|
||||
|
||||
return img.cmImg;
|
||||
};
|
||||
|
||||
return ColorMap;
|
||||
})();
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
import { FSM } from "../FiniteStateMachine";
|
||||
import { View } from "../View";
|
||||
import { Selector } from "../Selector";
|
||||
/******************************************************************************
|
||||
* Aladin Lite project
|
||||
*
|
||||
@@ -83,7 +84,8 @@ export class CircleSelect extends FSM {
|
||||
|
||||
x = this.startCoo.x;
|
||||
y = this.startCoo.y;
|
||||
(typeof this.callback === 'function') && this.callback({
|
||||
|
||||
let s = {
|
||||
x, y, r,
|
||||
label: 'circle',
|
||||
contains(s) {
|
||||
@@ -100,21 +102,25 @@ export class CircleSelect extends FSM {
|
||||
h: 2*r
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// execute general callback
|
||||
if (view.aladin.callbacksByEventName) {
|
||||
var callback = view.aladin.callbacksByEventName['select'];
|
||||
if (typeof callback === "function") {
|
||||
let objList = Selector.getObjects(s, view);
|
||||
callback(objList);
|
||||
}
|
||||
}
|
||||
|
||||
// execute selection callback only
|
||||
(typeof this.callback === 'function') && this.callback(s);
|
||||
|
||||
// TODO: remove these modes in the future
|
||||
view.aladin.showReticle(true)
|
||||
view.setCursor('default');
|
||||
console.log("end select", view)
|
||||
|
||||
// execute general callback
|
||||
if (view.callbacksByEventName) {
|
||||
var callback = view.callbacksByEventName['select'];
|
||||
if (typeof callback === "function") {
|
||||
// !todo
|
||||
let selectedObjects = view.selectObjects(this);
|
||||
callback(selectedObjects);
|
||||
}
|
||||
}
|
||||
view.setMode(View.PAN)
|
||||
view.requestRedraw();
|
||||
};
|
||||
|
||||
@@ -163,13 +163,23 @@ export class PolySelect extends FSM {
|
||||
let y = yMin;
|
||||
let w = xMax - xMin;
|
||||
let h = yMax - yMin;
|
||||
(typeof this.callback === 'function') && this.callback({
|
||||
|
||||
let s = {
|
||||
vertices: this.coos,
|
||||
label: 'polygon',
|
||||
bbox() {
|
||||
return {x, y, w, h}
|
||||
}
|
||||
});
|
||||
};
|
||||
(typeof this.callback === 'function') && this.callback(s);
|
||||
|
||||
// execute general callback
|
||||
if (view.aladin.callbacksByEventName) {
|
||||
var callback = view.aladin.callbacksByEventName['select'];
|
||||
if (typeof callback === "function") {
|
||||
console.warn('polygon selection is not fully implemented, PolySelect.contains is needed for finding sources inside a polygon')
|
||||
}
|
||||
}
|
||||
|
||||
this.coos = [];
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
import { FSM } from "../FiniteStateMachine";
|
||||
import { View } from "../View";
|
||||
import { Selector } from "../Selector";
|
||||
/******************************************************************************
|
||||
* Aladin Lite project
|
||||
*
|
||||
@@ -91,7 +92,7 @@ export class RectSelect extends FSM {
|
||||
h = -h;
|
||||
}
|
||||
|
||||
(typeof this.callback === 'function') && this.callback({
|
||||
let s = {
|
||||
x, y, w, h,
|
||||
label: 'rect',
|
||||
contains(s) {
|
||||
@@ -100,21 +101,20 @@ export class RectSelect extends FSM {
|
||||
bbox() {
|
||||
return {x, y, w, h}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
(typeof this.callback === 'function') && this.callback(s);
|
||||
|
||||
// TODO: remove these modes in the future
|
||||
view.aladin.showReticle(true)
|
||||
view.setCursor('default');
|
||||
|
||||
// execute general callback
|
||||
if (view.callbacksByEventName) {
|
||||
var callback = view.callbacksByEventName['select'];
|
||||
if (view.aladin.callbacksByEventName) {
|
||||
var callback = view.aladin.callbacksByEventName['select'];
|
||||
if (typeof callback === "function") {
|
||||
// !todo
|
||||
let selectedObjects = view.selectObjects(this);
|
||||
console.log(selectedObjects)
|
||||
|
||||
callback(selectedObjects);
|
||||
let objList = Selector.getObjects(s, view);
|
||||
callback(objList);
|
||||
}
|
||||
}
|
||||
view.setMode(View.PAN)
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Utils } from './Utils';
|
||||
export let GenericPointer = function (view, e) {
|
||||
const xymouse = Utils.relMouseCoords(e);
|
||||
|
||||
let radec = view.aladin.pix2world(xymouse.x, xymouse.y);
|
||||
let radec = view.aladin.pix2world(xymouse.x, xymouse.y, 'icrs');
|
||||
if (radec) {
|
||||
// sky case
|
||||
if (view.aladin.getBaseImageLayer().isPlanetaryBody() === false) {
|
||||
@@ -23,7 +23,7 @@ export let GenericPointer = function (view, e) {
|
||||
// planetary body case
|
||||
else {
|
||||
// TODO: replace with actual value
|
||||
const body = view.aladin.getBaseImageLayer().properties.hipsBody;
|
||||
const body = view.aladin.getBaseImageLayer().hipsBody;
|
||||
PlanetaryFeaturesPointer.query(radec[0], radec[1], Math.min(80, view.fov / 20.0), body, view.aladin);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -65,7 +65,6 @@ HiPSProperties.fetchFromID = async function(ID) {
|
||||
// Exactly one matching
|
||||
result = metadata[0];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +73,7 @@ HiPSProperties.fetchFromUrl = async function(urlOrId) {
|
||||
try {
|
||||
urlOrId = new URL(urlOrId);
|
||||
} catch (e) {
|
||||
// Relative path
|
||||
// Relative path test
|
||||
try {
|
||||
urlOrId = Utils.getAbsoluteURL(urlOrId)
|
||||
|
||||
|
||||
@@ -29,15 +29,11 @@
|
||||
*****************************************************************************/
|
||||
import { ALEvent } from "./events/ALEvent.js";
|
||||
import { ColorCfg } from "./ColorCfg.js";
|
||||
import { ImageLayer } from "./ImageLayer.js";
|
||||
import { Utils } from "./Utils";
|
||||
|
||||
export let ImageFITS = (function () {
|
||||
|
||||
function ImageFITS(url, name, view, options, successCallback = undefined, errorCallback = undefined) {
|
||||
this.view = view;
|
||||
this.wasm = view.wasm;
|
||||
|
||||
function ImageFITS(url, name, options, successCallback = undefined, errorCallback = undefined) {
|
||||
// Name of the layer
|
||||
this.layer = null;
|
||||
this.added = false;
|
||||
@@ -46,110 +42,102 @@ export let ImageFITS = (function () {
|
||||
this.url = url.toString();
|
||||
|
||||
this.id = url.toString();
|
||||
this.name = name;
|
||||
this.name = name || this.url;
|
||||
|
||||
this.imgFormat = "fits";
|
||||
this.properties = {
|
||||
formats: ["fits"]
|
||||
}
|
||||
this.formats = ["fits"]
|
||||
// callbacks
|
||||
this.successCallback = successCallback;
|
||||
this.errorCallback = errorCallback;
|
||||
// initialize the color meta data here
|
||||
// set a asinh stretch by default if there is none
|
||||
if (options) {
|
||||
/*if (options) {
|
||||
options.stretch = options.stretch || "asinh";
|
||||
}
|
||||
}*/
|
||||
this.colorCfg = new ColorCfg(options);
|
||||
|
||||
let self = this;
|
||||
|
||||
updateMetadata(self);
|
||||
ImageLayer.update(self);
|
||||
|
||||
this.query = Promise.resolve(self);
|
||||
}
|
||||
|
||||
// A cache storing directly the images to not query for the properties each time
|
||||
ImageFITS.cache = {};
|
||||
|
||||
ImageFITS.prototype.setView = function(view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
// @api
|
||||
ImageFITS.prototype.setOpacity = function (opacity) {
|
||||
let self = this;
|
||||
updateMetadata(self, () => {
|
||||
this._updateMetadata(() => {
|
||||
self.colorCfg.setOpacity(opacity);
|
||||
});
|
||||
};
|
||||
|
||||
// @api
|
||||
ImageFITS.prototype.setBlendingConfig = function (additive = false) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg.setBlendingConfig(additive);
|
||||
});
|
||||
};
|
||||
|
||||
// @api
|
||||
ImageFITS.prototype.setColormap = function (colormap, options) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg.setColormap(colormap, options);
|
||||
});
|
||||
}
|
||||
|
||||
// @api
|
||||
ImageFITS.prototype.setCuts = function (lowCut, highCut) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg.setCuts(lowCut, highCut);
|
||||
});
|
||||
};
|
||||
|
||||
// @api
|
||||
ImageFITS.prototype.setGamma = function (gamma) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg.setGamma(gamma);
|
||||
});
|
||||
};
|
||||
|
||||
ImageFITS.prototype.getAvailableFormats = function() {
|
||||
return this.properties.formats;
|
||||
}
|
||||
|
||||
// @api
|
||||
ImageFITS.prototype.setSaturation = function (saturation) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg.setSaturation(saturation);
|
||||
});
|
||||
};
|
||||
|
||||
ImageFITS.prototype.setBrightness = function (brightness) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg.setBrightness(brightness);
|
||||
});
|
||||
};
|
||||
|
||||
ImageFITS.prototype.setContrast = function (contrast) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg.setContrast(contrast);
|
||||
});
|
||||
};
|
||||
|
||||
ImageFITS.prototype.metadata = function () {
|
||||
return {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: false,
|
||||
imgFormat: this.imgFormat
|
||||
};
|
||||
}
|
||||
|
||||
// Private method for updating the view with the new meta
|
||||
var updateMetadata = function (self, callback = undefined) {
|
||||
ImageFITS.prototype._updateMetadata = function (callback) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
|
||||
// Tell the view its meta have changed
|
||||
try {
|
||||
if (self.added) {
|
||||
const metadata = self.metadata();
|
||||
self.wasm.setImageMetadata(self.layer, metadata);
|
||||
|
||||
ALEvent.HIPS_LAYER_CHANGED.dispatchedTo(self.view.aladinDiv, { layer: self });
|
||||
if (this.added) {
|
||||
this.view.wasm.setImageMetadata(this.layer, {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: false,
|
||||
imgFormat: this.imgFormat
|
||||
});
|
||||
ALEvent.HIPS_LAYER_CHANGED.dispatchedTo(this.view.aladinDiv, { layer: this });
|
||||
}
|
||||
} catch (e) {
|
||||
// Display the error message
|
||||
@@ -161,13 +149,19 @@ export let ImageFITS = (function () {
|
||||
this.layer = layer;
|
||||
|
||||
let self = this;
|
||||
const promise = self.wasm.addImageFITS({
|
||||
|
||||
const promise = self.view.wasm.addImageFITS({
|
||||
layer: self.layer,
|
||||
url: self.url,
|
||||
meta: self.metadata()
|
||||
meta: {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: false,
|
||||
imgFormat: this.imgFormat
|
||||
}
|
||||
}).then((imagesParams) => {
|
||||
// There is at least one entry in imageParams
|
||||
self.added = true;
|
||||
|
||||
self.children = [];
|
||||
|
||||
let hduIdx = 0;
|
||||
@@ -176,7 +170,6 @@ export let ImageFITS = (function () {
|
||||
let image = new ImageFITS(
|
||||
imageParams.url,
|
||||
self.name + "_ext_" + hduIdx.toString(),
|
||||
self.view,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
@@ -185,6 +178,7 @@ export let ImageFITS = (function () {
|
||||
// Set the layer corresponding to the onein the backend
|
||||
image.layer = imageParams.layer;
|
||||
image.added = true;
|
||||
image.setView(self.view);
|
||||
// deep copy of the color object of self
|
||||
image.colorCfg = Utils.deepCopy(self.colorCfg);
|
||||
// Set the automatic computed cuts
|
||||
@@ -259,7 +253,7 @@ export let ImageFITS = (function () {
|
||||
ImageFITS.prototype.setAlpha = ImageFITS.prototype.setOpacity;
|
||||
|
||||
ImageFITS.prototype.setColorCfg = function (colorCfg) {
|
||||
updateMetadata(this, () => {
|
||||
this._updateMetadata(() => {
|
||||
this.colorCfg = colorCfg;
|
||||
});
|
||||
};
|
||||
@@ -283,7 +277,7 @@ export let ImageFITS = (function () {
|
||||
|
||||
// @api
|
||||
ImageFITS.prototype.readPixel = function (x, y) {
|
||||
return this.wasm.readPixel(x, y, this.layer);
|
||||
return this.view.wasm.readPixel(x, y, this.layer);
|
||||
};
|
||||
|
||||
return ImageFITS;
|
||||
|
||||
@@ -1,218 +0,0 @@
|
||||
export let ImageLayer = {};
|
||||
|
||||
ImageLayer.update = function (layer) {
|
||||
const foundLayer = ImageLayer.contains(layer.id)
|
||||
|
||||
const options = layer.metadata;
|
||||
// The survey has not been found among the ones cached
|
||||
if (foundLayer) {
|
||||
foundLayer.options = options;
|
||||
} else {
|
||||
ImageLayer.LAYERS.push({
|
||||
id: layer.id,
|
||||
name: layer.name,
|
||||
url: layer.url,
|
||||
options,
|
||||
subtype: layer.subtype,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ImageLayer.contains = function(id) {
|
||||
return ImageLayer.LAYERS.find((layer) => layer.id.endsWith(id));
|
||||
}
|
||||
|
||||
ImageLayer.DEFAULT_SURVEY = {
|
||||
id: "P/DSS2/color",
|
||||
name: "DSS colored",
|
||||
url: "https://alasky.cds.unistra.fr/DSS/DSSColor",
|
||||
maxOrder: 9,
|
||||
subtype: "survey",
|
||||
tileSize: 512,
|
||||
formats: ['jpeg'],
|
||||
creatorDid: "ivo://CDS/P/DSS2/color",
|
||||
dataproductSubtype: ['color'],
|
||||
frame: "ICRS"
|
||||
}
|
||||
|
||||
ImageLayer.LAYERS = [
|
||||
ImageLayer.DEFAULT_SURVEY,
|
||||
{
|
||||
id: "P/2MASS/color",
|
||||
name: "2MASS colored",
|
||||
url: "https://alasky.cds.unistra.fr/2MASS/Color",
|
||||
maxOrder: 9,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/DSS2/red",
|
||||
name: "DSS2 Red (F+R)",
|
||||
url: "https://alasky.cds.unistra.fr/DSS/DSS2Merged",
|
||||
maxOrder: 9,
|
||||
subtype: "survey",
|
||||
// options
|
||||
options: {
|
||||
minCut: 1000.0,
|
||||
maxCut: 10000.0,
|
||||
colormap: "magma",
|
||||
stretch: 'Linear',
|
||||
imgFormat: "fits"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "P/DM/I/350/gaiaedr3",
|
||||
name: "Density map for Gaia EDR3 (I/350/gaiaedr3)",
|
||||
url: "https://alasky.cds.unistra.fr/ancillary/GaiaEDR3/density-map",
|
||||
maxOrder: 7,
|
||||
subtype: "survey",
|
||||
// options
|
||||
options: {
|
||||
minCut: 0,
|
||||
maxCut: 12000,
|
||||
stretch: 'asinh',
|
||||
colormap: "rdylbu",
|
||||
imgFormat: "fits",
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "P/PanSTARRS/DR1/g",
|
||||
name: "PanSTARRS DR1 g",
|
||||
url: "https://alasky.cds.unistra.fr/Pan-STARRS/DR1/g",
|
||||
maxOrder: 11,
|
||||
subtype: "survey",
|
||||
// options
|
||||
options: {
|
||||
minCut: -34,
|
||||
maxCut: 7000,
|
||||
stretch: 'asinh',
|
||||
colormap: "redtemperature",
|
||||
imgFormat: "fits",
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "P/PanSTARRS/DR1/color-z-zg-g",
|
||||
name: "PanSTARRS DR1 color",
|
||||
url: "https://alasky.cds.unistra.fr/Pan-STARRS/DR1/color-z-zg-g",
|
||||
maxOrder: 11,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/DECaPS/DR1/color",
|
||||
name: "DECaPS DR1 color",
|
||||
url: "https://alasky.cds.unistra.fr/DECaPS/DR1/color",
|
||||
maxOrder: 11,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/Fermi/color",
|
||||
name: "Fermi color",
|
||||
url: "https://alasky.cds.unistra.fr/Fermi/Color",
|
||||
maxOrder: 3,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/Finkbeiner",
|
||||
name: "Halpha",
|
||||
url: "https://alasky.cds.unistra.fr/FinkbeinerHalpha",
|
||||
maxOrder: 3,
|
||||
subtype: "survey",
|
||||
// options
|
||||
options: {
|
||||
minCut: -10,
|
||||
maxCut: 800,
|
||||
colormap: "rdbu",
|
||||
imgFormat: "fits",
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "P/GALEXGR6_7/NUV",
|
||||
name: "GALEXGR6_7 NUV",
|
||||
url: "http://alasky.cds.unistra.fr/GALEX/GALEXGR6_7_NUV/",
|
||||
maxOrder: 8,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/IRIS/color",
|
||||
name: "IRIS colored",
|
||||
url: "https://alasky.cds.unistra.fr/IRISColor",
|
||||
maxOrder: 3,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/Mellinger/color",
|
||||
name: "Mellinger colored",
|
||||
url: "https://alasky.cds.unistra.fr/MellingerRGB",
|
||||
maxOrder: 4,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/SDSS9/color",
|
||||
name: "SDSS9 colored",
|
||||
url: "https://alasky.cds.unistra.fr/SDSS/DR9/color",
|
||||
maxOrder: 10,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/SDSS9/g",
|
||||
name: "SDSS9 band-g",
|
||||
url: "https://alasky.cds.unistra.fr/SDSS/DR9/band-g",
|
||||
maxOrder: 10,
|
||||
subtype: "survey",
|
||||
options: {
|
||||
stretch: 'asinh',
|
||||
colormap: "redtemperature",
|
||||
imgFormat: 'fits'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "P/SPITZER/color",
|
||||
name: "IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)",
|
||||
url: "http://alasky.cds.unistra.fr/Spitzer/SpitzerI1I2I4color/",
|
||||
maxOrder: 9,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/VTSS/Ha",
|
||||
name: "VTSS-Ha",
|
||||
url: "https://alasky.cds.unistra.fr/VTSS/Ha",
|
||||
maxOrder: 3,
|
||||
subtype: "survey",
|
||||
options: {
|
||||
minCut: -10.0,
|
||||
maxCut: 100.0,
|
||||
colormap: "grayscale",
|
||||
imgFormat: "fits"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "xcatdb/P/XMM/PN/color",
|
||||
name: "XMM PN colored",
|
||||
url: "https://alasky.cds.unistra.fr/cgi/JSONProxy?url=https://saada.unistra.fr/PNColor",
|
||||
maxOrder: 7,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/allWISE/color",
|
||||
name: "AllWISE color",
|
||||
url: "https://alasky.cds.unistra.fr/AllWISE/RGB-W4-W2-W1/",
|
||||
maxOrder: 8,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/GLIMPSE360",
|
||||
name: "GLIMPSE360",
|
||||
// This domain is not giving the CORS headers
|
||||
// We need to query by with a proxy equipped with CORS header.
|
||||
url: "https://alasky.cds.unistra.fr/cgi/JSONProxy?url=https://www.spitzer.caltech.edu/glimpse360/aladin/data",
|
||||
subtype: "survey",
|
||||
options: {
|
||||
maxOrder: 9,
|
||||
imgFormat: "jpg",
|
||||
minOrder: 3,
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
ImageLayer.getAvailableLayers = function () {
|
||||
return ImageLayer.LAYERS;
|
||||
};
|
||||
@@ -30,14 +30,13 @@
|
||||
import { Utils } from "./Utils";
|
||||
import { ALEvent } from "./events/ALEvent.js";
|
||||
import { ColorCfg } from "./ColorCfg.js";
|
||||
import { ImageLayer } from "./ImageLayer.js";
|
||||
import { HiPSProperties } from "./HiPSProperties.js";
|
||||
|
||||
let PropertyParser = {};
|
||||
// Utilitary functions for parsing the properties and giving default values
|
||||
/// Mandatory tileSize property
|
||||
PropertyParser.tileSize = function(options, properties = {}) {
|
||||
let tileSize = (options && options.tileSize) || (properties.hips_tile_width && (+properties.hips_tile_width)) || 512;
|
||||
PropertyParser.tileSize = function(properties) {
|
||||
let tileSize = (properties && properties.hips_tile_width && (+properties.hips_tile_width)) || 512;
|
||||
|
||||
// Check if the tile width size is a power of 2
|
||||
if (tileSize & (tileSize - 1) !== 0) {
|
||||
@@ -48,35 +47,25 @@ PropertyParser.tileSize = function(options, properties = {}) {
|
||||
}
|
||||
|
||||
/// Mandatory frame property
|
||||
PropertyParser.frame = function(options, properties = {}) {
|
||||
let frame = (options && options.cooFrame) || (properties.hips_body && "ICRSd") || properties.hips_frame;
|
||||
|
||||
if (frame == "ICRS" || frame == "ICRSd" || frame == "equatorial" || frame == "j2000") {
|
||||
frame = "ICRS";
|
||||
} else if (frame == "galactic") {
|
||||
frame = "GAL";
|
||||
} else {
|
||||
frame = "ICRS";
|
||||
console.warn('Invalid cooframe given: ' + cooFrame + '. Coordinate systems supported: "ICRS", "ICRSd", "j2000" or "galactic". ICRS is chosen by default');
|
||||
}
|
||||
|
||||
return frame;
|
||||
PropertyParser.cooFrame = function(properties) {
|
||||
let cooFrame = (properties && properties.hips_body && "ICRSd") || (properties && properties.hips_frame) || "ICRS";
|
||||
return cooFrame;
|
||||
}
|
||||
|
||||
/// Mandatory maxOrder property
|
||||
PropertyParser.maxOrder = function(options, properties = {}) {
|
||||
let maxOrder = (options && options.maxOrder) || (properties.hips_order && (+properties.hips_order));
|
||||
PropertyParser.maxOrder = function(properties) {
|
||||
let maxOrder = properties && properties.hips_order && (+properties.hips_order);
|
||||
return maxOrder;
|
||||
}
|
||||
|
||||
/// Mandatory minOrder property
|
||||
PropertyParser.minOrder = function(options, properties = {}) {
|
||||
const minOrder = (options && options.minOrder) || (properties.hips_order_min && (+properties.hips_order_min)) || 0;
|
||||
PropertyParser.minOrder = function(properties) {
|
||||
const minOrder = (properties && properties.hips_order_min && (+properties.hips_order_min)) || 0;
|
||||
return minOrder;
|
||||
}
|
||||
|
||||
PropertyParser.formats = function(options, properties = {}) {
|
||||
let formats = properties.hips_tile_format || "jpeg";
|
||||
PropertyParser.formats = function(properties) {
|
||||
let formats = properties && properties.hips_tile_format || "jpeg";
|
||||
|
||||
formats = formats.split(' ')
|
||||
.map((fmt) => fmt.toLowerCase());
|
||||
@@ -84,8 +73,8 @@ PropertyParser.formats = function(options, properties = {}) {
|
||||
return formats;
|
||||
}
|
||||
|
||||
PropertyParser.initialFov = function(options, properties = {}) {
|
||||
let initialFov = properties.hips_initial_fov && +properties.hips_initial_fov;
|
||||
PropertyParser.initialFov = function(properties) {
|
||||
let initialFov = properties && properties.hips_initial_fov && (+properties.hips_initial_fov);
|
||||
|
||||
if (initialFov && initialFov < 0.00002777777) {
|
||||
initialFov = 360;
|
||||
@@ -94,13 +83,13 @@ PropertyParser.initialFov = function(options, properties = {}) {
|
||||
return initialFov;
|
||||
}
|
||||
|
||||
PropertyParser.skyFraction = function(options, properties = {}) {
|
||||
const skyFraction = (properties.moc_sky_fraction && (+properties.moc_sky_fraction)) || 0.0;
|
||||
PropertyParser.skyFraction = function(properties) {
|
||||
const skyFraction = (properties && properties.moc_sky_fraction && (+properties.moc_sky_fraction)) || 0.0;
|
||||
return skyFraction;
|
||||
}
|
||||
|
||||
PropertyParser.cutouts = function(options, properties = {}) {
|
||||
let cuts = properties.hips_pixel_cut && properties.hips_pixel_cut.split(" ");
|
||||
PropertyParser.cutouts = function(properties) {
|
||||
let cuts = properties && properties.hips_pixel_cut && properties.hips_pixel_cut.split(" ");
|
||||
|
||||
const minCutout = cuts && parseFloat(cuts[0]);
|
||||
const maxCutout = cuts && parseFloat(cuts[1]);
|
||||
@@ -108,25 +97,32 @@ PropertyParser.cutouts = function(options, properties = {}) {
|
||||
return [minCutout, maxCutout];
|
||||
}
|
||||
|
||||
PropertyParser.bitpix = function(options, properties = {}) {
|
||||
const bitpix = properties.hips_pixel_bitpix && (+properties.hips_pixel_bitpix);
|
||||
PropertyParser.bitpix = function(properties) {
|
||||
const bitpix = properties && properties.hips_pixel_bitpix && (+properties.hips_pixel_bitpix);
|
||||
return bitpix;
|
||||
}
|
||||
|
||||
PropertyParser.dataproductSubtype = function(options, properties = {}) {
|
||||
let dataproductSubtype = properties.dataproduct_subtype || "color";
|
||||
PropertyParser.dataproductSubtype = function(properties) {
|
||||
let dataproductSubtype = (properties && properties.dataproduct_subtype) || "color";
|
||||
dataproductSubtype = dataproductSubtype.split(" ")
|
||||
.map((subtype) => subtype.toLowerCase());
|
||||
return dataproductSubtype;
|
||||
}
|
||||
|
||||
PropertyParser.isPlanetaryBody = function(options, properties = {}) {
|
||||
return properties.hips_body !== undefined;
|
||||
PropertyParser.isPlanetaryBody = function(properties) {
|
||||
return properties && properties.hips_body !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} ImageSurveyOptions
|
||||
*
|
||||
* @property {string} [name] - The name of the survey to be displayed in the UI
|
||||
* @property {string} [imgFormat] - Formats accepted 'webp', 'png', 'jpeg' or 'fits'. Will raise an error if the HiPS does not contain tiles in this format
|
||||
* @property {CooFrame} [cooFrame="J2000"] - Coordinate frame of the survey tiles
|
||||
* @property {number} [maxOrder] - The maximum HEALPix order of the HiPS, i.e the HEALPix order of the most refined tile images of the HiPS.
|
||||
* @property {number} [numBitsPerPixel] - useful if you want to display the FITS tiles of a HiPS. It specifies the number of bits per pixel. Possible values are:
|
||||
* -64: double, -32: float, 8: unsigned byte, 16: short, 32: integer 32 bits, 64: integer 64 bits
|
||||
* @property {number} [tileSize] - The width of the HEALPix tile images. Mostly 512 pixels for can be 256, 128, 64, 32
|
||||
* @property {number} [opacity=1.0] - Opacity of the survey or image (value between 0 and 1).
|
||||
* @property {string} [colormap="native"] - The colormap configuration for the survey or image.
|
||||
* @property {string} [stretch="linear"] - The stretch configuration for the survey or image.
|
||||
@@ -138,12 +134,9 @@ PropertyParser.isPlanetaryBody = function(options, properties = {}) {
|
||||
* @property {number} [saturation=0.0] - The saturation value for the color configuration.
|
||||
* @property {number} [brightness=0.0] - The brightness value for the color configuration.
|
||||
* @property {number} [contrast=0.0] - The contrast value for the color configuration.
|
||||
* @property {number} [maxOrder] - If not given, retrieved from the properties of the survey.
|
||||
* @property {number} [minOrder] - If not given, retrieved from the properties of the survey.
|
||||
* @property {boolean} [longitudeReversed=false] - Set it to True for planetary survey visualization
|
||||
* @property {string} [imgFormat] - If not given, look into the properties to see the accepted format. The format is chosen from WEBP > PNG > JPEG > FITS (in this importance order).
|
||||
* @property {string} [cooFrame] - If not given, look into the properties. If it is a planet, then ICRS is chosen, otherwise its hips_frame key is read. If no value is found in the properties, ICRS is chosen by default.
|
||||
*/
|
||||
*/
|
||||
export let ImageSurvey = (function () {
|
||||
/**
|
||||
* The object describing an image survey
|
||||
@@ -151,36 +144,57 @@ export let ImageSurvey = (function () {
|
||||
* @class
|
||||
* @constructs ImageSurvey
|
||||
*
|
||||
* @param {string} [id] - Optional, a uniq id for the survey. See {@link https://aladin.cds.unistra.fr/hips/list|here} for the list of IDs.
|
||||
* Keep in mind that it is better to directly provide an url as it will not request our mocserver first to get final survey tiles retrieval url.
|
||||
* @param {string} [name] - The name of the survey to be displayed in the UI
|
||||
* @param {string} url - The url where the survey is located. Check the hips list {@link https://aladin.cds.unistra.fr/hips/list|here} for the valid survey urls to display.
|
||||
* @param {string} id - Mandatory unique identifier for the layer.
|
||||
* Can be an arbitrary name
|
||||
* @param {string} url - Can be an url to the survey or a "CDS" ID pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}
|
||||
* @param {ImageSurveyOptions} [options] - The option for the survey
|
||||
*
|
||||
* @description Prefer provide an url better than an id. If both are given, the url will be requested first for the survey data.
|
||||
* @description For the `url` param, prefer provide an url better than an CDS ID. Giving a CDS ID will do a query to the mocserver more but will also check for the presence of faster HiPS nodes.
|
||||
*/
|
||||
function ImageSurvey(id, name, url, options, view) {
|
||||
this.view = view;
|
||||
function ImageSurvey(id, url, options) {
|
||||
this.added = false;
|
||||
// Unique identifier for a survey
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.name = options.name || id || url;
|
||||
this.subtype = "survey";
|
||||
|
||||
this.properties = options.properties || {};
|
||||
this.url = url;
|
||||
this.maxOrder = options.maxOrder;
|
||||
this.minOrder = options.minOrder || 0;
|
||||
this.cooFrame = options.cooFrame;
|
||||
this.tileSize = options.tileSize;
|
||||
this.longitudeReversed = options.longitudeReversed === undefined ? false : options.longitudeReversed;
|
||||
this.imgFormat = options.imgFormat;
|
||||
this.numBitsPerPixel = options.numBitsPerPixel;
|
||||
this.creatorDid = options.creatorDid;
|
||||
|
||||
this.colorCfg = new ColorCfg(options);
|
||||
};
|
||||
|
||||
ImageSurvey.prototype.setView = function(view) {
|
||||
let self = this;
|
||||
self.query = (async () => {
|
||||
if (!options.properties) {
|
||||
let obsTitle, creatorDid, maxOrder, frame, tileSize, formats, minCutout, maxCutout, bitpix, skyFraction, minOrder, initialFov, initialRa, initialDec, hipsBody, isPlanetaryBody, dataproductSubtype;
|
||||
|
||||
self.view = view;
|
||||
|
||||
let isMOCServerToBeQueried = true;
|
||||
if (this.imgFormat === 'fits') {
|
||||
// a fits is given
|
||||
isMOCServerToBeQueried = !(this.maxOrder && this.url && this.imgFormat && this.tileSize && this.cooFrame && this.numBitsPerPixel)
|
||||
} else {
|
||||
isMOCServerToBeQueried = !(this.maxOrder && this.url && this.imgFormat && this.tileSize && this.cooFrame);
|
||||
}
|
||||
|
||||
self.query = (async () => {
|
||||
if (isMOCServerToBeQueried) {
|
||||
let properties;
|
||||
let isCDSId = false;
|
||||
try {
|
||||
properties = await HiPSProperties.fetchFromUrl(url)
|
||||
properties = await HiPSProperties.fetchFromUrl(self.url)
|
||||
.catch(async (e) => {
|
||||
// url not valid so we try with the id
|
||||
try {
|
||||
return await HiPSProperties.fetchFromID(id);
|
||||
isCDSId = true;
|
||||
return await HiPSProperties.fetchFromID(self.url);
|
||||
} catch(e) {
|
||||
throw e;
|
||||
}
|
||||
@@ -189,200 +203,201 @@ export let ImageSurvey = (function () {
|
||||
throw e;
|
||||
}
|
||||
|
||||
obsTitle = properties.obs_title;
|
||||
creatorDid = properties.creator_did;
|
||||
// Set it to a default value
|
||||
if (!properties.hips_service_url) {
|
||||
throw 'no valid service URL for retrieving the tiles'
|
||||
if (isCDSId) {
|
||||
self.url = properties.hips_service_url;
|
||||
}
|
||||
url = Utils.fixURLForHTTPS(properties.hips_service_url);
|
||||
//obsTitle = properties.obs_title;
|
||||
self.creatorDid = properties.creator_did || self.creatorDid;
|
||||
// url
|
||||
|
||||
// Request all the properties to see which mirror is the fastest
|
||||
HiPSProperties.getFasterMirrorUrl(properties)
|
||||
.then((url) => {
|
||||
self._setUrl(url);
|
||||
})
|
||||
.catch(e => {
|
||||
//alert(e);
|
||||
console.error(e);
|
||||
// the survey has been added so we remove it from the stack
|
||||
self.view.removeImageLayer(self.layer)
|
||||
//throw e;
|
||||
})
|
||||
if (!self.url) {
|
||||
self.url = properties.hips_service_url
|
||||
if (!self.url) {
|
||||
throw 'no valid service URL for retrieving the tiles'
|
||||
}
|
||||
|
||||
self.url = Utils.fixURLForHTTPS(self.url);
|
||||
|
||||
// Request all the properties to see which mirror is the fastest
|
||||
HiPSProperties.getFasterMirrorUrl(properties)
|
||||
.then((url) => {
|
||||
if (self.url !== url) {
|
||||
console.info("Change url of ", self.id, " from ", self.url, " to ", url)
|
||||
|
||||
// If added to the backend, then we need to tell it the url has changed
|
||||
if (self.added) {
|
||||
self.view.wasm.setHiPSUrl(self.url, url);
|
||||
}
|
||||
|
||||
self.url = url;
|
||||
|
||||
// save the new url to the cache
|
||||
ImageSurvey.cache[self.id].url = self.url;
|
||||
}
|
||||
})
|
||||
/*.catch(e => {
|
||||
//alert(e);
|
||||
console.error(e);
|
||||
// the survey has been added so we remove it from the stack
|
||||
self.view.removeImageLayer(self.layer)
|
||||
//throw e;
|
||||
})*/
|
||||
}
|
||||
|
||||
// Max order
|
||||
maxOrder = PropertyParser.maxOrder(options, properties);
|
||||
self.maxOrder = PropertyParser.maxOrder(properties) || self.maxOrder;
|
||||
|
||||
// Tile size
|
||||
tileSize = PropertyParser.tileSize(options, properties);
|
||||
self.tileSize = PropertyParser.tileSize(properties) || self.tileSize;
|
||||
|
||||
// Tile formats
|
||||
formats = PropertyParser.formats(options, properties);
|
||||
self.formats = PropertyParser.formats(properties) || self.formats;
|
||||
|
||||
// min order
|
||||
minOrder = PropertyParser.minOrder(options, properties);
|
||||
self.minOrder = PropertyParser.minOrder(properties) || self.minOrder;
|
||||
|
||||
// Frame
|
||||
frame = PropertyParser.frame(options, properties);
|
||||
self.cooFrame = PropertyParser.cooFrame(properties) || self.cooFrame;
|
||||
|
||||
// sky fraction
|
||||
skyFraction = PropertyParser.skyFraction(options, properties);
|
||||
self.skyFraction = PropertyParser.skyFraction(properties);
|
||||
|
||||
// Initial fov/ra/dec
|
||||
initialFov = PropertyParser.initialFov(options, properties);
|
||||
initialRa = +properties.hips_initial_ra;
|
||||
initialDec = +properties.hips_initial_dec;
|
||||
self.initialFov = PropertyParser.initialFov(properties);
|
||||
self.initialRa = properties && properties.hips_initial_ra && (+properties.hips_initial_ra);
|
||||
self.initialDec = properties && properties.hips_initial_dec && (+properties.hips_initial_dec);
|
||||
|
||||
// Cutouts
|
||||
[minCutout, maxCutout] = PropertyParser.cutouts(options, properties);
|
||||
const cutoutFromProperties = PropertyParser.cutouts(properties);
|
||||
self.minCut = cutoutFromProperties[0];
|
||||
self.maxCut = cutoutFromProperties[1];
|
||||
|
||||
// Bitpix
|
||||
bitpix = PropertyParser.bitpix(options, properties);
|
||||
|
||||
// Dataproduct subtype
|
||||
dataproductSubtype = PropertyParser.dataproductSubtype(options, properties);
|
||||
self.numBitsPerPixel = PropertyParser.bitpix(properties) || self.numBitsPerPixel;
|
||||
|
||||
// HiPS body
|
||||
isPlanetaryBody = PropertyParser.isPlanetaryBody(options, properties);
|
||||
if (properties.hips_body) {
|
||||
hipsBody = properties.hips_body;
|
||||
self.hipsBody = properties.hips_body;
|
||||
// Use the property to define and check some user given infos
|
||||
// Longitude reversed
|
||||
self.longitudeReversed = true;
|
||||
}
|
||||
|
||||
self.properties = {
|
||||
creatorDid,
|
||||
obsTitle,
|
||||
url,
|
||||
maxOrder,
|
||||
frame,
|
||||
tileSize,
|
||||
formats,
|
||||
minCutout,
|
||||
maxCutout,
|
||||
bitpix,
|
||||
skyFraction,
|
||||
minOrder,
|
||||
hipsInitialFov: initialFov,
|
||||
hipsInitialRa: initialRa,
|
||||
hipsInitialDec: initialDec,
|
||||
dataproductSubtype,
|
||||
isPlanetaryBody,
|
||||
hipsBody
|
||||
};
|
||||
// Give a better name if we have the HiPS metadata
|
||||
self.name = self.name || properties.obsTitle;
|
||||
|
||||
self.cooFrame = properties.cooFrame || self.cooFrame;
|
||||
}
|
||||
|
||||
// Give a better name if we have the HiPS metadata
|
||||
self.name = self.name || self.properties.obsTitle;
|
||||
|
||||
// Use the property to define and check some user given infos
|
||||
// Longitude reversed
|
||||
let longitudeReversed = false;
|
||||
if (options && options.longitudeReversed === true) {
|
||||
longitudeReversed = true;
|
||||
}
|
||||
|
||||
if (self.properties.hipsBody) {
|
||||
longitudeReversed = true;
|
||||
}
|
||||
|
||||
self.longitudeReversed = longitudeReversed;
|
||||
self.creatorDid = self.creatorDid || self.id || self.url;
|
||||
|
||||
// Image format
|
||||
let imgFormat = options && options.imgFormat;
|
||||
if (imgFormat) {
|
||||
if (self.imgFormat) {
|
||||
// transform to lower case
|
||||
imgFormat = imgFormat.toLowerCase();
|
||||
self.imgFormat = self.imgFormat.toLowerCase();
|
||||
// convert JPG -> JPEG
|
||||
if (imgFormat === "jpg") {
|
||||
imgFormat = "jpeg";
|
||||
if (self.imgFormat === "jpg") {
|
||||
self.imgFormat = "jpeg";
|
||||
}
|
||||
|
||||
// user wants a fits but the properties tells this format is not available
|
||||
if (imgFormat === "fits" && self.properties.formats && self.properties.formats.indexOf('fits') < 0) {
|
||||
if (self.imgFormat === "fits" && self.formats && self.formats.indexOf('fits') < 0) {
|
||||
throw self.name + " does not provide fits tiles";
|
||||
}
|
||||
|
||||
if (imgFormat === "webp" && self.properties.formats && self.properties.formats.indexOf('webp') < 0) {
|
||||
if (self.imgFormat === "webp" && self.formats && self.formats.indexOf('webp') < 0) {
|
||||
throw self.name + " does not provide webp tiles";
|
||||
}
|
||||
|
||||
if (imgFormat === "png" && self.properties.formats && self.properties.formats.indexOf('png') < 0) {
|
||||
if (self.imgFormat === "png" && self.formats && self.formats.indexOf('png') < 0) {
|
||||
throw self.name + " does not provide png tiles";
|
||||
}
|
||||
|
||||
if (imgFormat === "jpeg" && self.properties.formats && self.properties.formats.indexOf('jpeg') < 0) {
|
||||
if (self.imgFormat === "jpeg" && self.formats && self.formats.indexOf('jpeg') < 0) {
|
||||
throw self.name + " does not provide jpeg tiles";
|
||||
}
|
||||
} else {
|
||||
// user wants nothing then we choose one from the properties
|
||||
if (self.properties.formats.indexOf('webp') >= 0) {
|
||||
imgFormat = "webp";
|
||||
} else if (self.properties.formats.indexOf('png') >= 0) {
|
||||
imgFormat = "png";
|
||||
} else if (self.properties.formats.indexOf('jpeg') >= 0) {
|
||||
imgFormat = "jpeg";
|
||||
} else if (self.properties.formats.indexOf('fits') >= 0) {
|
||||
imgFormat = "fits";
|
||||
if (self.formats.indexOf('webp') >= 0) {
|
||||
self.imgFormat = "webp";
|
||||
} else if (self.formats.indexOf('png') >= 0) {
|
||||
self.imgFormat = "png";
|
||||
} else if (self.formats.indexOf('jpeg') >= 0) {
|
||||
self.imgFormat = "jpeg";
|
||||
} else if (self.formats.indexOf('fits') >= 0) {
|
||||
self.imgFormat = "fits";
|
||||
} else {
|
||||
throw "Unsupported format(s) found in the properties: " + self.properties.formats;
|
||||
throw "Unsupported format(s) found in the properties: " + self.formats;
|
||||
}
|
||||
}
|
||||
|
||||
self.imgFormat = imgFormat;
|
||||
|
||||
// Initialize the color meta data here
|
||||
// Cutouts
|
||||
let minCut, maxCut;
|
||||
if (imgFormat === "fits") {
|
||||
if (self.imgFormat === "fits") {
|
||||
// Take into account the default cuts given by the property file (this is true especially for FITS HiPSes)
|
||||
minCut = self.colorCfg.minCut || (options && options.minCut) || self.properties.minCutout || 0.0;
|
||||
maxCut = self.colorCfg.maxCut || (options && options.maxCut) || self.properties.maxCutout || 1.0;
|
||||
minCut = self.colorCfg.minCut || self.minCut || 0.0;
|
||||
maxCut = self.colorCfg.maxCut || self.maxCut || 1.0;
|
||||
} else {
|
||||
minCut = self.colorCfg.minCut || (options && options.minCut) || 0.0;
|
||||
maxCut = self.colorCfg.maxCut || (options && options.maxCut) || 1.0;
|
||||
minCut = self.colorCfg.minCut || 0.0;
|
||||
maxCut = self.colorCfg.maxCut || 1.0;
|
||||
}
|
||||
self.colorCfg.setCuts(minCut, maxCut);
|
||||
|
||||
ImageLayer.update(self);
|
||||
// Coo frame
|
||||
if (self.cooFrame == "ICRS" || self.cooFrame == "ICRSd" || self.cooFrame == "equatorial" || self.cooFrame == "j2000") {
|
||||
self.cooFrame = "ICRS";
|
||||
} else if (self.cooFrame == "galactic") {
|
||||
self.cooFrame = "GAL";
|
||||
} else {
|
||||
self.cooFrame = "ICRS";
|
||||
console.warn('Invalid cooframe given: ' + self.cooFrame + '. Coordinate systems supported: "ICRS", "ICRSd", "j2000" or "galactic". ICRS is chosen by default');
|
||||
}
|
||||
|
||||
self.formats = self.formats || [self.imgFormat];
|
||||
|
||||
self._save();
|
||||
|
||||
return self;
|
||||
})();
|
||||
};
|
||||
|
||||
ImageSurvey.fromLayerOptions = function(aladin, options) {
|
||||
return new ImageSurvey(
|
||||
options.id,
|
||||
options.name,
|
||||
options.url,
|
||||
{
|
||||
properties: options,
|
||||
...options.options
|
||||
},
|
||||
aladin.view
|
||||
);
|
||||
}
|
||||
|
||||
ImageSurvey.prototype._setUrl = function (url) {
|
||||
if (this.properties.url !== url) {
|
||||
console.info("Change url of ", this.id, " from ", this.properties.url, " to ", url)
|
||||
ImageSurvey.prototype._save = function() {
|
||||
let self = this;
|
||||
|
||||
// If added to the backend, then we need to tell it the url has changed
|
||||
if (this.added) {
|
||||
this.view.wasm.setHiPSUrl(this.properties.url, url);
|
||||
}
|
||||
|
||||
this.properties.url = url;
|
||||
let surveyOpt = {
|
||||
creatorDid: self.creatorDid,
|
||||
name: self.name,
|
||||
url: self.url,
|
||||
cooFrame: self.cooFrame,
|
||||
maxOrder: self.maxOrder,
|
||||
tileSize: self.tileSize,
|
||||
imgFormat: self.imgFormat,
|
||||
}
|
||||
}
|
||||
|
||||
if (self.numBitsPerPixel) {
|
||||
surveyOpt.numBitsPerPixel = self.numBitsPerPixel;
|
||||
}
|
||||
|
||||
ImageSurvey.cache[self.id] = {
|
||||
// Erase by the cache already put values which is considered
|
||||
// as the ground truth
|
||||
...ImageSurvey.cache[self.id],
|
||||
// append new important infos from the properties queried
|
||||
...surveyOpt,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ImageSurvey represents a planetary body.
|
||||
*
|
||||
* This method returns a boolean indicating whether the ImageSurvey corresponds to a planetary body, e.g. the earth or a celestial body.
|
||||
*
|
||||
* @memberof ImageSurvey
|
||||
*
|
||||
* @returns {boolean} Returns true if the ImageSurvey represents a planetary body; otherwise, returns false.
|
||||
*/
|
||||
* Checks if the ImageSurvey represents a planetary body.
|
||||
*
|
||||
* This method returns a boolean indicating whether the ImageSurvey corresponds to a planetary body, e.g. the earth or a celestial body.
|
||||
*
|
||||
* @memberof ImageSurvey
|
||||
*
|
||||
* @returns {boolean} Returns true if the ImageSurvey represents a planetary body; otherwise, returns false.
|
||||
*/
|
||||
ImageSurvey.prototype.isPlanetaryBody = function() {
|
||||
return this.properties.isPlanetaryBody;
|
||||
return self.hipsBody !== undefined;;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,7 +434,7 @@ export let ImageSurvey = (function () {
|
||||
|
||||
// Check the properties to see if the given format is available among the list
|
||||
// If the properties have not been retrieved yet, it will be tested afterwards
|
||||
const availableFormats = self.properties.formats;
|
||||
const availableFormats = self.formats;
|
||||
// user wants a fits but the metadata tells this format is not available
|
||||
if (imgFormat === "fits" && availableFormats.indexOf('fits') < 0) {
|
||||
throw self.id + " does not provide fits tiles";
|
||||
@@ -439,8 +454,8 @@ export let ImageSurvey = (function () {
|
||||
|
||||
// Switch from png/webp/jpeg to fits
|
||||
if ((self.imgFormat === 'png' || self.imgFormat === "webp" || self.imgFormat === "jpeg") && imgFormat === 'fits') {
|
||||
if (self.properties.minCutout && self.properties.maxCutout) {
|
||||
self.setCuts(self.properties.minCutout, self.properties.maxCutout)
|
||||
if (self.minCut && self.maxCut) {
|
||||
self.setCuts(self.minCut, self.maxCut)
|
||||
}
|
||||
// Switch from fits to png/webp/jpeg
|
||||
} else if (self.imgFormat === "fits") {
|
||||
@@ -453,7 +468,7 @@ export let ImageSurvey = (function () {
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Sets the opacity factor when rendering the ImageSurvey
|
||||
*
|
||||
* @memberof ImageSurvey
|
||||
@@ -461,7 +476,7 @@ export let ImageSurvey = (function () {
|
||||
* @returns {string[]} Returns the formats accepted for the survey, i.e. the formats of tiles that are availables. Could be PNG, WEBP, JPG and FITS.
|
||||
*/
|
||||
ImageSurvey.prototype.getAvailableFormats = function() {
|
||||
return this.properties.formats;
|
||||
return this.formats;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -624,14 +639,12 @@ export let ImageSurvey = (function () {
|
||||
|
||||
// Tell the view its meta have changed
|
||||
try {
|
||||
this.metadata = {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: this.longitudeReversed,
|
||||
imgFormat: this.imgFormat
|
||||
};
|
||||
|
||||
if (this.added) {
|
||||
this.view.wasm.setImageMetadata(this.layer, this.metadata);
|
||||
this.view.wasm.setImageMetadata(this.layer, {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: this.longitudeReversed,
|
||||
imgFormat: this.imgFormat
|
||||
});
|
||||
// once the meta have been well parsed, we can set the meta
|
||||
ALEvent.HIPS_LAYER_CHANGED.dispatchedTo(this.view.aladinDiv, { layer: this });
|
||||
}
|
||||
@@ -643,17 +656,31 @@ export let ImageSurvey = (function () {
|
||||
|
||||
ImageSurvey.prototype.add = function (layer) {
|
||||
this.layer = layer;
|
||||
|
||||
this.metadata = {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: this.longitudeReversed,
|
||||
imgFormat: this.imgFormat
|
||||
};
|
||||
let self = this;
|
||||
|
||||
this.view.wasm.addImageSurvey({
|
||||
layer,
|
||||
properties: this.properties,
|
||||
meta: this.metadata,
|
||||
properties: {
|
||||
creatorDid: self.creatorDid,
|
||||
url: self.url,
|
||||
maxOrder: self.maxOrder,
|
||||
cooFrame: self.cooFrame,
|
||||
tileSize: self.tileSize,
|
||||
formats: self.formats,
|
||||
bitpix: self.numBitsPerPixel,
|
||||
skyFraction: self.skyFraction,
|
||||
minOrder: self.minOrder,
|
||||
hipsInitialFov: self.initialFov,
|
||||
hipsInitialRa: self.initialRa,
|
||||
hipsInitialDec: self.initialDec,
|
||||
isPlanetaryBody: self.isPlanetaryBody(),
|
||||
hipsBody: self.hipsBody
|
||||
},
|
||||
meta: {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: this.longitudeReversed,
|
||||
imgFormat: this.imgFormat
|
||||
},
|
||||
});
|
||||
|
||||
this.added = true;
|
||||
@@ -696,7 +723,203 @@ export let ImageSurvey = (function () {
|
||||
return this.view.wasm.readPixel(x, y, this.layer);
|
||||
};
|
||||
|
||||
ImageSurvey.DEFAULT_SURVEY_ID = "P/DSS2/color";
|
||||
ImageSurvey.DEFAULT_SURVEY_ID = "DSS2_color";
|
||||
|
||||
// A cache storing directly surveys important information to not query for the properties each time
|
||||
ImageSurvey.cache = {
|
||||
DSS2_color: {
|
||||
creatorDid: "ivo://CDS/P/DSS2/color",
|
||||
name: "DSS colored",
|
||||
url: "https://alasky.cds.unistra.fr/DSS/DSSColor",
|
||||
maxOrder: 9,
|
||||
tileSize: 512,
|
||||
imgFormat: 'jpeg',
|
||||
cooFrame: "ICRS"
|
||||
},
|
||||
MASS2_color: {
|
||||
creatorDid: "ivo://CDS/P/2MASS/color",
|
||||
name: "2MASS colored",
|
||||
url: "https://alasky.cds.unistra.fr/2MASS/Color",
|
||||
maxOrder: 9,
|
||||
tileSize: 512,
|
||||
imgFormat: 'jpeg',
|
||||
cooFrame: "ICRS"
|
||||
},
|
||||
DSS2_red: {
|
||||
creatorDid: "ivo://CDS/P/DSS2/red",
|
||||
name: "DSS2 Red (F+R)",
|
||||
url: "https://alasky.cds.unistra.fr/DSS/DSS2Merged",
|
||||
maxOrder: 9,
|
||||
tileSize: 512,
|
||||
imgFormat: 'fits',
|
||||
cooFrame: "ICRS",
|
||||
numBitsPerPixel: 16,
|
||||
// options
|
||||
minCut: 1000.0,
|
||||
maxCut: 10000.0,
|
||||
colormap: "magma",
|
||||
stretch: 'Linear',
|
||||
imgFormat: "fits"
|
||||
},
|
||||
GAIA_EDR3: {
|
||||
creatorDid: "ivo://CDS/P/DM/I/350/gaiaedr3",
|
||||
name: "Density map for Gaia EDR3 (I/350/gaiaedr3)",
|
||||
url: "https://alasky.cds.unistra.fr/ancillary/GaiaEDR3/density-map",
|
||||
maxOrder: 7,
|
||||
tileSize: 512,
|
||||
numBitsPerPixel: -32,
|
||||
cooFrame: "ICRS",
|
||||
minCut: 0,
|
||||
maxCut: 12000,
|
||||
stretch: 'asinh',
|
||||
colormap: "rdylbu",
|
||||
imgFormat: "fits",
|
||||
},
|
||||
PanSTARRS_DR1_g: {
|
||||
creatorDid: "ivo://CDS/P/PanSTARRS/DR1/g",
|
||||
name: "PanSTARRS DR1 g",
|
||||
url: "https://alasky.cds.unistra.fr/Pan-STARRS/DR1/g",
|
||||
maxOrder: 11,
|
||||
tileSize: 512,
|
||||
imgFormat: 'fits',
|
||||
cooFrame: "ICRS",
|
||||
numBitsPerPixel: -32,
|
||||
// options
|
||||
minCut: -34,
|
||||
maxCut: 7000,
|
||||
stretch: 'asinh',
|
||||
colormap: "redtemperature",
|
||||
},
|
||||
PanSTARRS_DR1_color: {
|
||||
creatorDid: "ivo://CDS/P/PanSTARRS/DR1/color-z-zg-g",
|
||||
name: "PanSTARRS DR1 color",
|
||||
url: "https://alasky.cds.unistra.fr/Pan-STARRS/DR1/color-z-zg-g",
|
||||
maxOrder: 11,
|
||||
tileSize: 512,
|
||||
imgFormat: 'jpeg',
|
||||
cooFrame: "ICRS",
|
||||
},
|
||||
DECaPS_DR2_color: {
|
||||
creatorDid: "ivo://CDS/P/DECaPS/DR2/color",
|
||||
name: "DECaPS DR2 color",
|
||||
url: "https://alasky.cds.unistra.fr/DECaPS/DR2/CDS_P_DECaPS_DR2_color/",
|
||||
maxOrder: 11,
|
||||
cooFrame: "equatorial",
|
||||
tileSize: 512,
|
||||
imgFormat: 'png',
|
||||
},
|
||||
Fermi_color: {
|
||||
creatorDid: "ivo://CDS/P/Fermi/color",
|
||||
name: "Fermi color",
|
||||
url: "https://alasky.cds.unistra.fr/Fermi/Color",
|
||||
maxOrder: 3,
|
||||
imgFormat: 'jpeg',
|
||||
tileSize: 512,
|
||||
cooFrame: 'equatorial'
|
||||
},
|
||||
/*
|
||||
{
|
||||
id: "P/Finkbeiner",
|
||||
name: "Halpha",
|
||||
url: "https://alasky.cds.unistra.fr/FinkbeinerHalpha",
|
||||
maxOrder: 3,
|
||||
subtype: "survey",
|
||||
// options
|
||||
options: {
|
||||
minCut: -10,
|
||||
maxCut: 800,
|
||||
colormap: "rdbu",
|
||||
imgFormat: "fits",
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "P/GALEXGR6_7/NUV",
|
||||
name: "GALEXGR6_7 NUV",
|
||||
url: "http://alasky.cds.unistra.fr/GALEX/GALEXGR6_7_NUV/",
|
||||
maxOrder: 8,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/IRIS/color",
|
||||
name: "IRIS colored",
|
||||
url: "https://alasky.cds.unistra.fr/IRISColor",
|
||||
maxOrder: 3,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/Mellinger/color",
|
||||
name: "Mellinger colored",
|
||||
url: "https://alasky.cds.unistra.fr/MellingerRGB",
|
||||
maxOrder: 4,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/SDSS9/color",
|
||||
name: "SDSS9 colored",
|
||||
url: "https://alasky.cds.unistra.fr/SDSS/DR9/color",
|
||||
maxOrder: 10,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/SDSS9/g",
|
||||
name: "SDSS9 band-g",
|
||||
url: "https://alasky.cds.unistra.fr/SDSS/DR9/band-g",
|
||||
maxOrder: 10,
|
||||
subtype: "survey",
|
||||
options: {
|
||||
stretch: 'asinh',
|
||||
colormap: "redtemperature",
|
||||
imgFormat: 'fits'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "P/SPITZER/color",
|
||||
name: "IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)",
|
||||
url: "http://alasky.cds.unistra.fr/Spitzer/SpitzerI1I2I4color/",
|
||||
maxOrder: 9,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/VTSS/Ha",
|
||||
name: "VTSS-Ha",
|
||||
url: "https://alasky.cds.unistra.fr/VTSS/Ha",
|
||||
maxOrder: 3,
|
||||
subtype: "survey",
|
||||
options: {
|
||||
minCut: -10.0,
|
||||
maxCut: 100.0,
|
||||
colormap: "grayscale",
|
||||
imgFormat: "fits"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "xcatdb/P/XMM/PN/color",
|
||||
name: "XMM PN colored",
|
||||
url: "https://alasky.cds.unistra.fr/cgi/JSONProxy?url=https://saada.unistra.fr/PNColor",
|
||||
maxOrder: 7,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/allWISE/color",
|
||||
name: "AllWISE color",
|
||||
url: "https://alasky.cds.unistra.fr/AllWISE/RGB-W4-W2-W1/",
|
||||
maxOrder: 8,
|
||||
subtype: "survey",
|
||||
},
|
||||
{
|
||||
id: "P/GLIMPSE360",
|
||||
name: "GLIMPSE360",
|
||||
// This domain is not giving the CORS headers
|
||||
// We need to query by with a proxy equipped with CORS header.
|
||||
url: "https://alasky.cds.unistra.fr/cgi/JSONProxy?url=https://www.spitzer.caltech.edu/glimpse360/aladin/data",
|
||||
subtype: "survey",
|
||||
options: {
|
||||
maxOrder: 9,
|
||||
imgFormat: "jpg",
|
||||
minOrder: 3,
|
||||
}
|
||||
},*/
|
||||
};
|
||||
|
||||
return ImageSurvey;
|
||||
})();
|
||||
|
||||
@@ -92,12 +92,10 @@ export class Selector {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var objList = [];
|
||||
var cat, sources, s;
|
||||
var footprints, f;
|
||||
var objListPerCatalog = [];
|
||||
|
||||
if (view.catalogs) {
|
||||
for (var k = 0; k < view.catalogs.length; k++) {
|
||||
cat = view.catalogs[k];
|
||||
@@ -133,6 +131,9 @@ export class Selector {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(objList)
|
||||
|
||||
|
||||
return objList;
|
||||
}
|
||||
}
|
||||
@@ -50,10 +50,8 @@ import { ObsCore } from "./vo/ObsCore.js";
|
||||
import { DefaultActionsForContextMenu } from "./DefaultActionsForContextMenu.js";
|
||||
import { Layout } from "./gui/Layout.js";
|
||||
import { SAMPActionButton } from "./gui/Button/SAMP.js";
|
||||
import { Icon } from "./gui/Widgets/Icon.js";
|
||||
import openerIconUrl from '../../assets/icons/loading.svg'
|
||||
import { ImageSurvey } from "./ImageSurvey.js";
|
||||
import { ImageLayer } from "./ImageLayer.js";
|
||||
import { ImageFITS } from "./ImageFITS.js";
|
||||
|
||||
export let View = (function () {
|
||||
|
||||
@@ -84,9 +82,6 @@ export let View = (function () {
|
||||
|
||||
callback(self.wasm);
|
||||
});
|
||||
|
||||
// Retrieve all the possible colormaps
|
||||
ColorCfg.COLORMAPS = this.wasm.getAvailableColormapList();
|
||||
} catch (e) {
|
||||
// For browsers not supporting WebGL2:
|
||||
// 1. Print the original exception message in the console
|
||||
@@ -128,7 +123,6 @@ export let View = (function () {
|
||||
|
||||
this.aladinDiv.ondragover = Utils.dragOverHandler;
|
||||
|
||||
//this.location = location;
|
||||
this.mustClearCatalog = true;
|
||||
this.mode = View.PAN;
|
||||
|
||||
@@ -139,18 +133,8 @@ export let View = (function () {
|
||||
|
||||
var lon, lat;
|
||||
lon = lat = 0;
|
||||
this.projection = ProjectionEnum.SIN;
|
||||
|
||||
this.viewCenter = { lon: lon, lat: lat }; // position of center of view
|
||||
|
||||
this.cooFrame = CooFrameEnum.fromString(this.options.cooFrame, CooFrameEnum.J2000);
|
||||
|
||||
// Frame setting
|
||||
this.changeFrame(this.cooFrame);
|
||||
|
||||
this.selector = new Selector(this);
|
||||
|
||||
// Zoom starting setting
|
||||
// FoV init settings
|
||||
const si = 500000.0;
|
||||
const alpha = 40.0;
|
||||
let initialFov = this.options.fov || 180.0;
|
||||
@@ -160,7 +144,23 @@ export let View = (function () {
|
||||
initialDistance: undefined,
|
||||
initialAccDelta: Math.pow(si / initialFov, 1.0 / alpha)
|
||||
};
|
||||
|
||||
// Projection definition
|
||||
const projName = (this.options && this.options.projection) || "SIN";
|
||||
this.setProjection(projName)
|
||||
|
||||
// Then set the zoom properly once the projection is defined
|
||||
this.setZoom(initialFov);
|
||||
|
||||
// Target position settings
|
||||
this.viewCenter = { lon, lat }; // position of center of view
|
||||
|
||||
// Coo frame setting
|
||||
const cooFrame = CooFrameEnum.fromString(this.options.cooFrame, CooFrameEnum.J2000);
|
||||
this.changeFrame(cooFrame);
|
||||
|
||||
this.selector = new Selector(this);
|
||||
|
||||
// current reference image survey displayed
|
||||
this.imageLayers = new Map();
|
||||
|
||||
@@ -631,13 +631,9 @@ export let View = (function () {
|
||||
// Take as start cut values what is inside the properties
|
||||
// If the cuts are not defined in the metadata of the survey
|
||||
// then we take what has been defined by the user
|
||||
if (imageLayer.imgFormat === "fits") {
|
||||
cutMinInit = imageLayer.properties.minCutout || imageLayer.getColorCfg().minCut || 0.0;
|
||||
cutMaxInit = imageLayer.properties.maxCutout || imageLayer.getColorCfg().maxCut || 1.0;
|
||||
} else {
|
||||
cutMinInit = imageLayer.getColorCfg().minCut || 0.0;
|
||||
cutMaxInit = imageLayer.getColorCfg().maxCut || 1.0;
|
||||
}
|
||||
cutMinInit = imageLayer.getColorCfg().minCut || 0.0;
|
||||
cutMaxInit = imageLayer.getColorCfg().maxCut || 1.0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1353,6 +1349,7 @@ export let View = (function () {
|
||||
this.selection = Selector.getObjects(selection, this);
|
||||
}
|
||||
|
||||
|
||||
if (this.selection.length > 0) {
|
||||
this.selection.forEach((objListPerCatalog) => {
|
||||
objListPerCatalog.forEach((obj) => obj.select())
|
||||
@@ -1535,6 +1532,10 @@ export let View = (function () {
|
||||
};
|
||||
|
||||
View.prototype.setOverlayImageLayer = function (imageLayer, layer = "overlay") {
|
||||
// set the view to the image layer object
|
||||
// do the properties query if needed
|
||||
imageLayer.setView(this);
|
||||
|
||||
// register its promise
|
||||
this.imageLayersBeingQueried.set(layer, imageLayer);
|
||||
|
||||
@@ -1604,13 +1605,17 @@ export let View = (function () {
|
||||
}
|
||||
|
||||
// change the view frame in case we have a planetary hips loaded
|
||||
if (imageLayer.properties.hipsBody) {
|
||||
if (imageLayer.hipsBody) {
|
||||
if (this.options.showFrame) {
|
||||
this.aladin.setFrame('J2000d');
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
// remove it from the cache
|
||||
delete ImageSurvey.cache[imageLayer.id]
|
||||
delete ImageFITS.cache[imageLayer.id]
|
||||
|
||||
throw e;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -1629,9 +1634,7 @@ export let View = (function () {
|
||||
if (noMoreLayersToWaitFor) {
|
||||
if (self.empty) {
|
||||
// no promises to launch!
|
||||
const dssLayerOptions = ImageLayer.DEFAULT_SURVEY
|
||||
|
||||
self.aladin.setBaseImageLayer(ImageSurvey.fromLayerOptions(self, dssLayerOptions));
|
||||
//self.aladin.setBaseImageLayer(self.aladin.createImageSurvey(ImageSurvey.DEFAULT_SURVEY_ID));
|
||||
} else {
|
||||
// there is surveys that have been queried
|
||||
// rename the first overlay layer to "base"
|
||||
@@ -1758,7 +1761,7 @@ export let View = (function () {
|
||||
projName = 'SIN'
|
||||
}
|
||||
|
||||
if (this.projection.id === ProjectionEnum[projName].id) {
|
||||
if (this.projection && this.projection.id === ProjectionEnum[projName].id) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -248,9 +248,12 @@ import { CtxMenuActionButtonOpener } from "../Button/CtxMenuOpener.js";
|
||||
if (self.box) {
|
||||
self.box.remove();
|
||||
}
|
||||
self.box = new ConeSearchBox(aladin);
|
||||
// output the resulting cone search in the icrs frame
|
||||
self.box = new ConeSearchBox(aladin, {frame: 'icrs'});
|
||||
self.box.attach({
|
||||
callback: (cs) => {
|
||||
// the cone search services are asking for
|
||||
|
||||
self.fnIdSelected('coneSearch', {
|
||||
baseURL: self.selectedItem.cs_service_url,
|
||||
id: self.selectedItem.ID,
|
||||
|
||||
@@ -33,7 +33,7 @@ import { Angle } from "../../libs/astro/angle.js";
|
||||
*****************************************************************************/
|
||||
|
||||
export class ConeSearchBox extends Box {
|
||||
constructor(aladin) {
|
||||
constructor(aladin, options) {
|
||||
let self;
|
||||
let selectorBtn = new ConeSearchActionButton({
|
||||
tooltip: {content: 'Select the area to query the catalogue with', position: {direction: 'left'}},
|
||||
@@ -43,8 +43,8 @@ import { Angle } from "../../libs/astro/angle.js";
|
||||
action(circle) {
|
||||
// convert to ra, dec and radius in deg
|
||||
try {
|
||||
let [ra, dec] = aladin.pix2world(circle.x, circle.y);
|
||||
let radius = aladin.angularDist(circle.x, circle.y, circle.x + circle.r, circle.y);
|
||||
let [ra, dec] = aladin.pix2world(circle.x, circle.y, options.frame);
|
||||
let radius = aladin.angularDist(circle.x, circle.y, circle.x + circle.r, circle.y, options.frame);
|
||||
|
||||
//var hlon = this.lon/15.0;
|
||||
//var strlon = Numbers.toSexagesimal(hlon, this.prec+1, false);
|
||||
@@ -160,8 +160,6 @@ import { Angle } from "../../libs/astro/angle.js";
|
||||
aladin.aladinDiv
|
||||
)
|
||||
|
||||
// hide by default
|
||||
//console.log("hide cone search")
|
||||
this._hide();
|
||||
|
||||
self = this;
|
||||
|
||||
@@ -43,8 +43,8 @@ export class ConeSearchActionButton extends ActionButton {
|
||||
// Constructor
|
||||
constructor(options, aladin) {
|
||||
super({
|
||||
size: 'medium',
|
||||
icon: {
|
||||
size: 'medium',
|
||||
monochrome: true,
|
||||
url: targetIconUrl
|
||||
},
|
||||
@@ -65,7 +65,5 @@ export class ConeSearchActionButton extends ActionButton {
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
this.addClass('medium-sized-icon')
|
||||
}
|
||||
}
|
||||
@@ -44,10 +44,10 @@ import hideIconUrl from '../../../../assets/icons/hide.svg';
|
||||
import removeIconUrl from '../../../../assets/icons/remove.svg';
|
||||
import editIconUrl from '../../../../assets/icons/edit.svg';
|
||||
import { ImageFITS } from "../../ImageFITS.js";
|
||||
import { ImageLayer } from "../../ImageLayer.js";
|
||||
import searchIconImg from '../../../../assets/icons/search.svg';
|
||||
import { TogglerActionButton } from "../Button/Toggler.js";
|
||||
import { Icon } from "../Widgets/Icon.js";
|
||||
import { ImageSurvey } from "../../ImageSurvey.js";
|
||||
|
||||
export class OverlayStack extends ContextMenu {
|
||||
static previewImagesUrl = {
|
||||
@@ -293,10 +293,11 @@ export class OverlayStack extends ContextMenu {
|
||||
self._hide();
|
||||
|
||||
self.aladin.select('circle', c => {
|
||||
let [ra, dec] = self.aladin.pix2world(c.x, c.y);
|
||||
let [ra, dec] = self.aladin.pix2world(c.x, c.y, 'j2000');
|
||||
let radius = self.aladin.angularDist(c.x, c.y, c.x + c.r, c.y);
|
||||
|
||||
if (ra && dec && radius) {
|
||||
// the moc needs a
|
||||
let moc = A.MOCFromCircle(
|
||||
{ra, dec, radius},
|
||||
{name: 'cone', lineWidth: 3.0},
|
||||
@@ -321,10 +322,10 @@ export class OverlayStack extends ContextMenu {
|
||||
|
||||
self.aladin.select('rect', r => {
|
||||
try {
|
||||
let [ra1, dec1] = self.aladin.pix2world(r.x, r.y);
|
||||
let [ra2, dec2] = self.aladin.pix2world(r.x + r.w, r.y);
|
||||
let [ra3, dec3] = self.aladin.pix2world(r.x + r.w, r.y + r.h);
|
||||
let [ra4, dec4] = self.aladin.pix2world(r.x, r.y + r.h);
|
||||
let [ra1, dec1] = self.aladin.pix2world(r.x, r.y, 'j2000');
|
||||
let [ra2, dec2] = self.aladin.pix2world(r.x + r.w, r.y, 'j2000');
|
||||
let [ra3, dec3] = self.aladin.pix2world(r.x + r.w, r.y + r.h, 'j2000');
|
||||
let [ra4, dec4] = self.aladin.pix2world(r.x, r.y + r.h, 'j2000');
|
||||
|
||||
let moc = A.MOCFromPolygon(
|
||||
{
|
||||
@@ -356,7 +357,7 @@ export class OverlayStack extends ContextMenu {
|
||||
let ra = []
|
||||
let dec = []
|
||||
for (const v of p.vertices) {
|
||||
let [lon, lat] = self.aladin.pix2world(v.x, v.y);
|
||||
let [lon, lat] = self.aladin.pix2world(v.x, v.y, 'j2000');
|
||||
ra.push(lon)
|
||||
dec.push(lat)
|
||||
}
|
||||
@@ -528,15 +529,19 @@ export class OverlayStack extends ContextMenu {
|
||||
return;
|
||||
}*/
|
||||
|
||||
const defaultLayers = ImageLayer.LAYERS.sort(function (a, b) {
|
||||
const defaultLayers = Object.entries(ImageSurvey.cache).sort(function (e1, e2) {
|
||||
let a = e1[1]
|
||||
let b = e2[1]
|
||||
|
||||
if (!a.order) {
|
||||
return a.name > b.name ? 1 : -1;
|
||||
}
|
||||
|
||||
return a.maxOrder && a.maxOrder > b.maxOrder ? 1 : -1;
|
||||
});
|
||||
|
||||
for(const layer of layers) {
|
||||
let backgroundUrl = layer.properties.url + '/preview.jpg';
|
||||
let backgroundUrl = layer.url + '/preview.jpg';
|
||||
let cssStyle = {
|
||||
height: 'fit-content',
|
||||
};
|
||||
@@ -597,7 +602,6 @@ export class OverlayStack extends ContextMenu {
|
||||
|
||||
self._hide();
|
||||
|
||||
console.log("kjkj")
|
||||
//self.aladin.selectLayer(layer.layer);
|
||||
//self.attach()
|
||||
|
||||
@@ -618,35 +622,35 @@ export class OverlayStack extends ContextMenu {
|
||||
tooltip: {content: 'Add coverage', position: {direction: 'bottom'}},
|
||||
toggled: (() => {
|
||||
let overlays = self.aladin.getOverlays();
|
||||
let found = overlays.find((o) => o.type === "moc" && o.name === layer.properties.obsTitle);
|
||||
let found = overlays.find((o) => o.type === "moc" && o.name === layer.name);
|
||||
return found !== undefined;
|
||||
})(),
|
||||
actionOn: (e) => {
|
||||
let moc = A.MOCFromURL(layer.properties.url + '/Moc.fits', {lineWidth: 3, name: layer.properties.obsTitle});
|
||||
let moc = A.MOCFromURL(layer.url + '/Moc.fits', {lineWidth: 3, name: layer.name});
|
||||
self.aladin.addMOC(moc);
|
||||
|
||||
self.mocHiPSUrls[layer.properties.url] = moc;
|
||||
self.mocHiPSUrls[layer.url] = moc;
|
||||
loadMOCBtn.update({tooltip: {content: 'Remove coverage', position: {direction: 'bottom'}}})
|
||||
|
||||
if (self.aladin.statusBar) {
|
||||
self.aladin.statusBar.appendMessage({
|
||||
message: 'Coverage of ' + layer.properties.obsTitle + ' loaded',
|
||||
message: 'Coverage of ' + layer.name + ' loaded',
|
||||
duration: 2000,
|
||||
type: 'info'
|
||||
})
|
||||
}
|
||||
},
|
||||
actionOff: (e) => {
|
||||
let moc = self.mocHiPSUrls[layer.properties.url];
|
||||
let moc = self.mocHiPSUrls[layer.url];
|
||||
self.aladin.removeLayer(moc)
|
||||
|
||||
delete self.mocHiPSUrls[layer.properties.url];
|
||||
delete self.mocHiPSUrls[layer.url];
|
||||
|
||||
loadMOCBtn.update({tooltip: {content: 'Add coverage', position: {direction: 'bottom'}}})
|
||||
|
||||
if (self.aladin.statusBar) {
|
||||
self.aladin.statusBar.appendMessage({
|
||||
message: 'Coverage of ' + layer.properties.obsTitle + ' removed',
|
||||
message: 'Coverage of ' + layer.name + ' removed',
|
||||
duration: 2000,
|
||||
type: 'info'
|
||||
})
|
||||
@@ -697,7 +701,7 @@ export class OverlayStack extends ContextMenu {
|
||||
|
||||
l.subMenu = [];
|
||||
|
||||
for(let ll of defaultLayers) {
|
||||
for(const [id, ll] of defaultLayers) {
|
||||
backgroundUrl = OverlayStack.previewImagesUrl[ll.name];
|
||||
if (!backgroundUrl) {
|
||||
backgroundUrl = ll.url + '/preview.jpg'
|
||||
@@ -718,31 +722,7 @@ export class OverlayStack extends ContextMenu {
|
||||
label: '<div style="background-color: rgba(0, 0, 0, 0.6); padding: 3px; border-radius: 3px">' + ll.name + '</div>',
|
||||
cssStyle,
|
||||
action(e) {
|
||||
let cfg = ImageLayer.LAYERS.find((l) => l.name === ll.name);
|
||||
let newLayer;
|
||||
|
||||
// Max order is specific for surveys
|
||||
if (cfg.subtype === "fits") {
|
||||
// FITS
|
||||
newLayer = self.aladin.createImageFITS(
|
||||
cfg.url,
|
||||
cfg.name,
|
||||
cfg.options,
|
||||
);
|
||||
} else {
|
||||
// HiPS
|
||||
newLayer = self.aladin.createImageSurvey(
|
||||
cfg.id,
|
||||
cfg.name,
|
||||
cfg.url,
|
||||
undefined,
|
||||
cfg.maxOrder,
|
||||
cfg.options
|
||||
);
|
||||
}
|
||||
|
||||
self.aladin.setOverlayImageLayer(newLayer, layer.layer);
|
||||
//self._hide();
|
||||
self.aladin.setOverlayImageLayer(id, layer.layer);
|
||||
},
|
||||
hover(e, item) {
|
||||
item.style.filter = 'brightness(1.5)';
|
||||
@@ -806,11 +786,11 @@ export class OverlayStack extends ContextMenu {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!layer.properties || !layer.properties.creatorDid) {
|
||||
if (!layer.creatorDid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const creatorDid = layer.properties.creatorDid;
|
||||
const creatorDid = layer.creatorDid;
|
||||
|
||||
for (const key in Stack.previewImagesUrl) {
|
||||
if (creatorDid.includes(key)) {
|
||||
@@ -818,7 +798,7 @@ export class OverlayStack extends ContextMenu {
|
||||
}
|
||||
}
|
||||
// if not found
|
||||
return layer.properties.url + '/preview.jpg'
|
||||
return layer.url + '/preview.jpg'
|
||||
}
|
||||
|
||||
_addOverlayIcon(overlay) {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
value: cooFrame.label,
|
||||
options: [CooFrameEnum.J2000.label, CooFrameEnum.J2000d.label, CooFrameEnum.GAL.label],
|
||||
change(e) {
|
||||
self.setFrame(e.target.value)
|
||||
aladin.setFrame(e.target.value)
|
||||
},
|
||||
classList: ['aladin-cooFrame'],
|
||||
tooltip: {
|
||||
@@ -67,7 +67,6 @@
|
||||
let self = this;
|
||||
ALEvent.FRAME_CHANGED.listenedBy(aladin.aladinDiv, function (e) {
|
||||
let frame = e.detail.cooFrame;
|
||||
console.log(frame, e)
|
||||
|
||||
self.update({
|
||||
value: frame.label
|
||||
|
||||
@@ -67,10 +67,6 @@ export class Input extends DOMElement {
|
||||
_show() {
|
||||
this.el.innerHTML = '';
|
||||
|
||||
if (this.options.classList) {
|
||||
this.addClass(this.options.classList)
|
||||
}
|
||||
|
||||
if (this.options.type === "checkbox") {
|
||||
this.el.type = this.options.type;
|
||||
|
||||
@@ -214,6 +210,10 @@ export class Input extends DOMElement {
|
||||
Tooltip.add(this.options.tooltip, this)
|
||||
}
|
||||
|
||||
if (this.options.classList) {
|
||||
this.element().classList.add(this.options.classList)
|
||||
}
|
||||
|
||||
/*// Add padding for inputs except color ones
|
||||
if (Utils.hasTouchScreen() && this.options.type !== "color") {
|
||||
// Add a little padding
|
||||
|
||||
@@ -75,8 +75,9 @@ export class SelectorButton extends DOMElement {
|
||||
if (id === 'selected' || this.options.selected === id || id === 'tooltip') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let optSelect = this.options[id];
|
||||
console.log(optSelect)
|
||||
|
||||
menuOptions.push({
|
||||
label: new ActionButton(optSelect),
|
||||
action(e) {
|
||||
@@ -85,6 +86,8 @@ export class SelectorButton extends DOMElement {
|
||||
}
|
||||
|
||||
self.update({selected: id});
|
||||
self._show();
|
||||
|
||||
self.fsm.dispatch('closeCtxMenu')
|
||||
}
|
||||
})
|
||||
@@ -133,6 +136,7 @@ export class SelectorButton extends DOMElement {
|
||||
|
||||
// remove from the DOM tree
|
||||
const selectedId = this.options.selected;
|
||||
|
||||
let {target, position} = this.remove();
|
||||
this.el = new ActionButton({
|
||||
...this.options[selectedId],
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
// Copyright 2023 - UDS/CNRS
|
||||
// The Aladin Lite program is distributed under the terms
|
||||
// of the GNU General Public License version 3.
|
||||
//
|
||||
// This file is part of Aladin Lite.
|
||||
//
|
||||
// Aladin Lite is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 3 of the License.
|
||||
//
|
||||
// Aladin Lite is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// The GNU General Public License is available in COPYING file
|
||||
// along with Aladin Lite.
|
||||
//
|
||||
import { Layout } from "../Layout";
|
||||
import { Utils } from "../../Utils";
|
||||
/******************************************************************************
|
||||
* Aladin Lite project
|
||||
*
|
||||
* File gui/Widgets/layout/Horizontal.js
|
||||
*
|
||||
* A layout grouping widgets horizontaly
|
||||
*
|
||||
*
|
||||
* Author: Matthieu Baumann[CDS]
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*{
|
||||
direction: 'vertical' | 'horizontal',
|
||||
cssStyle: {...}
|
||||
position: {
|
||||
top,
|
||||
left
|
||||
} \ {
|
||||
container: NodeElement
|
||||
anchor: 'left top' |
|
||||
'left center' |
|
||||
'left bottom' |
|
||||
'right top' |
|
||||
'right center' |
|
||||
'right bottom' |
|
||||
'center top' |
|
||||
'center center' |
|
||||
'center bottom'
|
||||
}
|
||||
}
|
||||
}*/
|
||||
export class Toolbar extends Layout {
|
||||
/**
|
||||
* Create a layout
|
||||
* @param {layout: Array.<DOMElement | String>, cssStyle: Object} options - Represents the structure of the Tabs
|
||||
* @param {DOMElement} target - The parent element.
|
||||
* @param {String} position - The position of the tabs layout relative to the target.
|
||||
* For the list of possibilities, see https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
|
||||
*/
|
||||
constructor(options) {
|
||||
options.orientation = options.orientation || 'horizontal';
|
||||
options.position = options.position || {anchor: 'left top'};
|
||||
|
||||
if (!!options.direction === false) {
|
||||
if (options.orientation === 'horizontal') {
|
||||
// top or bottom
|
||||
if (options.position.anchor && options.position.anchor.includes('top')) {
|
||||
options.direction = 'bottom'
|
||||
} else {
|
||||
options.direction = 'top'
|
||||
}
|
||||
} else {
|
||||
// left or right
|
||||
if (options.position.anchor && options.position.anchor.includes('left')) {
|
||||
options.direction = 'right'
|
||||
} else {
|
||||
options.direction = 'left'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options.layout = options.layout || [];
|
||||
|
||||
super(options)
|
||||
|
||||
this.addClass(options.direction);
|
||||
|
||||
this.tools = {};
|
||||
}
|
||||
|
||||
update(options) {
|
||||
if (options.direction) {
|
||||
this.removeClass('left');
|
||||
this.removeClass('right');
|
||||
this.removeClass('top');
|
||||
this.removeClass('bottom');
|
||||
|
||||
this.addClass(options.direction)
|
||||
|
||||
// search for a tooltip
|
||||
/*this.el.querySelectorAll(".aladin-tooltip-container")
|
||||
.forEach((t) => {
|
||||
t.classList.remove('left');
|
||||
t.classList.remove('right');
|
||||
t.classList.remove('top');
|
||||
t.classList.remove('bottom');
|
||||
|
||||
if (options.direction === 'left') {
|
||||
t.classList.add('bottom')
|
||||
} else if (options.direction === 'right') {
|
||||
t.classList.add('bottom', 'left')
|
||||
} else if (options.direction === 'top') {
|
||||
t.classList.add('right')
|
||||
} else {
|
||||
t.classList.add('left')
|
||||
}
|
||||
})*/
|
||||
}
|
||||
|
||||
super.update(options);
|
||||
}
|
||||
|
||||
add(tool, name, position = 'after') {
|
||||
if (Array.isArray(tool)) {
|
||||
let tools = tool;
|
||||
tools.forEach(t => {
|
||||
this.appendAtLast(t)
|
||||
});
|
||||
} else {
|
||||
if (position === 'begin') {
|
||||
this.appendAtIndex(tool, name, 0)
|
||||
} else {
|
||||
this.appendAtLast(tool, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remove(name) {
|
||||
let tool = this.tools[name];
|
||||
|
||||
this.removeItem(tool)
|
||||
delete this.tools[name];
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
appendAtLast(tool, name) {
|
||||
if (!name) {
|
||||
name = Utils.uuidv4()
|
||||
}
|
||||
this.tools[name] = tool;
|
||||
this.appendLast(tool);
|
||||
}
|
||||
|
||||
appendAtIndex(tool, name, index) {
|
||||
this.tools[name] = tool;
|
||||
this.insertItemAtIndex(tool, index);
|
||||
}
|
||||
|
||||
/* Show a tool */
|
||||
show(name) {
|
||||
if (name && this.tools[name]) {
|
||||
this.tools[name]._show()
|
||||
}
|
||||
}
|
||||
|
||||
isShown(name) {
|
||||
return this.tools[name] && !this.tools[name].isHidden
|
||||
}
|
||||
|
||||
/* Hide a tool */
|
||||
hide(name) {
|
||||
if (name && this.tools[name]) {
|
||||
this.tools[name]._hide()
|
||||
}
|
||||
}
|
||||
|
||||
contains(name) {
|
||||
return this.tools[name] !== undefined;
|
||||
}
|
||||
}
|
||||
@@ -295,17 +295,12 @@ export class DOMElement {
|
||||
|
||||
_show() {
|
||||
this.el.style.display = ""
|
||||
//this.el.style.display = 'block';
|
||||
this.isHidden = false;
|
||||
}
|
||||
|
||||
_hide() {
|
||||
this.isHidden = true;
|
||||
this.el.style.display = 'none';
|
||||
|
||||
if (this.options && this.options.onHidden) {
|
||||
this.options.onHidden();
|
||||
}
|
||||
}
|
||||
|
||||
attachTo(target, position = 'beforeend') {
|
||||
@@ -324,6 +319,10 @@ export class DOMElement {
|
||||
this.options = {...this.options, ...options};
|
||||
}
|
||||
|
||||
if (this.isHidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._show();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user