mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-12 07:40:26 -08:00
fix from the tests
This commit is contained in:
committed by
Matthieu Baumann
parent
37bf5d94da
commit
14ccc6b5a0
@@ -10,7 +10,7 @@
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: ["P/PanSTARRS/DR1/color-i-r-g"], showReticle: false, gridOptions: {opacity: 0.5}, projection: "AIT", cooFrame: 'galactic', target: "93.2721132 -20.9942421", fov: 1000, showGotoControl: false, showFrame: false, fullScreen: true, showLayersControl: true, showCooGrid: false, showCooGridControl: false});
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: ["P/PanSTARRS/DR1/color-i-r-g"], showReticle: false, gridOptions: {opacity: 0.5, color: 'rgba(255, 0, 0)'}, projection: "AIT", cooFrame: 'galactic', target: "93.2721132 -20.9942421", fov: 1000, showGotoControl: false, showFrame: false, fullScreen: true, showLayersControl: true, showCooGrid: true, showCooGridControl: false});
|
||||
|
||||
const chft = aladin.createImageSurvey('CFHT', "CFHT deep view of NGC7331 and Stephan's quintet u+g+r", "https://cds.unistra.fr/~derriere/PR_HiPS/2022_Duc/", null, null, {imgFormat: 'png'});
|
||||
const nircamJWST = aladin.createImageSurvey('Nircam', "Stephans Quintet NIRCam+MIRI", "http://alasky.cds.unistra.fr/JWST/CDS_P_JWST_Stephans-Quintet_NIRCam+MIRI/", null, null, {imgFormat: 'png', colormap: "viridis"});
|
||||
@@ -21,7 +21,7 @@
|
||||
aladin.getOverlayImageLayer("CFHT").toggle();
|
||||
aladin.getOverlayImageLayer("Nircam").toggle();
|
||||
|
||||
let fov = 1000;
|
||||
let fov = 360;
|
||||
let rotation = 0;
|
||||
|
||||
setInterval(function zoom() {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
let a = A.aladin('#aladin-lite-div', {target: '03 47 00.00 +24 07 00.0', survey: 'P/DSS2/color', zoom: 2, showReticle: false});
|
||||
var cat = A.catalog({name: 'Some markers', sourceSize: 18});
|
||||
a.addCatalog(cat);
|
||||
|
||||
cat.addSources([A.marker(56.87115, 24.10514, {popupTitle: 'Alcyone', popupDesc: '<em>Bmag:</em> 2.806<br/><em>Spectral type:</em> B7III<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME%20ALCYONE&submit=submit">in Simbad</a>'})]);
|
||||
cat.addSources([A.marker(57.29673, 24.13671, {popupTitle: 'Pleione', popupDesc: '<em>Bmag:</em> 4.97<br/><em>Spectral type:</em> B8vne<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME+PLEIONE&NbIdent=1">in Simbad</a>'})]);
|
||||
cat.addSources([A.marker(56.58156, 23.94836, {popupTitle: 'Merope', popupDesc: '<em>Bmag:</em> 4.113<br/><em>Spectral type:</em> BVI4e<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=V*+V971+Tau&NbIdent=1">in Simbad</a>'})]);
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
|
||||
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
|
||||
|
||||
<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', {target: 'M 45', fov: 5, showContextMenu: true});
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<!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';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'M81', fov: 1});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,7 +5,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
|
||||
<script type="text/javascript" src="https://aladin.cds.unistra.fr/AladinLite/api/v3/latest/aladin.umd.cjs" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="https://aladin.cds.unistra.fr/AladinLite/api/v3/latest/aladin.js" charset="utf-8"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
let aladin;
|
||||
|
||||
@@ -160,6 +160,27 @@
|
||||
animation: leftright 5s infinite normal linear;
|
||||
}
|
||||
|
||||
.aladin-long-text {
|
||||
display: inline-block;
|
||||
max-width: 100px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@keyframes leftright {
|
||||
0%,
|
||||
20% {
|
||||
transform: translateX(0%);
|
||||
left: 0%;
|
||||
}
|
||||
80%,
|
||||
100% {
|
||||
/* the max width is 150px and a padding of 0.8em is added for href link */
|
||||
transform: translateX(-100%);
|
||||
left: -100%;
|
||||
}
|
||||
}
|
||||
|
||||
.aladin-measurement-div table th {
|
||||
padding: 0.3em 0.5em;
|
||||
}
|
||||
@@ -190,20 +211,6 @@
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
@keyframes leftright {
|
||||
0%,
|
||||
20% {
|
||||
transform: translateX(0%);
|
||||
left: 0%;
|
||||
}
|
||||
80%,
|
||||
100% {
|
||||
/* the max width is 150px and a padding of 0.8em is added for href link */
|
||||
transform: translateX(calc(-100% + 150px - 0.8em));
|
||||
left: calc(100% - 150px + 0.8em);
|
||||
}
|
||||
}
|
||||
|
||||
.aladin-marker-measurement {
|
||||
max-height: 130px;
|
||||
overflow-y: auto;
|
||||
|
||||
196
src/js/A.js
196
src/js/A.js
@@ -52,6 +52,16 @@ import { ActionButton } from "./gui/Widgets/ActionButton.js";
|
||||
///////////////////////////////
|
||||
/////// 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 ////
|
||||
@@ -59,17 +69,97 @@ let A = {};
|
||||
// rather than creating directly the corresponding JS objects
|
||||
// This facade allows for more flexibility as objects can be updated/renamed harmlessly
|
||||
|
||||
//@API
|
||||
/**
|
||||
* @typedef {Object} AladinOptions
|
||||
* @description Options for configuring the Aladin Lite instance.
|
||||
*
|
||||
* @property {string} [survey="https://alaskybis.unistra.fr/DSS/DSSColor"] URL or ID of the survey to use
|
||||
* @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 {number} [fov=60] - Field of view in degrees.
|
||||
* @property {string} [backgroundColor="rgb(60, 60, 60)"] - Background color in RGB format.
|
||||
*
|
||||
* @property {boolean} [showZoomControl=true] - Whether to show the zoom control toolbar.
|
||||
* @property {boolean} [showLayersControl=true] - Whether to show the layers control toolbar.
|
||||
* @property {boolean} [showFullscreenControl=true] - Whether to show the fullscreen control toolbar.
|
||||
* @property {boolean} [showGotoControl=true] - Whether to show the goto control toolbar.
|
||||
* @property {boolean} [showSimbadPointerControl=false] - Whether to show the Simbad pointer control toolbar.
|
||||
* @property {boolean} [showCooGridControl=false] - Whether to show the coordinate grid control toolbar.
|
||||
* @property {boolean} [showSettingsControl=true] - Whether to show the settings control toolbar.
|
||||
*
|
||||
* @property {boolean} [showShareControl=false] - Whether to show the share control toolbar.
|
||||
*
|
||||
* @property {boolean} [showFrame=true] - Whether to show the viewport frame.
|
||||
* @property {boolean} [showFov=true] - Whether to show the field of view indicator.
|
||||
* @property {boolean} [showCooLocation=true] - Whether to show the coordinate location indicator.
|
||||
* @property {boolean} [showProjectionControl=true] - Whether to show the projection control toolbar.
|
||||
*
|
||||
* @property {boolean} [showContextMenu=false] - Whether to show the context menu.
|
||||
* @property {boolean} [showReticle=true] - Whether to show the reticle.
|
||||
* @property {boolean} [showCatalog=true] - Whether to show the catalog.
|
||||
*
|
||||
* @property {boolean} [fullScreen=false] - Whether to start in full-screen mode.
|
||||
* @property {string} [reticleColor="rgb(178, 50, 178)"] - Color of the reticle in RGB format.
|
||||
* @property {number} [reticleSize=22] - Size of the reticle.
|
||||
* @property {string} [gridColor="rgb(0, 255, 0)"] - Color of the grid in RGB format.
|
||||
* @property {number} [gridOpacity=0.5] - Opacity of the grid (0 to 1).
|
||||
* @property {string} [projection="SIN"] - Projection type.
|
||||
* @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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates an Aladin Lite instance within the specified HTML element.
|
||||
*
|
||||
* @function
|
||||
* @name A.aladin
|
||||
* @memberof A
|
||||
* @param {string} divSelector - The ID selector for the HTML element.
|
||||
* @param {AladinOptions} [options] - Options for configuring the Aladin Lite instance.
|
||||
* @returns {Aladin} An instance of the Aladin Lite library.
|
||||
* @example
|
||||
* const aladinInstance = A.aladin('#aladin-container', options);
|
||||
*/
|
||||
A.aladin = function (divSelector, options) {
|
||||
return new Aladin(document.querySelector(divSelector), options);
|
||||
};
|
||||
|
||||
// @API
|
||||
/**
|
||||
* 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 {*} [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);
|
||||
};
|
||||
|
||||
// @API
|
||||
/**
|
||||
* 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 {*} [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;
|
||||
@@ -130,11 +220,6 @@ A.graphicOverlay = function (options) {
|
||||
return new Overlay(options);
|
||||
};
|
||||
|
||||
// @API
|
||||
A.catalog = function (options) {
|
||||
return new Catalog(options);
|
||||
};
|
||||
|
||||
// @API
|
||||
A.catalogHiPS = function (rootURL, options) {
|
||||
return new ProgressiveCat(rootURL, null, null, options);
|
||||
@@ -188,6 +273,75 @@ A.MOCFromPolygon= function (polygon, options, successCallback, errorCallback) {
|
||||
return moc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents options for configuring a catalog.
|
||||
*
|
||||
* @typedef {Object} CatalogOptions
|
||||
* @property {string} url - The URL of the catalog.
|
||||
* @property {string} [name="catalog"] - The name of the catalog.
|
||||
* @property {string} [color] - The color associated with the catalog.
|
||||
* @property {number} [sourceSize=8] - The size of the sources in the catalog.
|
||||
* @property {number} [markerSize=12] - The size of the markers associated with sources.
|
||||
* @property {string} [shape="square"] - The shape of the sources (e.g., "square", "circle", "rhomb", "triangle", "cross").
|
||||
* @property {number} [limit] - The maximum number of sources to display.
|
||||
* @property {function} [onClick] - The callback function to execute on a source click.
|
||||
* @property {boolean} [readOnly=false] - Whether the catalog is read-only.
|
||||
* @property {string} [raField] - The ID or name of the field holding Right Ascension (RA).
|
||||
* @property {string} [decField] - The ID or name of the field holding Declination (dec).
|
||||
* @property {function} [filter] - The filtering function for sources.
|
||||
* @property {boolean} [displayLabel=false] - Whether to display labels for sources.
|
||||
* @property {string} [labelColor] - The color of the source labels.
|
||||
* @property {string} [labelFont="10px sans-serif"] - The font for the source labels.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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 catalog = A.catalog(options);
|
||||
@@ -196,7 +350,7 @@ A.catalogFromURL = function (url, options, successCallback, errorCallback, usePr
|
||||
let {sources, footprints, fields, type} = table;
|
||||
catalog.setFields(fields);
|
||||
|
||||
if (catalog.isObsCore()) {
|
||||
if (catalog.type === 'ObsCore') {
|
||||
// The fields corresponds to obscore ones
|
||||
// Set the name of the catalog to be ObsCore:<catalog name>
|
||||
catalog.name = "ObsCore:" + url;
|
||||
@@ -365,6 +519,30 @@ A.getAvailableListOfColormaps = function() {
|
||||
return ColorCfg.COLORMAPS;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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')
|
||||
|
||||
@@ -188,24 +188,17 @@ export let Aladin = (function () {
|
||||
}
|
||||
|
||||
// Grid
|
||||
var color, opacity;
|
||||
if (options.gridOptions) {
|
||||
color = options.gridOptions.color && Color.hexToRgb(options.gridOptions.color);
|
||||
opacity = options.gridOptions.opacity;
|
||||
} else {
|
||||
color = Aladin.DEFAULT_OPTIONS.gridColor;
|
||||
opacity = Aladin.DEFAULT_OPTIONS.gridOpacity;
|
||||
}
|
||||
|
||||
this.setCooGrid({
|
||||
color: color,
|
||||
opacity: opacity,
|
||||
});
|
||||
|
||||
let gridOptions = {
|
||||
enabled: false,
|
||||
color: (options.gridOptions && options.gridOptions.color && Color.hexToRgb(options.gridOptions.color)) || Aladin.DEFAULT_OPTIONS.gridColor,
|
||||
opacity: (options.gridOptions && options.gridOptions.opacity) || Aladin.DEFAULT_OPTIONS.gridOpacity
|
||||
};
|
||||
if (options && options.showCooGrid) {
|
||||
this.showCooGrid();
|
||||
gridOptions.enabled = true;
|
||||
}
|
||||
|
||||
this.setCooGrid(gridOptions);
|
||||
|
||||
// Set the projection
|
||||
let projection = (options && options.projection) || 'SIN';
|
||||
this.setProjection(projection)
|
||||
@@ -1338,7 +1331,14 @@ export let Aladin = (function () {
|
||||
this.view.selectObjects(objects)
|
||||
};
|
||||
// Possible values are 'rect', 'poly' and 'circle'
|
||||
Aladin.prototype.select = function (mode = 'rect', callback) {
|
||||
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});
|
||||
};
|
||||
|
||||
@@ -1392,12 +1392,10 @@ export let Aladin = (function () {
|
||||
|
||||
Aladin.prototype.showCooGrid = function () {
|
||||
this.view.setGridConfig({enabled: true});
|
||||
this.cooGridEnabled = true;
|
||||
};
|
||||
|
||||
Aladin.prototype.hideCooGrid = function() {
|
||||
this.view.setGridConfig({enabled: false});
|
||||
this.cooGridEnabled = false;
|
||||
}
|
||||
|
||||
Aladin.prototype.layerByName = function (name) {
|
||||
|
||||
@@ -38,15 +38,60 @@ import { Footprint } from "./Footprint.js";
|
||||
import { ObsCore } from "./vo/ObsCore.js";
|
||||
import A from "./A.js";
|
||||
|
||||
// TODO : harmoniser parsing avec classe ProgressiveCat
|
||||
/**
|
||||
* Represents a catalog with configurable options for display and interaction.
|
||||
*
|
||||
* @namespace
|
||||
* @typedef {Object} Aladin
|
||||
*/
|
||||
export let Catalog = (function() {
|
||||
|
||||
/**
|
||||
* Constructor function for creating a new catalog instance.
|
||||
*
|
||||
* @constructor
|
||||
* @memberof Catalog
|
||||
* @param {Object} options - Configuration options for the catalog.
|
||||
* @param {string} options.url - The URL of the catalog.
|
||||
* @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.
|
||||
* @param {boolean} [options.readOnly=false] - Whether the catalog is read-only.
|
||||
* @param {string} [options.raField] - The ID or name of the field holding Right Ascension (RA).
|
||||
* @param {string} [options.decField] - The ID or name of the field holding Declination (dec).
|
||||
* @param {function} [options.filter] - The filtering function for sources.
|
||||
* @param {boolean} [options.displayLabel=false] - Whether to display labels for sources.
|
||||
* @param {string} [options.labelColor] - The color of the source labels.
|
||||
* @param {string} [options.labelFont="10px sans-serif"] - The font for the source labels.
|
||||
*
|
||||
* @example
|
||||
* const catalogOptions = {
|
||||
* url: "https://example.com/catalog",
|
||||
* name: "My Catalog",
|
||||
* color: "#ff0000",
|
||||
* sourceSize: 10,
|
||||
* markerSize: 15,
|
||||
* shape: "circle",
|
||||
* limit: 1000,
|
||||
* onClick: (source) => { /* handle source click * },
|
||||
* readOnly: true,
|
||||
* raField: "ra",
|
||||
* decField: "dec",
|
||||
* filter: (source) => source.mag < 15,
|
||||
* displayLabel: true,
|
||||
* labelColor: "#00ff00",
|
||||
* labelFont: "12px Arial"
|
||||
* };
|
||||
* const myCatalog = new Catalog(catalogOptions);
|
||||
*/
|
||||
function Catalog(options) {
|
||||
options = options || {};
|
||||
|
||||
this.url = options.url;
|
||||
this.uuid = Utils.uuidv4();
|
||||
this.type = 'catalog';
|
||||
|
||||
this.name = options.name || "catalog";
|
||||
this.color = options.color || Color.getNextColor();
|
||||
this.sourceSize = options.sourceSize || 8;
|
||||
@@ -63,15 +108,6 @@ export let Catalog = (function() {
|
||||
// allows for filtering of sources
|
||||
this.filterFn = options.filter || undefined; // TODO: do the same for catalog
|
||||
|
||||
this.showFieldCallback = {}; // callbacks when the user clicks on a cell in the measurement table associated
|
||||
this.fields = undefined;
|
||||
|
||||
this.indexationNorder = 5; // à quel niveau indexe-t-on les sources
|
||||
this.sources = [];
|
||||
this.ra = [];
|
||||
this.dec = [];
|
||||
this.footprints = [];
|
||||
|
||||
this.displayLabel = options.displayLabel || false;
|
||||
this.labelColor = options.labelColor || this.color;
|
||||
this.labelFont = options.labelFont || '10px sans-serif';
|
||||
@@ -84,6 +120,19 @@ export let Catalog = (function() {
|
||||
|
||||
this.selectionColor = '#00ff00';
|
||||
|
||||
this.showFieldCallback = {}; // callbacks when the user clicks on a cell in the measurement table associated
|
||||
this.fields = undefined;
|
||||
this.uuid = Utils.uuidv4();
|
||||
this.type = 'catalog';
|
||||
|
||||
this.indexationNorder = 5; // à quel niveau indexe-t-on les sources
|
||||
this.sources = [];
|
||||
this.ra = [];
|
||||
this.dec = [];
|
||||
this.footprints = [];
|
||||
|
||||
|
||||
|
||||
// create this.cacheCanvas
|
||||
// cacheCanvas permet de ne créer le path de la source qu'une fois, et de le réutiliser (cf. http://simonsarris.com/blog/427-increasing-performance-by-caching-paths-on-canvas)
|
||||
this.updateShape(options);
|
||||
@@ -734,11 +783,9 @@ export let Catalog = (function() {
|
||||
|
||||
Catalog.prototype.show = function() {
|
||||
if (this.isShowing) {
|
||||
console.log("jkjkj")
|
||||
return;
|
||||
}
|
||||
this.isShowing = true;
|
||||
console.log(this.isShowing)
|
||||
// Dispatch to the footprints
|
||||
if (this.footprints) {
|
||||
this.footprints.forEach((f) => f.show())
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
// along with Aladin Lite.
|
||||
//
|
||||
|
||||
import { Aladin } from "../Aladin";
|
||||
import { Color } from "../Color";
|
||||
import { FSM } from "../FiniteStateMachine";
|
||||
import { View } from "../View";
|
||||
/******************************************************************************
|
||||
@@ -116,6 +114,8 @@ export class RectSelect extends FSM {
|
||||
if (typeof callback === "function") {
|
||||
// !todo
|
||||
let selectedObjects = view.selectObjects(this);
|
||||
console.log(selectedObjects)
|
||||
|
||||
callback(selectedObjects);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,13 @@ import { PlanetaryFeaturesPointer } from "./PlanetaryFeaturesPointer.js";
|
||||
import { Utils } from './Utils';
|
||||
|
||||
// allow to call either Simbad or Planetary features Pointers
|
||||
export let GenericPointer = (function (view, e) {
|
||||
export let GenericPointer = function (view, e) {
|
||||
const xymouse = Utils.relMouseCoords(e);
|
||||
let radec = view.wasm.screenToWorld(xymouse.x, xymouse.y);
|
||||
if (radec) {
|
||||
// sky case
|
||||
if (view.aladin.getBaseImageLayer().isPlanetaryBody() === false) {
|
||||
const queryRadius = Math.min(1, 15 * view.fov / view.largestDim);
|
||||
console.log('queryRadius "generic pointer": ', queryRadius);
|
||||
SimbadPointer.query(radec[0], radec[1], queryRadius, view.aladin);
|
||||
}
|
||||
// planetary body case
|
||||
@@ -27,7 +26,7 @@ export let GenericPointer = (function (view, e) {
|
||||
PlanetaryFeaturesPointer.query(radec[0], radec[1], Math.min(80, view.fov / 20.0), body, view.aladin);
|
||||
}
|
||||
} else {
|
||||
console.log("The location you clicked on is out of the view.");
|
||||
}
|
||||
alert("The location you clicked on is out of the view.");
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -76,8 +76,6 @@ HiPSProperties.fetchFromUrl = async function(urlOrId) {
|
||||
// Relative path
|
||||
try {
|
||||
urlOrId = Utils.getAbsoluteURL(urlOrId)
|
||||
//console.log("jjjj", urlOrId)
|
||||
|
||||
|
||||
urlOrId = new URL(urlOrId);
|
||||
} catch(e) {
|
||||
@@ -105,7 +103,6 @@ HiPSProperties.fetchFromUrl = async function(urlOrId) {
|
||||
if (Utils.requestCORSIfNotSameOrigin(url)) {
|
||||
init = { mode: 'cors' };
|
||||
}
|
||||
console.log('url', url)
|
||||
|
||||
let result = fetch(url, init)
|
||||
.then((response) => {
|
||||
@@ -158,6 +155,8 @@ HiPSProperties.getFasterMirrorUrl = function (metadata) {
|
||||
|
||||
// Get all the possible hips_service_url urls
|
||||
let promises = [];
|
||||
let urls = [metadata.hips_service_url];
|
||||
|
||||
promises.push(pingHiPSServiceUrl(metadata.hips_service_url));
|
||||
|
||||
let numHiPSServiceURL = 1;
|
||||
@@ -167,6 +166,8 @@ HiPSProperties.getFasterMirrorUrl = function (metadata) {
|
||||
let curUrl = metadata[key];
|
||||
promises.push(pingHiPSServiceUrl(curUrl))
|
||||
numHiPSServiceURL += 1;
|
||||
|
||||
urls.push(curUrl)
|
||||
}
|
||||
|
||||
return Promise.all(promises)
|
||||
@@ -193,9 +194,12 @@ HiPSProperties.getFasterMirrorUrl = function (metadata) {
|
||||
} else {
|
||||
return validResponses[0].baseUrl;
|
||||
}
|
||||
} else {
|
||||
} else if (validResponses.length === 1) {
|
||||
return validResponses[0].baseUrl;
|
||||
} else {
|
||||
// no valid response => we return an error
|
||||
throw 'Survey not found. All mirrors urls have been tested:' + urls
|
||||
}
|
||||
})
|
||||
.then((url) => Utils.fixURLForHTTPS(url));
|
||||
.then((url) => Utils.fixURLForHTTPS(url))
|
||||
}
|
||||
|
||||
@@ -180,7 +180,13 @@ export let ImageSurvey = (function () {
|
||||
HiPSProperties.getFasterMirrorUrl(properties)
|
||||
.then((url) => {
|
||||
self.setUrl(url);
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
alert(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);
|
||||
|
||||
@@ -88,7 +88,7 @@ export let MeasurementTable = (function() {
|
||||
layout: layout,
|
||||
cssStyle: {
|
||||
position: 'absolute',
|
||||
bottom: '20px',
|
||||
bottom: '27px',
|
||||
zIndex: 100,
|
||||
maxWidth: '100%',
|
||||
}
|
||||
|
||||
@@ -89,13 +89,16 @@ export class Selector {
|
||||
}
|
||||
|
||||
if (!selection.contains) {
|
||||
// contains must be implemented for the region
|
||||
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];
|
||||
@@ -130,6 +133,7 @@ export class Selector {
|
||||
objListPerCatalog = [];
|
||||
}
|
||||
}
|
||||
|
||||
return objList;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,6 @@ export let SimbadPointer = (function() {
|
||||
var objCoo = new Coo();
|
||||
objCoo.parse(match[1]);
|
||||
var objName = match[2];
|
||||
console.log(encodeURIComponent(objName), objName)
|
||||
var title = '<div class="aladin-sp-title"><a target="_blank" href="https://simbad.cds.unistra.fr/simbad/sim-id?Ident=' + encodeURIComponent(objName) + '">' + objName + '</a></div>';
|
||||
var content = '<div class="aladin-sp-content">';
|
||||
content += '<em>Type: </em>' + match[4] + '<br>';
|
||||
|
||||
@@ -1148,7 +1148,6 @@ export let View = (function () {
|
||||
}
|
||||
// draw popup catalog
|
||||
if (this.catalogForPopup.isShowing && this.catalogForPopup.sources.length > 0) {
|
||||
console.log("draw popup")
|
||||
if (!this.catalogCanvasCleared) {
|
||||
ctx.clearRect(0, 0, this.width, this.height);
|
||||
this.catalogCanvasCleared = true;
|
||||
@@ -1342,6 +1341,9 @@ export let View = (function () {
|
||||
// Called for touchmove events
|
||||
// initialAccDelta must be consistent with fovDegrees here
|
||||
View.prototype.setZoom = function (fovDegrees) {
|
||||
fovDegrees = Math.min(fovDegrees, this.projection.fov);
|
||||
console.log(fovDegrees)
|
||||
|
||||
this.wasm.setFieldOfView(fovDegrees);
|
||||
this.updateZoomState();
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ import { SurveyCtxMenu } from "../CtxMenu/SurveyCtxMenu";
|
||||
super({
|
||||
...options,
|
||||
tooltip: {content: 'Survey name<br/>Click to change it!', position: { direction: 'bottom' }},
|
||||
content: 'Main survey',
|
||||
content: '<div class="aladin-long-text">Main survey</div>',
|
||||
cssStyle: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||
borderColor: 'white',
|
||||
@@ -61,16 +61,19 @@ import { SurveyCtxMenu } from "../CtxMenu/SurveyCtxMenu";
|
||||
this._addListeners(aladin)
|
||||
}
|
||||
|
||||
_hide() {
|
||||
super._hide()
|
||||
}
|
||||
|
||||
_addListeners(aladin) {
|
||||
ALEvent.HIPS_LAYER_ADDED.listenedBy(aladin.aladinDiv, (e) => {
|
||||
const layer = e.detail.layer;
|
||||
if (layer.layer === 'base') {
|
||||
let name = (layer.properties && layer.properties.obsTitle) || layer.name;
|
||||
this.update({
|
||||
content: layer.name,
|
||||
content: '<div class="aladin-long-text">' + name + '</div>',
|
||||
tooltip: {
|
||||
content: name,
|
||||
position: {
|
||||
direction: 'left'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
@@ -63,14 +63,9 @@ export class OverlayStack extends ContextMenu {
|
||||
let self = this;
|
||||
|
||||
let updateImageList = () => {
|
||||
const overlays = Array.from(self.aladin.getOverlays()).reverse().map((overlay) => {
|
||||
return overlay;
|
||||
});
|
||||
|
||||
|
||||
self.attach({overlays});
|
||||
// If it is shown, update it
|
||||
if (!self.isHidden) {
|
||||
// show will update the content of the stack
|
||||
self._show();
|
||||
}
|
||||
};
|
||||
@@ -90,8 +85,10 @@ export class OverlayStack extends ContextMenu {
|
||||
});
|
||||
}
|
||||
|
||||
attach(options) {
|
||||
const overlays = options && options.overlays || [];
|
||||
attach() {
|
||||
const overlays = Array.from(this.aladin.getOverlays()).reverse().map((overlay) => {
|
||||
return overlay;
|
||||
});
|
||||
|
||||
let self = this;
|
||||
|
||||
@@ -284,7 +281,7 @@ export class OverlayStack extends ContextMenu {
|
||||
|
||||
let item = Layout.horizontal({
|
||||
layout: [
|
||||
this._addOverlayIcon(overlay),
|
||||
this._addOverlayIcon(overlay),
|
||||
'<div style="background-color: rgba(0, 0, 0, 0.6); padding: 3px; border-radius: 3px; word-break: break-word;">' + name + '</div>',
|
||||
Layout.horizontal({layout: [showBtn, deleteBtn]})
|
||||
],
|
||||
@@ -343,6 +340,8 @@ export class OverlayStack extends ContextMenu {
|
||||
}
|
||||
|
||||
_show(options) {
|
||||
this.attach();
|
||||
|
||||
this.position = (options && options.position) || this.position || { anchor: 'center center'};
|
||||
super.show({
|
||||
...options,
|
||||
|
||||
@@ -113,13 +113,11 @@ export class SettingsCtxMenu extends ContextMenu {
|
||||
this.sampBtn = sampBtn;
|
||||
|
||||
this._attach();
|
||||
|
||||
}
|
||||
|
||||
_attach() {
|
||||
const toggleWindow = (window) => {
|
||||
let windowShown = self.menu.isShown(window);
|
||||
console.log(windowShown)
|
||||
if(windowShown) {
|
||||
self.menu.disable(window)
|
||||
} else {
|
||||
|
||||
@@ -314,6 +314,10 @@ export class Stack extends ContextMenu {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!layer.properties || !layer.properties.creatorDid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const creatorDid = layer.properties.creatorDid;
|
||||
|
||||
for (const key in Stack.previewImagesUrl) {
|
||||
|
||||
@@ -31,6 +31,48 @@ import { Tooltip } from "./Tooltip";
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Represents an action button that can be added to the DOM.
|
||||
*
|
||||
* @namespace
|
||||
* @typedef {Object} ActionButton
|
||||
* @extends DOMElement
|
||||
*
|
||||
* @param {Object} opt - Options for configuring the action button.
|
||||
* @param {HTMLElement} target - The target element to which the button will be attached.
|
||||
* @param {Object|string} [position="beforeend"] - The position to insert the button relative to the target.
|
||||
*
|
||||
* @property {boolean} [opt.toggled=false] - Whether the button is initially toggled.
|
||||
* @property {function} [opt.action] - The callback function to execute when the button is clicked.
|
||||
* @property {string} [opt.title] - The title attribute for the button.
|
||||
* @property {string} [opt.iconURL] - The URL of the icon image for the button.
|
||||
* @property {boolean} [opt.disable=false] - Whether the button is initially disabled.
|
||||
* @property {HTMLElement|string|Widget} [opt.content] - The content to be added to the button.
|
||||
* @property {CSSStyleSheet} [opt.cssStyle] - The CSS styles to apply to the button.
|
||||
* @property {string} [opt.tooltip] - The tooltip text for the button.
|
||||
* @property {Object|string} [opt.position] - The position of the button.
|
||||
* - If an object:
|
||||
* - `{ nextTo: DOMElement, direction: 'left' | 'right' | 'top' | 'bottom' }`
|
||||
* - `{ top: number, left: number }`
|
||||
* - `{ anchor: 'left top' | 'left center' | 'left bottom' | 'right top' | 'right center' | 'right bottom' | 'center top' | 'center center' | 'center bottom' }`
|
||||
* - If a string: One of the following values: "beforebegin", "afterbegin", "beforeend", "afterend".
|
||||
*
|
||||
* @example
|
||||
* const actionButton = new ActionButton({
|
||||
* toggled: false,
|
||||
* action: (e) => { /* callback function * },
|
||||
* title: "Click me",
|
||||
* iconURL: "path/to/icon.png",
|
||||
* cssStyle: "color: red;",
|
||||
* tooltip: {
|
||||
* position: {
|
||||
* direction: 'left,
|
||||
* },
|
||||
* content: 'A tooltip'
|
||||
* },
|
||||
* position: { nextTo: someDOMElement, direction: 'right' }
|
||||
* }, document.getElementById('container'));
|
||||
*/
|
||||
export class ActionButton extends DOMElement {
|
||||
constructor(opt, target, position = "beforeend") {
|
||||
let el = document.createElement('button');
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
* Author: Matthieu Baumann[CDS]
|
||||
*
|
||||
*****************************************************************************/
|
||||
import { VOTable } from "./VOTable.js";
|
||||
import { Datalink } from "./Datalink.js";
|
||||
import { Utils } from '../Utils';
|
||||
|
||||
|
||||
@@ -248,17 +248,19 @@ export class VOTable {
|
||||
static textDecoder = new TextDecoder();
|
||||
|
||||
constructor(url, successCallback, errorCallback, useProxy) {
|
||||
console.log(url, useProxy)
|
||||
Utils.fetch({
|
||||
url,
|
||||
useProxy,
|
||||
success: data => {
|
||||
try {
|
||||
//console.log(data)
|
||||
let xml = VOTable.parser.parseFromString(data, "text/xml")
|
||||
xml.querySelectorAll("RESOURCE").forEach((rsc) => { successCallback(rsc) })
|
||||
} catch(e) {
|
||||
errorCallback('Catalogue failed to be parsed: ' + e);
|
||||
if (errorCallback) {
|
||||
errorCallback('Catalogue failed to be parsed: ' + e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
},
|
||||
error: e => {
|
||||
@@ -484,8 +486,6 @@ export class VOTable {
|
||||
values[1] = +max.getAttribute("value");
|
||||
}
|
||||
|
||||
console.log(values)
|
||||
|
||||
inputParams['Band'] = {
|
||||
name: 'BAND',
|
||||
type: 'group',
|
||||
@@ -547,7 +547,6 @@ export class VOTable {
|
||||
}
|
||||
})
|
||||
|
||||
console.log("PARSE service RSC", { name, baseUrl, inputParams})
|
||||
return { name, baseUrl, inputParams}
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user