@cquiroz/aladin-lite
Version:
AladinLite module
1,404 lines (1,160 loc) • 61.5 kB
JavaScript
// 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 CooFrameEnum from "./CooFrameEnum";
import Coo from "./coo";
import AladinUtils from "./AladinUtils";
import { HpxImageSurvey } from "./HpxImageSurvey";
import CooConversion from "./CooConversion";
import MeasurementTable from "./MeasurementTable";
import Overlay from "./Overlay";
import View from "./View";
import Logger from "./Logger";
import Location from "./Location";
import Utils from "./Utils";
import ProjectionEnum from "./ProjectionEnum";
import ProgressiveCat from "./ProgressiveCat";
import Color from "./Color";
import ColorMap from "./ColorMap";
import Box from "./Box";
import Source from "./Source";
import { catalog, footprintsFromSTCS, catalogFromURL, marker } from "./A";
var Aladin = function () {
var urlParam = function urlParam(name, queryString) {
if (queryString === undefined) {
queryString = window.location.search;
}
return decodeURIComponent((new RegExp("[?|&]" + name + "=([^&;]+?)(&|#|;|$)").exec(queryString) || ["", ""])[1].replace(/\+/g, "%20")) || null;
}; // Constructor
var Aladin = function Aladin(aladinDiv, requestedOptions) {
// check that aladinDiv exists, stop immediately otherwise
if (!aladinDiv) {
console.log("Could not find div " + aladinDiv + ". Aborting creation of Aladin Lite instance");
return;
}
var self = this;
var aladin = this; // if not options was set, try to retrieve them from the query string
if (requestedOptions === undefined) {
requestedOptions = this.getOptionsFromQueryString();
}
requestedOptions = requestedOptions || {}; // merge with default options
var options = {};
for (var key in Aladin.DEFAULT_OPTIONS) {
if (requestedOptions[key] !== undefined) {
options[key] = requestedOptions[key];
} else {
options[key] = Aladin.DEFAULT_OPTIONS[key];
}
}
for (var _key in requestedOptions) {
if (Aladin.DEFAULT_OPTIONS[_key] === undefined) {
options[_key] = requestedOptions[_key];
}
}
this.options = options; // It seems this isn't in use
// $("<style type='text/css'> .aladin-reticleColor { color: " + this.options.reticleColor + "; font-weight:bold;} </style>").appendTo(aladinDiv);
this.aladinDiv = aladinDiv;
this.reduceDeformations = true; // parent div
aladinDiv.classList.add("aladin-container");
var cooFrame = CooFrameEnum.fromString(options.cooFrame, CooFrameEnum.J2000); // locationDiv is the div where we write the position
// var locationDiv = $(
// '<div class="aladin-location">' +
// (options.showFrame
// ? '<select class="aladin-frameChoice"><option value="' +
// CooFrameEnum.J2000.label +
// '" ' +
// (cooFrame === CooFrameEnum.J2000 ? 'selected="selected"' : "") +
// '>J2000</option><option value="' +
// CooFrameEnum.J2000d.label +
// '" ' +
// (cooFrame === CooFrameEnum.J2000d ? 'selected="selected"' : "") +
// '>J2000d</option><option value="' +
// CooFrameEnum.GAL.label +
// '" ' +
// (cooFrame === CooFrameEnum.GAL ? 'selected="selected"' : "") +
// ">GAL</option></select>"
// : "") +
// '<span class="aladin-location-text"></span></div>'
// ).appendTo(aladinDiv);
var locationDiv = document.createElement("div");
locationDiv.classList.add("aladin-location");
var frameSelect = document.createElement("select");
frameSelect.classList.add("aladin-frameChoice");
var all = [CooFrameEnum.J2000, CooFrameEnum.J2000d, CooFrameEnum.GAL];
all.forEach(f => {
var selectOption = document.createElement("option");
selectOption.value = f.label;
selectOption.innerHTML = f.label;
selectOption.selected = cooFrame === f;
frameSelect.appendChild(selectOption);
});
var locationText = document.createElement("span");
locationText.classList.add("aladin-location-text");
locationDiv.appendChild(frameSelect);
locationDiv.appendChild(locationText);
aladinDiv.appendChild(locationDiv);
if (!options.showCoordinates) {
locationDiv.style.display = "none";
} // div where FoV value is written
var fovDiv = null;
if (options.showFov) {
fovDiv = document.createElement("div");
fovDiv.classList.add("aladin-fov");
aladinDiv.appendChild(fovDiv); // $('<div class="aladin-fov"></div>').appendTo(aladinDiv);
} // zoom control
if (options.showZoomControl) {
// $(
// '<div class="aladin-zoomControl"><a href="#" class="zoomPlus" title="Zoom in">+</a><a href="#" class="zoomMinus" title="Zoom out">–</a></div>'
// ).appendTo(aladinDiv);
var zoomDiv = document.createElement("div");
zoomDiv.classList.add("aladin-zoomControl");
var zoomPlus = document.createElement("a");
zoomPlus.href = "#";
zoomPlus.title = "Zoom in";
zoomPlus.innerHTML = "+";
zoomPlus.classList.add("zoomPlus");
zoomDiv.appendChild(zoomPlus);
var zoomMinus = document.createElement("a");
zoomMinus.href = "#";
zoomMinus.title = "Zoom out";
zoomMinus.innerHTML = "–";
zoomMinus.classList.add("zoomMinus");
zoomDiv.appendChild(zoomMinus);
aladinDiv.appendChild(zoomDiv);
zoomPlus.addEventListener("click", e => {
e.preventDefault();
aladin.increaseZoom();
});
zoomPlus.addEventListener("mousedown", e => e.preventDefault());
zoomMinus.addEventListener("click", e => {
e.preventDefault();
aladin.decreaseZoom();
});
zoomMinus.addEventListener("mousedown", e => e.preventDefault());
} // maximize control
if (options.showFullscreenControl) {
var fullScreenDiv = document.createElement("div");
fullScreenDiv.title = "Full screen";
fullScreenDiv.classList.add("aladin-fullscreenControl");
fullScreenDiv.classList.add("aladin-maximize");
aladinDiv.appendChild(fullScreenDiv); // $(
// '<div class="aladin-fullscreenControl aladin-maximize" title="Full screen"></div>'
// ).appendTo(aladinDiv);
}
this.fullScreenBtn = aladinDiv.querySelectorAll(".aladin-fullscreenControl")[0];
if (this.fullScreenBtn) {
this.fullScreenBtn.addEventListener("click", () => {
self.toggleFullscreen(self.options.realFullscreen);
});
} // react to fullscreenchange event to restore initial width/height (if user pressed ESC to go back from full screen)
document.addEventListener("fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange", () => {
var fullscreenElt = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
if (fullscreenElt === null || fullscreenElt === undefined) {
self.fullScreenBtn.classList.remove("aladin-restore");
self.fullScreenBtn.classList.add("aladin-maximize");
self.fullScreenBtn.title = "Full screen";
self.aladinDiv.classList.remove("aladin-fullscreen");
var fullScreenToggledFn = self.callbacksByEventName["fullScreenToggled"];
var isInFullscreen = self.fullScreenBtn.classList.contains("aladin-restore");
typeof fullScreenToggledFn === "function" && fullScreenToggledFn(isInFullscreen);
}
}); // Aladin logo
var logo = document.createElement("div");
logo.classList.add("aladin-logo-container");
var logoRef = document.createElement("a");
logoRef.href = "http://aladin.unistra.fr";
logoRef.title = "Powored by Alading Lite";
logoRef.target = "_blank";
logoRef.target = "_blank";
var logoLogo = document.createElement("div");
logoLogo.classList.add("aladin-logo");
logoRef.appendChild(logoLogo);
logo.appendChild(logoRef);
aladinDiv.appendChild(logo); // $(
// "<div class='aladin-logo-container'><a href='http://aladin.unistra.fr/' title='Powered by Aladin Lite' target='_blank'><div class='aladin-logo'></div></a></div>"
// ).appendTo(aladinDiv);
// we store the boxes
this.boxes = []; // measurement table
this.measurementTable = new MeasurementTable(aladinDiv);
var aladinLocation = new Location(locationDiv.querySelectorAll(".aladin-location-text")[0]); // set different options
this.view = new View(this, aladinLocation, fovDiv, cooFrame, options.fov);
this.view.setShowGrid(options.showCooGrid);
this.setImageSurvey(options.survey);
this.view.showCatalog(options.showCatalog); // retrieve available surveys
// TODO: replace call with MocServer
// $.ajax({
// url: "//aladin.unistra.fr/java/nph-aladin.pl",
// data: { frame: "aladinLiteDic" },
// method: "GET",
// dataType: "jsonp", // could this be repaced by json ??
// success: function (data) {
// var map = {};
// for (let k = 0; k < data.length; k++) {
// map[data[k].id] = true;
// }
// // retrieve existing surveys
// for (let k = 0; k < HpxImageSurvey.SURVEYS.length; k++) {
// if (!map[HpxImageSurvey.SURVEYS[k].id]) {
// data.push(HpxImageSurvey.SURVEYS[k]);
// }
// }
// console.log(data)
// HpxImageSurvey.SURVEYS = data;
// self.view.setUnknownSurveyIfNeeded();
// },
// error: function () {},
// });
fetch("https://lucuma-cors-proxy.herokuapp.com/http://aladin.unistra.fr/java/nph-aladin.pl?frame=aladinLiteDic").then(response => response.json()).then(data => {
var map = {};
for (var _k = 0; _k < data.length; _k++) {
map[data[_k].id] = true;
} // retrieve existing surveys
for (var _k2 = 0; _k2 < HpxImageSurvey.SURVEYS.length; _k2++) {
if (!map[HpxImageSurvey.SURVEYS[_k2].id]) {
data.push(HpxImageSurvey.SURVEYS[_k2]);
}
}
HpxImageSurvey.SURVEYS = data;
self.view.setUnknownSurveyIfNeeded();
}); // layers control panel
// TODO : valeur des checkbox en fonction des options
// TODO : classe LayerBox
if (options.showLayersControl) {
// let d = $(
// '<div class="aladin-layersControl-container" title="Manage layers"><div class="aladin-layersControl"></div></div>'
// );
// d.appendTo(aladinDiv);
var innerDiv = document.createElement("div");
innerDiv.classList.add("aladin-layersControl");
var layerDiv = document.createElement("div");
layerDiv.title = "Manage layers";
layerDiv.classList.add("aladin-layersControl-container");
layerDiv.appendChild(innerDiv);
aladinDiv.appendChild(layerDiv); // var layerBox = $(
// '<div class="aladin-box aladin-layerBox aladin-cb-list"></div>'
// );
// layerBox.appendTo(aladinDiv);
var layerBox = document.createElement("div");
layerBox.classList.add("aladin-box", "aladin-layerBox", "aladin-cb-list");
aladinDiv.appendChild(layerBox);
this.boxes.push(layerBox); // we return false so that the default event is not submitted, and to prevent event bubbling
layerDiv.addEventListener('click', () => {
self.hideBoxes();
self.showLayerBox(layerBox);
}); // d1.click(function () {
// self.hideBoxes();
// self.showLayerBox();
// return false;
// });
} // goto control panel
if (options.showGotoControl) {
// let d = $(
// '<div class="aladin-gotoControl-container" title="Go to position"><div class="aladin-gotoControl"></div></div>'
// );
// d.appendTo(aladinDiv);
var _innerDiv = document.createElement("div");
_innerDiv.classList.add("aladin-gotoControl");
var controlDiv = document.createElement("div");
controlDiv.title = "Go to position";
controlDiv.classList.add("aladin-gotoControl-container");
controlDiv.appendChild(_innerDiv);
aladinDiv.appendChild(controlDiv); // var gotoBox = $(
// '<div class="aladin-box aladin-gotoBox">' +
// '<a class="aladin-closeBtn">×</a>' +
// '<div style="clear: both;"></div>' +
// '<form class="aladin-target-form">Go to: <input type="text" placeholder="Object name/position" /></form></div>'
// );
// gotoBox.appendTo(aladinDiv);
var inputInForm = document.createElement("input");
inputInForm.type = "text";
inputInForm.placeholder = "Object name/position";
var formInBox = document.createElement("form");
formInBox.classList.add("aladin-target-form");
formInBox.innerText = "Go to: ";
formInBox.appendChild(inputInForm);
var divInBox = document.createElement("div");
divInBox.style.clear = "both";
var aInBox = document.createElement("a");
aInBox.classList.add("aladin-closeBtn");
aInBox.innerHTML = "×";
var gotoBox = document.createElement("div");
gotoBox.classList.add("aladin-box", "aladin-gotoBox");
gotoBox.appendChild(aInBox);
gotoBox.appendChild(divInBox);
gotoBox.appendChild(formInBox);
aladinDiv.appendChild(gotoBox);
this.boxes.push(gotoBox);
formInBox.addEventListener("submit", e => {
e.preventDefault();
aladin.gotoObject(inputInForm.value, {
success: raDec => {
console.log("Callback response on success ".concat(raDec)); // targetFormInput.classList.add("aladin-unknownObject")
},
error: raDec => {
console.log("Callback response on error ".concat(raDec)); // targetFormInput.classList.add("aladin-unknownObject")
}
});
});
inputInForm.addEventListener("paste", () => inputInForm.classList.remove("aladin-unknownObject"));
inputInForm.addEventListener("keydown", () => inputInForm.classList.remove("aladin-unknownObject"));
aInBox.addEventListener("click", () => self.hideBoxes());
controlDiv.addEventListener("click", () => {
self.hideBoxes();
inputInForm.value = "";
inputInForm.classList.remove("aladin-unknownObject");
gotoBox.style.display = "block";
inputInForm.focus();
}); // // TODO : classe GotoBox
} // simbad pointer tool
if (options.showSimbadPointerControl) {
// let d = $(
// '<div class="aladin-simbadPointerControl-container" title="SIMBAD pointer"><div class="aladin-simbadPointerControl"></div></div>'
// );
// d.appendTo(aladinDiv);
var _innerDiv2 = document.createElement("div");
_innerDiv2.classList.add("aladin-simbadPointerControl");
var simbadPinterDiv = document.createElement("div");
simbadPinterDiv.title = "SIMBAD pointer";
simbadPinterDiv.classList.add("aladin-simbadPointerControl-container");
simbadPinterDiv.appendChild(_innerDiv2);
aladinDiv.appendChild(simbadPinterDiv); // d.click(function () {
// self.view.setMode(View.TOOL_SIMBAD_POINTER);
// });
simbadPinterDiv.addEventListener("click", () => self.view.setMode(View.TOOL_SIMBAD_POINTER));
} // share control panel
if (options.showShareControl) {
// let d = $(
// '<div class="aladin-shareControl-container" title="Get link for current view"><div class="aladin-shareControl"></div></div>'
// );
// d.appendTo(aladinDiv);
var _innerDiv3 = document.createElement("div");
_innerDiv3.classList.add("aladin-shareControl");
var shareControlDiv = document.createElement("div");
shareControlDiv.title = "Get link for current view";
shareControlDiv.classList.add("aladin-shareControl-container");
shareControlDiv.appendChild(_innerDiv3);
aladinDiv.appendChild(shareControlDiv); // var shareBox = $(
// '<div class="aladin-box aladin-shareBox">' +
// '<a class="aladin-closeBtn">×</a>' +
// '<div style="clear: both;"></div>' +
// 'Link to previewer: <span class="info"></span>' +
// '<input type="text" class="aladin-shareInput" />' +
// "</div>"
// );
// shareBox.appendTo(aladinDiv);
var inputShareBox = document.createElement("input");
inputShareBox.type = "text";
inputShareBox.classList.add("aladin-shareInput");
var spanShareBox = document.createElement("span");
spanShareBox.classList.add("info");
var divShareBox = document.createElement("div");
divShareBox.style.clear = "both";
var aShareBox = document.createElement("a");
aShareBox.innerHTML = "×";
aShareBox.classList.add("aladin-closeBtn");
var shareBox = document.createElement("div");
shareBox.classList.add("aladin-box", "aladin-shareBox");
shareBox.appendChild(aShareBox);
shareBox.appendChild(divShareBox);
shareBox.innerHTML += "Link to previewer: ";
shareBox.appendChild(spanShareBox);
shareBox.appendChild(inputShareBox);
aladinDiv.appendChild(shareBox);
this.boxes.push(shareBox); // TODO : classe GotoBox, GenericBox
// d.click(function () {
// self.hideBoxes();
// shareBox.show();
// var url = self.getShareURL();
// shareBox.find(".aladin-shareInput").val(url).select();
// document.execCommand("copy");
// return false;
// });
shareControlDiv.addEventListener("click", () => {
self.hideBoxes();
shareBox.style.display = "block";
var url = self.getShareURL();
inputShareBox.value = url;
inputShareBox.select();
inputShareBox.setSelectionRange(0, 99999);
navigator.clipboard.writeText(inputShareBox.value);
}); // shareBox.find(".aladin-closeBtn").click(function () {
// self.hideBoxes();
// return false;
// });
shareBox.getElementsByClassName("aladin-closeBtn")[0].addEventListener("click", () => self.hideBoxes());
}
this.gotoObject(options.target);
if (options.log) {
var params = Object.assign({}, requestedOptions);
params.version = Aladin.VERSION;
Logger.log("startup", params);
}
this.showReticle(options.showReticle);
if (options.catalogUrls) {
for (var k = 0, len = options.catalogUrls.length; k < len; k++) {
this.createCatalogFromVOTable(options.catalogUrls[k]);
}
} // this.setImageSurvey(options.survey);
// this.view.showCatalog(options.showCatalog);
var frameChoice = aladinDiv.getElementsByClassName("aladin-frameChoice")[0];
if (frameChoice) {
frameChoice.addEventListener("change", e => aladin.setFrame(e.target.value));
} // go to full screen ?
if (options.fullScreen) {
window.setTimeout(function () {
self.toggleFullscreen(self.options.realFullscreen);
}, 1000);
}
this.callbacksByEventName = {}; // we store the callback functions (on 'zoomChanged', 'positionChanged', ...) here
};
/**** CONSTANTS ****/
Aladin.VERSION = "{ALADIN-LITE-VERSION-NUMBER}"; // will be filled by the build.sh script
Aladin.JSONP_PROXY = "https://alasky.unistra.fr/cgi/JSONProxy"; //Aladin.JSONP_PROXY = "https://alaskybis.unistra.fr/cgi/JSONProxy";
Aladin.DEFAULT_OPTIONS = {
target: "0 +0",
cooFrame: "J2000",
survey: "P/DSS2/color",
fov: 60,
showReticle: true,
showZoomControl: true,
showFullscreenControl: true,
showLayersControl: true,
showGotoControl: true,
showSimbadPointerControl: false,
showShareControl: false,
showCatalog: true,
// TODO: still used ??
showFrame: true,
showCooGrid: false,
showFov: false,
showCoordinates: false,
fullScreen: false,
reticleColor: "rgb(178, 50, 178)",
reticleSize: 22,
log: true,
allowFullZoomout: false,
realFullscreen: false,
showAllskyRing: false,
allskyRingColor: "#c8c8ff",
allskyRingWidth: 8,
pixelateCanvas: true
};
Aladin.prototype.recalculateView = function () {
this.view.setZoomLevel(this.view.zoomLevel);
this.view.fixLayoutDimensions();
};
Aladin.prototype.fixLayoutDimensions = function () {
this.view.fixLayoutDimensions();
}; // realFullscreen: AL div expands not only to the size of its parent, but takes the whole available screen estate
Aladin.prototype.toggleFullscreen = function (realFullscreen) {
realFullscreen = Boolean(realFullscreen);
this.fullScreenBtn.classList.toggle("aladin-maximize");
this.fullScreenBtn.classList.toggle("aladin-restore");
var isInFullscreen = this.fullScreenBtn.classList.contains("aladin-restore");
this.fullScreenBtn.setAttribute("title", isInFullscreen ? "Restore original size" : "Full screen");
this.aladinDiv.classList.toggle("aladin-fullscreen");
if (realFullscreen) {
// go to "real" full screen mode
if (isInFullscreen) {
var d = this.aladinDiv;
if (d.requestFullscreen) {
d.requestFullscreen();
} else if (d.webkitRequestFullscreen) {
d.webkitRequestFullscreen();
} else if (d.mozRequestFullScreen) {
// notice the difference in capitalization for Mozilla functions ...
d.mozRequestFullScreen();
} else if (d.msRequestFullscreen) {
d.msRequestFullscreen();
}
} // exit from "real" full screen mode
else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
}
}
}
this.view.fixLayoutDimensions(); // force call to zoomChanged callback
var fovChangedFn = this.callbacksByEventName["zoomChanged"];
typeof fovChangedFn === "function" && fovChangedFn(this.view.fov);
var fullScreenToggledFn = this.callbacksByEventName["fullScreenToggled"];
typeof fullScreenToggledFn === "function" && fullScreenToggledFn(isInFullscreen);
};
Aladin.prototype.updateSurveysDropdownList = function (surveys) {
surveys = surveys.sort(function (a, b) {
if (!a.order) {
return a.id > b.id;
}
return a.order && a.order > b.order ? 1 : -1;
});
var select = this.aladinDiv.getElementsByClassName("aladin-surveySelection")[0];
if (select) {
select.innerHTML = "";
for (var i = 0; i < surveys.length; i++) {
var opt = document.createElement("option");
opt.selected = this.view.imageSurvey.id === surveys[i].id;
opt.value = surveys[i].id;
opt.innerText = surveys[i].name;
select.appendChild(opt);
}
} // var select = $(this.aladinDiv).find(".aladin-surveySelection");
// select.empty();
// for (var i = 0; i < surveys.length; i++) {
// var isCurSurvey = this.view.imageSurvey.id === surveys[i].id;
// select.append(
// $("<option />")
// .attr("selected", isCurSurvey)
// .val(surveys[i].id)
// .text(surveys[i].name)
// );
// }
};
Aladin.prototype.getOptionsFromQueryString = function () {
var options = {};
var requestedTarget = urlParam("target");
if (requestedTarget) {
options.target = requestedTarget;
}
var requestedFrame = urlParam("frame");
if (requestedFrame && CooFrameEnum[requestedFrame]) {
options.frame = requestedFrame;
}
var requestedSurveyId = urlParam("survey");
if (requestedSurveyId && HpxImageSurvey.getSurveyInfoFromId(requestedSurveyId)) {
options.survey = requestedSurveyId;
}
var requestedZoom = urlParam("zoom");
if (requestedZoom && requestedZoom > 0 && requestedZoom < 180) {
options.zoom = requestedZoom;
}
var requestedShowreticle = urlParam("showReticle");
if (requestedShowreticle) {
options.showReticle = requestedShowreticle.toLowerCase() === "true";
}
var requestedCooFrame = urlParam("cooFrame");
if (requestedCooFrame) {
options.cooFrame = requestedCooFrame;
}
var requestedFullscreen = urlParam("fullScreen");
if (requestedFullscreen !== undefined) {
options.fullScreen = requestedFullscreen;
}
return options;
}; // TODO: rename to setFoV
//@oldAPI
Aladin.prototype.setZoom = function (fovDegrees) {
this.view.setZoom(fovDegrees);
}; // @API
Aladin.prototype.setFoV = Aladin.prototype.setFov = function (fovDegrees) {
this.view.setZoom(fovDegrees);
}; // @API
// (experimental) try to adjust the FoV to the given object name. Does nothing if object is not known from Simbad
Aladin.prototype.adjustFovForObject = function (objectName) {
var self = this;
this.getFovForObject(objectName, function (fovDegrees) {
self.setFoV(fovDegrees);
});
};
Aladin.prototype.getFovForObject = function (objectName, callback) {
var query = "SELECT galdim_majaxis, V FROM basic JOIN ident ON oid=ident.oidref JOIN allfluxes ON oid=allfluxes.oidref WHERE id='".concat(objectName, "'");
var url = "//simbad.u-strasbg.fr/simbad/sim-tap/sync?query=".concat(encodeURIComponent(query), "&request=doQuery&lang=adql&format=json&phase=run");
fetch(url).then(response => response.json()).then(result => {
var defaultFov = 4 / 60; // 4 arcmin
var fov = defaultFov;
if ("data" in result && result.data.length > 0) {
var galdimMajAxis = Utils.isNumber(result.data[0][0]) ? result.data[0][0] / 60.0 : null; // result gives galdim in arcmin
var magV = Utils.isNumber(result.data[0][1]) ? result.data[0][1] : null;
if (galdimMajAxis !== null) {
fov = 2 * galdimMajAxis;
} else if (magV !== null) {
if (magV < 10) {
fov = 2 * Math.pow(2.0, 6 - magV / 2.0) / 60;
}
}
}
callback(fov);
});
};
Aladin.prototype.setFrame = function (frameName) {
if (!frameName) {
return;
}
var newFrame = CooFrameEnum.fromString(frameName, CooFrameEnum.J2000);
if (newFrame === this.view.cooFrame) {
return;
}
this.view.changeFrame(newFrame); // màj select box
var frameChoice = document.getElementsByClassName("aladin-frameChoice")[0];
if (frameChoice) frameChoice.value = newFrame.label; // $(this.aladinDiv).find(".aladin-frameChoice").val(newFrame.label);
};
Aladin.prototype.setProjection = function (projectionName) {
if (!projectionName) {
return;
}
projectionName = projectionName.toLowerCase();
switch (projectionName) {
case "aitoff":
this.view.changeProjection(ProjectionEnum.AITOFF);
break;
case "sinus":
default:
this.view.changeProjection(ProjectionEnum.SIN);
}
};
/** point view to a given object (resolved by Sesame) or position
* @api
*
* @param: target; object name or position
* @callbackOptions: (optional) the object with key 'success' and/or 'error' containing the success and error callback functions.
*
*/
Aladin.prototype.gotoObject = function (targetName, callbackOptions) {
// var errorCallback = undefined;
var successCallback = undefined;
if (typeof callbackOptions === "object") {
if (Object.prototype.hasOwnProperty.call(callbackOptions, "success")) {
successCallback = callbackOptions.success;
}
if (Object.prototype.hasOwnProperty.call(callbackOptions, "error")) {// errorCallback = callbackOptions.error;
}
} // this is for compatibility reason with the previous method signature which was function(targetName, errorCallback)
else if (typeof callbackOptions === "function") {// errorCallback = callbackOptions;
}
var isObjectName = /[a-zA-Z]/.test(targetName); // try to parse as a position
if (!isObjectName) {
var coo = new Coo();
coo.parse(targetName);
var lonlat = [coo.lon, coo.lat];
if (this.view.cooFrame === CooFrameEnum.GAL) {
lonlat = CooConversion.GalacticToJ2000(lonlat);
}
this.view.pointTo(lonlat[0], lonlat[1]);
typeof successCallback === "function" && successCallback(this.getRaDec());
} // ask resolution by Sesame
else {// TODO implement sesame resolution
// var self = this;
// Sesame.resolve(
// targetName,
// function (data) {
// // success callback
// var ra = data.Target.Resolver.jradeg;
// var dec = data.Target.Resolver.jdedeg;
// self.view.pointTo(ra, dec);
//
// typeof successCallback === "function" &&
// successCallback(self.getRaDec());
// },
// function (data) {
// // errror callback
// if (console) {
// console.log("Could not resolve object name " + targetName);
// console.log(data);
// }
// typeof errorCallback === "function" && errorCallback();
// }
// );
}
};
/**
* go to a given position, expressed in the current coordinate frame
*
* @API
*/
Aladin.prototype.gotoPosition = function (lon, lat) {
var radec; // first, convert to J2000 if needed
if (this.view.cooFrame === CooFrameEnum.GAL) {
radec = CooConversion.GalacticToJ2000([lon, lat]);
} else {
radec = [lon, lat];
}
this.view.pointTo(radec[0], radec[1]);
};
var doAnimation = function doAnimation(aladin) {
var params = aladin.animationParams;
if (params == null || !params["running"]) {
return;
}
var now = new Date().getTime(); // this is the animation end: set the view to the end position, and call complete callback
if (now > params["end"]) {
aladin.gotoRaDec(params["raEnd"], params["decEnd"]);
if (params["complete"]) {
params["complete"]();
}
return;
} // compute current position
var fraction = (now - params["start"]) / (params["end"] - params["start"]);
var curPos = intermediatePoint(params["raStart"], params["decStart"], params["raEnd"], params["decEnd"], fraction);
var curRa = curPos[0];
var curDec = curPos[1]; //var curRa = params['raStart'] + (params['raEnd'] - params['raStart']) * (now-params['start']) / (params['end'] - params['start']);
//var curDec = params['decStart'] + (params['decEnd'] - params['decStart']) * (now-params['start']) / (params['end'] - params['start']);
aladin.gotoRaDec(curRa, curDec);
setTimeout(function () {
doAnimation(aladin);
}, 50);
};
/*
* Stop all animations that have been initiated by animateToRaDec or by zoomToFoV
* @API
*
*/
Aladin.prototype.stopAnimation = function () {
if (this.zoomAnimationParams) {
this.zoomAnimationParams["running"] = false;
}
if (this.animationParams) {
this.animationParams["running"] = false;
}
};
/*
* animate smoothly from the current position to the given ra, dec
*
* the total duration (in seconds) of the animation can be given (otherwise set to 5 seconds by default)
*
* complete: a function to call once the animation has completed
*
* @API
*
*/
Aladin.prototype.animateToRaDec = function (ra, dec, duration, complete) {
duration = duration || 5;
this.animationParams = null;
var animationParams = {};
animationParams["start"] = new Date().getTime();
animationParams["end"] = new Date().getTime() + 1000 * duration;
var raDec = this.getRaDec();
animationParams["raStart"] = raDec[0];
animationParams["decStart"] = raDec[1];
animationParams["raEnd"] = ra;
animationParams["decEnd"] = dec;
animationParams["complete"] = complete;
this.animationParams = animationParams;
doAnimation(this);
};
var doZoomAnimation = function doZoomAnimation(aladin) {
var params = aladin.zoomAnimationParams;
if (params == null || !params["running"]) {
return;
}
var now = new Date().getTime(); // this is the zoom animation end: set the view to the end fov, and call complete callback
if (now > params["end"]) {
aladin.setFoV(params["fovEnd"]);
if (params["complete"]) {
params["complete"]();
}
return;
} // compute current position
var fraction = (now - params["start"]) / (params["end"] - params["start"]);
var curFov = params["fovStart"] + (params["fovEnd"] - params["fovStart"]) * Math.sqrt(fraction);
aladin.setFoV(curFov);
setTimeout(function () {
doZoomAnimation(aladin);
}, 50);
};
/*
* zoom smoothly from the current FoV to the given new fov to the given ra, dec
*
* the total duration (in seconds) of the animation can be given (otherwise set to 5 seconds by default)
*
* complete: a function to call once the animation has completed
*
* @API
*
*/
Aladin.prototype.zoomToFoV = function (fov, duration, complete) {
duration = duration || 5;
this.zoomAnimationParams = null;
var zoomAnimationParams = {};
zoomAnimationParams["start"] = new Date().getTime();
zoomAnimationParams["end"] = new Date().getTime() + 1000 * duration;
var fovArray = this.getFov();
zoomAnimationParams["fovStart"] = Math.max(fovArray[0], fovArray[1]);
zoomAnimationParams["fovEnd"] = fov;
zoomAnimationParams["complete"] = complete;
zoomAnimationParams["running"] = true;
this.zoomAnimationParams = zoomAnimationParams;
doZoomAnimation(this);
};
/**
* Compute intermediate point between points (lng1, lat1) and (lng2, lat2)
* at distance fraction times the total distance (fraction between 0 and 1)
*
* Return intermediate points in degrees
*
*/
function intermediatePoint(lng1a, lat1a, lng2a, lat2a, fraction) {
function degToRad(d) {
return d * Math.PI / 180;
}
function radToDeg(r) {
return r * 180 / Math.PI;
}
var lat1 = degToRad(lat1a);
var lng1 = degToRad(lng1a);
var lat2 = degToRad(lat2a);
var lng2 = degToRad(lng2a);
var d = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin((lat1 - lat2) / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin((lng1 - lng2) / 2), 2)));
var A = Math.sin((1 - fraction) * d) / Math.sin(d);
var B = Math.sin(fraction * d) / Math.sin(d);
var x = A * Math.cos(lat1) * Math.cos(lng1) + B * Math.cos(lat2) * Math.cos(lng2);
var y = A * Math.cos(lat1) * Math.sin(lng1) + B * Math.cos(lat2) * Math.sin(lng2);
var z = A * Math.sin(lat1) + B * Math.sin(lat2);
var lon = Math.atan2(y, x);
var lat = Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
return [radToDeg(lon), radToDeg(lat)];
}
/**
* get current [ra, dec] position of the center of the view
*
* @API
*/
Aladin.prototype.getRaDec = function () {
if (this.view.cooFrame.system === CooFrameEnum.SYSTEMS.J2000) {
return [this.view.viewCenter.lon, this.view.viewCenter.lat];
} else {
var radec = CooConversion.GalacticToJ2000([this.view.viewCenter.lon, this.view.viewCenter.lat]);
return radec;
}
};
/**
* point to a given position, expressed as a ra,dec coordinate
*
* @API
*/
Aladin.prototype.gotoRaDec = function (ra, dec) {
this.view.pointTo(ra, dec);
};
Aladin.prototype.showHealpixGrid = function (show) {
this.view.showHealpixGrid(show);
};
Aladin.prototype.showSurvey = function (show) {
this.view.showSurvey(show);
};
Aladin.prototype.showCatalog = function (show) {
this.view.showCatalog(show);
};
Aladin.prototype.showReticle = function (show) {
this.view.showReticle(show);
var reticleCheckbox = document.getElementById("displayReticle");
if (reticleCheckbox) reticleCheckbox.checked = show; // $("#displayReticle").attr("checked", show);
};
Aladin.prototype.removeLayers = function () {
this.view.removeLayers();
}; // these 3 methods should be merged into a unique "add" method
Aladin.prototype.addCatalog = function (catalog) {
this.view.addCatalog(catalog);
};
Aladin.prototype.addOverlay = function (overlay) {
this.view.addOverlay(overlay);
};
Aladin.prototype.addMOC = function (moc) {
this.view.addMOC(moc);
}; // @oldAPI
Aladin.prototype.createImageSurvey = function (id, name, rootUrl, cooFrame, maxOrder, options) {
return new HpxImageSurvey(id, name, rootUrl, cooFrame, maxOrder, options);
}; // @api
Aladin.prototype.getBaseImageLayer = function () {
return this.view.imageSurvey;
}; // @param imageSurvey : HpxImageSurvey object or image survey identifier
// @api
// @old
Aladin.prototype.setImageSurvey = function (imageSurvey, callback) {
this.view.setImageSurvey(imageSurvey, callback);
this.updateSurveysDropdownList(HpxImageSurvey.getAvailableSurveys());
if (this.options.log) {
var id = imageSurvey;
if (typeof imageSurvey !== "string") {
id = imageSurvey.rootUrl;
}
Logger.log("changeImageSurvey", id);
}
}; // @api
Aladin.prototype.setBaseImageLayer = Aladin.prototype.setImageSurvey; // @api
Aladin.prototype.getOverlayImageLayer = function () {
return this.view.overlayImageSurvey;
}; // @api
Aladin.prototype.setOverlayImageLayer = function (imageSurvey, callback) {
this.view.setOverlayImageSurvey(imageSurvey, callback);
};
Aladin.prototype.increaseZoom = function (step) {
if (!step) {
step = 5;
}
this.view.setZoomLevel(this.view.zoomLevel + step);
};
Aladin.prototype.decreaseZoom = function (step) {
if (!step) {
step = 5;
}
this.view.setZoomLevel(this.view.zoomLevel - step);
}; // @oldAPI
Aladin.prototype.createCatalog = function (options) {
return catalog(options);
};
Aladin.prototype.createProgressiveCatalog = function (url, frame, maxOrder, options) {
return new ProgressiveCat(url, frame, maxOrder, options);
}; // @oldAPI
Aladin.prototype.createSource = function (ra, dec, data) {
return new Source(ra, dec, data);
}; // @oldAPI
Aladin.prototype.createMarker = function (ra, dec, options, data) {
options = options || {};
options["marker"] = true;
return new Source(ra, dec, data, options);
};
Aladin.prototype.createOverlay = function (options) {
return new Overlay(options);
}; // @oldAPI
Aladin.prototype.createFootprintsFromSTCS = function (stcs) {
return footprintsFromSTCS(stcs);
}; // @oldAPI
Aladin.prototype.createCatalogFromVOTable = function (url, options) {
return catalogFromURL(url, options);
};
Aladin.AVAILABLE_CALLBACKS = ["select", "objectClicked", "objectHovered", "footprintClicked", "footprintHovered", "positionChanged", "zoomChanged", "click", "mouseMove", "fullScreenToggled"]; // API
//
// setting callbacks
Aladin.prototype.on = function (what, myFunction) {
if (Aladin.AVAILABLE_CALLBACKS.indexOf(what) < 0) {
return;
}
this.callbacksByEventName[what] = myFunction;
};
Aladin.prototype.select = function () {
this.fire("selectstart");
};
Aladin.prototype.fire = function (what, params) {
if (what === "selectstart") {
this.view.setMode(View.SELECT);
} else if (what === "selectend") {
this.view.setMode(View.PAN);
var callbackFn = this.callbacksByEventName["select"];
typeof callbackFn === "function" && callbackFn(params);
}
};
Aladin.prototype.hideBoxes = function () {
if (this.boxes) {
for (var k = 0; k < this.boxes.length; k++) {
// this.boxes[k].hide();
this.boxes[k].style.display = "none";
}
}
}; // TODO : LayerBox (or Stack?) must be extracted as a separate object
Aladin.prototype.showLayerBox = function (layerBox) {
var self = this;
layerBox.innerHTML = "";
var layerBoxCloseBtn = document.createElement("a");
layerBoxCloseBtn.classList.add("aladin-closeBtn");
layerBoxCloseBtn.innerHTML = "×";
var layerBoxClearDiv = document.createElement("div");
layerBoxClearDiv.style.clear = "both";
var layerBoxLabelDiv = document.createElement("div");
layerBoxLabelDiv.classList.add("aladin-label");
layerBoxLabelDiv.innerText = "Base image layer";
var layerBoxSelect = document.createElement("select");
layerBoxSelect.classList.add("aladin-surveySelection");
var layerBoxCmapDiv = document.createElement("div");
layerBoxCmapDiv.classList.add("aladin-cmap");
layerBoxCmapDiv.innerText = "Color map:";
var layerBoxCmapInnerDiv = document.createElement("div");
var layerBoxCmapSelect = document.createElement("select");
layerBoxCmapSelect.classList.add("aladin-cmSelection");
var layerBoxCmapBtn = document.createElement("button");
layerBoxCmapBtn.classList.add("aladin-btn", "aladin-btn-small", "aladin-reverseCm");
layerBoxCmapBtn.type = "button";
layerBoxCmapBtn.innerText = "Reverse";
layerBoxCmapInnerDiv.appendChild(layerBoxCmapSelect);
layerBoxCmapInnerDiv.appendChild(layerBoxCmapBtn);
layerBoxCmapDiv.appendChild(layerBoxCmapInnerDiv);
var layerBoxSeparatorDiv = document.createElement("div");
layerBoxSeparatorDiv.classList.add("aladin-box-separator");
var layerBoxOverlayDiv = document.createElement("div");
layerBoxOverlayDiv.classList.add("aladin-label");
layerBoxOverlayDiv.innerText = "Overlay layers";
layerBox.appendChild(layerBoxCloseBtn);
layerBox.appendChild(layerBoxClearDiv);
layerBox.appendChild(layerBoxSelect);
layerBox.appendChild(layerBoxCmapDiv);
layerBox.appendChild(layerBoxSeparatorDiv);
layerBox.appendChild(layerBoxOverlayDiv); // fill color maps options
for (var k = 0; k < ColorMap.MAPS_NAMES.length; k++) {
var auxOpt = document.createElement("option");
auxOpt.innerText = ColorMap.MAPS_NAMES[k];
layerBoxCmapSelect.appendChild(auxOpt);
}
layerBoxCmapSelect.value = self.getBaseImageLayer().getColorMap().mapName; // loop over all overlay layers
var layers = this.view.allOverlayLayers;
var ulElem = document.createElement("ul");
for (var _k3 = layers.length - 1; _k3 >= 0; _k3--) {
var liElem = document.createElement("li");
var inputElem = document.createElement("input");
var _divElem = document.createElement("div");
var labelElem = document.createElement("label");
inputElem.type = "checkbox";
var layer = layers[_k3];
var name = layer.name;
var tooltipText = "";
var iconSvg = "";
if (layer.isShowing) inputElem.checked = true;
if (layer.type === "catalog" || layer.type === "progressivecat") {
var nbSources = layer.getSources().length;
tooltipText = nbSources + " source" + (nbSources > 1 ? "s" : "");
iconSvg = AladinUtils.SVG_ICONS.CATALOG;
} else if (layer.type === "moc") {
tooltipText = "Coverage: " + (100 * layer.skyFraction()).toFixed(3) + " % of sky";
iconSvg = AladinUtils.SVG_ICONS.MOC;
} else if (layer.type === "overlay") {
iconSvg = AladinUtils.SVG_ICONS.OVERLAY;
} // trick to retrieve the color as 'rgb(,,)' - does not work for named colors :(
// var rgbColor = $("<div></div>").css("color", layer.color).css("color");
// var labelColor = Color.getLabelColorForBackground(rgbColor);
var labelColor = Color.getLabelColorForBackground(layer.color); // retrieve SVG icon, and apply the layer color
var svgBase64 = window.btoa(iconSvg.replace(/FILLCOLOR/g, layer.color));
_divElem.classList.add("aladin-stack-icon");
_divElem.style.backgroundImage = "url(\"data:image/svg+xml;base64,".concat(svgBase64, "\")");
inputElem.id = "aladin_lite_".concat(name);
labelElem.htmlFor = "aladin_lite_".concat(name);
labelElem.classList.add("aladin-layer-label");
labelElem.style.background = layer.color;
labelElem.style.color = labelColor;
labelElem.title = tooltipText;
labelElem.innerText = name;
liElem.appendChild(_divElem);
liElem.appendChild(inputElem);
liElem.appendChild(labelElem);
ulElem.appendChild(liElem); // handler to hide/show overlays
inputElem.addEventListener("change", e => {
if (e.target.checked) {
layer.show();
} else {
layer.hide();
}
});
}
layerBox.appendChild(ulElem);
var divElem = document.createElement("div");
divElem.classList.add("aladin-blank-separator");
layerBox.appendChild(divElem); // gestion du réticule
var reticleInput = document.createElement("input");
reticleInput.id = "displayReticle";
reticleInput.type = "checkbox";
if (this.view.displayReticle) reticleInput.checked = true;
var reticleLabel = document.createElement("label");
reticleLabel.setAttribute("for", "displayReticle");
reticleLabel.innerText = "Reticle";
layerBox.appendChild(reticleInput);
layerBox.appendChild(reticleLabel);
reticleInput.addEventListener("change", e => self.showReticle(e.target.checked)); // Gestion grille Healpix
var hpxInput = document.createElement("input");
hpxInput.id = "displayHpxGrid";
hpxInput.type = "checkbox";
if (this.view.displayHpxGrid) hpxInput.checked = true;
var hpxLabel = document.createElement("label");
hpxLabel.setAttribute("for", "displayHpxGrid");
hpxLabel.innerText = "HEALPix grid";
layerBox.appendChild(hpxInput);
layerBox.appendChild(hpxLabel);
hpxInput.addEventListener("change", e => self.showHealpixGrid(e.target.checked));
var layerBoxSeparator2 = document.createElement("div");
layerBoxSeparator2.classList.add("aladin-box-separator");
var layerBoxLabel2 = document.createElement("div");
layerBoxLabel2.classList.add("aladin-label");
layerBoxLabel2.innerText = "Tools";
layerBox.appendChild(layerBoxSeparator2);
layerBox.appendChild(layerBoxLabel2);
var exportBtn = document.createElement("button");
exportBtn.classList.add("aladin-btn");
exportBtn.type = "button";
exportBtn.innerText = "Export view as PNG";
layerBox.appendChild(exportBtn);
exportBtn.addEventListener("click", () => self.exportAsPNG());
/*
'<div class="aladin-box-separator"></div>' +
'<div class="aladin-label">Projection</div>' +
'<select id="projectionChoice"><option>SINUS</option><option>AITOFF</option></select><br/>'
*/
var projectionChoice = document.getElementById("projectionChoice");
if (projectionChoice) {
projectionChoice.addEventListener("change", e => self.setProjection(e.target.value));
}
layerBoxCloseBtn.addEventListener("click", () => self.hideBoxes()); // update list of surveys
this.updateSurveysDropdownList(HpxImageSurvey.getAvailableSurveys());
layerBoxSelect.addEventListener("change", e => {
var survey = HpxImageSurvey.getAvailableSurveys()[e.target.selectedIndex];
self.setImageSurvey(survey.id, () => {
var baseImgLayer = self.getBaseImageLayer();
if (baseImgLayer.useCors) {
// update color map list with current value color map
layerBoxCmapSelect.value = baseImgLayer.getColorMap().mapName;
layerBoxCmapDiv.style.display = "block";
exportBtn.style.display = "block";
} else {
layerBoxCmapDiv.style.display = "none";
exportBtn.style.display = "none";
}
});
}); //// COLOR MAP management ////////////////////////////////////////////
// update color map
layerBoxCmapSelect.addEventListener("change", e => {
self.getBaseImageLayer().getColorMap().update(e.target.value);
}); // reverse color map
layerBoxCmapBtn.addEventListener("click", () => {
self.getBaseImageLayer().getColorMap().reverse();
});
if (this.getBaseImageLayer().useCors) {
layerBoxCmapDiv.style.display = "block";
exportBtn.style.display = "block";
} else {
layerBoxCmapDiv.style.display = "none";
exportBtn.style.display = "none";
} // ? parent or should be the same layerBoxCmapBtn
layerBoxCmapInnerDiv.parentElement.disabled = true; // Finally display
layerBox.style.display = "block";
};
Aladin.prototype.layerByName = function (name) {
var c = this.view.allOverlayLayers;
for (var k = 0; k < c.length; k++) {
if (name === c[k].name) {
return c[k];
}
}
return null;
}; // TODO : integrate somehow into API ?
Aladin.prototype.exportAsPNG = function () {
var w = window.open();
w.document.write('<img src="' + this.getViewDataURL() + '">');
w.document.title = "Aladin Lite snapshot";
};
/**
* Return the current view as a data URL (base64-formatted string)
* Parameters:
* - options (optional): object with attributs
* * format (optional): 'image/png' or 'image/jpeg'
* * width: width in pixels of the image to output