Commit 57da6f04 authored by Moreau Nicolas's avatar Moreau Nicolas
Browse files

Merge branch 'markers' into develop

parents a31e3acb 96ffe6d5
......@@ -54,7 +54,7 @@ class AxesFactory extends ShapesFactory {
console.trace();
console.log(axes);
let lineString = new ol.geom.MultiLineString(axes.parallels.concat(axes.meridians));
let f = new ol.Feature({ geometry: lineString.simplify(1) });
f.setStyle(this.axisStyle);
......@@ -84,11 +84,9 @@ class AxesFactory extends ShapesFactory {
* @param {array} ra/dec coordinates
*/
addExtremityPoint(coords, label) {
let point = new ol.geom.Point(coords);
let f2 = new ol.Feature({ geometry: point });
f2.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'green',
......@@ -116,21 +114,24 @@ class AxesFactory extends ShapesFactory {
* @returns {array} an array of x, y arrays with all coordinates of the meridians
*/
getMeridians(limits) {
// Plot the meridians,
// Plot the meridians,
console.log("### getMeridians");
console.log(limits);
const x = FITS_HEADER.naxis1 * Math.abs(FITS_HEADER.cdelt1);
const stepx = x / this.numeridians;
const y = FITS_HEADER.naxis2 * Math.abs(FITS_HEADER.cdelt2);
const stepy = y / this.numeridians;
let ras = [];
let decs = [];
const radDegInterval = radToDeg(limits["RA_max"]) - radToDeg(limits["RA_min"]);
const decDegInterval = radToDeg(limits["DEC_max"]) - radToDeg(limits["DEC_min"]);
const coeff = 0.5;
for(let i = radToDeg(limits["RA_min"]) - coeff*radDegInterval; i <= radToDeg(limits["RA_max"])+ coeff*radDegInterval; i = i+stepx){
ras.push(i);
}
......@@ -140,21 +141,22 @@ class AxesFactory extends ShapesFactory {
}
let coordinates_list = [];
console.log(ras);
for(let i = 0; i < ras.length; i=i+2){
let coordinates = [];
for(let j = 0; j < decs.length; j=j+2){
let xy = this.projection.absToRel([ras[i]*(Math.PI/180)], [decs[j]*(Math.PI/180)]);
const i_xp = Math.round(FITS_HEADER.crpix1 + (xy['x'][0]) / (this.cdelt1) - 1);
const i_yp = Math.round(FITS_HEADER.crpix2 + (xy['y'][0]) / (this.cdelt2) - 1);
const i_xp = Math.round(FITS_HEADER.crpix1 + ((xy['x']) / (this.cdelt1)) - 1);
const i_yp = Math.round(FITS_HEADER.crpix2 + ((xy['y']) / (this.cdelt2)) - 1)
if (this.viewer.isInExtent(i_xp, i_yp)) {
coordinates.push([i_xp, i_yp]);
}
}
if (coordinates.length > 1)
coordinates_list.push(coordinates);
}
console.log(coordinates_list);
return coordinates_list;
}
......@@ -192,8 +194,8 @@ class AxesFactory extends ShapesFactory {
let coordinates = [];
for(let j = 0; j < ras.length; j=j+2){
let xy = this.projection.absToRel([ras[j]*(Math.PI/180)], [decs[i]*(Math.PI/180)]);
const i_xp = Math.round(FITS_HEADER.crpix1 + (xy['x'][0]) / (this.cdelt1) - 1);
const i_yp = Math.round(FITS_HEADER.crpix2 + (xy['y'][0]) / (this.cdelt2) - 1);
const i_xp = Math.round(FITS_HEADER.crpix1 + (xy['x']) / (this.cdelt1) - 1);
const i_yp = Math.round(FITS_HEADER.crpix2 + (xy['y']) / (this.cdelt2) - 1);
if (this.viewer.isInExtent(i_xp, i_yp)) {
coordinates.push([i_xp, i_yp]);
}
......@@ -204,7 +206,6 @@ class AxesFactory extends ShapesFactory {
}
return coordinates_list;
}
/**
......
import { ShapesFactory } from "./olqv_shapes.js";
import { FITS_HEADER } from "./fitsheader.js";
import { getProjection } from "./olqv_projections.js";
import { createAndAppendFromHTML, inRange, DecDeg2HMS, DecDeg2DMS, degToRad } from "./utils.js";
import { createAndAppendFromHTML, inRange, DecDeg2HMS, DecDeg2DMS, HMS2DecDeg, DMS2DecDeg, degToRad } from "./utils.js";
import { EventFactory } from './customevents.js'
/**
* Class representing an input list of markers
*/
class MarkerList{
class MarkerList {
/**
* @constructor
* @param {string} dataId id of element containing the list of markers
* @param {string} triggerId id of element triggering the list validation
* @param {string} clearId id of the element triggering a data clearing
*/
constructor(dataId, triggerId, clearId){
constructor(dataId, triggerId, clearId) {
// object listening events from this list
this._listeners = [];
this._markers = new Set([]);
......@@ -23,8 +23,8 @@ class MarkerList{
this._clearElement = document.getElementById(clearId);
this._triggerElement = document.getElementById(triggerId);
//this._triggerElement.addEventListener("click", ()=>{this._updateMarkers()});
this._clearElement.addEventListener("click", ()=>{this._clearMarkers()});
this._triggerElement.addEventListener("click", ()=>{this._updateMarkers()});
this._clearElement.addEventListener("click", () => { this._clearMarkers() });
}
......@@ -34,10 +34,10 @@ class MarkerList{
*
* @param {Event} event event sent by a SourceTable instance
*/
sourceTableCall(event){
if(! this._markers.has(event.detail.object)){
sourceTableCall(event) {
if (!this._markers.has(event.detail.object)) {
const source = DecDeg2HMS(event.detail.ra) + ";" + DecDeg2DMS(event.detail.dec) + ";" + event.detail.object;
if(this._dataElement.value.trim() !== "")
if (this._dataElement.value.trim() !== "")
this._dataElement.value = this._dataElement.value + "\n" + source.trim();
else
this._dataElement.value = source.trim();
......@@ -50,7 +50,7 @@ class MarkerList{
* Adds an object listening to event from this object
* @param {Object} listener
*/
addListener(listener){
addListener(listener) {
this._listeners.push(listener);
}
......@@ -58,7 +58,7 @@ class MarkerList{
* Removes an object listening to event from this object
* @param {Object} listener
*/
removeListener(listener){
removeListener(listener) {
for (let i = 0; i < this._listeners.length; i++) {
if (this._listeners[i] === listener) {
this._listeners.splice(i, 1);
......@@ -70,24 +70,27 @@ class MarkerList{
/**
* Returns the event sent to listening objects
* It contains RA, DEC coordinates and a label of an object
*
*
* @returns {CustomEvent}
*/
_getEvent(){
_getEvent() {
let data = this._dataElement.value;
const lines = data.trim().split("\n");
const lines = data.trim();
let markers = [];
for(let line of lines){
const marker = line.split(";");
markers.push({"ra":marker[0], "dec":marker[1], "label":marker[2]});
if(lines !== ""){
for (let line of lines.split("\n")) {
const marker = line.split(";");
markers.push({ "ra": marker[0], "dec": marker[1], "label": marker[2] });
}
}
let event = EventFactory.getEvent(EventFactory.EVENT_TYPES.custom, {
detail: {
markers: markers,
action : "plot"
action: "plot"
}
});
});
return event;
}
......@@ -98,7 +101,11 @@ class MarkerList{
_updateMarkers() {
const event = this._getEvent();
for (let l of this._listeners) {
l.markerListUpdate(event);
try{
l.markerListUpdate(event);
}catch(error){
return;
}
}
}
......@@ -153,7 +160,7 @@ class MarkerManager {
this._initialized = true;
}
if(!this._markers.has(marker_id)){
if (!this._markers.has(marker_id)) {
let f = new ol.Feature({ geometry: new ol.geom.Point([pixRa, pixDec]) });
f.setStyle(this._getStyle(label));
this._source.addFeature(f);
......@@ -165,7 +172,7 @@ class MarkerManager {
/**
* Removes all markers
*/
clearMarkers(){
clearMarkers() {
this._source.clear();
this._markers.clear();
this._source.refresh();
......@@ -250,7 +257,7 @@ class MarkersFactory extends ShapesFactory {
super(viewer, 'marker');
MarkersFactory.enter(this.constructor.name);
let self = this;
let context = this.infosBlock.getContext();
let context = this.infosBlock.getContext();
this.btype = context['array-phys-chars']['type'];
this.bunit = context['array-phys-chars']['unit'];
this.pixelValueColumnName = `${this.btype} (${this.bunit})`;
......@@ -289,7 +296,7 @@ class MarkersFactory extends ShapesFactory {
this.seetablebutton.onclick = () => { $(`#${this.overlayId}`).css("height", "100%"); };
this.interaction = new ol.interaction.Draw({ source: this.source, type: 'Point' });
let f = function(event) {
let f = function (event) {
MarkersFactory.enter("Entering Marker mode");
if (this.isOpened) {
this.close();
......@@ -337,13 +344,15 @@ class MarkersFactory extends ShapesFactory {
this.hiddenInfosBlock = this.overlay.querySelector("textarea");
/**
* @member {dictionary[]} - Defines the title, type, width in pixels, name and read/writability of the jexcel sheet's columns.
* @member {dictionary[]} - Defines the title, type, width in pixels, name and read/writability of the jexcel sheet's columns.
*/
this.columns = [
{ title: 'id', type: 'numeric', width: '50px', name: 'id', readOnly: true },
{ title: 'label', type: 'text', width: '100px', name: 'label', readOnly: true },
{ title: 'RA', type: 'text', width: '150px', name: 'RA', readOnly: true },
{ title: 'DEC', type: 'text', width: '150px', name: 'DEC', readOnly: true },
{ title: 'label', type: 'text', width: '100px', name: 'label', readOnly: false },
{ title: 'RA', type: 'text', width: '150px', name: 'RA', readOnly: false },
{ title: 'DEC', type: 'text', width: '150px', name: 'DEC', readOnly: false },
{ title: 'iRA', type: 'text', width: '150px', name: 'iRA', readOnly: true },
{ title: 'iDEC', type: 'text', width: '150px', name: 'iDEC', readOnly: true },
{ title: this.pixelValueColumnName, type: 'numeric', width: '150px', name: this.pixelValueColumnName, readOnly: true }
];
this.fieldNames = this.columns.map((o) => { return o.title });
......@@ -402,18 +411,7 @@ class MarkersFactory extends ShapesFactory {
context['slice range'] = `${this.viewer.getSliceRange()}`;
}
let collection = new Array();
this.source.getFeatures().filter(f => f.getGeometry().getType() == 'Point').forEach(marker => {
let d = {};
d["id"] = { "value": marker.getId(), "unit": "" };
d["label"] = { "value": marker.get("label"), "unit": "" };
[d["iRA"], d["iDEC"]] = marker.getGeometry().getCoordinates().map(x => { return { "value": Math.round(x), "unit": "pixels" } })
d["RA"] = { "value": marker.get("RA"), unit: "" };
d["DEC"] = { "value": marker.get("DEC"), unit: "" };
d[self.btype] = { "value": marker.get(self.btype), "unit": self.bunit };
collection.push(d);
});
let collection = this.getMarkersList();
this.hiddenInfosBlock.value = `Markers\r\n\r\n`;
this.hiddenInfosBlock.value += this.infosBlock.preamble2TXT();
......@@ -437,17 +435,8 @@ class MarkersFactory extends ShapesFactory {
$(`#${this.copyAsJSONId}`).click(() => {
MarkersFactory.enter("copy as JSON");
let collection = new Array();
this.source.getFeatures().filter(f => f.getGeometry().getType() == 'Point').forEach(marker => {
let d = {};
d["id"] = { "value": marker.getId(), "unit": "" };
d["label"] = { "value": marker.get("label"), "unit": "" };
[d["iRA"], d["iDEC"]] = marker.getGeometry().getCoordinates().map(x => { return { "value": Math.round(x), "unit": "pixels" } })
d["RA"] = { "value": marker.get("RA"), unit: "" };
d["DEC"] = { "value": marker.get("DEC"), unit: "" };
d[self.btype] = { "value": marker.get(self.btype), "unit": self.bunit };
collection.push(d);
});
let collection = this.getMarkersList();
//let data = this.getDataAsJSON();
this.hiddenInfosBlock.value = JSON.stringify($.extend(this.infosBlock.preamble2DICT(), { 'markers': collection }), 0, 4);
this.hiddenInfosBlock.select();
try {
......@@ -492,6 +481,29 @@ class MarkersFactory extends ShapesFactory {
MarkersFactory.exit();
}
/**
* Returns an array of objects representing markers with all their properties
* @returns array
*/
getMarkersList(){
let collection = [];
let data = this.getDataAsJSON();
for(let marker of data){
let d = {};
for(let prop of Object.keys(marker)){
let unit = "";
if(prop === 'iRA' || prop === 'iDEC')
unit = "pixels";
d[prop] = {"value" : marker[prop], "unit": unit };
}
collection.push(d);
}
return collection;
}
/**
* Behaviour when an instance is activated.
*
......@@ -518,9 +530,9 @@ class MarkersFactory extends ShapesFactory {
*/
a2O(a) {
MarkersFactory.enter(this.a2O.name);
var a2O_result = {};
let a2O_result = {};
if (this.fieldNames.length == a.length) {
for (var i = 0; i < a.length; i++) {
for (let i = 0; i < a.length; i++) {
a2O_result[this.fieldNames[i]] = a[i];
}
}
......@@ -534,12 +546,12 @@ class MarkersFactory extends ShapesFactory {
*/
getDataAsJSON() {
MarkersFactory.enter(this.getDataAsJSON.name);
var json_result = [];
var data = this.jexcel.getData();
for (var i = 0; i < data.length; i++) {
json_result.push(this.a2O(data[i]));
let json_result = [];
let data = this.jexcel.getData();
for (let i = 0; i < data.length; i++) {
let result = this.a2O(data[i]);
json_result.push(result);
}
MarkersFactory.exit();
return json_result;
}
......@@ -618,7 +630,7 @@ class MarkersFactory extends ShapesFactory {
MarkersFactory.enter(this.getPixelValuePromise.name);
MarkersFactory.exit();
var viewer = this.viewer;
return new Promise(function(resolve, reject) {
return new Promise(function (resolve, reject) {
var numDims = viewer.numDims();
switch (numDims) {
case 2:
......@@ -671,12 +683,15 @@ class MarkersFactory extends ShapesFactory {
const [iRAMax, iDECMax] = this.viewer.maxIndexes;
let row = this.data[y];
let self = this;
var p = new Promise(function(resolve, reject) {
const { RA, DEC } = that.validateRow(row);
var p = new Promise((resolve, reject)=>{
const { RA, DEC } = this.validateRow(row);
const iRaiDec = this.projection.raDecToiRaiDec(RA.decdegree, DEC.decdegree);
// if RA/DEC values have been modified
row.iRA = iRaiDec.iRa;
row.iDEC = iRaiDec.iDec;
if (RA && DEC) {
let result = this.projection.absToRel(degToRad(RA.decdegree), degToRad(DEC.decdegree));
if (inRange(iRA, 0, iRAMax) && inRange(iDEC, 0, iDECMax)) {
var q = self.getPixelValuePromise(result["ra"], result["dec"], self.viewer.getRelFITSFilePath());
if (inRange(iRaiDec.iRa, 0, iRAMax) && inRange(iRaiDec.iDec, 0, iDECMax)) {
var q = self.getPixelValuePromise(iRaiDec.iRa, iRaiDec.iDec, self.viewer.getRelFITSFilePath());
q.then(
result => {
resolve(result)
......@@ -694,7 +709,7 @@ class MarkersFactory extends ShapesFactory {
}).then(
result => {
row[this.pixelValueColumnName] = result["value"];
let context = this.infosBlock.getContext();
//let context = this.infosBlock.getContext();
console.dir(row);
if (row.id == -1) {
row.id = this.markerIndex;
......@@ -702,6 +717,7 @@ class MarkersFactory extends ShapesFactory {
}
},
error => {
console.log(error);
if (error.length > 0) alert(error);
row.id = -1;
row[this.pixelValueColumnName] = undefined;
......@@ -758,11 +774,11 @@ class MarkersFactory extends ShapesFactory {
var RAinDD = self.checkRA(row.RA).decdegree;
var DECinDD = self.checkDEC(row.DEC).decdegree;
if (RAinDD && DECinDD) {
let [iRA, iDEC] = self.projection.absToRel(degToRad(RAinDD), degToRad(DECinDD));
//let iRaiDec = self.projection.absToRel(degToRad(RAinDD), degToRad(DECinDD));
/* var x = Math.round(this.raDDtoPixelConverter.convert(RAinDD));
var y = Math.round(this.decDDtoPixelConverter.convert(DECinDD)); */
var label = row.label;
var f = new ol.Feature({ geometry: new ol.geom.Point([iRA, iDEC]) });
var f = new ol.Feature({ geometry: new ol.geom.Point([row.iRA, row.iDEC]) });
f.set("label", label);
f.setStyle(this.style_f(f));
self.numOfMarkers += 1;
......@@ -787,7 +803,7 @@ class MarkersFactory extends ShapesFactory {
MarkersFactory.enter(this.createJexcel.name);
var result = jexcel(document.getElementById(parentId), {
columns: this.columns,
allowInsertRow: false,
allowInsertRow: true,
onload: this.loaded.bind(this),
onselection: this.noteSelectedRows.bind(this),
ondeleterow: this.deleteSelectedMarkers.bind(this),
......@@ -840,8 +856,8 @@ class MarkersFactory extends ShapesFactory {
let properties = {};
let measurements = {};
measurements["iRA"] = { "value": Math.floor(coordinates[0]), "unit": "pixel" };
measurements["iDEC"] = { "value": Math.floor(coordinates[1]), "unit": "pixel" };
measurements["iRA"] = { "value": Math.round(coordinates[0]), "unit": "pixel" };
measurements["iDEC"] = { "value": Math.round(coordinates[1]), "unit": "pixel" };
measurements["RA"] = { "value": radec['ra'], "unit": "HMS" };
measurements["DEC"] = { "value": radec['dec'], "unit": "DMS" };
measurements[this.btype] = flux;
......@@ -849,9 +865,14 @@ class MarkersFactory extends ShapesFactory {
event.feature.set("properties", properties);
this.indexToMarker[this.markerIndex] = event.feature;
let d = { 'id': this.markerIndex, 'RA': radec['ra'],
'DEC': radec['dec'],
'label': label };
let d = {
'id': this.markerIndex,
'RA': radec['ra'],
'DEC': radec['dec'],
'iRA' : Math.round(coordinates[0]),
'iDEC' : Math.round(coordinates[1]),
'label': label
};
d[this.pixelValueColumnName] = flux["value"];
this.data.push(d);
this.jexcel.setData(this.data);
......@@ -901,7 +922,7 @@ class MarkersFactory extends ShapesFactory {
getAllMarkerFeatures() {
MarkersFactory.enter(this.getAllMarkerFeatures.name)
var allMarkers = [];
this.source.getFeatures().forEach(function(feature) {
this.source.getFeatures().forEach(function (feature) {
if (feature.getGeometry().getType() == 'Point') {
allMarkers.push(feature);
}
......@@ -927,7 +948,7 @@ class MarkersFactory extends ShapesFactory {
matchAndEvaluate(value, pat) {
MarkersFactory.enter(this.matchAndEvaluate.name);
var result = value.match(pat);
if (result) result = result.map(function(elem, index) {
if (result) result = result.map(function (elem, index) {
if (index > 0) return Number(elem);
else return elem;
});
......@@ -964,12 +985,14 @@ class MarkersFactory extends ShapesFactory {
RA.minute = result[2];
RA.second = result[3];
RA.decdegree = RA.hour * 15 + RA.minute / 4 + RA.second / 240;
RA.rad = degToRad(RA.decdegree);
result = RA;
} else {
pat = /(\d{1,3})\.(\d+)/;
result = this.matchAndEvaluate(value, pat);
if (result) {
RA.decdegree = parseFloat(value);
RA.rad = degToRad(RA.decdegree);
RA.hour = Math.floor(RA.decdegree / 15);
RA.minute = Math.floor((RA.decdegree / 15 - RA.hour) * 60);
RA.second = (RA.decdegree / 15 - RA.hour - RA.minute / 60) * 3600;
......@@ -1021,6 +1044,7 @@ class MarkersFactory extends ShapesFactory {
DEC.minute = result[2];
DEC.second = result[3];
DEC.decdegree = (DEC.degree + DEC.minute / 60. + DEC.second / 3600.) * (DEC.negative ? -1 : 1);
DEC.rad = degToRad(DEC.decdegree);
result = DEC;
} else {
if (value.charCodeAt(0) == 8722 || value.charCodeAt(0) == 45) { value = "-" + value.slice(1); }
......@@ -1028,6 +1052,7 @@ class MarkersFactory extends ShapesFactory {
var result1 = this.matchAndEvaluate(value, pat1);
if (result1) {
DEC.decdegree = result1[1];
DEC.rad = degToRad(DEC.decdegree);
if (value[0] == "-") {
DEC.decdegree = -DEC.decdegree;
}
......
......@@ -118,17 +118,26 @@ class Projection {
let ra = radec['ra'] / Math.PI * 180;
let dec = radec['dec'] / Math.PI * 180;
/*if (ra > 360) {
ra = ra - 360;
}
if (dec > 90) {
dec = dec - 180;
}*/
return { 'ra': ra, 'dec': dec };
}
/**
* Returns a coordinate in pixels from RA/DEC in degrees
* @param {number} ra RA in degrees (float)
* @param {number} dec DEC in degreess (float)
* @returns {Object} Object containing iRa, iDec coordinates
*/
raDecToiRaiDec(ra, dec) {
// absToRel expects radians
const iRaiDec = this.absToRel([degToRad(ra)], [degToRad(dec)]);
const x = iRaiDec['x'];
const y = iRaiDec['y'];
const i_xp=Math.round(FITS_HEADER.crpix1+x/(degToRad(FITS_HEADER.cdelt1))-1);
const i_yp=Math.round(FITS_HEADER.crpix2+y/(degToRad(FITS_HEADER.cdelt2))-1);
// pixels to coordinates in radians
return { 'iRa': i_xp, 'iDec': i_yp };
}
/**
* returns RA/Dec in HMS/DMS
......@@ -417,7 +426,11 @@ class GnomonicProjection extends Projection {
const n = a.length;
let x = new Array(n)
let y = new Array(n);
//console.log("### absToRel");
//console.log("a0 : " + this._a0);
//console.log("sind0 : " + this._sind0);
//console.log("cosd0 : " + this._cosd0);
//console.log("angle : " + this._angle);
if (Math.abs(this._sind0) >= Projection.precision) {
for (let i = 0; i < n; i++) {
const sindec = Math.sin(d[i]);
......@@ -426,12 +439,15 @@ class GnomonicProjection extends Projection {
const cosa = Math.cos(a[i] - this._a0);
const product = sindec * this._cosd0 - cosdec * this._sind0 * cosa;
const r = Math.acos((sindec - this._cosd0 * product) / this._sind0);
//console.log("product : " + product);
//console.log("r : " + r);
if (r > Projection.precision) {
const p = Math.atan2(cosdec * sina, product) + this._angle;
const expr = Math.tan(r);
x[i] = expr * Math.sin(p);
y[i] = expr * Math.cos(p);
} else {
x[i] = 0.0;
y[i] = 0.0;
}
......
......@@ -59,7 +59,7 @@ import { SPEED_OF_LIGHT, VELOCITY_SHIFT_TYPE, REDSHIFT_SHIFT_TYPE } from "./cons
format(olc) {
//CoordinatesFormatter.enter(this.format.name);
var result;
const radec = this.projection.iRaiDecToHMSDMS(olc[0], olc[1]);
const radec = this.getRaDec(Math.round(olc[0]), Math.round(olc[1]));