From 93a7c7c6425bf1b2d735e235af22cda640772429 Mon Sep 17 00:00:00 2001 From: Matthieu Baumann Date: Wed, 29 May 2024 19:26:35 +1000 Subject: [PATCH] points to moc/healpix released versions + multi selection --- examples/al-catalog-hips-shape.html | 28 ++- examples/al-ellipse.html | 6 +- examples/al-polyline.html | 4 + package.json | 2 +- src/core/Cargo.toml | 6 +- src/core/src/healpix/coverage.rs | 15 +- src/core/src/renderable/coverage/graph.rs | 8 +- src/core/src/renderable/coverage/moc.rs | 33 ++- src/core/src/renderable/coverage/mode/edge.rs | 14 +- .../src/renderable/coverage/mode/filled.rs | 4 +- .../src/renderable/coverage/mode/perimeter.rs | 10 +- src/css/aladin.css | 4 +- src/js/Aladin.js | 30 +++ src/js/AladinUtils.js | 4 +- src/js/ProgressiveCat.js | 36 +-- src/js/View.js | 232 ++++++++++-------- src/js/shapes/Ellipse.js | 26 +- src/js/shapes/Polyline.js | 14 ++ 18 files changed, 290 insertions(+), 186 deletions(-) diff --git a/examples/al-catalog-hips-shape.html b/examples/al-catalog-hips-shape.html index 957462ab..291b0d70 100644 --- a/examples/al-catalog-hips-shape.html +++ b/examples/al-catalog-hips-shape.html @@ -9,9 +9,10 @@ let aladin; A.init.then(() => { aladin = A.aladin("#aladin-lite-div", { - target: "12 25 41.512 +12 48 47.2", - inertia: false, - fov: 1, + target: "03 36 31.65 -35 17 43.1", + survey: "CDS/P/DES-DR2/ColorIRG", + fov: 3 / 60, + fullScreen: true, showContextMenu: true, showZoomControl: true, showSettingsControl: true, @@ -20,7 +21,7 @@ }); // define custom draw function - var hips = A.catalogHiPS( + /*var hips = A.catalogHiPS( "https://axel.u-strasbg.fr/HiPSCatService/Simbad", { onClick: "showTable", @@ -38,7 +39,24 @@ return A.ellipse(s.ra, s.dec, a / 60, b / 60, theta, { color: "cyan" }); }, } - ); + );*/ + var hips = A.catalogHiPS( + "https://axel.cds.unistra.fr/HiPSCatService/II/371/des_dr2", + { + onClick: "showTable", + name: "Simbad", + color: "cyan", + hoverColor: "red", + shape: (s) => { + let a = +s.data['Aimg']/3600; + let b = +s.data['Bimg']/3600; + + let theta = +s.data['PA']; + + return A.ellipse(s.ra, s.dec, a, b, theta, { color: "cyan" }); + }, + } + ) aladin.addCatalog(hips); }); diff --git a/examples/al-ellipse.html b/examples/al-ellipse.html index 651c4d6c..985eead2 100644 --- a/examples/al-ellipse.html +++ b/examples/al-ellipse.html @@ -19,11 +19,11 @@ overlay.addFootprints([ A.polygon([[83.64287, 22.01713], [83.59872, 22.01692], [83.59852, 21.97629], [83.64295, 21.97629]]), A.polygon([[83.62807, 22.06330], [83.58397, 22.02280], [83.62792, 22.02258]]), - A.ellipse(10.6833, 41.2669, 3.33333/2, 1.1798333/2, 35, {color: 'cyan'}), + A.ellipse(10.6833, 41.2669, 3.33333/2, 1.1798333/2, 10, {color: 'cyan'}), // NGC 3048 - A.ellipse(180.470842, -18.867589, 5.2/120, 3.1/120, 80, {color: 'cyan'}), + A.ellipse(180.470842, -18.867589, 5.2/120, 3.1/120, 10, {color: 'cyan'}), // NGC 3049 - A.ellipse(180.4742, -18.8850, 3.1/120, 1.6/120, 50, {color: 'cyan'}), + A.ellipse(180.4742, -18.8850, 3.1/120, 1.6/120, 10, {color: 'cyan'}), ]); //overlay.add(); // radius in degrees }); diff --git a/examples/al-polyline.html b/examples/al-polyline.html index 630656e0..59063220 100644 --- a/examples/al-polyline.html +++ b/examples/al-polyline.html @@ -16,6 +16,10 @@ var overlay = A.graphicOverlay({lineWidth: 2}); aladin.addOverlay(overlay); overlay.add(A.polyline([ [2.29452158, 59.14978110], [10.12683778, 56.53733116], [14.1772154, 60.7167403], [21.45396446, 60.23528403], [28.59885697, 63.67010079] ], {color: 'green'})); + + aladin.select('rect', (s) => { + console.log(s) + }) }); diff --git a/package.json b/package.json index b627051f..1e8ff858 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "preview": "vite preview", "test:build": "cd src/core && cargo test --release --features webgl2", "test:unit": "vitest run", - "doc": "jsdoc -d doc --readme README.md src/js && cp aladin-logo.png doc/", + "doc": "jsdoc -d doc --readme README.md src/js src/js/shapes && cp aladin-logo.png doc/", "doc:dev": "npm run doc && open doc/index.html" }, "devDependencies": { diff --git a/src/core/Cargo.toml b/src/core/Cargo.toml index ea8a9c4c..f533fa6b 100644 --- a/src/core/Cargo.toml +++ b/src/core/Cargo.toml @@ -40,13 +40,11 @@ rand = "0.8" [dependencies.healpix] package = "cdshealpix" -git = "https://github.com/bmatthieu3/cds-healpix-rust" -branch = "polygonIntersectVertices" +version = "0.6.9" [dependencies.moclib] package = "moc" -git = "https://github.com/bmatthieu3/cds-moc-rust" -branch = "cellsWithUnidirectionalNeigs" +version = "0.14.2" [dependencies.serde] version = "^1.0.183" diff --git a/src/core/src/healpix/coverage.rs b/src/core/src/healpix/coverage.rs index 424064c0..d07ff620 100644 --- a/src/core/src/healpix/coverage.rs +++ b/src/core/src/healpix/coverage.rs @@ -3,7 +3,11 @@ use crate::math::PI; use crate::math::{self, lonlat::LonLat}; use cgmath::{Vector3, Vector4}; -use moclib::{moc::range::RangeMOC, qty::Hpx, ranges::SNORanges}; +use moclib::{ + moc::range::{CellSelection, RangeMOC}, + qty::Hpx, + ranges::SNORanges, +}; pub type Smoc = RangeMOC>; use crate::healpix::cell::HEALPixCell; @@ -29,8 +33,12 @@ impl HEALPixCoverage { .collect::>(); let LonLatT(in_lon, in_lat) = inside.lonlat(); - let moc = - RangeMOC::from_polygon_with_control_point(&lonlat[..], (in_lon.0, in_lat.0), depth); + let moc = RangeMOC::from_polygon_with_control_point( + &lonlat[..], + (in_lon.0, in_lat.0), + depth, + CellSelection::All, + ); HEALPixCoverage(moc) } @@ -64,6 +72,7 @@ impl HEALPixCoverage { rad, depth, 0, + CellSelection::All, )) } } diff --git a/src/core/src/renderable/coverage/graph.rs b/src/core/src/renderable/coverage/graph.rs index 76799ecb..a7b281aa 100644 --- a/src/core/src/renderable/coverage/graph.rs +++ b/src/core/src/renderable/coverage/graph.rs @@ -1,7 +1,7 @@ use crate::healpix::coverage::HEALPixCoverage; use moclib::elem::cell::Cell; -use moclib::moc::range::CellAndNeighs; +//use moclib::moc::range::CellAndNeighs; use moclib::moc::RangeMOCIntoIterator; use moclib::moc::RangeMOCIterator; @@ -91,11 +91,10 @@ impl NodeEdgeNeigs { 1 << delta_depth } } - -pub(super) struct G { +/*pub(super) struct G { nodes: Vec, } - +use crate::renderable::coverage::mode::Node; impl G { pub(super) fn new(moc: &HEALPixCoverage) -> Self { let mut nodes: Vec<_> = (&moc.0) @@ -294,3 +293,4 @@ fn find_neig_dir(mut cell: HEALPixCell, mut neig: HEALPixCell) -> Option Self { - let nodes = match mode { + /*let nodes = match mode { RenderModeType::Edge { .. } => super::mode::edge::Edge::build(moc), RenderModeType::Filled { .. } => super::mode::filled::Fill::build(moc), RenderModeType::Perimeter { .. } => super::mode::perimeter::Perimeter::build(moc), - }; + };*/ + let mut sides = OrdinalMap::new(); + sides.put(healpix::compass_point::Ordinal::SE, 1); + sides.put(healpix::compass_point::Ordinal::SW, 1); + sides.put(healpix::compass_point::Ordinal::NE, 1); + sides.put(healpix::compass_point::Ordinal::NW, 1); + + let nodes = (&moc.0) + .into_range_moc_iter() + .cells() + .flat_map(|cell| { + let cell = HEALPixCell(cell.depth, cell.idx); + let dd = if 3 >= cell.depth() { + 3 - cell.depth() + } else { + 0 + }; + cell.get_tile_cells(dd) + }) + .map(|cell| Node { + vertices: cell.path_along_sides(&sides), + cell, + }) + .collect::>(); let hpx_idx_vec = IdxVec::from_hpx_cells(nodes.iter().map(|n| &n.cell)); diff --git a/src/core/src/renderable/coverage/mode/edge.rs b/src/core/src/renderable/coverage/mode/edge.rs index 753e4f38..ca575746 100644 --- a/src/core/src/renderable/coverage/mode/edge.rs +++ b/src/core/src/renderable/coverage/mode/edge.rs @@ -4,18 +4,9 @@ use super::RenderMode; use crate::HEALPixCoverage; -use healpix::{ - compass_point::{Ordinal, OrdinalMap}, -}; - - - - - - - - +use healpix::compass_point::{Ordinal, OrdinalMap}; +/* pub struct Edge; @@ -198,3 +189,4 @@ impl RenderMode for Edge { .collect() } } +*/ diff --git a/src/core/src/renderable/coverage/mode/filled.rs b/src/core/src/renderable/coverage/mode/filled.rs index 3ad6652c..e7bef19a 100644 --- a/src/core/src/renderable/coverage/mode/filled.rs +++ b/src/core/src/renderable/coverage/mode/filled.rs @@ -4,8 +4,9 @@ use super::RenderMode; use crate::HEALPixCoverage; use healpix::compass_point::{Ordinal, OrdinalMap}; - +/* use super::super::graph::G; + pub struct Fill; impl RenderMode for Fill { @@ -189,3 +190,4 @@ impl RenderMode for Fill { .collect() } } +*/ diff --git a/src/core/src/renderable/coverage/mode/perimeter.rs b/src/core/src/renderable/coverage/mode/perimeter.rs index a749c80a..ebeb5818 100644 --- a/src/core/src/renderable/coverage/mode/perimeter.rs +++ b/src/core/src/renderable/coverage/mode/perimeter.rs @@ -1,17 +1,12 @@ use super::Node; use super::RenderMode; use crate::healpix::cell::HEALPixCell; - -use healpix::{ - compass_point::{Ordinal, OrdinalMap}, -}; +use healpix::compass_point::{Ordinal, OrdinalMap}; use moclib::elem::cell::Cell; - - - use crate::HEALPixCoverage; use moclib::moc::range::CellAndEdges; +/* pub struct Perimeter; impl RenderMode for Perimeter { @@ -43,3 +38,4 @@ impl RenderMode for Perimeter { .collect() } } +*/ diff --git a/src/css/aladin.css b/src/css/aladin.css index 5cd57208..49584a64 100644 --- a/src/css/aladin.css +++ b/src/css/aladin.css @@ -104,7 +104,9 @@ } .aladin-measurement-div table tr td a { - display: block; + color: green; +} +.aladin-measurement-div table tr td a:hover { color: greenyellow; } diff --git a/src/js/Aladin.js b/src/js/Aladin.js index 81c72357..a66390f6 100644 --- a/src/js/Aladin.js +++ b/src/js/Aladin.js @@ -69,6 +69,9 @@ import { SimbadPointer } from "./gui/Button/SimbadPointer"; import { OverlayStackButton } from "./gui/Button/OverlayStack"; import { GridEnabler } from "./gui/Button/GridEnabler"; import { CooFrame } from "./gui/Input/CooFrame"; +import { Circle } from "./shapes/Circle"; +import { Ellipse } from "./shapes/Ellipse"; +import { Polyline } from "./shapes/Polyline"; /** * @typedef {Object} AladinOptions @@ -1981,7 +1984,34 @@ aladin.on("positionChanged", ({ra, dec}) => { new ALEvent(alEventName).listenedBy(this.aladinDiv, customFn); }; + /** + * Select specific objects in the view + * + * @memberof Aladin + * @param {?Array.} objects - If null is passed then nothing will be selected and sources already selected will be deselected + */ Aladin.prototype.selectObjects = function (objects) { + if (!objects) { + this.view.unselectObjects(); + return; + } + + let objListPerCatalog = {}; + + for (let o of objects) { + let cat = o.getCatalog(); + if (cat) { + let objList = objListPerCatalog[cat.name]; + if (!objList) { + objList = []; + } else { + objList.push(o); + } + } + } + objects = Object.values(objListPerCatalog); + console.log(objects); + this.view.selectObjects(objects); }; diff --git a/src/js/AladinUtils.js b/src/js/AladinUtils.js index b099e80e..33e68ab0 100644 --- a/src/js/AladinUtils.js +++ b/src/js/AladinUtils.js @@ -166,7 +166,9 @@ export let AladinUtils = { }, /** - * @function degreesToString + * @function + * @memberof AladinUtils + * @name degreesToString * Convert a number in degrees into a string
* * @param numberDegrees number in degrees (integer or decimal) diff --git a/src/js/ProgressiveCat.js b/src/js/ProgressiveCat.js index ffa28dbd..94e9b7d2 100644 --- a/src/js/ProgressiveCat.js +++ b/src/js/ProgressiveCat.js @@ -372,38 +372,43 @@ export let ProgressiveCat = (function() { } // Order must be >= 0 + if (this.order1Footprints) { + this.order1Footprints.forEach((f) => { + f.draw(ctx, this.view); + f.source.tooSmallFootprint = f.isTooSmall(); + }); + } if (this.order1Sources) { this.drawSources(this.order1Sources, ctx, width, height); } - if (this.order1Footprints) { - this.order1Footprints.forEach((f) => { - f.draw(ctx, this.view) - }); - } if (this.view.realNorder >= 1) { - if (this.order2Sources) { - this.drawSources(this.order2Sources, ctx, width, height); - } if (this.order2Footprints) { this.order2Footprints.forEach((f) => { f.draw(ctx, this.view) + f.source.tooSmallFootprint = f.isTooSmall(); }); } + + if (this.order2Sources) { + this.drawSources(this.order2Sources, ctx, width, height); + } } // For old allsky, tilesInView refers to tiles at orders 4.. // For new allsky, tilesInView will contains order3 sources if (this.maxOrderAllsky === 3) { if (this.view.realNorder >= 2) { - if (this.order3Sources) { - this.drawSources(this.order3Sources, ctx, width, height); - } if (this.order3Footprints) { this.order3Footprints.forEach((f) => { f.draw(ctx, this.view) + f.source.tooSmallFootprint = f.isTooSmall(); }); } + + if (this.order3Sources) { + this.drawSources(this.order3Sources, ctx, width, height); + } } } @@ -413,15 +418,16 @@ export let ProgressiveCat = (function() { sources = this.sourcesCache.get(key); footprints = this.footprintsCache.get(key); - if (sources) { - this.drawSources(sources, ctx, width, height); - } - if (footprints) { footprints.forEach((f) => { f.draw(ctx, this.view) + f.source.tooSmallFootprint = f.isTooSmall(); }); } + + if (sources) { + this.drawSources(sources, ctx, width, height); + } }); if (this._shapeIsFunction) { diff --git a/src/js/View.js b/src/js/View.js index 2fac78f2..28ccc0fc 100644 --- a/src/js/View.js +++ b/src/js/View.js @@ -547,38 +547,41 @@ export let View = (function () { // Deselect objects if any view.unselectObjects(); if (objs) { - var o = objs[0]; - - // footprint selection code adapted from Fabrizio Giordano dev. from Serco for ESA/ESDC - if (o.marker) { - // could be factorized in Source.actionClicked - view.aladin.popup.setTitle(o.popupTitle); - view.aladin.popup.setText(o.popupDesc); - view.aladin.popup.setSource(o); - view.aladin.popup.show(); - } - else { - if (view.lastClickedObject) { - view.lastClickedObject.actionOtherObjectClicked && view.lastClickedObject.actionOtherObjectClicked(); - } - } - - // show measurements - if (o.actionClicked) { - o.actionClicked(); - } - var objClickedFunction = view.aladin.callbacksByEventName['objectClicked']; - (typeof objClickedFunction === 'function') && objClickedFunction(o, xy); + var footprintClickedFunction = view.aladin.callbacksByEventName['footprintClicked']; - if (o.isFootprint()) { - var footprintClickedFunction = view.aladin.callbacksByEventName['footprintClicked']; - if (typeof footprintClickedFunction === 'function' && o != view.lastClickedObject) { - var ret = footprintClickedFunction(o, xy); + for (let o of objs) { + // footprint selection code adapted from Fabrizio Giordano dev. from Serco for ESA/ESDC + if (o.marker) { + // could be factorized in Source.actionClicked + view.aladin.popup.setTitle(o.popupTitle); + view.aladin.popup.setText(o.popupDesc); + view.aladin.popup.setSource(o); + view.aladin.popup.show(); + } + /*else { + if (view.lastClickedObject) { + view.lastClickedObject.actionOtherObjectClicked + view.lastClickedObject.actionOtherObjectClicked(); + } + }*/ + + // show measurements + /*if (o.actionClicked) { + o.actionClicked(); + }*/ + + (typeof objClickedFunction === 'function') && objClickedFunction(o, xy); + + if (o.isFootprint()) { + if (typeof footprintClickedFunction === 'function' && (!view.lastClickedObject || !view.lastClickedObject.includes(o))) { + footprintClickedFunction(o, xy); + } } } - view.lastClickedObject = o; + view.selectObjects([objs]); + view.lastClickedObject = objs; } else { // If there is a past clicked object if (view.lastClickedObject) { @@ -587,13 +590,14 @@ export let View = (function () { view.aladin.popup.hide(); // Deselect the last clicked object - if (view.lastClickedObject instanceof Ellipse || view.lastClickedObject instanceof Circle || view.lastClickedObject instanceof Polyline) { + /*if (view.lastClickedObject instanceof Ellipse || view.lastClickedObject instanceof Circle || view.lastClickedObject instanceof Polyline) { view.lastClickedObject.deselect(); } else { // Case where lastClickedObject is a Source view.lastClickedObject.actionOtherObjectClicked(); - } + }*/ + // TODO: do we need to keep that triggering ? var objClickedFunction = view.aladin.callbacksByEventName['objectClicked']; (typeof objClickedFunction === 'function') && objClickedFunction(null, xy); @@ -968,48 +972,63 @@ export let View = (function () { // closestObjects is very costly, we would like to not do it // especially if the objectHovered function is not defined. - var closest = view.closestObjects(xymouse.x, xymouse.y, 5); + var closests = view.closestObjects(xymouse.x, xymouse.y, 5); - if (closest) { - let o = closest[0]; + if (closests) { var objHoveredFunction = view.aladin.callbacksByEventName['objectHovered']; var footprintHoveredFunction = view.aladin.callbacksByEventName['footprintHovered']; view.setCursor('pointer'); - if (typeof objHoveredFunction === 'function' && o != lastHoveredObject) { - var ret = objHoveredFunction(o, xymouse); - } - if (o.isFootprint()) { - if (typeof footprintHoveredFunction === 'function' && o != lastHoveredObject) { - var ret = footprintHoveredFunction(o, xymouse); + for (let o of closests) { + if (typeof objHoveredFunction === 'function' && (!lastHoveredObject || !lastHoveredObject.includes(o))) { + var ret = objHoveredFunction(o, xymouse); + } + + if (o.isFootprint()) { + if (typeof footprintHoveredFunction === 'function' && (!lastHoveredObject || !lastHoveredObject.includes(o))) { + var ret = footprintHoveredFunction(o, xymouse); + } + } + + if (!lastHoveredObject || !lastHoveredObject.includes(o)) { + o.hover(); } } - if (lastHoveredObject && o != lastHoveredObject) { - lastHoveredObject.unhover(); - + // unhover the objects in lastHoveredObjects that are not in closest anymore + if (lastHoveredObject) { var objHoveredStopFunction = view.aladin.callbacksByEventName['objectHoveredStop']; - if (typeof objHoveredStopFunction === 'function') { - objHoveredStopFunction(lastHoveredObject, xymouse); + for (let lho of lastHoveredObject) { + if (!closests.includes(lho)) { + lho.unhover(); + + if (typeof objHoveredStopFunction === 'function') { + objHoveredStopFunction(lho, xymouse); + } + } } } - - if (o != lastHoveredObject) { - o.hover(); - } - lastHoveredObject = o; + lastHoveredObject = closests; } else { view.setCursor('default'); - var objHoveredStopFunction = view.aladin.callbacksByEventName['objectHoveredStop']; if (lastHoveredObject) { - if (typeof objHoveredStopFunction === 'function') { + var objHoveredStopFunction = view.aladin.callbacksByEventName['objectHoveredStop']; + + /*if (typeof objHoveredStopFunction === 'function') { // call callback function to notify we left the hovered object var ret = objHoveredStopFunction(lastHoveredObject, xymouse); } - lastHoveredObject.unhover(); + lastHoveredObject.unhover();*/ + for (let lho of lastHoveredObject) { + lho.unhover(); + + if (typeof objHoveredStopFunction === 'function') { + objHoveredStopFunction(lho, xymouse); + } + } } lastHoveredObject = null; @@ -1406,42 +1425,47 @@ export let View = (function () { this.unselectObjects(); if (Array.isArray(selection)) { - this.selection = [selection]; + this.selection = selection; } else { // select the new this.selection = Selector.getObjects(selection, this); } - if (this.selection.length > 0) { this.selection.forEach((objListPerCatalog) => { - objListPerCatalog.forEach((obj) => obj.select()) + objListPerCatalog.forEach((obj) => { + obj.select() + }) }); - let tables = this.selection.map((objList) => { - // Get the catalog containing that list of objects - let catalog = objList[0].getCatalog(); + let tables = this.selection + .filter(objList => { + return objList[0].getCatalog; + }) + .map(objList => { + // Get the catalog containing that list of objects + let catalog = objList[0].getCatalog(); - let source; - let sources = objList.map((o) => { - if (o instanceof Footprint) { - source = o.source; - } else { - source = o; - } - - return source; - }); - let table = { - 'name': catalog.name, - 'color': catalog.color, - 'rows': sources, - 'fields': catalog.fields, - 'showCallback': ObsCore.SHOW_CALLBACKS(this.aladin) - }; - - return table; - }) + let source; + let sources = objList.map((o) => { + if (o instanceof Footprint) { + source = o.source; + } else { + source = o; + } + + return source; + }); + let table = { + 'name': catalog.name, + 'color': catalog.color, + 'rows': sources, + 'fields': catalog.fields, + 'showCallback': ObsCore.SHOW_CALLBACKS(this.aladin) + }; + + return table; + }) this.aladin.measurementTable.showMeasurement(tables); let a = this.aladin; @@ -2019,8 +2043,8 @@ export let View = (function () { return null; } + let closests = []; let closest = null; - footprints.forEach((footprint) => { if (!footprint.source || !footprint.source.tooSmallFootprint) { // Hidden footprints are not considered @@ -2029,16 +2053,15 @@ export let View = (function () { footprint.setLineWidth(10.0); if (footprint.isShowing && footprint.isInStroke(ctx, this, x * window.devicePixelRatio, y * window.devicePixelRatio)) { closest = footprint; + if (closest) { + closests.push(closest); + } } footprint.setLineWidth(lineWidth); - - if (closest) { - return closest; - } } }) - return closest; + return closests; }; // return closest object within a radius of maxRadius pixels. maxRadius is an integer @@ -2050,15 +2073,12 @@ export let View = (function () { // this makes footprint selection easier as the catch-zone is larger //let pastLineWidth = ctx.lineWidth; + let closests = []; if (this.overlays) { for (var k = 0; k < this.overlays.length; k++) { overlay = this.overlays[k]; - let closest = this.closestFootprints(overlay.overlayItems, ctx, x, y); - if (closest) { - //ctx.lineWidth = pastLineWidth; - return [closest]; - } + closests = closests.concat(this.closestFootprints(overlay.overlayItems, ctx, x, y)); } } @@ -2068,11 +2088,7 @@ export let View = (function () { let catalog = this.catalogs[k]; let footprints = catalog.getFootprints(); - let closest = this.closestFootprints(footprints, ctx, x, y); - if (closest) { - //ctx.lineWidth = pastLineWidth; - return [closest]; - } + closests = closests.concat(this.closestFootprints(footprints, ctx, x, y)); } } @@ -2083,28 +2099,34 @@ export let View = (function () { //ctx.lineWidth = pastLineWidth; - var closest, dist; - for (var r = 0; r <= maxRadius; r++) { - closest = dist = null; + //var closest, dist; + //for (var r = 0; r <= maxRadius; r++) { + //closest = dist = null; for (var dx = -maxRadius; dx <= maxRadius; dx++) { if (!this.objLookup[x + dx]) { continue; } for (var dy = -maxRadius; dy <= maxRadius; dy++) { if (this.objLookup[x + dx][y + dy]) { - var d = dx * dx + dy * dy; - if (!closest || d < dist) { + //var d = dx * dx + dy * dy; + /*if (!closest || d < dist) { closest = this.objLookup[x + dx][y + dy]; - dist = d; - } + //dist = d; + }*/ + closests = closests.concat(this.objLookup[x + dx][y + dy]) } } } - if (closest) { - return closest; - } - } - return null; + + /*if (closest) { + closests = closests.concat(closest); + }*/ + //} + + if (closests.length === 0) + return null; + + return closests; }; return View; diff --git a/src/js/shapes/Ellipse.js b/src/js/shapes/Ellipse.js index a567e7aa..c1dbb640 100644 --- a/src/js/shapes/Ellipse.js +++ b/src/js/shapes/Ellipse.js @@ -31,26 +31,7 @@ import { Utils } from "./../Utils"; import { GraphicOverlay } from "./../Overlay.js"; -/** -* @typedef {Object} ShapeOptions -* @description Options for describing a shape -* -* @property {Object} options - Configuration options for the shape. -* @property {string} [options.color] - The color of the shape -* @property {string} [options.fill=false] - Fill the shape with fillColor -* @property {string} [options.fillColor] - A filling color for the shape -* @property {number} [options.lineWidth=2] - The line width in pixels -* @property {number} [options.opacity=1] - The opacity, between 0 (totally transparent) and 1 (totally opaque) -* @property {string} [options.selectionColor='#00ff00'] - A selection color -* @property {string} [options.hoverColor] - A hovered color -*/ -/** - * Represents an ellipse shape - * - * @namespace - * @typedef {Object} Ellipse - */ export let Ellipse = (function() { /** * Constructor function for creating a new ellipse. @@ -58,9 +39,9 @@ export let Ellipse = (function() { * @constructor * @memberof Ellipse * @param {number[]} centerRaDec - right-ascension/declination 2-tuple of the ellipse's center in degrees - * @param {number} a - semi-major axis length in degrees - * @param {number} b - semi-minor axis length in degrees - * @param {number} theta - angle of the ellipse in degrees + * @param {number} a - half-major axis length in degrees + * @param {number} b - half-minor axis length in degrees + * @param {number} theta - angle of the ellipse in degrees. Origin aligns the ellipsis' major axis with the north pole. Positive angle points towards the east. * @param {ShapeOptions} options - Configuration options for the ellipse * * @returns {Ellipse} - The ellipse shape object @@ -230,7 +211,6 @@ export let Ellipse = (function() { return true; } - // TODO Ellipse.prototype.draw = function(ctx, view, noStroke, noSmallCheck) { if (! this.isShowing) { return false; diff --git a/src/js/shapes/Polyline.js b/src/js/shapes/Polyline.js index 432ad0b9..95f1129d 100644 --- a/src/js/shapes/Polyline.js +++ b/src/js/shapes/Polyline.js @@ -37,6 +37,20 @@ import { Utils } from '../Utils'; import { GraphicOverlay } from "../Overlay.js"; import { ProjectionEnum } from "../ProjectionEnum.js"; +/** +* @typedef {Object} ShapeOptions +* @description Options for describing a shape +* +* @property {Object} options - Configuration options for the shape. +* @property {string} [options.color] - The color of the shape +* @property {string} [options.fill=false] - Fill the shape with fillColor +* @property {string} [options.fillColor] - A filling color for the shape +* @property {number} [options.lineWidth=3] - The line width in pixels +* @property {number} [options.opacity=1] - The opacity, between 0 (totally transparent) and 1 (totally opaque) +* @property {string} [options.selectionColor='#00ff00'] - A selection color +* @property {string} [options.hoverColor] - A hovered color +*/ + /** * Represents a polyline shape *