mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2026-04-28 11:53:18 -07:00
obscore fields reconize
This commit is contained in:
212
examples/ObsCore_003.xml
Normal file
212
examples/ObsCore_003.xml
Normal file
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0"?>
|
||||
<VOTABLE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.3"
|
||||
xmlns="http://www.ivoa.net/xml/VOTable/v1.1"
|
||||
xsi:schemaLocation="http://www.ivoa.net/xml/VOTable/v1.1 http://www.ivoa.net/xml/VOTable/v1.1">
|
||||
<DESCRIPTION>Mockup SKA discovery service response VOTable</DESCRIPTION>
|
||||
<COOSYS ID="J2000" equinox="2000." epoch="2000" system="eq_FK5" />
|
||||
<RESOURCE name="ska.srcnet.org.resp" type="results">
|
||||
<DESCRIPTION>ska.srcnet.resp/sia~1 SKA data discovery service from Italian node</DESCRIPTION>
|
||||
<TABLE name="ska.scrnet.org/italy/galacticCenter">
|
||||
<FIELD ID="calib_level" name="calib_level" ucd="meta.code;obs.calib" utype="obscore:ObsDataset.calibLevel"
|
||||
datatype="int">
|
||||
<DESCRIPTION>calibration level (0,1,2,3)</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="s_ra" name="s_ra" unit="deg" ucd="pos.eq.ra"
|
||||
utype="obscore:Char.SpatialAxis.Coverage.Location.Coord.Position2D.Value2.C1" datatype="double">
|
||||
<DESCRIPTION>RA of central coordinates</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="s_dec" name="s_dec" unit="deg" ucd="pos.eq.dec"
|
||||
utype="obscore:Char.SpatialAxis.Coverage.Location.Coord.Position2D.Value2.C2" datatype="double">
|
||||
<DESCRIPTION>DEC of central coordinates</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="s_fov" name="s_fov" unit="deg" ucd="phys.angSize;instr.fov"
|
||||
utype="obscore:Char.SpatialAxis.Coverage.Bounds.Extent.diameter" datatype="double">
|
||||
<DESCRIPTION>size of the region covered (~diameter of minimum bounding circle)</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="s_region" name="s_region" ucd="pos.outline;obs.field"
|
||||
utype="obscore:Char.SpatialAxis.Coverage.Support.Area" datatype="char" arraysize="*">
|
||||
<DESCRIPTION>region bounded by observation</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="obs_publisher_did" name="obs_publisher_did" ucd="meta.ref.ivoid"
|
||||
utype="obscore:Curation.PublisherDID" datatype="char" arraysize="256*">
|
||||
<DESCRIPTION>publisher dataset identifier</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="obs_collection" name="obs_collection" ucd="meta.id" utype="obscore:DataID.Collection"
|
||||
datatype="char" arraysize="128*">
|
||||
<DESCRIPTION>short name for the data colection</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="facility_name" name="facility_name" ucd="meta.id;instr.tel"
|
||||
utype="obscore:Provenance.ObsConfig.Facility.name" datatype="char" arraysize="128*">
|
||||
<DESCRIPTION>telescope name</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="instrument_name" name="instrument_name" ucd="meta.id;instr"
|
||||
utype="obscore:Provenance.ObsConfig.Instrument.name" datatype="char" arraysize="128*">
|
||||
<DESCRIPTION>instrument name</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="obs_id" name="obs_id" ucd="meta.id" utype="obscore:DataID.observationID" datatype="char"
|
||||
arraysize="128*">
|
||||
<DESCRIPTION>internal dataset identifier</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="dataproduct_type" name="dataproduct_type" ucd="meta.code.class"
|
||||
utype="obscore:ObsDataset.dataProductType" datatype="char" arraysize="128*">
|
||||
<DESCRIPTION>type of product</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="dataproduct_subtype" name="dataproduct_subtype" ucd="meta.code.class"
|
||||
utype="obscore:ObsDataset.dataProductSubType" datatype="char" arraysize="128*">
|
||||
<DESCRIPTION>free sub type of product</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="obs_release_date" name="obs_release_date" ucd="time.release" utype="obscore:Curation.releaseDate"
|
||||
datatype="char" arraysize="23*">
|
||||
<DESCRIPTION>timestamp of date the data becomes publicly available</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="target_name" name="target_name" ucd="meta.id;src" utype="obscore:Target.Name" datatype="char"
|
||||
arraysize="32*">
|
||||
<DESCRIPTION>name of intended target</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="s_resolution" name="s_resolution" unit="arcsec" ucd="pos.angResolution"
|
||||
utype="obscore:Char.SpatialAxis.Resolution.refval.value" datatype="double">
|
||||
<DESCRIPTION>typical spatial resolution</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="s_xel1" name="s_xel1" ucd="meta.number" utype="obscore:Char.SpatialAxis.numBins1"
|
||||
datatype="long">
|
||||
<DESCRIPTION>dimensions (number of pixels) along one spatial axis</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="s_xel2" name="s_xel2" ucd="meta.number" utype="obscore:Char.SpatialAxis.numBins2"
|
||||
datatype="long">
|
||||
<DESCRIPTION>dimensions (number of pixels) along the other spatial axis</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="t_min" name="t_min" unit="d" ucd="time.start;obs.exposure"
|
||||
utype="obscore:Char.TimeAxis.Coverage.Bounds.Limits.StartTime" datatype="double">
|
||||
<DESCRIPTION>start time of observation (MJD)</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="t_max" name="t_max" unit="d" ucd="time.end;obs.exposure"
|
||||
utype="obscore:Char.TimeAxis.Coverage.Bounds.Limits.StopTime" datatype="double">
|
||||
<DESCRIPTION>end time of observation (MJD)</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="t_exptime" name="t_exptime" unit="s" ucd="time.duration;obs.exposure"
|
||||
utype="obscore:Char.TimeAxis.Coverage.Support.Extent" datatype="double">
|
||||
<DESCRIPTION>exposure time of observation</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="t_resolution" name="t_resolution" unit="s" ucd="time.resolution"
|
||||
utype="obscore:Char.TimeAxis.Resolution.refval.value" datatype="double">
|
||||
<DESCRIPTION>typical temporal resolution</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="t_xel" name="t_xel" ucd="meta.number" utype="obscore:Char.TimeAxis.numBins" datatype="long">
|
||||
<DESCRIPTION>dimensions (number of pixels) along the time axis</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="em_min" name="em_min" unit="m" ucd="em.wl;stat.min"
|
||||
utype="obscore:Char.SpectralAxis.Coverage.Bounds.Limits.LoLimit" datatype="double">
|
||||
<DESCRIPTION>start spectral coordinate value</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="em_max" name="em_max" unit="m" ucd="em.wl;stat.max"
|
||||
utype="obscore:Char.SpectralAxis.Coverage.Bounds.Limits.HiLimit" datatype="double">
|
||||
<DESCRIPTION>stop spectral coordinate value</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="em_res_power" name="em_res_power" ucd="spect.resolution"
|
||||
utype="obscore:Char.SpectralAxis.Resolution.ResolPower.refval" datatype="double">
|
||||
<DESCRIPTION>typical spectral resolution</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="em_xel" name="em_xel" ucd="meta.number" utype="obscore:Char.SpectralAxis.numBins"
|
||||
datatype="long">
|
||||
<DESCRIPTION>dimensions (number of pixels) along the energy axis</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="pol_xel" name="pol_xel" ucd="meta.number" utype="obscore:Char.PolarizationAxis.numBins"
|
||||
datatype="long">
|
||||
<DESCRIPTION>dimensions (number of pixels) along the polarization axis</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="access_url" name="access_url" ucd="meta.ref.url" utype="obscore:Access.Reference" datatype="char"
|
||||
arraysize="*">
|
||||
<DESCRIPTION>URL to download the data</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="access_estsize" name="access_estsize" unit="kbyte" ucd="phys.size;meta.file"
|
||||
utype="obscore:Access.Size" datatype="long">
|
||||
<DESCRIPTION>estimated size of the download</DESCRIPTION>
|
||||
</FIELD>
|
||||
|
||||
<FIELD ID="pol_states" name="pol_states" ucd="meta.code;phys.polarization"
|
||||
utype="obscore:Char.PolarizationAxis.stateList" datatype="char" arraysize="32*">
|
||||
<DESCRIPTION>polarization states present in the data</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="o_ucd" name="o_ucd" ucd="meta.ucd" utype="obscore:Char.ObservableAxis.ucd" datatype="char"
|
||||
arraysize="32*">
|
||||
<DESCRIPTION>UCD describing the observable axis (pixel values)</DESCRIPTION>
|
||||
</FIELD>
|
||||
<FIELD ID="access_format" name="access_format" ucd="meta.code.mime" utype="obscore:Access.Format"
|
||||
datatype="char" arraysize="128*">
|
||||
<DESCRIPTION>format of the data file(s)</DESCRIPTION>
|
||||
</FIELD>
|
||||
<DATA>
|
||||
<TABLEDATA>
|
||||
<TR>
|
||||
<TD>3</TD>
|
||||
<TD>214.9</TD>
|
||||
<TD>56.7</TD>
|
||||
<TD>0.2</TD>
|
||||
<TD>polygon 215.92 56.25 214.03 56.25 214.03 57.34 215.92 57.34</TD>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>APERTIF_DR1</TD>
|
||||
<TD>wsrt</TD>
|
||||
<TD>Apertif</TD>
|
||||
<TD>200104010</TD>
|
||||
<TD>cube</TD>
|
||||
<TD>HI_spectral_cubes</TD>
|
||||
<TD>2020-01-04T06:38:21Z</TD>
|
||||
<TD>NGC 5585</TD>
|
||||
<TD>0.4</TD>
|
||||
<TD>661</TD>
|
||||
<TD>661</TD>
|
||||
<TD>61416.3556875</TD>
|
||||
<TD>61416.356376527775</TD>
|
||||
<TD>59.575</TD>
|
||||
<TD>0.1</TD>
|
||||
<TD>1218</TD>
|
||||
<TD>0.211</TD>
|
||||
<TD>0.217</TD>
|
||||
<TD>7000000</TD>
|
||||
<TD>100000</TD>
|
||||
<TD>4</TD>
|
||||
<TD>https://raw.githubusercontent.com/VisIVOLab/SKA-Discovery-Service-Mockup/main/DataLink/DataLink_003.xml</TD>
|
||||
<TD>2128688640</TD>
|
||||
<TD>I Q U V</TD>
|
||||
<TD>phot.flux.density;phys.polarization</TD>
|
||||
<TD>application/x-votable+xml;content=datalink</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>3</TD>
|
||||
<TD>214.9</TD>
|
||||
<TD>56.7</TD>
|
||||
<TD>0.2</TD>
|
||||
<TD>polygon 215.92 56.25 214.03 56.25 214.03 57.34 215.92 57.34</TD>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>APERTIF_DR1</TD>
|
||||
<TD>wsrt</TD>
|
||||
<TD>Apertif</TD>
|
||||
<TD>200104010</TD>
|
||||
<TD>cube</TD>
|
||||
<TD>HI_spectral_cubes</TD>
|
||||
<TD>2020-01-04T06:38:21Z</TD>
|
||||
<TD>NGC 5585</TD>
|
||||
<TD>0.4</TD>
|
||||
<TD>661</TD>
|
||||
<TD>661</TD>
|
||||
<TD>61416.3556875</TD>
|
||||
<TD>61416.356376527775</TD>
|
||||
<TD>59.575</TD>
|
||||
<TD>0.1</TD>
|
||||
<TD>1218</TD>
|
||||
<TD>0.211</TD>
|
||||
<TD>0.217</TD>
|
||||
<TD>7000000</TD>
|
||||
<TD>100000</TD>
|
||||
<TD>4</TD>
|
||||
<TD>https://raw.githubusercontent.com/VisIVOLab/SKA-Discovery-Service-Mockup/main/DataLink/DataLink_003.xml</TD>
|
||||
<TD>2128688640</TD>
|
||||
<TD>I Q U V</TD>
|
||||
<TD>phot.flux.density;phys.polarization</TD>
|
||||
<TD>application/x-votable+xml;content=datalink</TD>
|
||||
</TR>
|
||||
</TABLEDATA>
|
||||
</DATA>
|
||||
</TABLE>
|
||||
</RESOURCE>
|
||||
</VOTABLE>
|
||||
21
examples/al-obscore.html
Normal file
21
examples/al-obscore.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
|
||||
<div id='aladin-statsDiv'></div>
|
||||
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: '14 18 16.868 +56 44 29.37', fov: 5});
|
||||
|
||||
const catalog = A.catalogFromURL('./ObsCore_003.xml', {onClick: 'showTable'});
|
||||
aladin.addCatalog(catalog);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
aladin.addCatalog(A.catalogFromURL('https://aladin.cds.unistra.fr/AladinLite/doc/API/examples/data/alma-footprints.xml', {}, function(sources) {
|
||||
sources.forEach(source => {
|
||||
console.log(A.footprintsFromSTCS(source.data['s_region']))
|
||||
|
||||
overlay.addFootprints(A.footprintsFromSTCS(source.data['s_region']))
|
||||
});
|
||||
}));
|
||||
|
||||
99
examples/datalink.xml
Normal file
99
examples/datalink.xml
Normal file
@@ -0,0 +1,99 @@
|
||||
<VOTABLE xmlns="http://www.ivoa.net/xml/VOTable/v1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
version="1.4">
|
||||
<DESCRIPTION>Mockup SKA discovery service response VOTable</DESCRIPTION>
|
||||
<COOSYS ID="J2000" equinox="2000." epoch="2000" system="eq_FK5" />
|
||||
<RESOURCE type="results">
|
||||
<TABLE>
|
||||
<FIELD name="ID" datatype="char" arraysize="*" ucd="meta.id;meta.main" />
|
||||
<FIELD name="access_url" datatype="char" arraysize="*" ucd="meta.ref.url" />
|
||||
<FIELD name="service_def" datatype="char" arraysize="*" ucd="meta.ref" />
|
||||
<FIELD name="error_message" datatype="char" arraysize="*" ucd="meta.code.error" />
|
||||
<FIELD name="semantics" datatype="char" arraysize="*" ucd="meta.code" />
|
||||
<FIELD name="description" datatype="char" arraysize="*" ucd="meta.note" />
|
||||
<FIELD name="content_type" datatype="char" arraysize="*" ucd="meta.code.mime" />
|
||||
<FIELD name="content_length" datatype="long" ucd="phys.size;meta.file" unit="byte" />
|
||||
<FIELD name="content_qualifier" datatype="char" arraysize="*" ucd="meta.code" />
|
||||
<DATA>
|
||||
<TABLEDATA>
|
||||
<TR>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>https://vo.astron.nl/getproduct/APERTIF_DR1/200110007_AP_B037/HI_image_cube3.fits</TD>
|
||||
<TD><TD />
|
||||
<TD><TD />
|
||||
<TD>#this</TD>
|
||||
<TD>The full dataset</TD>
|
||||
<TD>image/fits</TD>
|
||||
<TD>2128688640</TD>
|
||||
<TD>cube</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>https://alasky.cds.unistra.fr/hips-cube-services/compute/hips:httpsalasky.cds.unistra.fr;SKA-demo;hips;APERTIF;HiPS_APERTIF_cube_NGC5585-cubic-tiles%7Cexpr:s0_1211</TD>
|
||||
<TD><TD />
|
||||
<TD><TD />
|
||||
<TD>#derived</TD>
|
||||
<TD>Moment zero map of the cube (in HiPS format)</TD>
|
||||
<TD>application/hips</TD>
|
||||
<TD>2128688640</TD>
|
||||
<TD>image</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>https://alasky.cds.unistra.fr/hips-cube-services/compute/hips:httpsalasky.cds.unistra.fr;SKA-demo;hips;APERTIF;HiPS_APERTIF_cube_NGC5585-cubic-tiles%7Cexpr:s345_410-(s0_1211;24)</TD>
|
||||
<TD><TD />
|
||||
<TD><TD />
|
||||
<TD>#derived</TD>
|
||||
<TD>HI Line map derived from the cube (in HiPS format)</TD>
|
||||
<TD>application/hips</TD>
|
||||
<TD>2128688640</TD>
|
||||
<TD>image</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>https://alasky.cds.unistra.fr/hips-cube-services/color/hips:httpsalasky.cds.unistra.fr;SKA-demo;hips;APERTIF;HiPS_APERTIF_cube_NGC5585%7Cblue:345-365%7Cgreen:365-385%7Cred:385-405</TD>
|
||||
<TD><TD />
|
||||
<TD><TD />
|
||||
<TD>#derived</TD>
|
||||
<TD>velocity variation color map derived from the cube (in HiPS format)</TD>
|
||||
<TD>application/hips</TD>
|
||||
<TD>2128688640</TD>
|
||||
<TD>image</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD><TD />
|
||||
<TD>soda-HiPS</TD>
|
||||
<TD><TD />
|
||||
<TD>#cutout</TD>
|
||||
<TD>SODA-HiPS cutout of moment zero map of ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>image/fits</TD>
|
||||
<TD><TD />
|
||||
<TD></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD><TD />
|
||||
<TD>soda-sync</TD>
|
||||
<TD><TD />
|
||||
<TD>#cutout</TD>
|
||||
<TD>SODA-sync cutout of ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>image/fits</TD>
|
||||
<TD><TD />
|
||||
<TD></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD><TD />
|
||||
<TD>soda-async</TD>
|
||||
<TD><TD />
|
||||
<TD>#cutout</TD>
|
||||
<TD>SODA-async cutout of ivo://SKA/SrcNet/APERTIF_DR1/200110007_AP_B037/HI_image_cube3</TD>
|
||||
<TD>image/fits</TD>
|
||||
<TD><TD />
|
||||
<TD></TD>
|
||||
</TR>
|
||||
</TABLEDATA>
|
||||
</DATA>
|
||||
</TABLE>
|
||||
</RESOURCE>
|
||||
</VOTABLE>
|
||||
@@ -569,9 +569,9 @@ impl WebClient {
|
||||
/// * `lon` - A longitude in degrees
|
||||
/// * `lat` - A latitude in degrees
|
||||
#[wasm_bindgen(js_name = worldToScreen)]
|
||||
pub fn world_to_screen(&self, lon: f64, lat: f64) -> Option<Box<[f64]>> {
|
||||
pub fn world_to_screen(&self, lon: f64, lat: f64) -> Option<Box<[i32]>> {
|
||||
self.app.world_to_screen(lon, lat)
|
||||
.map(|v| Box::new([v.x, v.y]) as Box<[f64]>)
|
||||
.map(|v| Box::new([v.x as i32, v.y as i32]) as Box<[i32]>)
|
||||
}
|
||||
|
||||
/// Screen to world unprojection
|
||||
@@ -820,7 +820,7 @@ impl WebClient {
|
||||
#[wasm_bindgen(js_name = parseVOTable)]
|
||||
pub fn parse_votable(&mut self, s: &str) -> Result<JsValue, JsValue> {
|
||||
let votable: VOTableWrapper<votable::impls::mem::InMemTableDataRows> = votable::votable::VOTableWrapper::from_ivoa_xml_str(s)
|
||||
.map_err(|_| JsValue::from_str("Error parsing votable"))?;
|
||||
.map_err(|err| JsValue::from_str(&format!("Error parsing votable: {:?}", err)))?;
|
||||
|
||||
let votable = serde_wasm_bindgen::to_value(&votable)
|
||||
.map_err(|_| JsValue::from_str("cannot convert votable to js type"))?;
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
position: relative;
|
||||
border: 1px solid #ddd;
|
||||
height: 100%;
|
||||
/*overflow: hidden;*/
|
||||
}
|
||||
|
||||
/* disable x swipe on chrome, firefox */
|
||||
/* see. https://stackoverflow.com/questions/30636930/disable-web-page-navigation-on-swipeback-and-forward */
|
||||
overscroll-behavior-x: none;
|
||||
}
|
||||
|
||||
.aladin-imageCanvas {
|
||||
position: absolute;
|
||||
@@ -89,19 +91,31 @@
|
||||
}
|
||||
|
||||
.aladin-measurement-div {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
|
||||
z-index: 77;
|
||||
position:absolute;
|
||||
bottom: 20px;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
display: none;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
/* Allow scrolling but disable scroll bar */
|
||||
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
||||
scrollbar-width: none; /* for Firefox */
|
||||
overflow-y: scroll;
|
||||
|
||||
/* disable x swipe on chrome, firefox */
|
||||
overscroll-behavior-x: none;
|
||||
}
|
||||
|
||||
.aladin-measurement-div::-webkit-scrollbar {
|
||||
display: none; /* for Chrome, Safari, and Opera */
|
||||
}
|
||||
|
||||
.aladin-measurement-div table {
|
||||
padding: 2px 4px 2px 4px;
|
||||
|
||||
table-layout: fixed;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -221,10 +235,6 @@ word-wrap:break-word;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
element {
|
||||
|
||||
}
|
||||
|
||||
.aladin-box {
|
||||
display: none;
|
||||
z-index: 30;
|
||||
|
||||
@@ -68,6 +68,7 @@ import $ from 'jquery';
|
||||
|
||||
// Import aladin css inside the project
|
||||
import './../css/aladin.css';
|
||||
import { VOTable } from "./vo/VOTable.js";
|
||||
|
||||
|
||||
export let Aladin = (function () {
|
||||
@@ -1832,8 +1833,8 @@ Aladin.prototype.setReduceDeformations = function (reduce) {
|
||||
}
|
||||
|
||||
// API
|
||||
A.footprintsFromSTCS = function (stcs) {
|
||||
var footprints = Overlay.parseSTCS(stcs);
|
||||
A.footprintsFromSTCS = function (stcs, options) {
|
||||
var footprints = Overlay.parseSTCS(stcs, options);
|
||||
|
||||
return footprints;
|
||||
}
|
||||
@@ -1861,8 +1862,25 @@ A.catalogFromURL = function (url, options, successCallback, useProxy) {
|
||||
var catalog = A.catalog(options);
|
||||
Catalog.parseVOTable(
|
||||
url,
|
||||
function (sources) {
|
||||
function (sources, footprints, fields) {
|
||||
if (fields["access_url"]) {
|
||||
// It is an obsore table pointing to a datalink table
|
||||
catalog.addFieldClickCallback("access_url", (url) => {
|
||||
VOTable.parse(
|
||||
"./examples/datalink.xml",
|
||||
(fields, rows) => {
|
||||
let sources = [];
|
||||
let footprints = [];
|
||||
|
||||
console.log(fields, rows)
|
||||
}
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
catalog.addFootprints(footprints)
|
||||
catalog.addSources(sources);
|
||||
|
||||
if (successCallback) {
|
||||
successCallback(sources);
|
||||
}
|
||||
@@ -1875,24 +1893,6 @@ A.catalogFromURL = function (url, options, successCallback, useProxy) {
|
||||
return catalog;
|
||||
};
|
||||
|
||||
A.obscoreFromURL = function (url, options, successCallback, useProxy) {
|
||||
options = options.color || Obscore.COLOR;
|
||||
let catalog = A.catalog(options);
|
||||
|
||||
Obscore.parseVOTable(
|
||||
url,
|
||||
function (sources) {
|
||||
catalog.addSources(sources);
|
||||
|
||||
if (successCallback) {
|
||||
successCallback(sources);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return catalog;
|
||||
};
|
||||
|
||||
// API
|
||||
// @param target: can be either a string representing a position or an object name, or can be an object with keys 'ra' and 'dec' (values being in decimal degrees)
|
||||
A.catalogFromSimbad = function (target, radius, options, successCallback) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import { Utils } from "./Utils.js";
|
||||
import { AladinUtils } from "./AladinUtils.js";
|
||||
import { Coo } from "./libs/astro/coo.js";
|
||||
import { ALEvent } from "./events/ALEvent.js";
|
||||
import { Obscore } from "./vo/Obscore.js";
|
||||
import { VOTable } from "./vo/VOTable.js";
|
||||
|
||||
import $ from 'jquery';
|
||||
@@ -60,11 +61,11 @@ export let Catalog = (function() {
|
||||
this.raField = options.raField || undefined; // ID or name of the field holding RA
|
||||
this.decField = options.decField || undefined; // ID or name of the field holding dec
|
||||
|
||||
this.fieldsClickCallbacks = {}; // callbacks when the user clicks on a cell in the measurement table associated
|
||||
|
||||
this.indexationNorder = 5; // à quel niveau indexe-t-on les sources
|
||||
this.sources = [];
|
||||
this.footprints = [];
|
||||
//this.hpxIdx = new HealpixIndex(this.indexationNorder);
|
||||
//this.hpxIdx.init();
|
||||
|
||||
this.displayLabel = options.displayLabel || false;
|
||||
this.labelColor = options.labelColor || this.color;
|
||||
@@ -266,149 +267,92 @@ export let Catalog = (function() {
|
||||
};
|
||||
|
||||
|
||||
Catalog.parseFields = function(fields, raField, decField) {
|
||||
// This votable is not an obscore one
|
||||
let [raFieldIdx, decFieldIdx] = findRADecFields(fields, raField, decField);
|
||||
|
||||
let parsedFields = {};
|
||||
let fieldIdx = 0;
|
||||
fields.forEach((field) => {
|
||||
let key = field.name ? field.name : field.id;
|
||||
|
||||
let nameField;
|
||||
if (fieldIdx == raFieldIdx) {
|
||||
nameField = 'ra';
|
||||
} else if (fieldIdx == decFieldIdx) {
|
||||
nameField = 'dec';
|
||||
} else {
|
||||
nameField = key;
|
||||
}
|
||||
|
||||
parsedFields[nameField] = {
|
||||
name: key,
|
||||
idx: fieldIdx,
|
||||
};
|
||||
|
||||
fieldIdx++;
|
||||
})
|
||||
|
||||
return parsedFields;
|
||||
};
|
||||
|
||||
// return an array of Source(s) from a VOTable url
|
||||
// callback function is called each time a TABLE element has been parsed
|
||||
Catalog.parseVOTable = function(url, callback, maxNbSources, useProxy, raField, decField) {
|
||||
/*
|
||||
// adapted from votable.js
|
||||
function getPrefix($xml) {
|
||||
var prefix;
|
||||
// If Webkit chrome/safari/... (no need prefix)
|
||||
if($xml.find('RESOURCE').length>0) {
|
||||
prefix = '';
|
||||
}
|
||||
else {
|
||||
// Select all data in the document
|
||||
prefix = $xml.find("*").first();
|
||||
VOTable.parse(
|
||||
url,
|
||||
(fields, rows) => {
|
||||
let sources = [];
|
||||
let footprints = [];
|
||||
|
||||
if (prefix.length==0) {
|
||||
return '';
|
||||
}
|
||||
rows.every(row => {
|
||||
let ra, dec, region;
|
||||
var mesures = {};
|
||||
|
||||
// get name of the first tag
|
||||
prefix = prefix.prop("tagName");
|
||||
for (const [fieldName, field] of Object.entries(fields)) {
|
||||
if (fieldName === 's_region') {
|
||||
// Obscore s_region param
|
||||
region = row[field.idx];
|
||||
} else if (fieldName === 'ra' || fieldName === 's_ra') {
|
||||
ra = row[field.idx]
|
||||
} else if (fieldName === 'dec' || fieldName === 's_dec') {
|
||||
dec = row[field.idx]
|
||||
}
|
||||
|
||||
var idx = prefix.indexOf(':');
|
||||
|
||||
prefix = prefix.substring(0, idx) + "\\:";
|
||||
|
||||
|
||||
}
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
function doParseVOTable(xml, callback) {
|
||||
xml = xml.replace(/^\s+/g, ''); // we need to trim whitespaces at start of document
|
||||
var attributes = ["name", "ID", "ucd", "utype", "unit", "datatype", "arraysize", "width", "precision"];
|
||||
|
||||
var fields = [];
|
||||
var k = 0;
|
||||
var $xml = $($.parseXML(xml));
|
||||
var prefix = getPrefix($xml);
|
||||
$xml.find(prefix + "FIELD").each(function() {
|
||||
var f = {};
|
||||
for (var i=0; i<attributes.length; i++) {
|
||||
var attribute = attributes[i];
|
||||
if ($(this).attr(attribute)) {
|
||||
f[attribute] = $(this).attr(attribute);
|
||||
var key = field.name;
|
||||
mesures[key] = row[field.idx];
|
||||
}
|
||||
|
||||
if (ra && dec) {
|
||||
const source = new Source(ra, dec, mesures);
|
||||
|
||||
sources.push(source);
|
||||
if (maxNbSources && sources.length == maxNbSources) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (region) {
|
||||
let footprint = A.footprintsFromSTCS(region, {lineWidth: 2});
|
||||
footprints = footprints.concat(footprint);
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
|
||||
if (callback) {
|
||||
callback(sources, footprints, fields);
|
||||
}
|
||||
if ( ! f.ID) {
|
||||
f.ID = "col_" + k;
|
||||
}
|
||||
fields.push(f);
|
||||
k++;
|
||||
});
|
||||
|
||||
var raDecFieldIdxes = findRADecFields(fields, raField, decField);
|
||||
var raFieldIdx, decFieldIdx;
|
||||
raFieldIdx = raDecFieldIdxes[0];
|
||||
decFieldIdx = raDecFieldIdxes[1];
|
||||
|
||||
var sources = [];
|
||||
|
||||
var coo = new Coo();
|
||||
var ra, dec;
|
||||
$xml.find(prefix + "TR").each(function() {
|
||||
var mesures = {};
|
||||
var k = 0;
|
||||
$(this).find(prefix + "TD").each(function() {
|
||||
var key = fields[k].name ? fields[k].name : fields[k].id;
|
||||
mesures[key] = $(this).text();
|
||||
k++;
|
||||
});
|
||||
var keyRa = fields[raFieldIdx].name ? fields[raFieldIdx].name : fields[raFieldIdx].id;
|
||||
var keyDec = fields[decFieldIdx].name ? fields[decFieldIdx].name : fields[decFieldIdx].id;
|
||||
|
||||
if (Utils.isNumber(mesures[keyRa]) && Utils.isNumber(mesures[keyDec])) {
|
||||
ra = parseFloat(mesures[keyRa]);
|
||||
dec = parseFloat(mesures[keyDec]);
|
||||
} else {
|
||||
coo.parse(mesures[keyRa] + " " + mesures[keyDec]);
|
||||
ra = coo.lon;
|
||||
dec = coo.lat;
|
||||
}
|
||||
sources.push(new Source(ra, dec, mesures));
|
||||
if (maxNbSources && sources.length == maxNbSources) {
|
||||
return false; // break the .each loop
|
||||
}
|
||||
});
|
||||
if (callback) {
|
||||
callback(sources);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
new VOTable(url, (votable) => {
|
||||
let sources = [];
|
||||
votable.votable.get("resources")
|
||||
.forEach((resource) => {
|
||||
let tables = resource.get("tables")
|
||||
tables.forEach((table) => {
|
||||
let fields = table.get("elems")
|
||||
.map((field) => {
|
||||
// convert a map into a javascript object
|
||||
return Object.fromEntries(field);
|
||||
})
|
||||
|
||||
var raDecFieldIdxes = findRADecFields(fields, raField, decField);
|
||||
const raFieldIdx = raDecFieldIdxes[0];
|
||||
const decFieldIdx = raDecFieldIdxes[1];
|
||||
|
||||
let data = table.get("data");
|
||||
let rows = data.get("rows");
|
||||
|
||||
rows.every(row => {
|
||||
var mesures = {};
|
||||
|
||||
let idxField = 0;
|
||||
for (const field of fields) {
|
||||
var key = field.name ? field.name : field.id;
|
||||
|
||||
mesures[key] = row[idxField];
|
||||
idxField += 1;
|
||||
}
|
||||
|
||||
const ra = row[raFieldIdx];
|
||||
const dec = row[decFieldIdx];
|
||||
|
||||
sources.push(new Source(ra, dec, mesures));
|
||||
if (maxNbSources && sources.length == maxNbSources) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
if (callback) {
|
||||
callback(sources);
|
||||
}
|
||||
})
|
||||
},
|
||||
raField,
|
||||
decField
|
||||
)
|
||||
};
|
||||
|
||||
Catalog.prototype.addFieldClickCallback = function(field, callback) {
|
||||
this.fieldsClickCallbacks[field] = callback;
|
||||
}
|
||||
|
||||
// API
|
||||
Catalog.prototype.updateShape = function(options) {
|
||||
options = options || {};
|
||||
@@ -557,13 +501,7 @@ export let Catalog = (function() {
|
||||
if (this._shapeIsFunction) {
|
||||
ctx.save();
|
||||
}
|
||||
/*var sourcesInView = [];
|
||||
for (var k=0, len = this.sources.length; k<len; k++) {
|
||||
var inView = Catalog.drawSource(this, this.sources[k], ctx, frame, width, height, largestDim, zoomFactor);
|
||||
if (inView) {
|
||||
sourcesInView.push(this.sources[k]);
|
||||
}
|
||||
}*/
|
||||
|
||||
const sourcesInView = this.drawSources(ctx, width, height);
|
||||
|
||||
if (this._shapeIsFunction) {
|
||||
@@ -578,6 +516,9 @@ export let Catalog = (function() {
|
||||
Catalog.drawSourceLabel(this, s, ctx);
|
||||
})
|
||||
}
|
||||
|
||||
// Draw the footprints
|
||||
this.drawFootprints(ctx);
|
||||
};
|
||||
|
||||
Catalog.prototype.drawSources = function(ctx, width, height) {
|
||||
@@ -630,11 +571,6 @@ export let Catalog = (function() {
|
||||
s.popup.setPosition(s.x, s.y);
|
||||
}
|
||||
|
||||
// Draw the source footprint if there is any
|
||||
if (s.footprint) {
|
||||
s.footprint.draw(ctx, this.view);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -655,7 +591,13 @@ export let Catalog = (function() {
|
||||
ctx.fillText(label, s.x, s.y);
|
||||
};
|
||||
|
||||
|
||||
Catalog.prototype.drawFootprints = function(ctx) {
|
||||
this.footprints.forEach((f) => {
|
||||
f.draw(ctx, this.view)
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// callback function to be called when the status of one of the sources has changed
|
||||
Catalog.prototype.reportChange = function() {
|
||||
this.view && this.view.requestRedraw();
|
||||
|
||||
@@ -43,6 +43,8 @@ export let MeasurementTable = (function() {
|
||||
this.numPages = 1;
|
||||
this.numRowsByPage = 5;
|
||||
|
||||
this.columnClickAction = {};
|
||||
|
||||
$(aladinLiteDiv).append(this.divEl);
|
||||
}
|
||||
|
||||
@@ -51,7 +53,21 @@ export let MeasurementTable = (function() {
|
||||
rows.forEach(row => {
|
||||
tbody += '<tr>'
|
||||
for (let key in row.data) {
|
||||
tbody += '<td>' + row.data[key] + '</td>';
|
||||
// check the type here
|
||||
const val = row.data[key];
|
||||
tbody += '<td class="' + key + '">'
|
||||
if (typeof(val) === "string") {
|
||||
try {
|
||||
let url = new URL(val);
|
||||
let link = '<a href=' + url + '>' + url + '</a>';
|
||||
tbody += link;
|
||||
} catch(e) {
|
||||
tbody += val
|
||||
}
|
||||
} else {
|
||||
tbody += val
|
||||
}
|
||||
tbody += '</td>'
|
||||
}
|
||||
tbody += '</tr>';
|
||||
});
|
||||
@@ -67,13 +83,27 @@ export let MeasurementTable = (function() {
|
||||
let tbody = this.divEl[0].querySelector(".content");
|
||||
tbody.innerHTML = MeasurementTable.updateBodyTable(fullRows.slice(rowIdxStart, rowIdxStart + this.numRowsByPage));
|
||||
|
||||
if (this.fieldsClickCallbacks) {
|
||||
Object.entries(this.fieldsClickCallbacks)
|
||||
.forEach(([key, callback]) => {
|
||||
this.divEl[0].querySelectorAll("." + key).forEach((e) => {
|
||||
e.addEventListener('click', (e) => {
|
||||
callback(e.target.innerText)
|
||||
|
||||
e.preventDefault();
|
||||
}, false)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// recompute page idx
|
||||
let pageIdxElt = this.divEl[0].querySelector("#pageIdx");
|
||||
pageIdxElt.innerHTML = '<p id="pageIdx" style="display: inline-block; margin: 0">' + this.curPage + '/' + this.numPages + '</p>';
|
||||
}
|
||||
|
||||
// show measurement associated with a given source
|
||||
MeasurementTable.prototype.showMeasurement = function(rows) {
|
||||
MeasurementTable.prototype.showMeasurement = function(rows, table) {
|
||||
this.fieldsClickCallbacks = table.fieldsClickCallbacks;
|
||||
// compute the number of pages
|
||||
this.numPages = Math.floor(rows.length / this.numRowsByPage);
|
||||
if (rows.length % this.numRowsByPage > 0) {
|
||||
@@ -89,13 +119,25 @@ export let MeasurementTable = (function() {
|
||||
thead += '</tr></thead>';
|
||||
|
||||
let tbody = MeasurementTable.updateBodyTable(rows.slice(0, this.numRowsByPage));
|
||||
|
||||
this.divEl.append('<table>' + thead + tbody + '</table>');
|
||||
// Add the callbacks to the cells
|
||||
if (this.fieldsClickCallbacks) {
|
||||
Object.entries(this.fieldsClickCallbacks)
|
||||
.forEach(([key, callback]) => {
|
||||
this.divEl[0].querySelectorAll("." + key).forEach((e) => {
|
||||
e.addEventListener('click', (e) => {
|
||||
callback(e.target.innerText)
|
||||
|
||||
e.preventDefault();
|
||||
}, false)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (this.numPages > 1) {
|
||||
this.divEl.append('<div class="footer"><button id="prevButton" style="display: inline-block">Previous</button><button id="nextButton" style="display: inline-block">Next</button><p id="pageIdx" style="display: inline-block; margin: 0">' + this.curPage + '/' + this.numPages + '</p></div>');
|
||||
|
||||
document.querySelector('#nextButton').addEventListener(
|
||||
this.divEl[0].querySelector('#nextButton').addEventListener(
|
||||
'click',
|
||||
() => {
|
||||
this.curPage++;
|
||||
@@ -107,7 +149,8 @@ export let MeasurementTable = (function() {
|
||||
}
|
||||
,false
|
||||
);
|
||||
document.querySelector('#prevButton').addEventListener(
|
||||
|
||||
this.divEl[0].querySelector('#prevButton').addEventListener(
|
||||
'click',
|
||||
() => {
|
||||
this.curPage--;
|
||||
|
||||
@@ -74,7 +74,9 @@ export let Overlay = (function() {
|
||||
};
|
||||
|
||||
// return an array of Footprint from a STC-S string
|
||||
Overlay.parseSTCS = function(stcs) {
|
||||
Overlay.parseSTCS = function(stcs, options) {
|
||||
options = options || {};
|
||||
|
||||
var footprints = [];
|
||||
var parts = stcs.match(/\S+/g);
|
||||
var k = 0, len = parts.length;
|
||||
@@ -99,7 +101,9 @@ export let Overlay = (function() {
|
||||
curPolygon.push([ra, dec]);
|
||||
k += 2;
|
||||
}
|
||||
footprints.push(A.polygon(curPolygon, {closed: true}));
|
||||
|
||||
options.closed = true;
|
||||
footprints.push(A.polygon(curPolygon, options));
|
||||
}
|
||||
}
|
||||
else if (s=='circle') {
|
||||
@@ -114,7 +118,7 @@ export let Overlay = (function() {
|
||||
dec = parseFloat(parts[k+2]);
|
||||
radiusDegrees = parseFloat(parts[k+3]);
|
||||
|
||||
footprints.push(A.circle(ra, dec, radiusDegrees));
|
||||
footprints.push(A.circle(ra, dec, radiusDegrees, options));
|
||||
|
||||
k += 3;
|
||||
}
|
||||
|
||||
@@ -43,8 +43,6 @@ export let Source = (function() {
|
||||
this.useMarkerDefaultIcon = (options && options.useMarkerDefaultIcon!==undefined) ? options.useMarkerDefaultIcon : true;
|
||||
}
|
||||
|
||||
this.footprint = (options && options.footprint) || undefined;
|
||||
|
||||
this.isShowing = true;
|
||||
this.isSelected = false;
|
||||
};
|
||||
@@ -100,7 +98,7 @@ export let Source = (function() {
|
||||
|
||||
if (this.catalog.onClick=='showTable') {
|
||||
this.select();
|
||||
view.aladin.measurementTable.showMeasurement([this]);
|
||||
view.aladin.measurementTable.showMeasurement([this], this.catalog);
|
||||
}
|
||||
else if (this.catalog.onClick=='showPopup') {
|
||||
|
||||
|
||||
@@ -572,12 +572,13 @@ export let View = (function () {
|
||||
view.dragy - view.selectStartCoo.y
|
||||
);
|
||||
|
||||
selectedObjects.forEach((obj) => {
|
||||
obj.select()
|
||||
});
|
||||
console.log(selectedObjects)
|
||||
view.aladin.measurementTable.showMeasurement(selectedObjects);
|
||||
selectedObjects.forEach((obj) => obj.select());
|
||||
|
||||
if (selectedObjects.length > 0) {
|
||||
let table = selectedObjects[0].catalog;
|
||||
view.aladin.measurementTable.showMeasurement(selectedObjects, table);
|
||||
}
|
||||
|
||||
view.selectedObjects = selectedObjects;
|
||||
|
||||
view.aladin.fire(
|
||||
|
||||
@@ -71,79 +71,56 @@
|
||||
'instrument_name': { name: 'instrument_name', ucd: 'meta.id;instr', utype: 'Provenance.ObsConfig.Instrument.name', units: null },
|
||||
}
|
||||
|
||||
Obscore.clickOnAccessUrlAction = function(accessUrl) {
|
||||
// Parse the datalink as a votable
|
||||
VOTable.parse(accessUrl, (fields, rows) => {
|
||||
console.log(fields)
|
||||
})
|
||||
}
|
||||
|
||||
Obscore.COLOR = '#004500'
|
||||
|
||||
function Obscore() {};
|
||||
|
||||
Obscore.parseVOTable = function(url, callback) {
|
||||
new VOTable(url, (votable) => {
|
||||
votable.votable.get("resources")
|
||||
.forEach((resource) => {
|
||||
let tables = resource.get("tables")
|
||||
tables.forEach((table) => {
|
||||
let fields = table.get("elems")
|
||||
.map((field) => {
|
||||
// convert a map into a javascript object
|
||||
return Object.fromEntries(field);
|
||||
})
|
||||
Obscore.parseFields = function(fields) {
|
||||
let parsedFields = {};
|
||||
|
||||
let obsCoreFieldIndices = {};
|
||||
// Check for mandatory fields
|
||||
['s_ra', 's_dec', 'access_url', 's_region']
|
||||
.map((mandatoryFieldName) => {
|
||||
const mandatoryField = Obscore.MANDATORY_FIELDS[mandatoryFieldName];
|
||||
const raField = Obscore.MANDATORY_FIELDS['s_ra'];
|
||||
const decField = Obscore.MANDATORY_FIELDS['s_dec'];
|
||||
const regionField = Obscore.MANDATORY_FIELDS['s_region'];
|
||||
const accessUrlField = Obscore.MANDATORY_FIELDS['access_url'];
|
||||
|
||||
const fieldIdx = Obscore.findMandatoryField(fields,
|
||||
mandatoryField.name,
|
||||
mandatoryField.ucd,
|
||||
mandatoryField.utype
|
||||
);
|
||||
let raFieldIdx = Obscore.findMandatoryField(fields, raField.name, raField.ucd, raField.utype);
|
||||
let decFieldIdx = Obscore.findMandatoryField(fields, decField.name, decField.ucd, decField.utype);
|
||||
let regionFieldIdx = Obscore.findMandatoryField(fields, regionField.name, regionField.ucd, regionField.utype);
|
||||
let accessUrlFieldIdx = Obscore.findMandatoryField(fields, accessUrlField.name, accessUrlField.ucd, accessUrlField.utype);
|
||||
|
||||
let field = fields[fieldIdx];
|
||||
let key = field.name ? field.name : field.id;
|
||||
let fieldIdx = 0;
|
||||
fields.forEach((field) => {
|
||||
let key = field.name ? field.name : field.id;
|
||||
|
||||
obsCoreFieldIndices[mandatoryFieldName] = {
|
||||
columnName: key,
|
||||
idx: fieldIdx,
|
||||
};
|
||||
})
|
||||
let nameField;
|
||||
if (fieldIdx == raFieldIdx) {
|
||||
nameField = 's_ra';
|
||||
} else if (fieldIdx == decFieldIdx) {
|
||||
nameField = 's_dec';
|
||||
} else if (fieldIdx == regionFieldIdx) {
|
||||
nameField = 's_region';
|
||||
} else if (fieldIdx == accessUrlFieldIdx) {
|
||||
nameField = 'access_url';
|
||||
} else {
|
||||
nameField = key;
|
||||
}
|
||||
|
||||
// At this point we sure know we have an obscore table
|
||||
let rows = table.get("data").get("rows");
|
||||
// We compute the obscore sources
|
||||
let sources = [];
|
||||
let footprints = [];
|
||||
const raFieldIdx = obsCoreFieldIndices['s_ra'].idx;
|
||||
const decFieldIdx = obsCoreFieldIndices['s_dec'].idx;
|
||||
const sRegionIdx = obsCoreFieldIndices['s_region'].idx;
|
||||
|
||||
parsedFields[nameField] = {
|
||||
name: key,
|
||||
idx: fieldIdx,
|
||||
};
|
||||
|
||||
rows.forEach(row => {
|
||||
var mesures = {};
|
||||
|
||||
let idxField = 0;
|
||||
for (const field of fields) {
|
||||
var key = field.name ? field.name : field.id;
|
||||
|
||||
mesures[key] = row[idxField];
|
||||
idxField += 1;
|
||||
}
|
||||
|
||||
const ra = row[raFieldIdx];
|
||||
const dec = row[decFieldIdx];
|
||||
const region = row[sRegionIdx];
|
||||
let footprint = A.footprintsFromSTCS(region)[0];
|
||||
|
||||
sources.push(new Source(ra, dec, mesures, {footprint: footprint}));
|
||||
})
|
||||
|
||||
// Give the source list and a table of correspondance of mandatory obscore fields to source fields
|
||||
if (callback) {
|
||||
callback(sources, footprints)
|
||||
}
|
||||
})
|
||||
});
|
||||
fieldIdx++;
|
||||
})
|
||||
|
||||
return parsedFields;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
import { ALEvent } from "../events/ALEvent.js";
|
||||
import { Catalog } from "../Catalog.js";
|
||||
import { Obscore } from "./Obscore.js";
|
||||
|
||||
export let VOTable = (function() {
|
||||
|
||||
@@ -39,6 +41,42 @@ export let VOTable = (function() {
|
||||
}});
|
||||
})
|
||||
};
|
||||
|
||||
VOTable.parse = function (url, callback, raField, decField) {
|
||||
fetch(url)
|
||||
.then((response) => response.text())
|
||||
.then((xml) => {
|
||||
ALEvent.AL_USE_WASM.dispatchedTo(document.body, {callback: (wasm) => {
|
||||
let votable = wasm.parseVOTable(xml);
|
||||
|
||||
votable.votable.get("resources")
|
||||
.forEach((resource) => {
|
||||
let tables = resource.get("tables")
|
||||
tables.forEach((table) => {
|
||||
let fields = table.get("elems")
|
||||
.map((field) => {
|
||||
// convert a map into a javascript object
|
||||
return Object.fromEntries(field);
|
||||
})
|
||||
|
||||
try {
|
||||
fields = Obscore.parseFields(fields);
|
||||
} catch(e) {
|
||||
// It is not an obscore table
|
||||
fields = Catalog.parseFields(fields, raField, decField);
|
||||
}
|
||||
|
||||
let data = table.get("data");
|
||||
let rows = data.get("rows");
|
||||
|
||||
callback(fields, rows)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
// return an array of Source(s) from a VOTable url
|
||||
// callback function is called each time a TABLE element has been parsed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user