// 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 Aladin.js (main class)
* Facade to expose Aladin Lite methods
*
* Author: Thomas Boch[CDS]
*
*****************************************************************************/
import { MOC } from "./MOC.js";
import { GraphicOverlay } from "./Overlay.js";
import { Circle } from "./shapes/Circle.js";
import { Ellipse } from "./shapes/Ellipse.js";
import { Polyline } from "./shapes/Polyline.js";
import { Vector } from "./shapes/Vector.js";
import { Catalog } from "./Catalog.js";
import { ProgressiveCat } from "./ProgressiveCat.js";
import { Source } from "./Source.js";
import { Coo } from "./libs/astro/coo.js";
import { URLBuilder } from "./URLBuilder.js";
import { Footprint } from './Footprint.js';
import { Aladin } from "./Aladin.js";
import { ActionButton } from "./gui/Widgets/ActionButton.js";
import { Box } from "./gui/Widgets/Box.js";
import { AladinUtils } from "./AladinUtils.js";
import { Sesame } from "./Sesame.js";
// Wasm top level import
import init, * as module from './../core/pkg';
// Import aladin css inside the project
import aladinCSS from './../css/aladin.css?inline';
///////////////////////////////
/////// Aladin Lite API ///////
///////////////////////////////
/**
* @namespace A
* @description Aladin Lite API namespace for creating celestial objects.
* @example
* // Usage example:
* import { A } from 'aladin-lite';
*
* const aladin = new A.aladin("#aladin-lite-div", { survey: 'your survey url', fov: 180, projection: 'SIN' });
*/
let A = {};
//// New API ////
// For developers using Aladin lite: all objects should be created through the API,
// rather than creating directly the corresponding JS objects
// This facade allows for more flexibility as objects can be updated/renamed harmlessly
/**
* Creates an Aladin Lite instance within the specified HTML element.
*
* @function
* @name A.aladin
* @memberof A
* @param {string|HTMLElement} divSelector - The ID selector for the HTML element or the HTML element itself
* @param {AladinOptions} [options] - Options for configuring the Aladin Lite instance.
* @returns {Aladin} An instance of the Aladin Lite library.
* @example
* var aladin;
* A.init.then(() => {
* aladin = A.aladin('#aladin-lite-div', {fullScreen: true, cooFrame: "ICRSd", showSimbadPointerControl: true, showShareControl: true, showShareControl: true, survey: 'https://alasky.cds.unistra.fr/DSS/DSSColor/', fov: 180, showContextMenu: true});
* })
*/
A.aladin = function (divSelector, options) {
let divElement;
if (!(divSelector instanceof HTMLElement)) {
divElement = document.querySelector(divSelector)
} else {
divElement = divSelector;
}
// Associate the CSS inside the div
var cssStyleSheet = document.createElement('style')
cssStyleSheet.classList.add("aladin-css");
cssStyleSheet.innerHTML = aladinCSS;
divElement.appendChild(cssStyleSheet)
return new Aladin(divElement, options);
};
/**
* Creates a HiPS image object
*
* @function
* @name A.HiPS
* @memberof A
* @param {string} id - Can be:
* <ul>
* <li>An http url towards a HiPS.</li>
* <li>A relative path to your HiPS</li>
* <li>A special ID pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}</li>
* </ul>
* @param {HiPSOptions} [options] - Options describing the survey
* @returns {HiPS} - A HiPS image object
*/
A.HiPS = function (id, options) {
return Aladin.createImageSurvey(
id,
options && options.name,
(options && options.url) || id,
options && options.cooFrame,
options && options.maxOrder,
options
);
}
/**
* @function
* @name A.imageHiPS
* @memberof A
* @deprecated
* Old method name, use {@link A.HiPS} instead.
*/
A.imageHiPS = A.HiPS;
/**
* Creates a celestial source object with the given coordinates.
*
* @function
* @name A.image
* @memberof A
* @param {string} url - Options describing the fits file. An url is mandatory
* @param {ImageOptions} [options] - Options describing the fits file. An url is mandatory
* @returns {Image} - A HiPS image object
* @example
* aladin.setOverlayImageLayer(A.image(
* "https://nova.astrometry.net/image/25038473?filename=M61.jpg",
* {
* name: "M61",
* imgFormat: 'jpeg',
* wcs: {
* NAXIS: 0, // Minimal header
* CTYPE1: 'RA---TAN', // TAN (gnomic) projection
* CTYPE2: 'DEC--TAN', // TAN (gnomic) projection
* EQUINOX: 2000.0, // Equatorial coordinates definition (yr)
* LONPOLE: 180.0, // no comment
* LATPOLE: 0.0, // no comment
* CRVAL1: 185.445488837, // RA of reference point
* CRVAL2: 4.47896032431, // DEC of reference point
* CRPIX1: 588.995094299, // X reference pixel
* CRPIX2: 308.307905197, // Y reference pixel
* CUNIT1: 'deg', // X pixel scale units
* CUNIT2: 'deg', // Y pixel scale units
* CD1_1: -0.000223666022989, // Transformation matrix
* CD1_2: 0.000296578064584, // no comment
* CD2_1: -0.000296427555509, // no comment
* CD2_2: -0.000223774308964, // no comment
* NAXIS1: 1080, // Image width, in pixels.
* NAXIS2: 705 // Image height, in pixels.
* },
* successCallback: (ra, dec, fov, image) => {
* aladin.gotoRaDec(ra, dec);
* aladin.setFoV(fov * 5)
* }
* },
* ));
*/
A.image = function (url, options) {
return Aladin.createImageFITS(url, options, options.successCallback, options.errorCallback);
}
/**
* Creates a celestial source object with the given coordinates.
*
* @function
* @name A.source
* @memberof A
* @param {number} ra - Right Ascension (RA) coordinate in degrees.
* @param {number} dec - Declination (Dec) coordinate in degrees.
* @param {Object} [data] - Additional data associated with the source.
* @param {SourceOptions} [options] - Options for configuring the source object.
* @returns {Source} A celestial source object.
* @example
* const sourceObj = A.source(180.0, 30.0, data, options);
*/
A.source = function (ra, dec, data, options) {
return new Source(ra, dec, data, options);
};
/**
* Creates a marker at the specified celestial coordinates.
*
* @function
* @name A.marker
* @memberof A
* @param {number} ra - Right Ascension (RA) coordinate in degrees.
* @param {number} dec - Declination (Dec) coordinate in degrees.
* @param {MarkerOptions} [options] - Options for configuring the marker.
* @param {Object} [data] - Additional data associated with the marker.
* @returns {Source} A marker source object.
* @example
* const markerObj = A.marker(180.0, 30.0, data, options);
*/
A.marker = function (ra, dec, options, data) {
options = options || {};
options['marker'] = true;
return A.source(ra, dec, data, options);
};
/**
* Creates a polygon object using an array of celestial coordinates (RA, Dec).
*
* @function
* @memberof A
* @name polygon
*
* @param {Array.<number[]>} radecArray - right-ascension/declination 2-tuple array describing the polyline's vertices in degrees
* @param {ShapeOptions} options - Options for configuring the polygon
* @throws {string} Throws an error if the number of vertices is less than 3.
*
* @returns {Polyline}
*/
A.polygon = function (raDecArray, options) {
const lastVertexIdx = raDecArray.length - 1;
// User gave a closed polygon, so we remove the last vertex
if (raDecArray[0][0] == raDecArray[lastVertexIdx][0] && raDecArray[0][1] == raDecArray[lastVertexIdx][1]) {
raDecArray.pop()
// but declare the polygon as closed
}
options = options || {};
options.closed = true;
return new Polyline(raDecArray, options);
};
/**
* Creates a polyline shape
*
* @function
* @memberof A
* @name polyline
*
* @param {Array.<number[]>} radecArray - right-ascension/declination 2-tuple array describing the polyline's vertices in degrees
* @param {ShapeOptions} options - Options for configuring the polyline.
*
* @returns {Polyline}
*/
A.polyline = function (raDecArray, options) {
return new Polyline(raDecArray, options);
};
/**
* Creates a circle shape
*
* @function
* @memberof A
* @name circle
*
* @param {number} ra - Right Ascension (RA) coordinate of the center in degrees.
* @param {number} dec - Declination (Dec) coordinate of the center in degrees.
* @param {number} radiusDeg - Radius in degrees.
* @param {ShapeOptions} options - Options for configuring the circle.
* @returns {Circle}
*/
A.circle = function (ra, dec, radiusDeg, options) {
return new Circle([ra, dec], radiusDeg, options);
};
/**
* Creates an ellipse shape
*
* @function
* @memberof A
* @name ellipse
*
* @param {number} ra - Right Ascension (RA) coordinate of the center in degrees.
* @param {number} dec - Declination (Dec) coordinate of the center in degrees.
* @param {number} radiusRaDeg - the radius along the ra axis in degrees
* @param {number} radiusDecDeg - the radius along the dec axis in degrees
* @param {number} rotationDeg - the rotation angle in degrees
* @param {ShapeOptions} options - Options for configuring the ellipse.
* @returns {Ellipse}
*/
A.ellipse = function (ra, dec, radiusRaDeg, radiusDecDeg, rotationDeg, options) {
return new Ellipse([ra, dec], radiusRaDeg, radiusDecDeg, rotationDeg, options);
};
/**
* Creates a vector shape
*
* @function
* @memberof A
* @name vector
*
* @param {number} ra1 - Right Ascension (RA) coordinate of the center in degrees.
* @param {number} dec1 - Declination (Dec) coordinate of the center in degrees.
* @param {number} ra2 - Right Ascension (RA) coordinate of the center in degrees.
* @param {number} dec2 - Declination (Dec) coordinate of the center in degrees.
* @param {ShapeOptions} options - Options for configuring the vector.
*
* @returns {Vector}
*/
A.vector = function (ra1, dec1, ra2, dec2, options) {
options = options || {};
options['arrow'] = true;
return new Vector(ra1, dec1, ra2, dec2, options);
}
/**
* Creates a graphic overlay on the Aladin Lite view.
*
* @function
* @memberof A
* @name graphicOverlay
*
* @param {Object} options - Options for configuring the graphic overlay.
* @param {string} [options.color] - The color of the graphic overlay.
* @param {number} [options.lineWidth] - The width of the lines in the graphic overlay.
* @param {Array} [options.lineDash] - The dash pattern for the lines in the graphic overlay.
* @returns {Overlay} Returns a new Overlay object representing the graphic overlay.
*
* @example
* var overlay = A.graphicOverlay({ color: '#ee2345', lineWidth: 3, lineDash: [2, 4]});
*/
A.graphicOverlay = function (options) {
return new GraphicOverlay(options);
};
/**
* Creates progressive catalog object (i.e. Simbad/Gaia)
*
* @function
* @memberof A
* @name catalogHiPS
*
* @param {string} url - Root url of the catalog
* @param {CatalogOptions} options - Options for configuring the catalogue.
* @returns {ProgressiveCat} Returns a new Overlay object representing the graphic overlay.
*
* @example
* let gaia = A.catalogHiPS('http://axel.u-strasbg.fr/HiPSCatService/I/345/gaia2', {onClick: 'showTable', color: 'orange', name: 'Gaia', filter: myFilterFunction});
* aladin.addCatalog(gaia)
*/
A.catalogHiPS = function (url, options) {
return new ProgressiveCat(url, null, null, options);
};
/**
* Creates a new coo from a longitude and latitude given in degrees
*
* @function
* @memberof A
* @name coo
*
* @param {number} longitude - longitude (decimal degrees)
* @param {number} latitude - latitude (decimal degrees)
* @param {number} prec - precision
* (8: 1/1000th sec, 7: 1/100th sec, 6: 1/10th sec, 5: sec, 4: 1/10th min, 3: min, 2: 1/10th deg, 1: deg
* @returns {Coo} Returns a new Coo object
*/
A.coo = function (longitude, latitude, prec) {
return new Coo(longitude, latitude, prec);
};
/**
* Creates a new footprint from an array of polygons and optionally a source
*
* @function
* @memberof A
* @name footprint
*
* @param {Circle[]|Polyline[]|Ellipse[]|Vector[]} shapes - an array of A.polygon objects
* @param {Source} [source] - a A.source object associated with the footprint
*
* @returns {Footprint} Returns a new Footprint object
*/
A.footprint = function(shapes, source) {
return new Footprint(shapes, source);
};
/**
* Parse shapes from a STC-S string
*
* @function
* @memberof A
* @name footprintsFromSTCS
*
* @param {string} stcs - The STC-S string describing the shapes
* @param {ShapeOptions} [options] - Options for the shape
* @returns {Array.<Polyline|Circle>} Returns a list of shapes from the STC-S string
*/
A.footprintsFromSTCS = function (stcs, options) {
var footprints = GraphicOverlay.parseSTCS(stcs, options);
return footprints;
}
/**
* Creates a new MOC (Multi-Order-Coverage) from an url
*
* @function
* @memberof A
* @name MOCFromURL
*
* @param {string} url - The url to the MOC (e.g. stored as FITS file)
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*/
A.MOCFromURL = function (url, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(url, successCallback, errorCallback);
return moc;
};
/**
* Creates a new MOC (Multi-Order-Coverage) from a JSON-like dictionary (javascript Object)
*
* @function
* @memberof A
* @name MOCFromJSON
*
* @param {Object} jsonMOC - The MOC stores as a JSON-like dictionary
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*
* @example
* var json = {
* "3": [517],
* "4": [2065,2066,2067,2112,2344,2346,2432],
* "5": [8221,8257,8258,8259,8293,8304,8305,8307,8308,8452,8456,9346,9352,9354,9736],
* "6": [32861,32862,32863,32881,32882,32883,32892,32893,33025,33026,33027,33157,33168,33169,33171,
* 33181,33224,33225,33227,33236,33240,33812,33816,33828,33832,37377,37378,37379,37382,37388,
* 37390,37412,37414,37420,37422,37562,38928,38930,38936,38948,38952],
* "7": [131423,131439,131443,131523,131556,131557,131580,131581,132099,132612,132613,132624,132625,132627,132637,
* 132680,132681,132683,132709,132720,132721,132904,132905,132948,132952,132964,132968,133008,133009,133012,135252,135256,135268,135316,135320,135332,135336,148143,148152,148154,149507,149520
* ,149522,149523,149652,149654,149660,149662,149684,149686,149692,149694,149695,150120,150122,150208,150210,150216,150218,150240,150242,150243,155748,155752,155796,155800,155812,155816]
* };
* var moc = A.MOCFromJSON(json, {opacity: 0.25, color: 'magenta', lineWidth: 3});
* aladin.addMOC(moc);
*/
A.MOCFromJSON = function (jsonMOC, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(jsonMOC, successCallback, errorCallback);
return moc;
};
/**
* Creates a new MOC (Multi-Order-Coverage) from an object describing a cone on the sky
*
* @function
* @memberof A
* @name MOCFromCone
*
* @param {Object} circle - A object describing a cone in the sky
* @param {number} circle.ra - Right-ascension of the circle's center (in deg)
* @param {number} circle.dec - Declination of the circle's center (in deg)
* @param {number} circle.radius - Radius of the circle (in deg)
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*/
A.MOCFromCone = function (circle, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(circle, successCallback, errorCallback);
return moc;
};
/**
* Creates a new MOC (Multi-Order-Coverage) from an object describing a polygon on the sky
*
* @function
* @memberof A
* @name MOCFromPolygon
*
* @param {Object} polygon - A object describing a polygon in the sky
* @param {number[]} polygon.ra - Right-ascensions of the polygon's vertices (in deg)
* @param {number[]} polygon.dec - Declination of the polygon's vertices (in deg)
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*/
A.MOCFromPolygon= function (polygon, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(polygon, successCallback, errorCallback);
return moc;
};
/**
* Represents a catalog with configurable options for display and interaction.
*
* @function
* @name A.catalog
* @memberof A
* @param {CatalogOptions} options - Configuration options for the catalog.
* @returns {Catalog}
*/
A.catalog = function (options) {
return new Catalog(options);
};
/**
* Asynchronously creates a new catalog instance from the specified URL with additional options.
*
* @function
* @memberof A
* @name A.catalogFromURL
* @param {string} url - The URL of the catalog.
* @param {CatalogOptions} [options] - Additional configuration options for the catalog.
* @param {function} [successCallback] - The callback function to execute on successful catalog creation.
* @param {function} [errorCallback] - The callback function to execute on error during catalog creation.
* @param {boolean} [useProxy=false] - Indicates whether to use a proxy for loading the catalog.
* @returns {Catalog} A new instance of the Catalog class created from the specified URL.
*
* @example
* // Create a catalog from a URL using the A.catalogFromURL method
* const catalogURL = "https://example.com/catalog";
* const catalogOptions = {
* name: "My Catalog",
* color: "#ff0000",
* sourceSize: 10,
* // ... other options
* };
*
* const myCatalog = A.catalogFromURL(
* catalogURL,
* catalogOptions,
* (catalog) => {
* // Catalog successfully loaded
* aladin.addCatalog(catalog)
* },
* (error) => {
* // Error loading catalog
* console.error("Error loading catalog:", error);
* },
* );
*/
A.catalogFromURL = function (url, options, successCallback, errorCallback, useProxy) {
options.url = url;
var c = A.catalog(options);
const processVOTable = function (table) {
let {sources, fields} = table;
c.setFields(fields);
c.addSources(sources);
const s_regionFieldFound = Array.from(Object.keys(fields)).find((f) => f.toLowerCase() === 's_region');
if (s_regionFieldFound && typeof c.shape !== 'function') {
// set the shape
c.setShape((s) => {
if (!s.data.s_region)
return;
const shapes = A.footprintsFromSTCS(s.data.s_region, options)
let fp = new Footprint(shapes, s);
fp.setColor(c.color);
fp.setHoverColor(c.hoverColor);
fp.setSelectionColor(c.selectionColor);
return fp;
})
}
if (successCallback) {
successCallback(c);
}
if (sources.length === 0) {
console.warn(c.name + ' has no sources!')
}
// Even if the votable is not a proper ObsCore one, try to see if specific columns are given
// e.g. access_format and access_url
//ObsCore.handleActions(c);
};
if (useProxy !== undefined) {
Catalog.parseVOTable(
url,
processVOTable,
errorCallback,
c.maxNbSources,
useProxy,
c.raField, c.decField
);
} else {
Catalog.parseVOTable(
url,
processVOTable,
() => {
Catalog.parseVOTable(
url,
processVOTable,
errorCallback,
c.maxNbSources,
true,
c.raField, c.decField
);
},
c.maxNbSources,
false,
c.raField, c.decField
);
}
return c;
};
/**
* Create a catalog from a SIMBAD cone search query
*
* @function
* @memberof A
* @name A.catalogFromSimbad
* @param {string|Object} target - can be either a string representing a position or an object name, or can be an object with keys 'ra' and 'dec' (values being in decimal degrees)
* @param {number} target.ra - Right Ascenscion in degrees of the cone's center
* @param {number} target.dec - Declination in degrees of the cone's center
* @param {number} radius - Radius of the cone in degrees
* @param {Object|CatalogOptions} [options] - Additional configuration options for SIMBAD cone search. See the {@link https://simbad.cds.unistra.fr/cone/help/#/ConeSearch/get_ SIMBAD cone search} parameters.
* @param {number} [options.limit] - The max number of sources to return
* @param {string} [options.orderBy='nb_ref'] - Order the result by specific ref number
* @param {number} [options.verbosity=2] - Verbosity, put 3 if you want all the column
* @param {function} [successCallback] - The callback function to execute on successful catalog creation.
* @param {function} [errorCallback] - The callback function to execute on error during catalog creation.
* @returns {Catalog} A new instance of the Catalog class created from the SIMBAD cone search.
*
* @example
* A.catalogFromSimbad('09 55 52.4 +69 40 47', 0.1, {onClick: 'showTable', limit: 1000}, (cat) => {
* aladin.addCatalog(cat)
* });
*/
A.catalogFromSimbad = function (target, radius, options, successCallback, errorCallback) {
options = options || {};
if (!('name' in options)) {
options['name'] = 'Simbad';
}
let cat = A.catalog(options);
new Promise((resolve, reject) => {
let coo;
if (target && (typeof target === "object")) {
if ('ra' in target && 'dec' in target) {
coo = new Coo(target.ra, target.dec, 7);
resolve(coo)
}
} else {
var isObjectName = /[a-zA-Z]/.test(target);
// Try to parse as a position
if (!isObjectName) {
coo = new Coo();
coo.parse(target);
resolve(coo);
} else {
// object name, use sesame
Sesame.resolve(target,
function (data) { // success callback
// Location given in icrs at J2000
coo = new Coo(data.coo.jradeg, data.coo.jdedeg);
resolve(coo)
},
function (data) { // errror callback
if (console) {
console.log("Could not resolve object name " + target);
console.log(data);
}
reject(data)
}
);
}
}
}).then((coo) => {
const url = URLBuilder.buildSimbadCSURL(coo.lon, coo.lat, radius, options)
const processVOTable = function (table) {
let {sources, fields} = table;
cat.setFields(fields);
cat.addSources(sources);
cat.url = url;
if (successCallback) {
successCallback(cat);
}
if (sources.length === 0) {
console.warn(cat.name + ' has no sources!')
}
};
Catalog.parseVOTable(
url,
processVOTable,
errorCallback,
cat.maxNbSources,
false,
cat.raField, cat.decField
);
})
return cat;
};
/**
* Create a catalog from a NED cone search query
*
* @function
* @memberof A
* @name A.catalogFromNED
* @param {string|Object} target - can be either a string representing a position or an object name, or can be an object with keys 'ra' and 'dec' (values being in decimal degrees)
* @param {number} target.ra - Right Ascenscion in degrees of the cone's center
* @param {number} target.dec - Declination in degrees of the cone's center
* @param {number} radius - Radius of the cone in degrees
* @param {CatalogOptions} [options] - Additional configuration options for the catalogue.
*
* @param {function} [successCallback] - The callback function to execute on successful catalog creation.
* @param {function} [errorCallback] - The callback function to execute on error during catalog creation.
* @returns {Catalog}
*
* @example
* A.catalogFromNED('09 55 52.4 +69 40 47', 0.1, {onClick: 'showPopup', shape: 'plus'})
*/
A.catalogFromNED = function (target, radius, options, successCallback, errorCallback) {
options = options || {};
if (!('name' in options)) {
options['name'] = 'NED';
}
var url;
if (target && (typeof target === "object")) {
if ('ra' in target && 'dec' in target) {
url = URLBuilder.buildNEDPositionCSURL(target.ra, target.dec, radius);
}
}
else {
var isObjectName = /[a-zA-Z]/.test(target);
if (isObjectName) {
url = URLBuilder.buildNEDObjectCSURL(target, radius);
}
else {
var coo = new Coo();
coo.parse(target);
url = URLBuilder.buildNEDPositionCSURL(coo.lon, coo.lat, radius);
}
}
return A.catalogFromURL(url, options, successCallback, errorCallback, true);
};
/**
* Create a catalog from a SKAORucio cone search query
*
* @function
* @memberof A
* @name A.catalogFromSKAORucio
* @param {string|Object} target - can be either a string representing a position or an object name, or can be an object with keys 'ra' and 'dec' (values being in decimal degrees)
* @param {number} target.ra - Right Ascenscion in degrees of the cone's center
* @param {number} target.dec - Declination in degrees of the cone's center
* @param {number} radiusDegrees - Radius of the cone in degrees
* @param {CatalogOptions} [options] - Additional configuration options for the catalogue.
*
* @param {function} [successCallback] - The callback function to execute on successful catalog creation.
* @param {function} [errorCallback] - The callback function to execute on error during catalog creation.
* @returns {Catalog}
*
* @example
* A.catalogFromSKAORucio('09 55 52.4 +69 40 47', 0.1, {onClick: 'showPopup', shape: 'plus'})
*/
A.catalogFromSKAORucio = function (target, radiusDegrees, options, successCallback, errorCallback) {
options = options || {};
if (!('name' in options)) {
options['name'] = 'SKAO';
}
var url = URLBuilder.buildSKAORucioCSURL(target, radiusDegrees);
return A.catalogFromURL(url, options, successCallback, errorCallback, true);
};
/**
* Create a catalog from a SKAORucio cone search query
*
* @function
* @memberof A
* @name A.catalogFromVizieR
* @param {string} vizCatId - the id of the ViZieR catalog
* @param {string|Object} target - can be either a string representing a position or an object name, or can be an object with keys 'ra' and 'dec' (values being in decimal degrees)
* @param {number} target.ra - Right Ascenscion in degrees of the cone's center
* @param {number} target.dec - Declination in degrees of the cone's center
* @param {number} radius - Radius of the cone in degrees
* @param {CatalogOptions} [options] - Additional configuration options for the catalogue.
*
* @param {function} [successCallback] - The callback function to execute on successful catalog creation.
* @param {function} [errorCallback] - The callback function to execute on error during catalog creation.
* @returns {Catalog}
*
* @example
* const cat = A.catalogFromVizieR('I/311/hip2', 'M 45', 5, {onClick: 'showTable'});
* const cat2 = A.catalogFromVizieR('I/311/hip2', '12 +9', 5, {onClick: 'showTable'});
*/
A.catalogFromVizieR = function (vizCatId, target, radius, options, successCallback, errorCallback) {
options = options || {};
if (!('name' in options)) {
options['name'] = 'VizieR:' + vizCatId;
}
var url = URLBuilder.buildVizieRCSURL(vizCatId, target, radius, options);
return A.catalogFromURL(url, options, successCallback, errorCallback, false);
};
/**
* Create a catalog from a SkyBot cone search query
*
* @function
* @memberof A
* @name A.catalogFromSkyBot
* @param {number} ra - Right Ascenscion in degrees of the cone's center
* @param {number} dec - Declination in degrees of the cone's center
* @param {number} radius - Radius of the cone in degrees
* @param {string} epoch - Requested epoch, expressed in Julian day or ISO dateTime
* @param {Object} queryOptions - options passed to SkyBot, see {@link https://vo.imcce.fr/webservices/skybot/?conesearch}
* @param {CatalogOptions} [options] - Additional configuration options for the catalogue.
* @param {function} [successCallback] - The callback function to execute on successful catalog creation.
* @param {function} [errorCallback] - The callback function to execute on error during catalog creation.
* @returns {Catalog}
*/
A.catalogFromSkyBot = function (ra, dec, radius, epoch, queryOptions, options, successCallback, errorCallback) {
queryOptions = queryOptions || {};
options = options || {};
if (!('name' in options)) {
options['name'] = 'SkyBot';
}
var url = URLBuilder.buildSkyBotCSURL(ra, dec, radius, epoch, queryOptions);
return A.catalogFromURL(url, options, successCallback, errorCallback, false);
};
/**
* Creates a user interface button for Aladin Lite
*
* @function
* @memberof A
* @name button
*
* @param {Object} options - Options for configuring the button.
* @param {boolean} [options.toggled=false] - Whether the button is initially toggled.
* @param {function} [options.action] - The callback function to execute when the button is clicked.
* @param {string} [options.title] - The title attribute for the button.
* @param {Object} [options.icon] - An icon object for the button.
* @param {boolean} [options.disable=false] - Whether the button is initially disabled.
* @param {HTMLElement|string|Widget} [options.content] - The content to be added to the button.
* @param {CSSStyleSheet} [options.cssStyle] - The CSS styles to apply to the button.
* @param {Object} [options.tooltip] - A tooltip.
* @param {Object|string} [options.position] - The position of the button.
* @param {string} [options.size] - The size of the button. Can be 'medium' or 'small'
* @returns {ActionButton} Returns a new button object representing the graphic overlay.
*
* @example
* <!-- This example instanciates a customized button that when clicked, enters the user in
* the polygonal selection mode. Once the polygon selection is done, the vertices are converted
* to sky coords and a Multi-Order Coverage (MOC) is created from that list of sky coords. -->
<!doctype html>
<html>
<head>
</head>
<body>
<div id="aladin-lite-div" style="width: 512px; height: 512px"></div>
<script type="module">
import A from aladin-lite;
let aladin;
A.init.then(() => {
var aladin = A.aladin(
'#aladin-lite-div',
{
survey: 'P/allWISE/color', // set initial image survey
projection: 'AIT', // set a projection
fov: 1.5, // initial field of view in degrees
target: 'NGC 2175', // initial target
cooFrame: 'icrs', // set galactic frame
reticleColor: '#ff89ff', // change reticle color
reticleSize: 64, // change reticle size
showContextMenu: true,
}
);
let btn = A.button({
content: 'My button',
classList: ['myButton'],
tooltip: {cssStyle: {color: 'red'}, content: 'Create a moc in pink!', position: {direction: 'top'}},
action(o) {
aladin.select('poly', p => {
try {
let ra = []
let dec = []
for (const v of p.vertices) {
let [lon, lat] = aladin.pix2world(v.x, v.y);
ra.push(lon)
dec.push(lat)
}
let moc = A.MOCFromPolygon(
{ra, dec},
{name: 'poly', lineWidth: 3.0, color: 'pink'},
);
aladin.addMOC(moc)
} catch(_) {
alert('Selection covers a region out of the projection definition domain.');
}
})
}
});
aladin.addUI(btn)
});
</script>
<style>
.myButton {
position: absolute;
bottom: 0;
left: 0;
background-color: pink;
}
</style>
</body>
</html>
*/
A.button = function(options) {
return new ActionButton(options);
}
/**
* Creates a box user interface for Aladin Lite.
*
* @function
* @memberof A
* @name box
*
* @param {Object} options - Options for configuring the button.
* @param {Object} [options.header] - The header of the box
* @param {boolean} [options.header.draggable=false] - Can move the window by dragging its title.
* @param {string} [options.header.title] - A title name for the window
* @param {HTMLElement|string|Widget} [options.content] - The content to be added to the button.
* @param {CSSStyleSheet} [options.cssStyle] - The CSS styles to apply to the button.
* @param {Object|string} [options.position] - The position of the button.
* @returns {Box} Returns a new box window object.
*
* @example
* let box = A.box({
* header: {
* title: "My window",
* draggable: true,
* },
* // Adding a CSS class allowing you to position your window on the aladin lite view
* classList: ['myBox'],
* content: "This is the content of my window<br/> I can write proper html",
* })
* aladin.addUI(box)
*/
A.box = function(options) {
return new Box(options)
}
/**
* Returns Utils object.
*
* This contains utilitary methods such as HEALPix basic or projection methods.
*
* @function
* @memberof A
* @name Utils
*
* @returns {AladinUtils} Returns a new box window object.
*/
A.Utils = AladinUtils;
/**
* Initializes the Aladin Lite library, checking for WebGL2 support.
* This method must be called before instancing an Aladin Lite object.
*
* @function
* @name A.init
* @memberof A
* @async
*
* @throws {string} Throws an error if WebGL2 is not supported by the browser.
*
* @returns {Promise<void>} A promise that resolves once the initialization is complete.
*
* @example
* // Usage example:
* A.init
* .then(async () => {
* const aladinInstance = A.aladin('div', requestedOptions);
* // Perform further actions with the Aladin Lite instance
* })
* .catch(error => {
* console.error('Error initializing Aladin Lite:', error);
* });
*/
A.init = (async () => {
const isWebGL2Supported = document
.createElement('canvas')
.getContext('webgl2');
await init({});
// Check for webgl2 support
if (isWebGL2Supported) {
Aladin.wasmLibs.core = module;
} else {
// WebGL1 not supported
// According to caniuse, https://caniuse.com/webgl2, webgl2 is supported by 89% of users
throw "WebGL2 not supported by your browser";
}
})();
export default A;