mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-29 14:15:25 -08:00
Compare commits
81 Commits
cssUI
...
feature/pn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3571741f01 | ||
|
|
ce7d115d71 | ||
|
|
9d978c780c | ||
|
|
27bc342d27 | ||
|
|
c881d1c01c | ||
|
|
93a7c7c642 | ||
|
|
bada1dcecb | ||
|
|
e080f9f7d0 | ||
|
|
fea04ae118 | ||
|
|
fade1f95d2 | ||
|
|
ccb7347e54 | ||
|
|
6ab5abae09 | ||
|
|
00f7005bce | ||
|
|
219761c512 | ||
|
|
cd363ca4b9 | ||
|
|
fda33df813 | ||
|
|
ee1c23e34f | ||
|
|
22db1baac7 | ||
|
|
2981e634d2 | ||
|
|
5e8d0aca42 | ||
|
|
9e0caa54c2 | ||
|
|
5c4f60d4fd | ||
|
|
669fb26114 | ||
|
|
d655d8f8bd | ||
|
|
027a76f2ab | ||
|
|
d765dc9ec2 | ||
|
|
63aebf738a | ||
|
|
116ba0d2e3 | ||
|
|
34460eb9e7 | ||
|
|
1d68495f57 | ||
|
|
fee97bed40 | ||
|
|
c797aec7f7 | ||
|
|
b68358f6b2 | ||
|
|
9109c69fc3 | ||
|
|
d56dbd1659 | ||
|
|
8b8c1460eb | ||
|
|
f1a1247a43 | ||
|
|
54fcfe9f2b | ||
|
|
dfd91d9632 | ||
|
|
dc027e89c4 | ||
|
|
9617b233b0 | ||
|
|
7b2458ac8a | ||
|
|
02d97d7eba | ||
|
|
28c4a6144a | ||
|
|
e2e426493f | ||
|
|
f9f205f1d5 | ||
|
|
d070facc13 | ||
|
|
be0c84aa28 | ||
|
|
091effc92c | ||
|
|
cf26bd840c | ||
|
|
2062d6bfeb | ||
|
|
2a199aaf73 | ||
|
|
08a9c290ee | ||
|
|
5efcb20b5c | ||
|
|
0a6686835a | ||
|
|
e133f36fef | ||
|
|
a7773b4618 | ||
|
|
a3cea97d61 | ||
|
|
328923cbb2 | ||
|
|
856fc84025 | ||
|
|
7ad1e56912 | ||
|
|
c2bb0980af | ||
|
|
4ea8530528 | ||
|
|
7c27227d60 | ||
|
|
54199ceadc | ||
|
|
12c71624e7 | ||
|
|
2c50214a4e | ||
|
|
a421453078 | ||
|
|
f0c3bfc9f6 | ||
|
|
389654ba39 | ||
|
|
2b618ff38d | ||
|
|
19fa8f3a27 | ||
|
|
84a4d357c0 | ||
|
|
63ab255003 | ||
|
|
cc97efa707 | ||
|
|
7e581db86d | ||
|
|
ee43d0a786 | ||
|
|
90d49dbad9 | ||
|
|
473d60608f | ||
|
|
56dbb6656a | ||
|
|
d6e4e875a3 |
6
.github/workflows/api_doc.yml
vendored
6
.github/workflows/api_doc.yml
vendored
@@ -4,8 +4,10 @@ name: Deploy static content to Pages
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["develop"]
|
||||
|
||||
tags:
|
||||
- '*'
|
||||
branches:
|
||||
- develop
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
16
.github/workflows/codemeta_validator.yml
vendored
Normal file
16
.github/workflows/codemeta_validator.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: test_codemeta
|
||||
|
||||
on:
|
||||
release:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: gitlab-registry.in2p3.fr/escape2020/wp3/eossr:v1.0
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: validate codemeta
|
||||
run: eossr-metadata-validator codemeta.json
|
||||
3
.github/workflows/npm-publish.yml
vendored
3
.github/workflows/npm-publish.yml
vendored
@@ -6,6 +6,9 @@ name: Publish to NPM
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
36
CHANGELOG.md
36
CHANGELOG.md
@@ -1,7 +1,39 @@
|
||||
# Changelogs
|
||||
|
||||
## Unreleased
|
||||
|
||||
* [feat] Add new method `Aladin#getViewImageBuffer` to get the current view as a PNG buffer
|
||||
|
||||
## 3.3.3
|
||||
|
||||
* [feat] UI: add HiPS basic filter that filters the `hipsList` given
|
||||
* [feat] New `hipsList` option parameter when instancing a new Aladin object.
|
||||
* [feat] Zoom smoothing using hermite cubic interpolation functions
|
||||
* [feat] shape option of Catalog and ProgressiveCat accepts a function returning a Footprint. This allow user to
|
||||
associate a footprint to a specific source
|
||||
* [feat] Hover color support by @pmatsson and @bmatthieu3 in <https://github.com/cds-astro/aladin-lite/pull/145>
|
||||
|
||||
## 3.3.2
|
||||
|
||||
* [fixed] do not allow to query the properties several times for an imageHiPS
|
||||
* [fixed] Detecting raytracing rendering mode. Adapt the rendering mode in function of the fov value and the projection used. Some projections do have more distortions with wide FoVs so it is better to use the raytracing rendering mode when fov >= smaller FoV threshold.
|
||||
|
||||
## 3.3.0
|
||||
|
||||
* [fixed] multiple calls to setImageSurvey with the same survey object led to strange behaviour.
|
||||
* [perf] Display the first tile received instantly with no blending. Should enhance the slow reported in issue #88.
|
||||
* [fixed] A.on('select') (debugged from ipyaladin)
|
||||
* [fixed] Simbad pointer in galactical frame, cone search of simbad/vizier cats/other cone search services in galactical frame and MOC creation from selection in galactical frame => there is now a new `frame` optional param to Aladin.pix2world. If not given, the coo returned are in the frame of the view.
|
||||
* [doc] Add doc for image survey definition
|
||||
* [deprecation] A.createImageSurvey/A.newImageSurvey are now deprecated (but still in the API). Please use `A.imageHiPS` instead by providing a valid url or CDS ID conformed to <https://aladin.cds.unistra.fr/hips/list>
|
||||
* [refac] Simplify the instanciation of an imageHiPS/ imageFITS. Add a `A.imageHiPS` method for defining a HiPS object
|
||||
* [fixed] At initialisation, giving a fov > 180 was clamped back to 180 even if we specify allsky projection (i.e. accepting fov > 180). This is now fixed.
|
||||
* [fixed] MeasurementTable now display the full cell values (no ellipsis anymore)
|
||||
* [fixed] aladin.on('select') has been implemented. Callback is triggered on a circle and rect selections for not on polygonal selection.
|
||||
* [fixed] the cooFrame UI selector is updated if the user calls `aladin.setFrame`
|
||||
* [fixed] `reticleColor` and `reticleSize` options in the public API
|
||||
* Restore setFoVRange
|
||||
* Add CSS class for positioning the UI elements as the user wants. See the API doc aladin options for the class names to use.
|
||||
* [style] The default grid color is now `rgb(178, 50, 178)` to fit the classic Aladin color palette
|
||||
* [feat] The object of grid options `gridOptions` is now available in the public API
|
||||
* [fixed] The parameters `gridColor` and `gridOpacity`, `gridOptions.showLabels` now work as expected
|
||||
@@ -9,7 +41,7 @@
|
||||
* New release page here: <https://aladin.cds.unistra.fr/AladinLite/doc/release/>
|
||||
* A major UI update by @bmatthieu3
|
||||
1. Some API new classes A.box, A.button
|
||||
2. A status bar where the user can enque messages for a specific amount of time (Aladin.appendStatusBarMessage)
|
||||
2. A status bar where the user can enque messages for a specific amount of time (Aladin.addStatusBarMessage)
|
||||
* Remove of JQuery and autocompletejs dependencies by @bmatthieu3
|
||||
* Fix some performances issues, i.e. a bug when resizing the aladin lite view and which launched several parallel requestAnimationFrame by @bmatthieu3
|
||||
* Polygon and circular selection (see Aladin class API documentation for how to use it)
|
||||
@@ -325,4 +357,4 @@ New in the API:
|
||||
### Fin 2013
|
||||
|
||||
* ajout catalogue progressif
|
||||
* ajout on select, objectClicked, objectHovered
|
||||
* ajout on select, objectClicked, objectHovered
|
||||
|
||||
44
README.md
44
README.md
@@ -11,6 +11,7 @@ Aladin Lite is built to be easily embeddable in any web page. It powers astronom
|
||||
More details on [Aladin Lite documentation page](http://aladin.u-strasbg.fr/AladinLite/doc/).
|
||||
|
||||
[](https://github.com/cds-astro/aladin-lite/actions/workflows/test.yml)
|
||||
[](https://cds-astro.github.io/aladin-lite)
|
||||
|
||||
# How to test it ?
|
||||
|
||||
@@ -24,6 +25,7 @@ Always prefer using the latest version. If you want the new features without min
|
||||
## API documentation
|
||||
|
||||
There is a new in progress API documentation at [this link](https://cds-astro.github.io/aladin-lite).
|
||||
Editable examples showing the API can also be found [here](https://aladin.cds.unistra.fr/AladinLite/doc/API/examples/).
|
||||
|
||||
## Embed it into your projects
|
||||
|
||||
@@ -142,33 +144,53 @@ to compile the core project into WebAssembly.
|
||||
Follow the steps from the Rust official website [here](https://www.rust-lang.org/learn/get-started)
|
||||
You will also need [wasm-pack](https://rustwasm.github.io/wasm-pack/), a tool helping compiling rust into a proper .wasm file.
|
||||
|
||||
Once it's installed you can only build the project:
|
||||
Once it's installed you will need to switch to the nightly rust version:
|
||||
|
||||
```bash
|
||||
rustup default nightly
|
||||
```
|
||||
|
||||
Then you can build the project:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
Or build it and launch a localhost server (usually starting on port 8080 but it can be another one if 8080 is occupied):
|
||||
:warning: **If you are experimenting rust error compilations**:
|
||||
|
||||
- Make sure you have your **wasm-pack** version updated. To do so:
|
||||
|
||||
```bash
|
||||
cargo install wasm-pack --version ~0.12
|
||||
```
|
||||
|
||||
- Make sure you are using the rust **nightly** toolchain
|
||||
- Remove your `src/core/Cargo.lock` file and `src/core/target` directory -- this ensures that you'd escape any bad compilation state:
|
||||
|
||||
```bash
|
||||
git clean -di
|
||||
```
|
||||
|
||||
- then recompile with `npm run build`.
|
||||
|
||||
It will generate the aladin lite compiled code into a `dist/` directory located at the root of the repository. This directory contains two javascript files. `aladin.umd.cjs` follows the UMD module export convention and it is the one you can use for your project.
|
||||
|
||||
To run the examples, you can start a localhost server with the following command:
|
||||
|
||||
```bash
|
||||
npm run serve
|
||||
```
|
||||
|
||||
For just compiling the rust core from the root location (it is faster to do so)
|
||||
For just compiling the rust core, from the root location do:
|
||||
|
||||
```bash
|
||||
cd src/core
|
||||
cargo check --features webgl2
|
||||
```
|
||||
|
||||
and run the tests
|
||||
and run the tests:
|
||||
|
||||
```bash
|
||||
cd src/core
|
||||
cargo test --features webgl2
|
||||
```
|
||||
|
||||
To generate the Rust backend API documentation
|
||||
|
||||
```bash
|
||||
cd src/core
|
||||
cargo doc --no-deps --open
|
||||
```
|
||||
|
||||
5
assets/icons/add.svg
Normal file
5
assets/icons/add.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11 8C11 7.44772 11.4477 7 12 7C12.5523 7 13 7.44771 13 8V11H16C16.5523 11 17 11.4477 17 12C17 12.5523 16.5523 13 16 13H13V16C13 16.5523 12.5523 17 12 17C11.4477 17 11 16.5523 11 16V13H8C7.44772 13 7 12.5523 7 12C7 11.4477 7.44771 11 8 11H11V8Z" fill="#0F0F0F"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23 4C23 2.34315 21.6569 1 20 1H4C2.34315 1 1 2.34315 1 4V20C1 21.6569 2.34315 23 4 23H20C21.6569 23 23 21.6569 23 20V4ZM21 4C21 3.44772 20.5523 3 20 3H4C3.44772 3 3 3.44772 3 4V20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20V4Z" fill="#0F0F0F"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 811 B |
4
assets/icons/filter-off.svg
Normal file
4
assets/icons/filter-off.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15 15L21 21M21 15L15 21M10 21V14.6627C10 14.4182 10 14.2959 9.97237 14.1808C9.94787 14.0787 9.90747 13.9812 9.85264 13.8917C9.7908 13.7908 9.70432 13.7043 9.53137 13.5314L3.46863 7.46863C3.29568 7.29568 3.2092 7.2092 3.14736 7.10828C3.09253 7.01881 3.05213 6.92127 3.02763 6.81923C3 6.70414 3 6.58185 3 6.33726V4.6C3 4.03995 3 3.75992 3.10899 3.54601C3.20487 3.35785 3.35785 3.20487 3.54601 3.10899C3.75992 3 4.03995 3 4.6 3H19.4C19.9601 3 20.2401 3 20.454 3.10899C20.6422 3.20487 20.7951 3.35785 20.891 3.54601C21 3.75992 21 4.03995 21 4.6V6.33726C21 6.58185 21 6.70414 20.9724 6.81923C20.9479 6.92127 20.9075 7.01881 20.8526 7.10828C20.7908 7.2092 20.7043 7.29568 20.5314 7.46863L17 11" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1012 B |
4
assets/icons/filter-on.svg
Normal file
4
assets/icons/filter-on.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 4.6C3 4.03995 3 3.75992 3.10899 3.54601C3.20487 3.35785 3.35785 3.20487 3.54601 3.10899C3.75992 3 4.03995 3 4.6 3H19.4C19.9601 3 20.2401 3 20.454 3.10899C20.6422 3.20487 20.7951 3.35785 20.891 3.54601C21 3.75992 21 4.03995 21 4.6V6.33726C21 6.58185 21 6.70414 20.9724 6.81923C20.9479 6.92127 20.9075 7.01881 20.8526 7.10828C20.7908 7.2092 20.7043 7.29568 20.5314 7.46863L14.4686 13.5314C14.2957 13.7043 14.2092 13.7908 14.1474 13.8917C14.0925 13.9812 14.0521 14.0787 14.0276 14.1808C14 14.2959 14 14.4182 14 14.6627V17L10 21V14.6627C10 14.4182 10 14.2959 9.97237 14.1808C9.94787 14.0787 9.90747 13.9812 9.85264 13.8917C9.7908 13.7908 9.70432 13.7043 9.53137 13.5314L3.46863 7.46863C3.29568 7.29568 3.2092 7.2092 3.14736 7.10828C3.09253 7.01881 3.05213 6.92127 3.02763 6.81923C3 6.70414 3 6.58185 3 6.33726V4.6Z" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
2
assets/icons/jupyter.svg
Normal file
2
assets/icons/jupyter.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title>file_type_jupyter</title><path d="M26.233,3.588A1.69,1.69,0,1,1,24.473,2a1.67,1.67,0,0,1,1.76,1.585Z" style="fill:#767677"/><path d="M16.375,23.111c-4.487,0-8.43-1.61-10.469-3.988a11.162,11.162,0,0,0,20.938,0C24.81,21.5,20.882,23.111,16.375,23.111Z" style="fill:#f37726"/><path d="M16.375,7.648c4.487,0,8.43,1.61,10.469,3.988a11.162,11.162,0,0,0-20.938,0C7.945,9.253,11.869,7.648,16.375,7.648Z" style="fill:#f37726"/><path d="M10.2,27.739a2.109,2.109,0,1,1-.2-.8,2.129,2.129,0,0,1,.2.8Z" style="fill:#9e9e9e"/><path d="M6.416,7.106A1.226,1.226,0,1,1,7.608,5.83,1.241,1.241,0,0,1,6.416,7.106Z" style="fill:#616262"/></svg>
|
||||
|
After Width: | Height: | Size: 836 B |
5
assets/icons/link.svg
Normal file
5
assets/icons/link.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.197 3.35462C16.8703 1.67483 19.4476 1.53865 20.9536 3.05046C22.4596 4.56228 22.3239 7.14956 20.6506 8.82935L18.2268 11.2626M10.0464 14C8.54044 12.4882 8.67609 9.90087 10.3494 8.22108L12.5 6.06212" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M13.9536 10C15.4596 11.5118 15.3239 14.0991 13.6506 15.7789L11.2268 18.2121L8.80299 20.6454C7.12969 22.3252 4.55237 22.4613 3.0464 20.9495C1.54043 19.4377 1.67609 16.8504 3.34939 15.1706L5.77323 12.7373" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 776 B |
83
codemeta.json
Normal file
83
codemeta.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
|
||||
"@type": "SoftwareSourceCode",
|
||||
"license": "https://spdx.org/licenses/GPL-3.0",
|
||||
"codeRepository": "https://github.com/cds-astro/aladin-lite",
|
||||
"dateCreated": "2013-05-01",
|
||||
"datePublished": "2013-05-01",
|
||||
"dateModified": "2023-01-31",
|
||||
"issueTracker": "https://github.com/cds-astro/aladin-lite/issues",
|
||||
"name": "Aladin Lite",
|
||||
"version": "3.4.1-beta",
|
||||
"softwareVersion": "3.4.1-beta",
|
||||
"description": "An astronomical HiPS visualizer in the browser.",
|
||||
"identifier": "10.5281/zenodo.7638833",
|
||||
"applicationCategory": "Astronomy, Visualization",
|
||||
"funding": "ESCAPE 824064",
|
||||
"referencePublication": "http://aspbooks.org/publications/532/007.pdf",
|
||||
"readme": "https://aladin.cds.unistra.fr/AladinLite/doc/",
|
||||
"releaseNotes": "https://aladin.cds.unistra.fr/AladinLite/doc/#release-notes",
|
||||
"funder": {
|
||||
"@type": "Organization",
|
||||
"name": "European Commission Framework Programme Horizon 2020 Research and Innovation action"
|
||||
},
|
||||
"keywords": [
|
||||
"IVOA",
|
||||
"Astronomy"
|
||||
],
|
||||
"programmingLanguage": [
|
||||
"Rust",
|
||||
"Javascript"
|
||||
],
|
||||
"relatedLink": [
|
||||
"https://aladin.cds.unistra.fr/"
|
||||
],
|
||||
"author": [
|
||||
{
|
||||
"@type": "Person",
|
||||
"@id": "https://orcid.org/0000-0002-7123-773X",
|
||||
"givenName": "Matthieu",
|
||||
"familyName": "Baumann",
|
||||
"email": "matthieu.baumann@unistra.fr",
|
||||
"affiliation": {
|
||||
"@type": "Organization",
|
||||
"name": "Universit\u00e9 de Strasbourg, CNRS, Observatoire astronomique de Strasbourg, UMR 7550, F-67000 Strasbourg, France"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Person",
|
||||
"@id": "https://orcid.org/0000-0001-5818-2781",
|
||||
"givenName": "Thomas",
|
||||
"familyName": "Boch",
|
||||
"email": "thomas.boch@astro.unistra.fr",
|
||||
"affiliation": {
|
||||
"@type": "Organization",
|
||||
"name": "Universit\u00e9 de Strasbourg, CNRS, Observatoire astronomique de Strasbourg, UMR 7550, F-67000 Strasbourg, France"
|
||||
}
|
||||
}
|
||||
],
|
||||
"maintainer": [
|
||||
{
|
||||
"@type": "Person",
|
||||
"@id": "https://orcid.org/0000-0002-7123-773X",
|
||||
"givenName": "Matthieu",
|
||||
"familyName": "Baumann",
|
||||
"email": "matthieu.baumann@unistra.fr",
|
||||
"affiliation": {
|
||||
"@type": "Organization",
|
||||
"name": "Universit\u00e9 de Strasbourg, CNRS, Observatoire astronomique de Strasbourg, UMR 7550, F-67000 Strasbourg, France"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Person",
|
||||
"@id": "https://orcid.org/0000-0001-5818-2781",
|
||||
"givenName": "Thomas",
|
||||
"familyName": "Boch",
|
||||
"email": "thomas.boch@astro.unistra.fr",
|
||||
"affiliation": {
|
||||
"@type": "Organization",
|
||||
"name": "Universit\u00e9 de Strasbourg, CNRS, Observatoire astronomique de Strasbourg, UMR 7550, F-67000 Strasbourg, France"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: ["P/PanSTARRS/DR1/color-i-r-g"], showReticle: false, gridOptions: {opacity: 0.5, color: 'rgba(255, 0, 0)'}, projection: "AIT", cooFrame: 'icrs', target: "stephan's quintet", fov: 1000, showGotoControl: false, showFrame: false, fullScreen: true, showLayersControl: true, showCooGrid: true, showCooGridControl: false});
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: ["P/PanSTARRS/DR1/color-i-r-g"], showReticle: false, projection: "AIT", cooFrame: 'icrs', target: "stephan's quintet", fov: 1000, showGotoControl: false, showFrame: false, fullScreen: true, showLayersControl: true, showCooGrid: true, showCooGridControl: false});
|
||||
|
||||
const chft = aladin.createImageSurvey('CFHT', "CFHT deep view of NGC7331 and Stephan's quintet u+g+r", "https://cds.unistra.fr/~derriere/PR_HiPS/2022_Duc/", null, null, {imgFormat: 'png'});
|
||||
const nircamJWST = aladin.createImageSurvey('Nircam', "Stephans Quintet NIRCam+MIRI", "http://alasky.cds.unistra.fr/JWST/CDS_P_JWST_Stephans-Quintet_NIRCam+MIRI/", null, null, {imgFormat: 'png', colormap: "viridis"});
|
||||
|
||||
@@ -15,19 +15,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
var aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {cooFrame: 'galactic', fov: 400, fullScreen: true, showCooGrid: false, showReticle: false})
|
||||
aladin = A.aladin('#aladin-lite-div', {projection: 'MOL', cooFrame: 'galactic', fov: 360, fullScreen: true, showCooGrid: false, showReticle: false})
|
||||
aladin.gotoRaDec(79.9525321, -69.2742586)
|
||||
const gaiaFlux = aladin.createImageSurvey('P/DM/flux-G/I/355/gaiadr3', "GaiaDR3GFlux", null, null, null, {imgFormat: 'fits', stretch: 'log'})
|
||||
aladin.setBaseImageLayer(gaiaFlux)
|
||||
gaiaFlux.setCuts(3e5, 1e8)
|
||||
|
||||
aladin.setProjection('MOL')
|
||||
|
||||
|
||||
|
||||
function notify(title, sub, delay) {
|
||||
@@ -54,8 +51,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
aladin.view.setGridConfig({opacity: 0, color: {r: 51/255, g: 209/255, b: 1}})
|
||||
aladin.view.setGridConfig({enabled: true})
|
||||
aladin.setCooGrid({enabled: true, opacity: 0, color: {r: 51, g: 209, b: 255}})
|
||||
|
||||
async function s_1() {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -100,7 +96,7 @@
|
||||
|
||||
async function showGrid() {
|
||||
for await(const it of interval(50, 40)) {
|
||||
aladin.view.setGridConfig({opacity: it / 40})
|
||||
aladin.setCooGrid({opacity: it / 40})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +153,7 @@
|
||||
|
||||
async function hideGrid() {
|
||||
for await(const it of interval(50, 40)) {
|
||||
aladin.view.setGridConfig({opacity: 1 - it / 40})
|
||||
aladin.setCooGrid({opacity: 1 - it / 40})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 100%;"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
@@ -19,7 +19,6 @@
|
||||
target: '19 24 51.556 +45 16 44.36', // initial target
|
||||
cooFrame: 'equatorial', // set galactic frame
|
||||
showCooGrid: true, // set the grid
|
||||
fullScreen: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
A.init.then(() => {
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 70,projection: "AIT"});
|
||||
|
||||
//let hsc = aladin.newImageSurvey("P/HSC/DR2/deep/g", {colormap:"Purples", imgFormat: "fits"});
|
||||
//aladin.setBaseImageLayer(hsc);
|
||||
let hsc = aladin.newImageSurvey("P/HSC/DR2/deep/g", {colormap:"Purples", imgFormat: "fits"});
|
||||
aladin.setBaseImageLayer(hsc);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
45
examples/al-cat-galaxy-shape.html
Normal file
45
examples/al-cat-galaxy-shape.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
<script>let aladin;</script>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
// Start up Aladin Lite
|
||||
aladin = A.aladin('#aladin-lite-div', {
|
||||
target: "M31",
|
||||
fov: 89.78,
|
||||
showContextMenu: true,
|
||||
fullScreen: true,
|
||||
showSimbadPointerControl: true,
|
||||
showShareControl: true,
|
||||
showSettingsControl: true,
|
||||
showStackLayerControl: true,
|
||||
samp: true,
|
||||
});
|
||||
|
||||
aladin.addCatalog(A.catalogFromVizieR("VII/237/pgc", "M31", 3, {
|
||||
limit: 1000,
|
||||
//orderBy: 'nb_ref',
|
||||
onClick: 'showTable',
|
||||
color: 'yellow',
|
||||
hoverColor: 'blue',
|
||||
shape: (s) => {
|
||||
let coo = A.coo();
|
||||
coo.parse(s.data['RAJ2000'] + ' ' + s.data['DEJ2000'])
|
||||
|
||||
let a = (0.1 * Math.pow(10, +s.data.logD25)) / 60;
|
||||
let b = (1.0 / Math.pow(10, +s.data.logR25)) * a
|
||||
|
||||
return A.ellipse(coo.lon, coo.lat, a, b, +s.data.PA, {lineWidth: 3});
|
||||
}
|
||||
}));
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
109
examples/al-cat-proper-motion.html
Normal file
109
examples/al-cat-proper-motion.html
Normal file
@@ -0,0 +1,109 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
<script>let aladin;</script>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
// Start up Aladin Lite
|
||||
aladin = A.aladin('#aladin-lite-div', {
|
||||
target: "LMC",
|
||||
fov: 10,
|
||||
showContextMenu: true,
|
||||
fullScreen: true,
|
||||
showSimbadPointerControl: true,
|
||||
showShareControl: true,
|
||||
showSettingsControl: true,
|
||||
showStackLayerControl: true,
|
||||
samp: true,
|
||||
});
|
||||
|
||||
let pmraMean = null, pmdecMean = null;
|
||||
|
||||
const pmCat = A.catalogFromURL('./data/proper_motion.xml', {
|
||||
onClick: 'showTable',
|
||||
name: 'mean pm over HPX cells around LMC from GaiaDR2',
|
||||
hoverColor: 'yellow',
|
||||
selectionColor: 'white',
|
||||
// Footprint associated to sources
|
||||
shape: (s) => {
|
||||
// discard drawing a vector for big pm
|
||||
let totalPmSquared = s.data.pmra*s.data.pmra + s.data.pmdec*s.data.pmdec;
|
||||
if (totalPmSquared > 6) {
|
||||
return;
|
||||
}
|
||||
|
||||
let color = rainbowColorMap((totalPmSquared - 2.5) / 2)
|
||||
|
||||
// Compute the mean of pm over the catalog sources
|
||||
if (!pmraMean || !pmdecMean) {
|
||||
pmraMean = 0, pmdecMean = 0;
|
||||
for (var s of pmCat.getSources()) {
|
||||
pmraMean += +s.data.pmra;
|
||||
pmdecMean += +s.data.pmdec;
|
||||
}
|
||||
|
||||
const numSources = pmCat.getSources().length;
|
||||
|
||||
pmraMean /= numSources
|
||||
pmdecMean /= numSources
|
||||
}
|
||||
|
||||
let dra = +s.data.pmra - pmraMean;
|
||||
let ddec = +s.data.pmdec - pmdecMean;
|
||||
|
||||
return A.vector(
|
||||
s.ra,
|
||||
s.dec,
|
||||
s.ra + dra,
|
||||
s.dec + ddec,
|
||||
{lineWidth: 3, color}
|
||||
)
|
||||
}
|
||||
});
|
||||
aladin.addCatalog(pmCat);
|
||||
});
|
||||
|
||||
function rainbowColorMap(value) {
|
||||
// Ensure value is within range [0, 1]
|
||||
value = Math.max(0, Math.min(1, value));
|
||||
|
||||
// Convert value to hue
|
||||
var hue = (1 - value) * 240; // 240 is the maximum hue value for blue
|
||||
|
||||
// Convert HSV to RGB
|
||||
var chroma = 1;
|
||||
var x = chroma * (1 - Math.abs((hue / 60) % 2 - 1));
|
||||
var r1, g1, b1;
|
||||
|
||||
if (hue >= 0 && hue < 60) {
|
||||
[r1, g1, b1] = [chroma, x, 0];
|
||||
} else if (hue >= 60 && hue < 120) {
|
||||
[r1, g1, b1] = [x, chroma, 0];
|
||||
} else if (hue >= 120 && hue < 180) {
|
||||
[r1, g1, b1] = [0, chroma, x];
|
||||
} else if (hue >= 180 && hue < 240) {
|
||||
[r1, g1, b1] = [0, x, chroma];
|
||||
}
|
||||
|
||||
var m = 1 - chroma;
|
||||
var r = r1 + m;
|
||||
var g = g1 + m;
|
||||
var b = b1 + m;
|
||||
|
||||
// Convert RGB to HEX
|
||||
r = Math.round(r * 255);
|
||||
g = Math.round(g * 255);
|
||||
b = Math.round(b * 255);
|
||||
var colorHex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
||||
|
||||
return colorHex;
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,42 +1,64 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<head> </head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
<script type="module">
|
||||
import A from "../src/js/A.js";
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin("#aladin-lite-div", {
|
||||
target: "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,
|
||||
showSimbadPointerControl: true,
|
||||
samp: true,
|
||||
});
|
||||
// define custom draw function
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'LMC', fov: 55, showContextMenu: true});
|
||||
// define custom draw function
|
||||
var drawFunction = function(source, canvasCtx, viewParams) {
|
||||
canvasCtx.beginPath();
|
||||
canvasCtx.arc(source.x, source.y, source.data['coo_err_min'] * 5, 0, 2 * Math.PI, false);
|
||||
canvasCtx.closePath();
|
||||
canvasCtx.strokeStyle = '#c38';
|
||||
canvasCtx.lineWidth = 3;
|
||||
canvasCtx.globalAlpha = 0.7,
|
||||
canvasCtx.stroke();
|
||||
var fov = Math.max(viewParams['fov'][0], viewParams['fov'][1]);
|
||||
/*var hips = A.catalogHiPS(
|
||||
"https://axel.u-strasbg.fr/HiPSCatService/Simbad",
|
||||
{
|
||||
onClick: "showTable",
|
||||
name: "Simbad",
|
||||
color: "cyan",
|
||||
hoverColor: "red",
|
||||
shape: (s) => {
|
||||
let galaxy = ["Seyfert","Seyfert_1", "Seyfert_2","LSB_G","PartofG","RadioG","Gin","GinPair","HII_G","LensedG","BClG","BlueCompG","EmG","GinCl","GinGroup","StarburstG","LINER","AGN","Galaxy"].some((n) => s.data.main_type.indexOf(n) >= 0);
|
||||
if (!galaxy) return;
|
||||
|
||||
// object name is displayed only if fov<10°
|
||||
if (fov>10) {
|
||||
return;
|
||||
}
|
||||
let a = +s.data.size_maj;
|
||||
let b = +s.data.size_min;
|
||||
|
||||
canvasCtx.globalAlpha = 0.9;
|
||||
canvasCtx.globalAlpha = 1;
|
||||
};
|
||||
let theta = +s.data.size_angle || 0.0;
|
||||
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;
|
||||
|
||||
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {onClick: 'showTable', name: 'Simbad', shape: drawFunction});
|
||||
aladin.addCatalog(hips);
|
||||
});
|
||||
</script>
|
||||
let theta = +s.data['PA'];
|
||||
|
||||
</body>
|
||||
return A.ellipse(s.ra, s.dec, a, b, theta, { color: "cyan" });
|
||||
},
|
||||
}
|
||||
)
|
||||
aladin.addCatalog(hips);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'LMC', fov: 55, showContextMenu: true});
|
||||
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {onClick: 'showPopup', name: 'Simbad'});
|
||||
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {hoverColor: 'yellow', onClick: 'showPopup', name: 'Simbad'});
|
||||
aladin.addCatalog(hips);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
|
||||
A.init.then(() => {
|
||||
var hipsDir="http://alasky.u-strasbg.fr/CDS_P_Coronelli";
|
||||
aladin = A.aladin("#aladin-lite-div", {showSimbadPointerControl: true, realFullscreen: true, fov: 100, allowFullZoomout: true, showReticle: false });
|
||||
aladin = A.aladin("#aladin-lite-div", {showSimbadPointerControl: true, expandLayersControl: true, realFullscreen: true, fov: 100, allowFullZoomout: true, showReticle: false });
|
||||
aladin.createImageSurvey('illenoroC', 'illenoroC', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: false});
|
||||
aladin.createImageSurvey('Coronelli', 'Coronelli', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: true});
|
||||
aladin.setImageSurvey('Coronelli');
|
||||
@@ -252,13 +252,13 @@
|
||||
aladin.addCatalog(hipsCats['constellations-boundaries']);
|
||||
aladin.addCatalog(hipsCats['gaia']);
|
||||
|
||||
|
||||
var coronelliStars = {
|
||||
'coronelli-stars-white': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/white.xml", {name: 'Coronelli white', color: '#ffffff', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-yellow': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/yellow.xml", {name: 'Coronelli yellow', color: '#f6f874', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-red': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/red.xml", {name: 'Coronelli red', color: '#ff5555', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-blue': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/blue.xml", {name: 'Coronelli blue', color: '#1ca5ec', shape: 'rhomb', sourceSize: 10})
|
||||
'coronelli-stars-white': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/white.xml", {name: 'Coronelli white', color: '#ffffff', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-yellow': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/yellow.xml", {name: 'Coronelli yellow', color: '#f6f874', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-red': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/red.xml", {name: 'Coronelli red', color: '#ff5555', shape: 'rhomb', sourceSize: 10}),
|
||||
'coronelli-stars-blue': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/blue.xml", {name: 'Coronelli blue', color: '#1ca5ec', shape: 'rhomb', sourceSize: 20})
|
||||
};
|
||||
|
||||
coronelliStars['coronelli-stars-white'].hide();
|
||||
coronelliStars['coronelli-stars-yellow'].hide();
|
||||
coronelliStars['coronelli-stars-red'].hide();
|
||||
|
||||
@@ -27,9 +27,7 @@
|
||||
|
||||
let btn = A.button({
|
||||
content: 'My button',
|
||||
position: {
|
||||
anchor: 'left bottom'
|
||||
},
|
||||
classList: ['myButton'],
|
||||
tooltip: {cssStyle: {color: 'red'}, content: 'Create a moc in pink!', position: {direction: 'top'}},
|
||||
action(o) {
|
||||
aladin.select('poly', p => {
|
||||
@@ -65,16 +63,14 @@
|
||||
title: "My window",
|
||||
draggable: true,
|
||||
},
|
||||
classList: ['myBox'],
|
||||
content: "This is the content of my window<br/> I can write proper html",
|
||||
position: {
|
||||
anchor: 'center center'
|
||||
}
|
||||
}))
|
||||
|
||||
aladin.appendStatusBarMessage({
|
||||
aladin.addStatusBarMessage({
|
||||
duration: 10000,
|
||||
type: 'info',
|
||||
message: 'Aladin Lite v3.3 is out. New features available:<ul><li>New Button, Box objects</li><li>Polygonal, circular selection</li></ul>'
|
||||
message: 'Aladin Lite v3.3 is out. New features available:<ul><li>New Button, Box <b>objects</b></li><li>Polygonal, circular selection</li></ul>'
|
||||
})
|
||||
});
|
||||
</script>
|
||||
@@ -84,6 +80,25 @@
|
||||
top: 10rem;
|
||||
left: 10rem;
|
||||
}
|
||||
|
||||
.myBox {
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.myButton {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
background-color: pink;
|
||||
}
|
||||
|
||||
.aladin-cooFrame {
|
||||
position: absolute;
|
||||
top: 10rem;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
aladin.setBaseImageLayer("P/PanSTARRS/DR1/g", {imgFormat: "fits"});
|
||||
aladin.getBaseImageLayer().setColormap('redtemperature', {stretch: "Asinh"});*/
|
||||
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: 'CDS/P/SDSS9/color', fov: 60, target: '0 90', fullScreen: true, cooFrame: 'equatorial', showCooGridControl: true, showSimbadPointerControl: true, showCooGrid: true});
|
||||
aladin.setProjection('SIN');
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: 'CDS/P/SDSS9/color', fov: 150, target: '0 90', fullScreen: true, cooFrame: 'equatorial', showCooGridControl: true, showSimbadPointerControl: true, showCooGrid: true});
|
||||
|
||||
//let survey = aladin.createImageSurvey("P/PanSTARRS/DR1/g", null, null, null, null, );
|
||||
/*aladin.setBaseImageLayer("P/PanSTARRS/DR1/g");
|
||||
|
||||
@@ -16,21 +16,13 @@
|
||||
showContextMenu: true,
|
||||
fullScreen: true,
|
||||
showSimbadPointerControl: true,
|
||||
showSimbadPointerControl: false,
|
||||
showShareControl: true,
|
||||
showStatusBar: {
|
||||
position: {
|
||||
bottom: 0,
|
||||
left: '3rem'
|
||||
},
|
||||
},
|
||||
showSettingsControl: true,
|
||||
showStackLayerControl: true,
|
||||
samp: true,
|
||||
});
|
||||
|
||||
A.catalogFromSimbad('09 55 52.4 +69 40 47', 0.1, {onClick: 'showTable', limit: 1000}, (cat) => {
|
||||
aladin.addCatalog(cat)
|
||||
});
|
||||
aladin.addCatalog(A.catalogFromSimbad('M 82', 0.1, {onClick: 'showTable'}));
|
||||
aladin.addCatalog(A.catalogFromNED('09 55 52.4 +69 40 47', 0.1, {onClick: 'showPopup', shape: 'plus'}));
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -21,7 +21,7 @@ var pessto = 'https://archive.eso.org/tap_cat/sync?REQUEST=doQuery&LANG=ADQL&MAX
|
||||
|
||||
A.init.then(() => {
|
||||
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: 'https://alasky.cds.unistra.fr/DSS/DSSColor/', target: 'LMC', fov: 5, showContextMenu: true});
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: 'https://alasky.cds.unistra.fr/DSS/DSSColor/', target: 'LMC', fov: 5, showContextMenu: true, showSettingsControl:true, samp:true});
|
||||
|
||||
aladin.addCatalog(A.catalogFromURL('https://vizier.u-strasbg.fr/viz-bin/votable?-source=HIP2&-c=LMC&-out.add=_RAJ,_DEJ&-oc.form=dm&-out.meta=DhuL&-out.max=9999&-c.rm=180', {sourceSize:12, color: '#f08080'}));
|
||||
|
||||
@@ -29,13 +29,14 @@ A.init.then(() => {
|
||||
|
||||
aladin.addCatalog(A.catalogFromURL(vmc_cepheids, {onClick: 'showTable', sourceSize:14, color: '#fff080'}));
|
||||
|
||||
|
||||
|
||||
aladin.addCatalog(A.catalogFromURL(pessto, {onClick: 'showPopup', sourceSize:14, color: '#00f080'}));
|
||||
aladin.on('select', (objs) => {
|
||||
console.log(objs, "are selected");
|
||||
})
|
||||
|
||||
aladin.select();
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
var aladin = A.aladin('#aladin-lite-div', {target: '05 37 58 +08 17 35', fov: 12, backgroundColor: 'rgb(120, 0, 0)'});
|
||||
var cat = A.catalog({sourceSize: 20});
|
||||
var cat = A.catalog({sourceSize: 20, onClick: 'showTable'});
|
||||
aladin.addCatalog(cat);
|
||||
cat.addSources([A.source(83.784490, 9.934156, {name: 'Meissa'}), A.source(88.792939, 7.407064, {name: 'Betelgeuse'}), A.source(81.282764, 6.349703, {name: 'Bellatrix'})]);
|
||||
var msg;
|
||||
@@ -51,6 +51,8 @@
|
||||
}
|
||||
$('#infoDiv').html(msg);
|
||||
});
|
||||
|
||||
cat.sources[0].actionClicked();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
A.init.then(() => {
|
||||
// Start up Aladin Lite
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'M 1', fov: 0.2, showContextMenu: true, fullScreen: true});
|
||||
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 3});
|
||||
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 3, lineDash: [2, 2]});
|
||||
aladin.addOverlay(overlay);
|
||||
overlay.addFootprints([
|
||||
A.polygon([[83.64287, 22.01713], [83.59872, 22.01692], [83.59852, 21.97629], [83.64295, 21.97629]]),
|
||||
A.polygon([[83.64287, 22.01713], [83.59872, 22.01692], [83.59852, 21.97629], [83.64295, 21.97629]], {hoverColor: 'green'}),
|
||||
A.polygon([[83.62807, 22.06330], [83.58397, 22.02280], [83.62792, 22.02258]]),
|
||||
A.polygon([[8.62807, 220.06330], [83.58397, 10.02280], [150.62792, 87.02258]])
|
||||
]);
|
||||
@@ -34,7 +34,7 @@
|
||||
console.log("Object hovered stopped: ", object, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
|
||||
})
|
||||
|
||||
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 100, {onClick: 'showTable', limit: 1000});
|
||||
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 10, {onClick: 'showTable', hoverColor: 'purple', limit: 10000});
|
||||
aladin.addCatalog(cat);
|
||||
});
|
||||
</script>
|
||||
|
||||
42
examples/al-fov-range.html
Normal file
42
examples/al-fov-range.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
var aladin = A.aladin(
|
||||
'#aladin-lite-div',
|
||||
{
|
||||
survey: 'P/allWISE/color', // set initial image survey
|
||||
projection: 'AIT', // set a projection
|
||||
fov: 1.5, // initial field of view in degrees
|
||||
target: 'NGC 2175', // initial target
|
||||
cooFrame: 'galactic', // set galactic frame
|
||||
reticleColor: '#00ff00', // change reticle color
|
||||
reticleSize: 40, // change reticle size
|
||||
gridOptions: {color: 'pink'},
|
||||
showCooGrid: true, // set the grid
|
||||
fullScreen: true,
|
||||
showShareControl: true,
|
||||
showSettingsControl: true,
|
||||
showLayersControl: true,
|
||||
showZoomControl: true,
|
||||
showContextMenu: true,
|
||||
showCooGridControl: true,
|
||||
showSimbadPointerControl: true,
|
||||
showFullscreenControl: true,
|
||||
}
|
||||
);
|
||||
|
||||
aladin.setFoVRange(1, 60)
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
26
examples/al-fullscreen.html
Normal file
26
examples/al-fullscreen.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div id="offset" style="display: inline-block; width: 200px; height: 100px"></div>
|
||||
<div id="aladin-lite-div" style="display: inline-block; width: 50%"></div>
|
||||
</div>
|
||||
<!--<script type="text/javascript" src="https://aladin.cds.unistra.fr/AladinLite/api/v3/latest/aladin.js" charset="utf-8"></script>-->
|
||||
|
||||
|
||||
<script>let aladin, hips</script>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {projection: 'TAN', cooFrame: 'galactic', showSettingsControl: true, showSimbadPointerControl: true, showContextMenu: true, target: 'galactic center', survey: 'P/Finkbeiner'});
|
||||
// possible values are 'blues', 'cividis', 'cubehelix', 'eosb', 'grayscale', 'inferno', 'magma', 'native', 'parula', 'plasma', 'rainbow',
|
||||
// 'rdbu', 'rdylbu', 'redtemperature', 'sinebow', 'spectral', 'summer', 'viridis', 'ylgnbu' and 'ylorbr'
|
||||
|
||||
//aladin.getBaseImageLayer().setColor([1.0, 0.0, 1.0, 1.0], { tf: 'Linear'} );
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -13,9 +13,9 @@
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: 'http://alasky.cds.unistra.fr/ancillary/GaiaDR2/hips-density-map/', showProjectionControl: true, showContextMenu: true, showStatusBar: true, fullScreen: true, target: 'galactic center'});
|
||||
|
||||
const fluxMap = aladin.createImageSurvey('gdr3-color-flux-map', 'Gaia DR3 flux map', 'https://alasky.u-strasbg.fr/ancillary/GaiaEDR3/color-Rp-G-Bp-flux-map', 'equatorial', 7);
|
||||
const densityMap = aladin.createImageSurvey('gdr3-density-map', 'Gaia DR3 density map', 'sdfsg', 'equatorial', 7, {imgFormat: 'fits'});
|
||||
const decaps = aladin.createImageSurvey("decaps", "DECaPS DR1", "http://alasky.u-strasbg.fr/DECaPS/DR1/color/", "equatorial", 11, {imgFormat: 'png'});
|
||||
const panstarrs = aladin.createImageSurvey("panstarrs", "PanSTARRS", "http://alasky.u-strasbg.fr/Pan-STARRS/DR1/color-i-r-g/", "equatorial", 11, {imgFormat: 'jpg'});
|
||||
const densityMap = aladin.createImageSurvey('gdr3-density-map', 'Gaia DR3 density map', 'sdfsg', 'equatorial', 7, {formats: ['fits']});
|
||||
const decaps = aladin.createImageSurvey("decaps", "DECaPS DR1", "http://alasky.u-strasbg.fr/DECaPS/DR1/color/", "equatorial", 11, {formats: ['png'], tileSize: 512});
|
||||
const panstarrs = aladin.createImageSurvey("panstarrs", "PanSTARRS", "http://alasky.u-strasbg.fr/Pan-STARRS/DR1/color-i-r-g/", "equatorial", 11, {formats: ['jpg']});
|
||||
|
||||
aladin.setOverlayImageLayer(fluxMap)
|
||||
aladin.setOverlayImageLayer(densityMap, "density")
|
||||
|
||||
35
examples/al-image-hips.html
Normal file
35
examples/al-image-hips.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, maximum-scale=1.0, initial-scale=1.0, user-scalable=no">
|
||||
</head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 500px; height: 500px"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
var aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {fullScreen: true, cooFrame: "ICRSd", showSimbadPointerControl: true, showShareControl: true, showShareControl: true, survey: 'https://alasky.cds.unistra.fr/DSS/DSSColor/', fov: 180, showContextMenu: true});
|
||||
// manage URL parameters
|
||||
let survey1 = aladin.getBaseImageLayer();
|
||||
survey1.setColormap('magma', {stretch: 'linear'});
|
||||
|
||||
let survey2 = aladin.newImageSurvey("CSIRO/P/RACS/mid/I");
|
||||
aladin.setImageLayer(survey2)
|
||||
survey2.setColormap('rdbu', {stretch: 'linear'});
|
||||
|
||||
let survey3 = aladin.newImageSurvey("CSIRO/P/RACS/low/I");
|
||||
aladin.setImageLayer(survey3)
|
||||
survey3.setColormap('cubehelix', {stretch: 'asinh'});
|
||||
aladin.setImageLayer(survey3)
|
||||
aladin.setImageLayer(survey3)
|
||||
|
||||
aladin.setImageLayer(survey2);
|
||||
|
||||
aladin.setImageLayer(survey3)
|
||||
aladin.setImageLayer(survey2);
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
@@ -10,8 +10,7 @@
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'galactic center'});
|
||||
aladin.setImageSurvey('P/allWISE/color');
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: 'P/allWISE/color', target: 'galactic center'});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<script> let aladin;
|
||||
</script>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
var aladin = A.aladin(
|
||||
aladin = A.aladin(
|
||||
'#aladin-lite-div',
|
||||
{
|
||||
survey: 'P/allWISE/color', // set initial image survey
|
||||
@@ -21,16 +21,18 @@
|
||||
reticleColor: '#00ff00', // change reticle color
|
||||
reticleSize: 40, // change reticle size
|
||||
gridOptions: {color: 'pink'},
|
||||
showCooGrid: true, // set the grid
|
||||
showCooGrid: false, // set the grid
|
||||
fullScreen: true,
|
||||
inertia: false,
|
||||
showStatusBar: true,
|
||||
showShareControl: true,
|
||||
showSettingsControl: true,
|
||||
showLayersControl: true,
|
||||
showZoomControl: true,
|
||||
showContextMenu: true,
|
||||
showCooGridControl: true,
|
||||
showSimbadPointerControl: true,
|
||||
//showSimbadPointerControl: true,
|
||||
showFullscreenControl: true,
|
||||
showZoomControl: false,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: '00 00 00 +07 00 00', fov: 130, survey: 'P/Mellinger/color'});
|
||||
var moc11 = A.MOCFromURL('http://skies.esac.esa.int/HST/NICMOS/Moc.fits', {color: '#84f', lineWidth: 3, fill: true}, (moc) => {
|
||||
var moc11 = A.MOCFromURL('http://skies.esac.esa.int/HST/NICMOS/Moc.fits', {color: '#84f', lineWidth: 3, perimeter: true}, (moc) => {
|
||||
// moc is ready
|
||||
console.log(moc.contains(205.9019247, +2.4492764));
|
||||
console.log(moc.contains(-205.9019247, +2.4492764));
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<script>var aladin;</script>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {fullScreen: true, survey: ['P/DM/vizMine', 'P/HST/GOODS/color', 'P/MATLAS/g'], target: '0 0', showProjectionControl: true, showCooGrid: true, fov: 180});
|
||||
aladin = A.aladin('#aladin-lite-div', {projection: 'MOL', fullScreen: true, fov: 360, survey: ['P/DM/vizMine', 'P/HST/GOODS/color', 'P/MATLAS/g'], target: '0 0', showProjectionControl: true, showSettingsControl: true, showCooGrid: true});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
27
examples/al-no-properties.html
Normal file
27
examples/al-no-properties.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 70,projection: "AIT"});
|
||||
|
||||
aladin.setOverlayImageLayer(A.imageHiPS(
|
||||
'Fermi',
|
||||
"https://alasky.cds.unistra.fr/Fermi/Color",
|
||||
{
|
||||
name: "Fermi color",
|
||||
maxOrder: 3,
|
||||
imgFormat: 'jpeg',
|
||||
tileSize: 512,
|
||||
cooFrame: 'equatorial'
|
||||
}
|
||||
));
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -16,7 +16,7 @@
|
||||
fov: 360,
|
||||
target: '0 0',
|
||||
fullScreen: true,
|
||||
survey: ["fsdfsd", "jfjfj", "jfj", "P/allWISE/color"],
|
||||
survey: ["azef", "jfjfj", "jfj", "P/allWISE/color"],
|
||||
showCooGrid: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'NGC 1367', fov: 360, samp: false, projection: 'AIT', fullScreen: true, showContextMenu: true});
|
||||
|
||||
A.catalogFromURL('https://raw.githubusercontent.com/VisIVOLab/SKA-Discovery-Service-Mockup/main/ObsCore/ObsCore_003.xml', {onClick: 'showTable'}, (catalog) => {
|
||||
A.catalogFromURL('https://raw.githubusercontent.com/VisIVOLab/SKA-Discovery-Service-Mockup/main/ObsCore/ObsCore_003.xml', {onClick: 'showTable', hoverColor: 'purple'}, (catalog) => {
|
||||
aladin.addCatalog(catalog)
|
||||
});
|
||||
|
||||
aladin.addCatalog(A.catalogFromVizieR("B/assocdata/obscore", "0 +0", 20, {limit: 1000}))
|
||||
aladin.addCatalog(A.catalogFromVizieR("B/assocdata/obscore", "0 +0", 20, {onClick: 'showTable', hoverColor: 'yellow', limit: 1000}))
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
88
examples/al-onthefly.html
Normal file
88
examples/al-onthefly.html
Normal file
@@ -0,0 +1,88 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {
|
||||
fullScreen: true,
|
||||
target: "ngc 1436",
|
||||
fov: 2,
|
||||
projection: 'TAN',
|
||||
showContextMenu: true,
|
||||
showSimbadPointerControl: true,
|
||||
expandLayersControl: true,
|
||||
hipsList: [
|
||||
// High energy (Gamma and X-rays)
|
||||
'CDS/P/HGPS/Flux',
|
||||
'CDS/P/Fermi/5',
|
||||
'CDS/P/Fermi/4',
|
||||
'CDS/P/Fermi/3',
|
||||
'ov-gso/P/Fermi/Band2',
|
||||
'ov-gso/P/BAT/150-195keV',
|
||||
'ov-gso/P/BAT/35-50keV',
|
||||
'ov-gso/P/BAT/14-20keV',
|
||||
'erosita/dr1/rate/023',
|
||||
'erosita/dr1/rate/024',
|
||||
// Uv/Optical/Infrared
|
||||
'CDS/P/GALEXGR6_7/FUV',
|
||||
'CDS/P/GALEXGR6_7/NUV',
|
||||
'CDS/P/DSS2/color',
|
||||
'CDS/P/PanSTARRS/DR1/g',
|
||||
'CDS/P/PanSTARRS/DR1/r',
|
||||
'CDS/P/Finkbeiner',
|
||||
'CDS/P/PanSTARRS/DR1/i',
|
||||
'CDS/P/PanSTARRS/DR1/color-i-r-g',
|
||||
'CDS/P/PanSTARRS/DR1/z',
|
||||
'CDS/P/PanSTARRS/DR1/y',
|
||||
'CDS/P/DES-DR2/ColorIRG',
|
||||
'CDS/P/2MASS/color',
|
||||
'ov-gso/P/GLIMPSE/irac1',
|
||||
'ov-gso/P/GLIMPSE/irac2',
|
||||
'CDS/P/unWISE/color-W2-W1W2-W1',
|
||||
'ov-gso/P/GLIMPSE/irac3',
|
||||
'ov-gso/P/GLIMPSE/irac4',
|
||||
'CDS/P/IRIS/color',
|
||||
'ESAVO/P/AKARI/N60',
|
||||
'ESAVO/P/AKARI/WideL',
|
||||
'ESAVO/P/HERSCHEL/SPIRE-250',
|
||||
'ESAVO/P/HERSCHEL/SPIRE-350',
|
||||
'ESAVO/P/HERSCHEL/SPIRE-500',
|
||||
// sub-mm/mm/radio
|
||||
'CDS/P/PLANCK/R3/HFI/color',
|
||||
'CDS/P/ACT_Planck/DR5/f220',
|
||||
'CDS/P/CO',
|
||||
'CDS/P/PLANCK/R3/HFI100',
|
||||
'CDS/P/PLANCK/R3/LFI30',
|
||||
'CDS/P/NVSS',
|
||||
'CSIRO/P/RACS/mid/I',
|
||||
'ov-gso/P/CGPS/VGPS',
|
||||
'CDS/C/HI4PI/HI',
|
||||
'CDS/P/MeerKAT/Galactic-Centre-1284MHz-StokesI',
|
||||
'CSIRO/P/RACS/low/I',
|
||||
'astron.nl/P/tgssadr',
|
||||
'ov-gso/P/GLEAM/170-231',
|
||||
'ov-gso/P/GLEAM/139-170',
|
||||
'astron.nl/P/lotss_dr2_high',
|
||||
'ov-gso/P/GLEAM/103-134',
|
||||
'ov-gso/P/GLEAM/072-103'
|
||||
]
|
||||
});
|
||||
|
||||
aladin.addCatalog(
|
||||
A.catalogFromSKAORucio("ngc 1436", 15, {
|
||||
onClick: 'showTable',
|
||||
hoverColor: "yellow",
|
||||
})
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -14,13 +14,14 @@
|
||||
// Start up Aladin Lite
|
||||
aladin = A.aladin('#aladin-lite-div', {
|
||||
fov: 360,
|
||||
projection: 'MER',
|
||||
target: '0 0',
|
||||
fullScreen: true,
|
||||
survey: "CDS/P/Mars/Pan-Perseverance-PIA24422",
|
||||
showCooGrid: true,
|
||||
showCooGridControl: true,
|
||||
});
|
||||
aladin.setProjection('MER');
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -11,11 +11,15 @@
|
||||
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'Gamma Cas', fov: 10});
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'Gamma Cas', fov: 10, cooFrame: 'icrs'});
|
||||
|
||||
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 2});
|
||||
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] ]));
|
||||
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)
|
||||
})
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
32
examples/al-save-colormap.html
Normal file
32
examples/al-save-colormap.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<!--<link rel="stylesheet" href="./layers.css" />-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
var aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {fullScreen: true, cooFrame: "ICRSd", showSimbadPointerControl: true, showShareControl: true, showShareControl: true, survey: 'https://alasky.cds.unistra.fr/DSS/DSSColor/', fov: 180, showContextMenu: true});
|
||||
// manage URL parameters
|
||||
let survey1 = aladin.getBaseImageLayer();
|
||||
survey1.setColormap('magma', {stretch: 'linear'});
|
||||
|
||||
let survey2 = aladin.newImageSurvey("CSIRO/P/RACS/low/I");
|
||||
aladin.setImageLayer(survey2)
|
||||
survey2.setColormap('rdbu', {stretch: 'linear'});
|
||||
|
||||
let survey3 = aladin.newImageSurvey("CSIRO/P/RACS/mid/I");
|
||||
aladin.setImageLayer(survey3)
|
||||
survey3.setColormap('cubehelix', {stretch: 'asinh'});
|
||||
|
||||
aladin.setImageLayer(survey2);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,14 +6,18 @@
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<div id='aladin-statsDiv'></div>
|
||||
<script>let aladin, hips</script>
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {cooFrame: 'galactic', target: 'galactic center', survey: 'P/Finkbeiner'});
|
||||
// possible values are 'blues', 'cividis', 'cubehelix', 'eosb', 'grayscale', 'inferno', 'magma', 'native', 'parula', 'plasma', 'rainbow',
|
||||
// 'rdbu', 'rdylbu', 'redtemperature', 'sinebow', 'spectral', 'summer', 'viridis', 'ylgnbu' and 'ylorbr'
|
||||
aladin.getBaseImageLayer().setColormap("cubehelix");
|
||||
hips = aladin.getBaseImageLayer()
|
||||
hips.setColormap("cubehelix");
|
||||
|
||||
aladin.setImageSurvey('astron.nl/P/lotss_dr2_high')
|
||||
|
||||
//aladin.getBaseImageLayer().setColor([1.0, 0.0, 1.0, 1.0], { tf: 'Linear'} );
|
||||
});
|
||||
</script>
|
||||
|
||||
45
examples/al-simbad-filter.html
Normal file
45
examples/al-simbad-filter.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
Show sources with proper motion greater than:
|
||||
<input id='slider' style='vertical-align:middle;width:60vw;' step='1' min='0' max='10' type='range' value='0'>
|
||||
<span id='pmVal' >0 mas/yr</span><br><br><div id='aladin-lite-div' style='width: 500px;height: 500px;'></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
var colorThreshold = 0;
|
||||
var slider = document.getElementById('slider');
|
||||
slider.oninput = function() {
|
||||
colorThreshold = this.value;
|
||||
$('#colorVal').html(colorThreshold);
|
||||
cat.reportChange();
|
||||
}
|
||||
var myFilterFunction = function(source) {
|
||||
const magB = parseFloat(source.data['B']);
|
||||
const magV = parseFloat(source.data['V']);
|
||||
if (isNaN(magB) || isNaN(magV) ) {
|
||||
return false;
|
||||
}
|
||||
const color = magB - magV;
|
||||
return color>colorThreshold;
|
||||
}
|
||||
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'M 81', fov: 0.5, survey: 'CDS/P/SDSS9/color'});
|
||||
var cat = A.catalogFromSimbad('M 81', 0.25, {onClick: 'showTable', verbosity: 3, filter: myFilterFunction});
|
||||
aladin.addCatalog(cat);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
95
examples/al-ska-hips-list.html
Normal file
95
examples/al-ska-hips-list.html
Normal file
@@ -0,0 +1,95 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {
|
||||
fullScreen: true,
|
||||
target: "centaurus A",
|
||||
fov: 10,
|
||||
projection: 'TAN',
|
||||
showContextMenu: true,
|
||||
showSimbadPointerControl: true,
|
||||
expandLayersControl: true,
|
||||
hipsList: [
|
||||
// High energy (Gamma and X-rays)
|
||||
'CDS/P/HGPS/Flux',
|
||||
'CDS/P/Fermi/5',
|
||||
'CDS/P/Fermi/4',
|
||||
'CDS/P/Fermi/3',
|
||||
'ov-gso/P/Fermi/Band2',
|
||||
'ov-gso/P/BAT/150-195keV',
|
||||
'ov-gso/P/BAT/35-50keV',
|
||||
'ov-gso/P/BAT/14-20keV',
|
||||
'erosita/dr1/rate/023',
|
||||
'erosita/dr1/rate/024',
|
||||
// Uv/Optical/Infrared
|
||||
'CDS/P/GALEXGR6_7/FUV',
|
||||
'CDS/P/GALEXGR6_7/NUV',
|
||||
'CDS/P/DSS2/color',
|
||||
'CDS/P/PanSTARRS/DR1/g',
|
||||
'CDS/P/PanSTARRS/DR1/r',
|
||||
'CDS/P/Finkbeiner',
|
||||
'CDS/P/PanSTARRS/DR1/i',
|
||||
'CDS/P/PanSTARRS/DR1/color-i-r-g',
|
||||
'CDS/P/PanSTARRS/DR1/z',
|
||||
'CDS/P/PanSTARRS/DR1/y',
|
||||
'CDS/P/DES-DR2/ColorIRG',
|
||||
'CDS/P/2MASS/color',
|
||||
'ov-gso/P/GLIMPSE/irac1',
|
||||
'ov-gso/P/GLIMPSE/irac2',
|
||||
'CDS/P/unWISE/color-W2-W1W2-W1',
|
||||
'ov-gso/P/GLIMPSE/irac3',
|
||||
'ov-gso/P/GLIMPSE/irac4',
|
||||
'CDS/P/IRIS/color',
|
||||
'ESAVO/P/AKARI/N60',
|
||||
'ESAVO/P/AKARI/WideL',
|
||||
'ESAVO/P/HERSCHEL/SPIRE-250',
|
||||
'ESAVO/P/HERSCHEL/SPIRE-350',
|
||||
'ESAVO/P/HERSCHEL/SPIRE-500',
|
||||
// sub-mm/mm/radio
|
||||
'CDS/P/PLANCK/R3/HFI/color',
|
||||
'CDS/P/ACT_Planck/DR5/f220',
|
||||
'CDS/P/CO',
|
||||
'CDS/P/PLANCK/R3/HFI100',
|
||||
'CDS/P/PLANCK/R3/LFI30',
|
||||
'CDS/P/NVSS',
|
||||
'CSIRO/P/RACS/mid/I',
|
||||
'ov-gso/P/CGPS/VGPS',
|
||||
'CDS/C/HI4PI/HI',
|
||||
'CDS/P/MeerKAT/Galactic-Centre-1284MHz-StokesI',
|
||||
'CSIRO/P/RACS/low/I',
|
||||
'astron.nl/P/tgssadr',
|
||||
'ov-gso/P/GLEAM/170-231',
|
||||
'ov-gso/P/GLEAM/139-170',
|
||||
'astron.nl/P/lotss_dr2_high',
|
||||
'ov-gso/P/GLEAM/103-134',
|
||||
'ov-gso/P/GLEAM/072-103'
|
||||
]
|
||||
});
|
||||
|
||||
const gleam072_103 = aladin.newImageSurvey('ov-gso/P/GLEAM/072-103', {imgFormat: 'fits', colormap: "red", stretch: "asinh"});
|
||||
const gleam103_134 = aladin.newImageSurvey('ov-gso/P/GLEAM/103-134', {imgFormat: 'fits', colormap: "green", additive: true, stretch: "asinh"});
|
||||
const gleam170_231 = aladin.newImageSurvey('ov-gso/P/GLEAM/170-231', {imgFormat: 'fits', colormap: "blue", additive: true, stretch: "asinh"});
|
||||
|
||||
//const HSCBlueSurvey = aladin.newImageSurvey('CDS/P/HSC/DR2/deep/z', {imgFormat: 'fits', colormap: "blue", minCut: -0.01218, maxCut: 2.27397, additive: true, stretch: "asinh"});
|
||||
|
||||
aladin.setBaseImageLayer(gleam072_103);
|
||||
aladin.setOverlayImageLayer(gleam103_134, 'gl2');
|
||||
aladin.setOverlayImageLayer(gleam170_231, 'gl3');
|
||||
|
||||
//aladin.setOverlayImageLayer('CDS/P/HSC/DR2/deep/z', 'hsc blue layer');
|
||||
|
||||
//const c1 = A.catalogFromURL('./data/eso.xml', {onClick: 'showTable'});
|
||||
//aladin.addCatalog(c1);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,33 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {fullScreen: true, target: "Abell 194", fov: 180, projection: 'SIN', showContextMenu: true});
|
||||
|
||||
A.catalogFromSKAORucio("m51", 90, {onClick: 'showTable'}, (cat) => {
|
||||
aladin.addCatalog(cat);
|
||||
});
|
||||
|
||||
/*A.catalogFromURL('https://aladin.cds.unistra.fr/AladinLite/ska/obscoreRucio.xml', {onClick: 'showTable'}, (cat) => {
|
||||
aladin.addCatalog(cat);
|
||||
});
|
||||
|
||||
A.catalogFromURL('data/votable/CDS-B-jcmt-obscore.xml', {onClick: 'showTable'}, (cat) => {
|
||||
aladin.addCatalog(cat);
|
||||
});*/
|
||||
A.catalogFromURL('https://aladin.cds.unistra.fr/ObsCoreRucioScs.xml', {onClick: 'showTable'}, (cat) => {
|
||||
aladin.addCatalog(cat);
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -14,7 +14,7 @@
|
||||
let aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'Sgr a*', fov: 0.5, showContextMenu: true});
|
||||
// This table contains a s_region column containing stcs expressed regions
|
||||
// that are automatically parsed
|
||||
aladin.addCatalog(A.catalogFromURL('https://aladin.cds.unistra.fr/AladinLite/doc/API/examples/data/alma-footprints.xml', {name: 'ALMA footprints', onClick: 'showTable'}));
|
||||
aladin.addCatalog(A.catalogFromURL('https://aladin.cds.unistra.fr/AladinLite/doc/API/examples/data/alma-footprints.xml', {name: 'ALMA footprints', onClick: 'showTable', hoverColor: 'lightgreen'}));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -8,15 +8,13 @@
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
import {AladinUtils} from '../src/js/AladinUtils.js';
|
||||
|
||||
A.init.then(() => {
|
||||
let vertices = AladinUtils.HEALPix.vertices(8, 0n)
|
||||
|
||||
let lonlat = AladinUtils.HEALPix.pix2ang(8, 0n)
|
||||
|
||||
let ipix = AladinUtils.HEALPix.ang2pix(8, 0.1, 0.4)
|
||||
console.log(vertices, lonlat, ipix)
|
||||
let vertices = A.Utils.HEALPix.vertices(Math.pow(2, 3), BigInt(276))
|
||||
//let lonlat = A.Utils.HEALPix.pix2ang(8, 0n)
|
||||
//let ipix = A.Utils.HEALPix.ang2pix(8, 0.1, 0.4)
|
||||
//console.log("vertices", vertices, lonlat, ipix)
|
||||
console.log(vertices)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
|
||||
<div id='aladin-statsDiv'></div>
|
||||
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
|
||||
|
||||
@@ -14,17 +14,16 @@
|
||||
aladin = A.aladin('#aladin-lite-div', {target: "30 0", fov: 360, fullScreen: true, cooFrame: 'galactic', showCooGridControl: true, showSimbadPointerControl: true, showCooGrid: true});
|
||||
aladin.setProjection('AIT');
|
||||
|
||||
|
||||
aladin.on("zoomChanged", () => {
|
||||
console.log("zoomChanged")
|
||||
})
|
||||
aladin.on("positionChanged", ({ra, dec, dragging}) => {
|
||||
console.log("positionChanged", ra, dec)
|
||||
aladin.on("positionChanged", ({ra, dec}) => {
|
||||
console.log('call to aladin', aladin.pix2world(300, 300))
|
||||
console.log('positionChanged in icrs', ra, dec)
|
||||
})
|
||||
|
||||
aladin.gotoRaDec(0, 20);
|
||||
|
||||
|
||||
aladin.on('rightClickMove', (x, y) => {
|
||||
console.log("right click move", x, y)
|
||||
})
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
}
|
||||
if (searchParams.has('showCooGrid')) {
|
||||
const b = searchParams.get('showCooGrid') === 'true';
|
||||
aladin.view.setGridConfig({
|
||||
aladin.setCooGrid({
|
||||
enabled: b
|
||||
});
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
}
|
||||
if (searchParams.has('showCooGrid')) {
|
||||
const b = searchParams.get('showCooGrid') === 'true';
|
||||
aladin.view.setGridConfig({
|
||||
aladin.setCooGrid({
|
||||
enabled: b
|
||||
});
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
}
|
||||
if (searchParams.has('showCooGrid')) {
|
||||
const b = searchParams.get('showCooGrid') === 'true';
|
||||
aladin.view.setGridConfig({
|
||||
aladin.setCooGrid({
|
||||
enabled: b
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"homepage": "https://aladin.u-strasbg.fr/",
|
||||
"name": "aladin-lite",
|
||||
"type": "module",
|
||||
"version": "3.3.1-beta",
|
||||
"version": "3.4.2-beta",
|
||||
"description": "An astronomical HiPS visualizer in the browser",
|
||||
"author": "Thomas Boch and Matthieu Baumann",
|
||||
"license": "GPL-3",
|
||||
@@ -33,7 +33,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"wasm": "wasm-pack build ./src/core --target web --release --out-name core -- --features webgl2 -Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort ",
|
||||
"predeploy": "npm run build && rm -rf aladin-lite.tgz && npm pack",
|
||||
"predeploy": "npm run build && rm -rf aladin-lite*.tgz && npm pack",
|
||||
"deploy": "python3 deploy/deploy.py",
|
||||
"build": "npm run wasm && vite build && cp examples/index.html dist/index.html",
|
||||
"dev": "npm run build && vite",
|
||||
@@ -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": {
|
||||
@@ -50,7 +50,7 @@
|
||||
"vite": "^4.3.8",
|
||||
"vite-plugin-css-injected-by-js": "^3.1.1",
|
||||
"vite-plugin-glsl": "^1.1.2",
|
||||
"vite-plugin-top-level-await": "^1.3.1",
|
||||
"vite-plugin-top-level-await": "^1.4.1",
|
||||
"vite-plugin-wasm": "^3.2.2",
|
||||
"vite-plugin-wasm-pack": "^0.1.12",
|
||||
"vitest": "^0.32.2"
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "aladin-lite"
|
||||
description = "Aladin Lite v3 introduces a new graphical engine written in Rust with the use of WebGL"
|
||||
license = "BSD-3-Clause"
|
||||
repository = "https://github.com/cds-astro/aladin-lite"
|
||||
version = "3.3.0"
|
||||
version = "3.4.1-beta"
|
||||
authors = [ "baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr",]
|
||||
edition = "2018"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -43,10 +43,9 @@ pub struct HiPSProperties {
|
||||
// Associated with the HiPS
|
||||
url: String,
|
||||
max_order: u8,
|
||||
frame: CooSystem,
|
||||
coo_frame: CooSystem,
|
||||
tile_size: i32,
|
||||
formats: Vec<ImageExt>,
|
||||
dataproduct_subtype: Option<Vec<String>>,
|
||||
|
||||
is_planetary_body: Option<bool>,
|
||||
|
||||
@@ -103,7 +102,7 @@ impl HiPSProperties {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_frame(&self) -> CooSystem {
|
||||
self.frame
|
||||
self.coo_frame
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -125,11 +124,6 @@ impl HiPSProperties {
|
||||
pub fn get_initial_dec(&self) -> Option<f64> {
|
||||
self.hips_initial_dec
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_dataproduct_subtype(&self) -> &Option<Vec<String>> {
|
||||
&self.dataproduct_subtype
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
||||
@@ -17,45 +17,34 @@ pub enum Data<'a> {
|
||||
I32(Cow<'a, [i32]>),
|
||||
F32(Cow<'a, [f32]>),
|
||||
}
|
||||
use fitsrs::{fits::Fits as FitsData, hdu::data::InMemData};
|
||||
use std::io::Cursor;
|
||||
use fitsrs::{
|
||||
hdu::data::InMemData,
|
||||
fits::Fits as FitsData,
|
||||
};
|
||||
|
||||
impl<'a> Fits<'a> {
|
||||
pub fn from_byte_slice(bytes_reader: &'a mut Cursor<&[u8]>) -> Result<Self, JsValue> {
|
||||
let FitsData { hdu } = FitsData::from_reader(bytes_reader)
|
||||
.map_err(|_| {
|
||||
JsValue::from_str(&"Parsing fits error")
|
||||
})?;
|
||||
.map_err(|_| JsValue::from_str(&"Parsing fits error"))?;
|
||||
|
||||
let header = hdu.get_header();
|
||||
let xtension = header.get_xtension();
|
||||
let width = xtension.get_naxisn(1)
|
||||
let width = xtension
|
||||
.get_naxisn(1)
|
||||
.ok_or_else(|| JsValue::from_str("NAXIS1 not found in the fits"))?;
|
||||
|
||||
let height = xtension.get_naxisn(2)
|
||||
let height = xtension
|
||||
.get_naxisn(2)
|
||||
.ok_or_else(|| JsValue::from_str("NAXIS2 not found in the fits"))?;
|
||||
|
||||
|
||||
let data = hdu.get_data();
|
||||
let data = match *data {
|
||||
InMemData::U8(slice) => {
|
||||
Data::U8(Cow::Borrowed(slice))
|
||||
},
|
||||
InMemData::I16(slice) => {
|
||||
Data::I16(Cow::Borrowed(slice))
|
||||
},
|
||||
InMemData::I32(slice) => {
|
||||
Data::I32(Cow::Borrowed(slice))
|
||||
},
|
||||
InMemData::U8(slice) => Data::U8(Cow::Borrowed(slice)),
|
||||
InMemData::I16(slice) => Data::I16(Cow::Borrowed(slice)),
|
||||
InMemData::I32(slice) => Data::I32(Cow::Borrowed(slice)),
|
||||
InMemData::I64(slice) => {
|
||||
let data = slice.iter().map(|v| *v as i32).collect();
|
||||
Data::I32(Cow::Owned(data))
|
||||
},
|
||||
InMemData::F32(slice) => {
|
||||
Data::F32(Cow::Borrowed(slice))
|
||||
},
|
||||
}
|
||||
InMemData::F32(slice) => Data::F32(Cow::Borrowed(slice)),
|
||||
InMemData::F64(slice) => {
|
||||
let data = slice.iter().map(|v| *v as f32).collect();
|
||||
Data::F32(Cow::Owned(data))
|
||||
@@ -66,8 +55,8 @@ impl<'a> Fits<'a> {
|
||||
// Tile size
|
||||
size: Vector2::new(*width as i32, *height as i32),
|
||||
|
||||
// Allocation info of the layout
|
||||
data
|
||||
// Allocation info of the layout
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -121,14 +110,14 @@ impl<'a> Fits<'a> {
|
||||
// Tile size
|
||||
size: Vector2::new(*width as i32, *height as i32),
|
||||
|
||||
// Allocation info of the layout
|
||||
// Allocation info of the layout
|
||||
data
|
||||
})
|
||||
}
|
||||
}*/
|
||||
|
||||
use crate::Texture2DArray;
|
||||
use crate::image::Image;
|
||||
use crate::Texture2DArray;
|
||||
impl Image for Fits<'_> {
|
||||
fn tex_sub_image_3d(
|
||||
&self,
|
||||
@@ -138,7 +127,7 @@ impl Image for Fits<'_> {
|
||||
offset: &Vector3<i32>,
|
||||
) -> Result<(), JsValue> {
|
||||
match &self.data {
|
||||
Data::U8(data) => {
|
||||
Data::U8(data) => {
|
||||
let view = unsafe { R8UI::view(&data) };
|
||||
textures[offset.z as usize]
|
||||
.bind()
|
||||
@@ -150,7 +139,7 @@ impl Image for Fits<'_> {
|
||||
Some(view.as_ref()),
|
||||
);
|
||||
}
|
||||
Data::I16(data) => {
|
||||
Data::I16(data) => {
|
||||
let view = unsafe { R16I::view(&data) };
|
||||
textures[offset.z as usize]
|
||||
.bind()
|
||||
@@ -162,7 +151,7 @@ impl Image for Fits<'_> {
|
||||
Some(view.as_ref()),
|
||||
);
|
||||
}
|
||||
Data::I32(data) => {
|
||||
Data::I32(data) => {
|
||||
let view = unsafe { R32I::view(&data) };
|
||||
textures[offset.z as usize]
|
||||
.bind()
|
||||
@@ -174,7 +163,7 @@ impl Image for Fits<'_> {
|
||||
Some(view.as_ref()),
|
||||
);
|
||||
}
|
||||
Data::F32(data) => {
|
||||
Data::F32(data) => {
|
||||
let view = unsafe { R32F::view(&data) };
|
||||
textures[offset.z as usize]
|
||||
.bind()
|
||||
@@ -192,8 +181,8 @@ impl Image for Fits<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
use wasm_bindgen::JsValue;
|
||||
use crate::image::format::ImageFormat;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
pub trait FitsImageFormat: ImageFormat {
|
||||
const BITPIX: i8;
|
||||
@@ -205,7 +194,7 @@ impl FitsImageFormat for R32F {
|
||||
}
|
||||
|
||||
#[cfg(feature = "webgl2")]
|
||||
use crate::image::{R16I, R32I, R8UI, R64F};
|
||||
use crate::image::{R16I, R32I, R64F, R8UI};
|
||||
#[cfg(feature = "webgl2")]
|
||||
impl FitsImageFormat for R64F {
|
||||
const BITPIX: i8 = -64;
|
||||
|
||||
@@ -44,7 +44,9 @@ impl ImageFormat for RGB8U {
|
||||
|
||||
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
|
||||
let mut decoder = jpeg::Decoder::new(raw_bytes);
|
||||
let bytes = decoder.decode().map_err(|_| "Cannot decoder jpeg. This image may not be compressed.")?;
|
||||
let bytes = decoder
|
||||
.decode()
|
||||
.map_err(|_| "Cannot decoder jpeg. This image may not be compressed.")?;
|
||||
|
||||
Ok(Bytes::Owned(bytes))
|
||||
}
|
||||
@@ -70,7 +72,9 @@ impl ImageFormat for RGBA8U {
|
||||
|
||||
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
|
||||
let mut decoder = jpeg::Decoder::new(raw_bytes);
|
||||
let bytes = decoder.decode().map_err(|_| "Cannot decoder png. This image may not be compressed.")?;
|
||||
let bytes = decoder
|
||||
.decode()
|
||||
.map_err(|_| "Cannot decoder png. This image may not be compressed.")?;
|
||||
|
||||
Ok(Bytes::Owned(bytes))
|
||||
}
|
||||
@@ -93,7 +97,9 @@ impl ImageFormat for RGBA8U {
|
||||
|
||||
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
|
||||
let mut decoder = jpeg::Decoder::new(raw_bytes);
|
||||
let bytes = decoder.decode().map_err(|_| "Cannot decoder png. This image may not be compressed.")?;
|
||||
let bytes = decoder
|
||||
.decode()
|
||||
.map_err(|_| "Cannot decoder png. This image may not be compressed.")?;
|
||||
|
||||
Ok(Bytes::Owned(bytes))
|
||||
}
|
||||
@@ -188,7 +194,6 @@ impl ImageFormat for R32F {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "webgl2")]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct R64F;
|
||||
@@ -310,6 +315,8 @@ pub enum ChannelType {
|
||||
R32I,
|
||||
}
|
||||
|
||||
pub const NUM_CHANNELS: usize = 9;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
pub struct ImageFormatType {
|
||||
pub ext: ImageExt,
|
||||
@@ -327,8 +334,11 @@ impl ImageFormatType {
|
||||
|
||||
pub fn is_colored(&self) -> bool {
|
||||
match self.channel {
|
||||
ChannelType::RGBA32F | ChannelType::RGB32F | ChannelType::RGBA8U | ChannelType::RGB8U => true,
|
||||
_ => false
|
||||
ChannelType::RGBA32F
|
||||
| ChannelType::RGB32F
|
||||
| ChannelType::RGBA8U
|
||||
| ChannelType::RGB8U => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,14 +60,14 @@ pub struct Texture2D {
|
||||
pub enum SamplerType {
|
||||
Float,
|
||||
Integer,
|
||||
Unsigned
|
||||
Unsigned,
|
||||
}
|
||||
|
||||
use crate::image::format::ImageFormat;
|
||||
//use super::pixel::PixelType;
|
||||
use std::cell::RefCell;
|
||||
use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
impl Texture2D {
|
||||
pub fn create_from_path<P: AsRef<Path>, F: ImageFormat>(
|
||||
gl: &WebGlContext,
|
||||
@@ -145,7 +145,6 @@ impl Texture2D {
|
||||
onload.forget();
|
||||
onerror.forget();
|
||||
|
||||
|
||||
let gl = gl.clone();
|
||||
Ok(Texture2D {
|
||||
texture,
|
||||
@@ -163,16 +162,12 @@ impl Texture2D {
|
||||
tex_params: &'static [(u32, u32)],
|
||||
data: Option<&[<F::P as Pixel>::Item]>,
|
||||
) -> Result<Texture2D, JsValue> {
|
||||
let texture = Texture2D::create_empty_with_format::<F>(
|
||||
gl,
|
||||
width,
|
||||
height,
|
||||
tex_params
|
||||
)?;
|
||||
let texture = Texture2D::create_empty_with_format::<F>(gl, width, height, tex_params)?;
|
||||
|
||||
if let Some(data) = data {
|
||||
let buf_data = unsafe { F::view(data) };
|
||||
texture.bind()
|
||||
texture
|
||||
.bind()
|
||||
.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_array_buffer_view(
|
||||
0,
|
||||
0,
|
||||
@@ -235,7 +230,6 @@ impl Texture2D {
|
||||
None,
|
||||
)
|
||||
.expect("Texture 2D");
|
||||
//gl.generate_mipmap(WebGlRenderingCtx::TEXTURE_2D);
|
||||
|
||||
let gl = gl.clone();
|
||||
let metadata = Some(Rc::new(RefCell::new(Texture2DMeta {
|
||||
@@ -329,7 +323,8 @@ impl Texture2D {
|
||||
} else {
|
||||
// set the viewport as the FBO won't be the same dimension as the screen
|
||||
let metadata = self.metadata.as_ref().unwrap_abort().borrow();
|
||||
self.gl.viewport(x, y, metadata.width as i32, metadata.height as i32);
|
||||
self.gl
|
||||
.viewport(x, y, metadata.width as i32, metadata.height as i32);
|
||||
#[cfg(feature = "webgl2")]
|
||||
let value = match (metadata.format, metadata.type_) {
|
||||
(WebGlRenderingCtx::RED_INTEGER, WebGlRenderingCtx::UNSIGNED_BYTE) => {
|
||||
@@ -650,4 +645,4 @@ impl<'a> Texture2DBoundMut<'a> {
|
||||
)
|
||||
.expect("Sub texture 2d");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,12 +27,12 @@ impl Texture2DArray {
|
||||
tex_params: &'static [(u32, u32)],
|
||||
) -> Result<Texture2DArray, JsValue> {
|
||||
let textures: Result<Vec<_>, _> = (0..num_slices)
|
||||
.map(|_| {
|
||||
Texture2D::create_empty_with_format::<F>(gl, width, height, tex_params)
|
||||
})
|
||||
.map(|_| Texture2D::create_empty_with_format::<F>(gl, width, height, tex_params))
|
||||
.collect();
|
||||
|
||||
Ok(Texture2DArray { textures: textures? })
|
||||
Ok(Texture2DArray {
|
||||
textures: textures?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,16 +106,15 @@ pub struct App {
|
||||
|
||||
ack_send: async_channel::Sender<ImageParams>,
|
||||
ack_recv: async_channel::Receiver<ImageParams>,
|
||||
|
||||
// callbacks
|
||||
callback_position_changed: js_sys::Function,
|
||||
//callback_position_changed: js_sys::Function,
|
||||
}
|
||||
|
||||
use cgmath::{Vector2, Vector3};
|
||||
use futures::{io::BufReader, stream::StreamExt}; // for `next`
|
||||
|
||||
use crate::math::projection::*;
|
||||
pub const BLENDING_ANIM_DURATION: DeltaTime = DeltaTime::from_millis(400.0); // in ms
|
||||
pub const BLENDING_ANIM_DURATION: DeltaTime = DeltaTime::from_millis(200.0); // in ms
|
||||
//use crate::buffer::Tile;
|
||||
use crate::time::Time;
|
||||
use cgmath::InnerSpace;
|
||||
@@ -131,7 +130,7 @@ impl App {
|
||||
mut shaders: ShaderManager,
|
||||
resources: Resources,
|
||||
// Callbacks
|
||||
callback_position_changed: js_sys::Function,
|
||||
//callback_position_changed: js_sys::Function,
|
||||
) -> Result<Self, JsValue> {
|
||||
let gl = gl.clone();
|
||||
//let exec = Rc::new(RefCell::new(TaskExecutor::new()));
|
||||
@@ -261,8 +260,7 @@ impl App {
|
||||
fits_recv,
|
||||
ack_send,
|
||||
ack_recv,
|
||||
|
||||
callback_position_changed,
|
||||
//callback_position_changed,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -270,6 +268,8 @@ impl App {
|
||||
// Move the views of the different active surveys
|
||||
self.tile_fetcher.clear();
|
||||
// Loop over the surveys
|
||||
let raytracer = self.layers.get_raytracer();
|
||||
|
||||
for survey in self.layers.values_mut_hips() {
|
||||
if self.camera.get_texture_depth() == 0
|
||||
&& self
|
||||
@@ -290,7 +290,8 @@ impl App {
|
||||
let root_url = survey.get_config().get_root_url().to_string();
|
||||
let format = survey.get_config().get_format();
|
||||
|
||||
if let Some(tiles_iter) = survey.look_for_new_tiles(&mut self.camera) {
|
||||
if let Some(tiles_iter) = survey.look_for_new_tiles(&mut self.camera, &self.projection)
|
||||
{
|
||||
for tile_cell in tiles_iter.into_iter() {
|
||||
self.tile_fetcher.append(
|
||||
query::Tile::new(&tile_cell, creator_did.clone(), root_url.clone(), format),
|
||||
@@ -537,8 +538,12 @@ impl App {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn set_callback_position_changed(&mut self, callback: js_sys::Function) {
|
||||
/*pub(crate) fn set_callback_position_changed(&mut self, callback: js_sys::Function) {
|
||||
self.callback_position_changed = callback;
|
||||
}*/
|
||||
|
||||
pub(crate) fn is_inerting(&self) -> bool {
|
||||
return self.inertia.is_some();
|
||||
}
|
||||
|
||||
pub(crate) fn update(&mut self, _dt: DeltaTime) -> Result<bool, JsValue> {
|
||||
@@ -557,7 +562,7 @@ impl App {
|
||||
let cur_speed = inertia.get_cur_speed();
|
||||
|
||||
// Create the javascript object to pass to the callback
|
||||
let args: js_sys::Object = js_sys::Object::new();
|
||||
/*let args: js_sys::Object = js_sys::Object::new();
|
||||
let center = self.camera.get_center().lonlat();
|
||||
js_sys::Reflect::set(
|
||||
&args,
|
||||
@@ -575,6 +580,7 @@ impl App {
|
||||
// Position has changed, we call the callback
|
||||
self.callback_position_changed
|
||||
.call1(&JsValue::null(), &args)?;
|
||||
*/
|
||||
|
||||
if cur_speed < thresh_speed {
|
||||
self.inertia = None;
|
||||
@@ -603,11 +609,11 @@ impl App {
|
||||
for rsc in rscs_received {
|
||||
match rsc {
|
||||
Resource::Tile(tile) => {
|
||||
if !has_camera_moved {
|
||||
if !_has_camera_zoomed {
|
||||
if let Some(survey) =
|
||||
self.layers.get_mut_hips_from_url(&tile.get_hips_url())
|
||||
self.layers.get_mut_hips_from_cdid(&tile.get_hips_cdid())
|
||||
{
|
||||
let cfg = survey.get_config();
|
||||
let cfg = survey.get_config_mut();
|
||||
|
||||
if cfg.get_format() == tile.format {
|
||||
let delta_depth = cfg.delta_depth();
|
||||
@@ -620,10 +626,10 @@ impl App {
|
||||
fov_coverage.intersects_cell(&neighbor_tile_cell)
|
||||
});
|
||||
|
||||
let is_tile_root = tile.cell().depth() == delta_depth;
|
||||
let _depth = tile.cell().depth();
|
||||
//let is_tile_root = tile.cell().depth() == delta_depth;
|
||||
//let _depth = tile.cell().depth();
|
||||
// do not perform tex_sub costly GPU calls while the camera is zooming
|
||||
if is_tile_root || included_or_near_coverage {
|
||||
if included_or_near_coverage {
|
||||
let is_missing = tile.missing();
|
||||
/*self.tile_fetcher.notify_tile(
|
||||
&tile,
|
||||
@@ -646,9 +652,65 @@ impl App {
|
||||
} else {
|
||||
Some(image)
|
||||
};
|
||||
use al_core::image::ImageType;
|
||||
use fitsrs::fits::Fits;
|
||||
use std::{io::Cursor, rc::Rc};
|
||||
if let Some(image) = image.as_ref() {
|
||||
match &*image.lock().unwrap_abort() {
|
||||
Some(ImageType::FitsImage {
|
||||
raw_bytes: raw_bytes_buf,
|
||||
}) => {
|
||||
// check if the metadata has not been set
|
||||
if !cfg.fits_metadata {
|
||||
let num_bytes =
|
||||
raw_bytes_buf.length() as usize;
|
||||
let mut raw_bytes = vec![0; num_bytes];
|
||||
raw_bytes_buf.copy_to(&mut raw_bytes[..]);
|
||||
|
||||
let mut bytes_reader =
|
||||
Cursor::new(raw_bytes.as_slice());
|
||||
let Fits { hdu } =
|
||||
Fits::from_reader(&mut bytes_reader)
|
||||
.map_err(|_| {
|
||||
JsValue::from_str(
|
||||
"Parsing fits error",
|
||||
)
|
||||
})?;
|
||||
|
||||
let header = hdu.get_header();
|
||||
let bscale = if let Some(
|
||||
fitsrs::card::Value::Float(bscale),
|
||||
) = header.get(b"BSCALE ")
|
||||
{
|
||||
*bscale as f32
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let bzero = if let Some(
|
||||
fitsrs::card::Value::Float(bzero),
|
||||
) = header.get(b"BZERO ")
|
||||
{
|
||||
*bzero as f32
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let blank = if let Some(
|
||||
fitsrs::card::Value::Float(blank),
|
||||
) = header.get(b"BLANK ")
|
||||
{
|
||||
*blank as f32
|
||||
} else {
|
||||
std::f32::NAN
|
||||
};
|
||||
|
||||
cfg.set_fits_metadata(bscale, bzero, blank);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
survey.add_tile(&cell, image, time_req)?;
|
||||
|
||||
self.request_redraw = true;
|
||||
|
||||
self.time_start_blending = Time::now();
|
||||
@@ -660,9 +722,9 @@ impl App {
|
||||
}
|
||||
}
|
||||
Resource::Allsky(allsky) => {
|
||||
let hips_url = allsky.get_hips_url();
|
||||
let hips_cdid = allsky.get_hips_cdid();
|
||||
|
||||
if let Some(survey) = self.layers.get_mut_hips_from_url(hips_url) {
|
||||
if let Some(survey) = self.layers.get_mut_hips_from_cdid(hips_cdid) {
|
||||
let is_missing = allsky.missing();
|
||||
if is_missing {
|
||||
// The allsky image is missing so we donwload all the tiles contained into
|
||||
@@ -691,7 +753,8 @@ impl App {
|
||||
}
|
||||
}
|
||||
Resource::PixelMetadata(metadata) => {
|
||||
if let Some(hips) = self.layers.get_mut_hips_from_url(&metadata.hips_url) {
|
||||
if let Some(hips) = self.layers.get_mut_hips_from_cdid(&metadata.hips_cdid)
|
||||
{
|
||||
let mut cfg = hips.get_config_mut();
|
||||
|
||||
if let Some(metadata) = *metadata.value.lock().unwrap_abort() {
|
||||
@@ -702,9 +765,9 @@ impl App {
|
||||
}
|
||||
}
|
||||
Resource::Moc(moc) => {
|
||||
let moc_url = moc.get_url();
|
||||
let url = &moc_url[..moc_url.find("/Moc.fits").unwrap_abort()];
|
||||
if let Some(hips) = self.layers.get_mut_hips_from_url(url) {
|
||||
let moc_hips_cdid = moc.get_hips_cdid();
|
||||
//let url = &moc_url[..moc_url.find("/Moc.fits").unwrap_abort()];
|
||||
if let Some(hips) = self.layers.get_mut_hips_from_cdid(moc_hips_cdid) {
|
||||
let request::moc::Moc { moc, .. } = moc;
|
||||
|
||||
if let Some(moc) = &*moc.lock().unwrap_abort() {
|
||||
@@ -756,14 +819,13 @@ impl App {
|
||||
// - there is at least one tile in its blending phase
|
||||
let blending_anim_occuring =
|
||||
(Time::now() - self.time_start_blending) < BLENDING_ANIM_DURATION;
|
||||
|
||||
let start_fading = self.layers.values_hips().any(|hips| {
|
||||
/*let start_fading = self.layers.values_hips().any(|hips| {
|
||||
if let Some(start_time) = hips.get_ready_time() {
|
||||
Time::now() - *start_time < BLENDING_ANIM_DURATION
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
// Finally update the camera that reset the flag camera changed
|
||||
//if has_camera_moved {
|
||||
@@ -787,8 +849,7 @@ impl App {
|
||||
})
|
||||
}
|
||||
|
||||
self.rendering =
|
||||
blending_anim_occuring | has_camera_moved | self.request_redraw | start_fading;
|
||||
self.rendering = blending_anim_occuring | has_camera_moved | self.request_redraw /*| start_fading*/;
|
||||
self.request_redraw = false;
|
||||
|
||||
self.draw(false)?;
|
||||
@@ -820,6 +881,10 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn draw_grid_labels(&mut self) -> Result<(), JsValue> {
|
||||
self.grid.draw_labels(&self.camera)
|
||||
}
|
||||
|
||||
pub(crate) fn draw(&mut self, force_render: bool) -> Result<(), JsValue> {
|
||||
/*let scene_redraw = self.rendering | force_render;
|
||||
let mut ui = self.ui.lock();
|
||||
@@ -962,10 +1027,10 @@ impl App {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn add_image_survey(&mut self, hips_cfg: HiPSCfg) -> Result<(), JsValue> {
|
||||
pub(crate) fn add_image_hips(&mut self, hips_cfg: HiPSCfg) -> Result<(), JsValue> {
|
||||
let hips =
|
||||
self.layers
|
||||
.add_image_survey(&self.gl, hips_cfg, &mut self.camera, &self.projection)?;
|
||||
.add_image_hips(&self.gl, hips_cfg, &mut self.camera, &self.projection)?;
|
||||
self.tile_fetcher
|
||||
.launch_starting_hips_requests(hips, &mut self.downloader);
|
||||
|
||||
@@ -1189,17 +1254,13 @@ impl App {
|
||||
self.layers.get_layer_cfg(layer)
|
||||
}
|
||||
|
||||
pub(crate) fn set_hips_url(
|
||||
&mut self,
|
||||
past_url: String,
|
||||
new_url: String,
|
||||
) -> Result<(), JsValue> {
|
||||
self.layers.set_survey_url(past_url, new_url.clone())?;
|
||||
pub(crate) fn set_hips_url(&mut self, cdid: &String, new_url: String) -> Result<(), JsValue> {
|
||||
self.layers.set_survey_url(cdid, new_url.clone())?;
|
||||
|
||||
let hips = self.layers.get_hips_from_url(&new_url).unwrap_abort();
|
||||
//let hips = self.layers.get_hips_from_url(&new_url).unwrap_abort();
|
||||
// Relaunch the base tiles for the survey to be ready with the new url
|
||||
self.tile_fetcher
|
||||
.launch_starting_hips_requests(hips, &mut self.downloader);
|
||||
//self.tile_fetcher
|
||||
// .launch_starting_hips_requests(hips, &mut self.downloader);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1302,12 +1363,8 @@ impl App {
|
||||
self.request_redraw = true;
|
||||
}
|
||||
|
||||
pub(crate) fn set_survey_url(
|
||||
&mut self,
|
||||
past_url: String,
|
||||
new_url: String,
|
||||
) -> Result<(), JsValue> {
|
||||
self.layers.set_survey_url(past_url, new_url)
|
||||
pub(crate) fn set_survey_url(&mut self, cdid: &String, new_url: String) -> Result<(), JsValue> {
|
||||
self.layers.set_survey_url(cdid, new_url)
|
||||
}
|
||||
|
||||
pub(crate) fn set_catalog_opacity(
|
||||
@@ -1376,6 +1433,10 @@ impl App {
|
||||
crate::math::projection::screen_to_clip_space(pos, &self.camera)
|
||||
}
|
||||
|
||||
pub(crate) fn get_coo_system(&self) -> CooSystem {
|
||||
self.camera.get_coo_system()
|
||||
}
|
||||
|
||||
pub(crate) fn view_to_icrs_coosys(&self, lonlat: &LonLatT<f64>) -> LonLatT<f64> {
|
||||
let icrs_pos: Vector4<_> = lonlat.vector();
|
||||
let view_system = self.camera.get_coo_system();
|
||||
@@ -1504,6 +1565,10 @@ impl App {
|
||||
self.request_redraw = true;
|
||||
}
|
||||
|
||||
pub(crate) fn set_inertia(&mut self, inertia: bool) {
|
||||
*self.disable_inertia.borrow_mut() = !inertia;
|
||||
}
|
||||
|
||||
/*pub(crate) fn project_line(&self, lon1: f64, lat1: f64, lon2: f64, lat2: f64) -> Vec<Vector2<f64>> {
|
||||
let v1: Vector3<f64> = LonLatT::new(ArcDeg(lon1).into(), ArcDeg(lat1).into()).vector();
|
||||
let v2: Vector3<f64> = LonLatT::new(ArcDeg(lon2).into(), ArcDeg(lat2).into()).vector();
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::HEALPixCoverage;
|
||||
use std::ops::Range;
|
||||
|
||||
use al_api::cell::HEALPixCellProjeted;
|
||||
use al_core::log::console_log;
|
||||
|
||||
pub fn project(
|
||||
cell: HEALPixCellProjeted,
|
||||
|
||||
@@ -9,7 +9,9 @@ pub enum UserAction {
|
||||
use super::{fov::FieldOfView, view_hpx_cells::ViewHpxCells};
|
||||
use crate::healpix::cell::HEALPixCell;
|
||||
use crate::healpix::coverage::HEALPixCoverage;
|
||||
use crate::math::angle::ToAngle;
|
||||
use crate::math::{projection::coo_space::XYZWModel, projection::domain::sdf::ProjDef};
|
||||
use al_core::log::console_log;
|
||||
use al_core::{info, inforec, log};
|
||||
|
||||
use cgmath::{Matrix4, Vector2};
|
||||
@@ -210,12 +212,31 @@ impl CameraViewPort {
|
||||
|
||||
pub fn get_hpx_cells<'a>(
|
||||
&'a mut self,
|
||||
depth: u8,
|
||||
mut depth: u8,
|
||||
frame: CooSystem,
|
||||
) -> impl Iterator<Item = &'a HEALPixCell> {
|
||||
self.view_hpx_cells.get_cells(depth, frame)
|
||||
}
|
||||
|
||||
pub fn is_raytracing(&self, proj: &ProjectionType) -> bool {
|
||||
// Check whether the tile depth is 0 for square projection
|
||||
// definition domains i.e. Mercator
|
||||
if self.is_allsky() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check the projection
|
||||
match proj {
|
||||
ProjectionType::Tan(_) => self.aperture >= 100.0_f64.to_radians().to_angle(),
|
||||
ProjectionType::Mer(_) => self.aperture >= 200.0_f64.to_radians().to_angle(),
|
||||
ProjectionType::Stg(_) => self.aperture >= 200.0_f64.to_radians().to_angle(),
|
||||
ProjectionType::Sin(_) => false,
|
||||
ProjectionType::Ait(_) => false,
|
||||
ProjectionType::Mol(_) => false,
|
||||
ProjectionType::Zea(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn recompute_scissor(&self) {
|
||||
// Clear all the screen before updating the scissor
|
||||
//self.gl.scissor(0, 0, self.width as i32, self.height as i32);
|
||||
@@ -253,41 +274,6 @@ impl CameraViewPort {
|
||||
);
|
||||
}
|
||||
|
||||
fn set_canvas_size(&self, width: f32, height: f32) {
|
||||
let canvas = self
|
||||
.gl
|
||||
.canvas()
|
||||
.unwrap_abort()
|
||||
.dyn_into::<web_sys::HtmlCanvasElement>()
|
||||
.unwrap_abort();
|
||||
|
||||
canvas
|
||||
.style()
|
||||
.set_property("width", &format!("{}px", width))
|
||||
.unwrap_abort();
|
||||
canvas
|
||||
.style()
|
||||
.set_property("height", &format!("{}px", height))
|
||||
.unwrap_abort();
|
||||
/*grid_canvas
|
||||
.style()
|
||||
.set_property("width", &format!("{}px", width))
|
||||
.unwrap_abort();
|
||||
grid_canvas
|
||||
.style()
|
||||
.set_property("height", &format!("{}px", height))
|
||||
.unwrap_abort();*/
|
||||
|
||||
canvas.set_width(self.width as u32);
|
||||
canvas.set_height(self.height as u32);
|
||||
//grid_canvas.set_width(self.width as u32);
|
||||
//grid_canvas.set_height(self.height as u32);
|
||||
|
||||
// Once the canvas size is changed, we have to set the viewport as well
|
||||
self.gl
|
||||
.viewport(0, 0, self.width as i32, self.height as i32);
|
||||
}
|
||||
|
||||
pub fn set_screen_size(&mut self, width: f32, height: f32, projection: &ProjectionType) {
|
||||
self.width = (width as f32) * self.dpi;
|
||||
self.height = (height as f32) * self.dpi;
|
||||
@@ -310,7 +296,18 @@ impl CameraViewPort {
|
||||
));
|
||||
|
||||
// Update the size of the canvas
|
||||
self.set_canvas_size(width, height);
|
||||
let canvas = self
|
||||
.gl
|
||||
.canvas()
|
||||
.unwrap_abort()
|
||||
.dyn_into::<web_sys::HtmlCanvasElement>()
|
||||
.unwrap_abort();
|
||||
|
||||
canvas.set_width(self.width as u32);
|
||||
canvas.set_height(self.height as u32);
|
||||
// Once the canvas size is changed, we have to set the viewport as well
|
||||
self.gl
|
||||
.viewport(0, 0, self.width as i32, self.height as i32);
|
||||
// Once it is done, recompute the scissor
|
||||
self.recompute_scissor();
|
||||
}
|
||||
@@ -384,6 +381,8 @@ impl CameraViewPort {
|
||||
}
|
||||
};
|
||||
|
||||
//console_log(&format!("clip factor {:?}", self.aperture));
|
||||
|
||||
// Project this vertex into the screen
|
||||
self.moved = true;
|
||||
self.zoomed = true;
|
||||
|
||||
@@ -2,18 +2,20 @@ use cgmath::{BaseFloat, Vector4};
|
||||
|
||||
use al_api::coo_system::CooBaseFloat;
|
||||
use al_api::coo_system::CooSystem;
|
||||
|
||||
use crate::math::lonlat::LonLat;
|
||||
/// This is conversion method returning a transformation
|
||||
/// matrix when the system requested by the user is not
|
||||
/// icrs j2000.
|
||||
/// The core projections are always performed in icrs j2000
|
||||
/// so one must call these methods to convert them to icrs before.
|
||||
#[inline]
|
||||
pub fn apply_coo_system<S>(c1: CooSystem, c2: CooSystem, v1: &Vector4<S>) -> Vector4<S>
|
||||
pub fn apply_coo_system<S>(c1: CooSystem, c2: CooSystem, v: &Vector4<S>) -> Vector4<S>
|
||||
where
|
||||
S: BaseFloat + CooBaseFloat,
|
||||
{
|
||||
let c1_2_c2_mat = c1.to::<S>(c2);
|
||||
c1_2_c2_mat * (*v1)
|
||||
c1_2_c2_mat * (*v)
|
||||
}
|
||||
|
||||
mod tests {
|
||||
|
||||
@@ -11,8 +11,8 @@ pub struct Downloader {
|
||||
requests: Vec<RequestType>,
|
||||
queried_list: HashSet<QueryId>,
|
||||
|
||||
cache: Cache<Url, Resource>,
|
||||
queried_cached_urls: Vec<Url>,
|
||||
cache: Cache<QueryId, Resource>,
|
||||
queried_cached_ids: Vec<QueryId>,
|
||||
}
|
||||
|
||||
use crate::fifo_cache::Cache;
|
||||
@@ -25,12 +25,12 @@ impl Downloader {
|
||||
let requests = Vec::with_capacity(32);
|
||||
let queried_list = HashSet::with_capacity(64);
|
||||
let cache = Cache::new();
|
||||
let queried_cached_urls = Vec::with_capacity(64);
|
||||
let queried_cached_ids = Vec::with_capacity(64);
|
||||
Self {
|
||||
requests,
|
||||
queried_list,
|
||||
cache,
|
||||
queried_cached_urls,
|
||||
queried_cached_ids,
|
||||
}
|
||||
}
|
||||
// Returns true if the fetch has been done
|
||||
@@ -39,8 +39,8 @@ impl Downloader {
|
||||
where
|
||||
T: Query,
|
||||
{
|
||||
let url = query.url();
|
||||
if self.cache.contains(url) {
|
||||
let id = query.id();
|
||||
if self.cache.contains(id) {
|
||||
//self.queried_cached_urls.push(url.clone());
|
||||
false
|
||||
} else {
|
||||
@@ -85,8 +85,8 @@ impl Downloader {
|
||||
self.queried_list.remove(&query_id);
|
||||
}
|
||||
|
||||
while let Some(url) = self.queried_cached_urls.pop() {
|
||||
if let Some(rsc) = self.cache.extract(&url) {
|
||||
while let Some(id) = self.queried_cached_ids.pop() {
|
||||
if let Some(rsc) = self.cache.extract(&id) {
|
||||
rscs.push(rsc);
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ impl Downloader {
|
||||
}*/
|
||||
|
||||
pub fn delay_rsc(&mut self, rsc: Resource) {
|
||||
self.queried_cached_urls.push(rsc.url().clone());
|
||||
self.cache.insert(rsc.url().clone(), rsc);
|
||||
self.queried_cached_ids.push(rsc.id().clone());
|
||||
self.cache.insert(rsc.id().clone(), rsc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::request::RequestType;
|
||||
pub trait Query: Sized {
|
||||
type Request: From<Self> + Into<RequestType>;
|
||||
|
||||
fn url(&self) -> &Url;
|
||||
fn hips_cdid(&self) -> &CreatorDid;
|
||||
fn id(&self) -> &QueryId;
|
||||
}
|
||||
|
||||
@@ -17,17 +17,18 @@ pub struct Tile {
|
||||
pub cell: HEALPixCell,
|
||||
pub format: ImageFormatType,
|
||||
// The root url of the HiPS
|
||||
pub hips_url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
// The total url of the query
|
||||
pub url: Url,
|
||||
pub id: QueryId,
|
||||
}
|
||||
|
||||
use crate::renderable::CreatorDid;
|
||||
use crate::{healpix::cell::HEALPixCell, survey::config::HiPSConfig};
|
||||
impl Tile {
|
||||
pub fn new(
|
||||
cell: &HEALPixCell,
|
||||
hips_id: String,
|
||||
hips_cdid: String,
|
||||
hips_url: String,
|
||||
format: ImageFormatType,
|
||||
) -> Self {
|
||||
@@ -42,10 +43,10 @@ impl Tile {
|
||||
hips_url, depth, dir_idx, idx, ext
|
||||
);
|
||||
|
||||
let id = format!("{}{}{}{}", hips_id, depth, idx, ext);
|
||||
let id = format!("{}{}{}{}", hips_cdid, depth, idx, ext);
|
||||
|
||||
Tile {
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
cell: *cell,
|
||||
format,
|
||||
@@ -58,8 +59,8 @@ use super::request::tile::TileRequest;
|
||||
impl Query for Tile {
|
||||
type Request = TileRequest;
|
||||
|
||||
fn url(&self) -> &Url {
|
||||
&self.url
|
||||
fn hips_cdid(&self) -> &CreatorDid {
|
||||
&self.hips_cdid
|
||||
}
|
||||
|
||||
fn id(&self) -> &QueryId {
|
||||
@@ -73,7 +74,7 @@ pub struct Allsky {
|
||||
pub tile_size: i32,
|
||||
pub texture_size: i32,
|
||||
// The root url of the HiPS
|
||||
pub hips_url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
// The total url of the query
|
||||
pub url: Url,
|
||||
pub id: QueryId,
|
||||
@@ -81,20 +82,20 @@ pub struct Allsky {
|
||||
|
||||
impl Allsky {
|
||||
pub fn new(cfg: &HiPSConfig) -> Self {
|
||||
let hips_url = cfg.get_root_url().to_string();
|
||||
let hips_cdid = cfg.get_creator_did().to_string();
|
||||
let tile_size = cfg.get_tile_size();
|
||||
let texture_size = cfg.get_texture_size();
|
||||
let format = cfg.get_format();
|
||||
let ext = format.get_ext_file();
|
||||
|
||||
let url = format!("{}/Norder3/Allsky.{}", hips_url, ext);
|
||||
let url = format!("{}/Norder3/Allsky.{}", cfg.get_root_url(), ext);
|
||||
|
||||
let id = format!("{}Allsky{}", cfg.get_creator_did(), ext);
|
||||
|
||||
Allsky {
|
||||
tile_size,
|
||||
texture_size,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
format,
|
||||
id,
|
||||
@@ -106,8 +107,8 @@ use super::request::allsky::AllskyRequest;
|
||||
impl Query for Allsky {
|
||||
type Request = AllskyRequest;
|
||||
|
||||
fn url(&self) -> &Url {
|
||||
&self.url
|
||||
fn hips_cdid(&self) -> &CreatorDid {
|
||||
&self.hips_cdid
|
||||
}
|
||||
|
||||
fn id(&self) -> &QueryId {
|
||||
@@ -119,7 +120,7 @@ impl Query for Allsky {
|
||||
pub struct PixelMetadata {
|
||||
pub format: ImageFormatType,
|
||||
// The root url of the HiPS
|
||||
pub hips_url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
// The total url of the query
|
||||
pub url: Url,
|
||||
pub id: QueryId,
|
||||
@@ -127,15 +128,15 @@ pub struct PixelMetadata {
|
||||
|
||||
impl PixelMetadata {
|
||||
pub fn new(cfg: &HiPSConfig) -> Self {
|
||||
let hips_url = cfg.get_root_url().to_string();
|
||||
let hips_cdid = cfg.get_creator_did().to_string();
|
||||
let format = cfg.get_format();
|
||||
let ext = format.get_ext_file();
|
||||
|
||||
let url = format!("{}/Norder3/Allsky.{}", hips_url, ext);
|
||||
let url = format!("{}/Norder3/Allsky.{}", cfg.get_root_url(), ext);
|
||||
|
||||
let id = format!("{}Allsky{}", cfg.get_creator_did(), ext);
|
||||
let id = format!("{}Allsky{}", hips_cdid, ext);
|
||||
PixelMetadata {
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
format,
|
||||
id,
|
||||
@@ -147,8 +148,8 @@ use super::request::blank::PixelMetadataRequest;
|
||||
impl Query for PixelMetadata {
|
||||
type Request = PixelMetadataRequest;
|
||||
|
||||
fn url(&self) -> &Url {
|
||||
&self.url
|
||||
fn hips_cdid(&self) -> &CreatorDid {
|
||||
&self.hips_cdid
|
||||
}
|
||||
|
||||
fn id(&self) -> &QueryId {
|
||||
@@ -161,10 +162,15 @@ pub struct Moc {
|
||||
// The total url of the query
|
||||
pub url: Url,
|
||||
pub params: al_api::moc::MOC,
|
||||
pub hips_cdid: CreatorDid,
|
||||
}
|
||||
impl Moc {
|
||||
pub fn new(url: String, params: al_api::moc::MOC) -> Self {
|
||||
Moc { url, params }
|
||||
pub fn new(url: String, hips_cdid: CreatorDid, params: al_api::moc::MOC) -> Self {
|
||||
Moc {
|
||||
url,
|
||||
params,
|
||||
hips_cdid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,8 +178,8 @@ use super::request::moc::MOCRequest;
|
||||
impl Query for Moc {
|
||||
type Request = MOCRequest;
|
||||
|
||||
fn url(&self) -> &Url {
|
||||
&self.url
|
||||
fn hips_cdid(&self) -> &CreatorDid {
|
||||
&self.hips_cdid
|
||||
}
|
||||
|
||||
fn id(&self) -> &QueryId {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::io::Cursor;
|
||||
|
||||
use crate::downloader::query;
|
||||
use crate::renderable::CreatorDid;
|
||||
use al_core::image::format::ChannelType;
|
||||
use al_core::image::ImageType;
|
||||
|
||||
@@ -9,7 +10,7 @@ use fitsrs::{fits::Fits, hdu::data::InMemData};
|
||||
use super::{Request, RequestType};
|
||||
use crate::downloader::QueryId;
|
||||
pub struct AllskyRequest {
|
||||
pub hips_url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
pub url: Url,
|
||||
pub depth_tile: u8,
|
||||
pub id: QueryId,
|
||||
@@ -76,7 +77,7 @@ impl From<query::Allsky> for AllskyRequest {
|
||||
format,
|
||||
tile_size,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
texture_size,
|
||||
id,
|
||||
} = query;
|
||||
@@ -207,7 +208,7 @@ impl From<query::Allsky> for AllskyRequest {
|
||||
|
||||
Self {
|
||||
id,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
depth_tile,
|
||||
url,
|
||||
request,
|
||||
@@ -309,7 +310,7 @@ pub struct Allsky {
|
||||
pub time_req: Time,
|
||||
pub depth_tile: u8,
|
||||
|
||||
pub hips_url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
url: Url,
|
||||
}
|
||||
|
||||
@@ -320,8 +321,8 @@ impl Allsky {
|
||||
self.image.lock().unwrap_abort().is_none()
|
||||
}
|
||||
|
||||
pub fn get_hips_url(&self) -> &Url {
|
||||
&self.hips_url
|
||||
pub fn get_hips_cdid(&self) -> &CreatorDid {
|
||||
&self.hips_cdid
|
||||
}
|
||||
|
||||
pub fn get_url(&self) -> &Url {
|
||||
@@ -333,7 +334,7 @@ impl<'a> From<&'a AllskyRequest> for Option<Allsky> {
|
||||
fn from(request: &'a AllskyRequest) -> Self {
|
||||
let AllskyRequest {
|
||||
request,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
depth_tile,
|
||||
url,
|
||||
..
|
||||
@@ -346,7 +347,7 @@ impl<'a> From<&'a AllskyRequest> for Option<Allsky> {
|
||||
time_req: *time_request,
|
||||
// This is a clone on a Arc, it is supposed to be fast
|
||||
image: data.clone(),
|
||||
hips_url: hips_url.clone(),
|
||||
hips_cdid: hips_cdid.clone(),
|
||||
url: url.clone(),
|
||||
depth_tile: *depth_tile,
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ use al_core::image::format::ChannelType;
|
||||
use std::io::Cursor;
|
||||
|
||||
use crate::downloader::query;
|
||||
use crate::renderable::CreatorDid;
|
||||
use fitsrs::fits::Fits;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -27,7 +28,7 @@ use crate::downloader::QueryId;
|
||||
pub struct PixelMetadataRequest {
|
||||
pub id: QueryId,
|
||||
pub url: Url,
|
||||
pub hips_url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
request: Request<Metadata>,
|
||||
}
|
||||
|
||||
@@ -49,7 +50,7 @@ impl From<query::PixelMetadata> for PixelMetadataRequest {
|
||||
let query::PixelMetadata {
|
||||
format,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
id,
|
||||
} = query;
|
||||
|
||||
@@ -126,7 +127,7 @@ impl From<query::PixelMetadata> for PixelMetadataRequest {
|
||||
Self {
|
||||
id,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
request,
|
||||
}
|
||||
}
|
||||
@@ -136,7 +137,7 @@ use std::sync::{Arc, Mutex};
|
||||
#[derive(Debug)]
|
||||
pub struct PixelMetadata {
|
||||
pub value: Arc<Mutex<Option<Metadata>>>,
|
||||
pub hips_url: String,
|
||||
pub hips_cdid: CreatorDid,
|
||||
pub url: String,
|
||||
}
|
||||
use crate::Abort;
|
||||
@@ -144,7 +145,7 @@ impl<'a> From<&'a PixelMetadataRequest> for Option<PixelMetadata> {
|
||||
fn from(request: &'a PixelMetadataRequest) -> Self {
|
||||
let PixelMetadataRequest {
|
||||
request,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
..
|
||||
} = request;
|
||||
@@ -152,7 +153,7 @@ impl<'a> From<&'a PixelMetadataRequest> for Option<PixelMetadata> {
|
||||
let Request::<Metadata> { data, .. } = request;
|
||||
// It will always be resolved and found as we will request a well know tile (Norder0/Tile0)
|
||||
Some(PixelMetadata {
|
||||
hips_url: hips_url.clone(),
|
||||
hips_cdid: hips_cdid.clone(),
|
||||
url: url.to_string(),
|
||||
value: data.clone(),
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::downloader::query;
|
||||
use crate::renderable::CreatorDid;
|
||||
|
||||
use super::{Request, RequestType};
|
||||
use crate::downloader::QueryId;
|
||||
@@ -8,7 +9,7 @@ use moclib::qty::Hpx;
|
||||
|
||||
pub struct MOCRequest {
|
||||
//pub id: QueryId,
|
||||
pub url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
pub params: al_api::moc::MOC,
|
||||
request: Request<HEALPixCoverage>,
|
||||
}
|
||||
@@ -48,7 +49,11 @@ use wasm_bindgen::JsValue;
|
||||
impl From<query::Moc> for MOCRequest {
|
||||
// Create a tile request associated to a HiPS
|
||||
fn from(query: query::Moc) -> Self {
|
||||
let query::Moc { url, params } = query;
|
||||
let query::Moc {
|
||||
url,
|
||||
params,
|
||||
hips_cdid,
|
||||
} = query;
|
||||
|
||||
let url_clone = url.clone();
|
||||
|
||||
@@ -88,7 +93,8 @@ impl From<query::Moc> for MOCRequest {
|
||||
|
||||
Self {
|
||||
//id,
|
||||
url,
|
||||
//url,
|
||||
hips_cdid,
|
||||
request,
|
||||
params,
|
||||
}
|
||||
@@ -99,12 +105,12 @@ use std::sync::{Arc, Mutex};
|
||||
pub struct Moc {
|
||||
pub moc: Arc<Mutex<Option<HEALPixCoverage>>>,
|
||||
pub params: al_api::moc::MOC,
|
||||
pub url: Url,
|
||||
pub hips_cdid: Url,
|
||||
}
|
||||
|
||||
impl Moc {
|
||||
pub fn get_url(&self) -> &Url {
|
||||
&self.url
|
||||
pub fn get_hips_cdid(&self) -> &Url {
|
||||
&self.hips_cdid
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +118,7 @@ impl<'a> From<&'a MOCRequest> for Option<Moc> {
|
||||
fn from(request: &'a MOCRequest) -> Self {
|
||||
let MOCRequest {
|
||||
request,
|
||||
url,
|
||||
hips_cdid,
|
||||
params,
|
||||
..
|
||||
} = request;
|
||||
@@ -121,7 +127,7 @@ impl<'a> From<&'a MOCRequest> for Option<Moc> {
|
||||
Some(Moc {
|
||||
// This is a clone on a Arc, it is supposed to be fast
|
||||
moc: data.clone(),
|
||||
url: url.clone(),
|
||||
hips_cdid: hips_cdid.clone(),
|
||||
params: params.clone(),
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -95,7 +95,7 @@ impl RequestType {
|
||||
RequestType::Tile(request) => &request.id,
|
||||
RequestType::Allsky(request) => &request.id,
|
||||
RequestType::PixelMetadata(request) => &request.id,
|
||||
RequestType::Moc(request) => &request.url,
|
||||
RequestType::Moc(request) => &request.hips_cdid,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,12 +125,12 @@ pub enum Resource {
|
||||
}
|
||||
|
||||
impl Resource {
|
||||
pub fn url(&self) -> &Url {
|
||||
pub fn id(&self) -> &String {
|
||||
match self {
|
||||
Resource::Tile(tile) => tile.get_url(),
|
||||
Resource::Allsky(allsky) => allsky.get_url(),
|
||||
Resource::PixelMetadata(PixelMetadata { url, .. }) => url,
|
||||
Resource::Moc(moc) => moc.get_url(),
|
||||
Resource::Tile(tile) => tile.get_hips_cdid(),
|
||||
Resource::Allsky(allsky) => allsky.get_hips_cdid(),
|
||||
Resource::PixelMetadata(PixelMetadata { hips_cdid, .. }) => hips_cdid,
|
||||
Resource::Moc(moc) => moc.get_hips_cdid(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::healpix::cell::HEALPixCell;
|
||||
use crate::renderable::CreatorDid;
|
||||
use al_core::image::format::{ChannelType, ImageFormatType, RGB8U, RGBA8U};
|
||||
|
||||
use crate::downloader::query;
|
||||
@@ -12,7 +13,7 @@ pub struct TileRequest {
|
||||
pub id: QueryId,
|
||||
|
||||
cell: HEALPixCell,
|
||||
hips_url: Url,
|
||||
hips_cdid: CreatorDid,
|
||||
url: Url,
|
||||
format: ImageFormatType,
|
||||
|
||||
@@ -57,7 +58,7 @@ impl From<query::Tile> for TileRequest {
|
||||
format,
|
||||
cell,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
id,
|
||||
} = query;
|
||||
|
||||
@@ -177,7 +178,7 @@ impl From<query::Tile> for TileRequest {
|
||||
cell,
|
||||
format,
|
||||
id,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
request,
|
||||
}
|
||||
@@ -191,7 +192,7 @@ pub struct Tile {
|
||||
pub time_req: Time,
|
||||
pub cell: HEALPixCell,
|
||||
pub format: ImageFormatType,
|
||||
hips_url: Url,
|
||||
hips_cdid: CreatorDid,
|
||||
url: Url,
|
||||
}
|
||||
|
||||
@@ -203,8 +204,8 @@ impl Tile {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_hips_url(&self) -> &Url {
|
||||
&self.hips_url
|
||||
pub fn get_hips_cdid(&self) -> &CreatorDid {
|
||||
&self.hips_cdid
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -228,7 +229,7 @@ impl<'a> From<&'a TileRequest> for Option<Tile> {
|
||||
let TileRequest {
|
||||
cell,
|
||||
request,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
format,
|
||||
..
|
||||
@@ -242,7 +243,7 @@ impl<'a> From<&'a TileRequest> for Option<Tile> {
|
||||
time_req: *time_request,
|
||||
// This is a clone on a Arc, it is supposed to be fast
|
||||
image: data.clone(),
|
||||
hips_url: hips_url.clone(),
|
||||
hips_cdid: hips_cdid.clone(),
|
||||
url: url.clone(),
|
||||
format: *format,
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ pub mod label;
|
||||
pub mod meridian;
|
||||
pub mod parallel;
|
||||
|
||||
use crate::grid::parallel::Parallel;
|
||||
use crate::math::projection::coo_space::XYScreen;
|
||||
use crate::Abort;
|
||||
|
||||
@@ -31,6 +32,9 @@ pub struct ProjetedGrid {
|
||||
fmt: angle::SerializeFmt,
|
||||
|
||||
line_style: line::Style,
|
||||
|
||||
meridians: Vec<Meridian>,
|
||||
parallels: Vec<Parallel>,
|
||||
}
|
||||
|
||||
use crate::shader::ShaderManager;
|
||||
@@ -40,6 +44,8 @@ use crate::renderable::line::RasterizedLineRenderer;
|
||||
use crate::renderable::text::TextRenderManager;
|
||||
use web_sys::HtmlElement;
|
||||
|
||||
use self::meridian::Meridian;
|
||||
|
||||
impl ProjetedGrid {
|
||||
pub fn new(aladin_div: &HtmlElement) -> Result<ProjetedGrid, JsValue> {
|
||||
let text_renderer = TextRenderManager::new(aladin_div)?;
|
||||
@@ -56,6 +62,8 @@ impl ProjetedGrid {
|
||||
let line_style = line::Style::None;
|
||||
let fmt = angle::SerializeFmt::DMS;
|
||||
let thickness = 2.0;
|
||||
let meridians = Vec::new();
|
||||
let parallels = Vec::new();
|
||||
|
||||
let grid = ProjetedGrid {
|
||||
color,
|
||||
@@ -66,6 +74,8 @@ impl ProjetedGrid {
|
||||
thickness,
|
||||
|
||||
text_renderer,
|
||||
meridians,
|
||||
parallels,
|
||||
fmt,
|
||||
};
|
||||
// Initialize the vertices & labels
|
||||
@@ -126,9 +136,9 @@ impl ProjetedGrid {
|
||||
if let Some(enabled) = enabled {
|
||||
self.enabled = enabled;
|
||||
|
||||
if !self.enabled {
|
||||
/*if !self.enabled {
|
||||
self.text_renderer.clear_text_canvas();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -147,7 +157,7 @@ impl ProjetedGrid {
|
||||
let step_line_px = max_dim_px * 0.2;
|
||||
|
||||
// update meridians
|
||||
let meridians = {
|
||||
self.meridians = {
|
||||
// Select the good step with a binary search
|
||||
let step_lon_precised =
|
||||
(bbox.get_lon_size() as f64) * step_line_px / (camera.get_width() as f64);
|
||||
@@ -173,7 +183,7 @@ impl ProjetedGrid {
|
||||
meridians
|
||||
};
|
||||
|
||||
let parallels = {
|
||||
self.parallels = {
|
||||
let step_lat_precised =
|
||||
(bbox.get_lat_size() as f64) * step_line_px / (camera.get_height() as f64);
|
||||
let step_lat = select_fixed_step(step_lat_precised);
|
||||
@@ -196,11 +206,12 @@ impl ProjetedGrid {
|
||||
};
|
||||
|
||||
// update the line buffers
|
||||
let paths = meridians
|
||||
let paths = self
|
||||
.meridians
|
||||
.iter()
|
||||
.map(|meridian| meridian.get_lines_vertices())
|
||||
.chain(
|
||||
parallels
|
||||
self.parallels
|
||||
.iter()
|
||||
.map(|parallel| parallel.get_lines_vertices()),
|
||||
)
|
||||
@@ -213,12 +224,16 @@ impl ProjetedGrid {
|
||||
let m = camera.get_screen_size().magnitude();
|
||||
rasterizer.add_stroke_paths(paths, self.thickness, &self.color, &self.line_style);
|
||||
|
||||
// update labels
|
||||
if self.show_labels {
|
||||
let labels = meridians
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn draw_labels(&mut self, camera: &CameraViewPort) -> Result<(), JsValue> {
|
||||
if self.enabled && self.show_labels {
|
||||
let labels = self
|
||||
.meridians
|
||||
.iter()
|
||||
.filter_map(|m| m.get_label())
|
||||
.chain(parallels.iter().filter_map(|p| p.get_label()));
|
||||
.chain(self.parallels.iter().filter_map(|p| p.get_label()));
|
||||
|
||||
let dpi = camera.get_dpi();
|
||||
self.text_renderer.begin();
|
||||
|
||||
@@ -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<u64, Hpx<u64>>;
|
||||
|
||||
use crate::healpix::cell::HEALPixCell;
|
||||
@@ -29,8 +33,12 @@ impl HEALPixCoverage {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ extern "C" {
|
||||
#[macro_use]
|
||||
mod utils;
|
||||
|
||||
use al_core::log::console_log;
|
||||
use math::projection::*;
|
||||
use renderable::coverage::moc::MOC;
|
||||
//use votable::votable::VOTableWrapper;
|
||||
@@ -165,13 +166,10 @@ impl WebClient {
|
||||
let shaders = ShaderManager::new(&gl, shaders).unwrap_abort();
|
||||
|
||||
// Event listeners callbacks
|
||||
let callback_position_changed = js_sys::Function::new_no_args("");
|
||||
//let callback_position_changed = js_sys::Function::new_no_args("");
|
||||
let app = App::new(
|
||||
&gl,
|
||||
aladin_div,
|
||||
shaders,
|
||||
resources,
|
||||
callback_position_changed,
|
||||
&gl, aladin_div, shaders, resources,
|
||||
//callback_position_changed,
|
||||
)?;
|
||||
|
||||
let dt = DeltaTime::zero();
|
||||
@@ -181,9 +179,14 @@ impl WebClient {
|
||||
Ok(webclient)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = setCallbackPositionChanged)]
|
||||
/*#[wasm_bindgen(js_name = setCallbackPositionChanged)]
|
||||
pub fn set_callback_position_changed(&mut self, callback: js_sys::Function) {
|
||||
self.app.set_callback_position_changed(callback);
|
||||
}*/
|
||||
|
||||
#[wasm_bindgen(js_name = isInerting)]
|
||||
pub fn is_inerting(&self) -> bool {
|
||||
return self.app.is_inerting();
|
||||
}
|
||||
|
||||
/// Update the view
|
||||
@@ -363,11 +366,11 @@ impl WebClient {
|
||||
/// * If the number of surveys is greater than 4. For the moment, due to the limitations
|
||||
/// of WebGL2 texture units on some architectures, the total number of surveys rendered is
|
||||
/// limited to 4.
|
||||
#[wasm_bindgen(js_name = addImageSurvey)]
|
||||
pub fn add_image_survey(&mut self, hips: JsValue) -> Result<(), JsValue> {
|
||||
#[wasm_bindgen(js_name = addImageHiPS)]
|
||||
pub fn add_image_hips(&mut self, hips: JsValue) -> Result<(), JsValue> {
|
||||
// Deserialize the survey objects that compose the survey
|
||||
let hips = serde_wasm_bindgen::from_value(hips)?;
|
||||
self.app.add_image_survey(hips)?;
|
||||
self.app.add_image_hips(hips)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -404,8 +407,8 @@ impl WebClient {
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = setHiPSUrl)]
|
||||
pub fn set_hips_url(&mut self, past_url: String, new_url: String) -> Result<(), JsValue> {
|
||||
self.app.set_hips_url(past_url, new_url)
|
||||
pub fn set_hips_url(&mut self, cdid: String, new_url: String) -> Result<(), JsValue> {
|
||||
self.app.set_hips_url(&cdid, new_url)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = getImageMetadata)]
|
||||
@@ -422,8 +425,8 @@ impl WebClient {
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = setImageSurveyUrl)]
|
||||
pub fn set_survey_url(&mut self, past_url: String, new_url: String) -> Result<(), JsValue> {
|
||||
self.app.set_survey_url(past_url, new_url)
|
||||
pub fn set_survey_url(&mut self, cdid: String, new_url: String) -> Result<(), JsValue> {
|
||||
self.app.set_survey_url(&cdid, new_url)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = setBackgroundColor)]
|
||||
@@ -442,7 +445,7 @@ impl WebClient {
|
||||
/// * `green` - Green amount (between 0.0 and 1.0)
|
||||
/// * `blue` - Blue amount (between 0.0 and 1.0)
|
||||
/// * `alpha` - Alpha amount (between 0.0 and 1.0)
|
||||
#[wasm_bindgen(js_name = setGridConfig)]
|
||||
#[wasm_bindgen(js_name = setGridOptions)]
|
||||
pub fn set_grid_cfg(&mut self, cfg: JsValue) -> Result<(), JsValue> {
|
||||
let cfg = serde_wasm_bindgen::from_value(cfg)?;
|
||||
|
||||
@@ -484,6 +487,13 @@ impl WebClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = setInertia)]
|
||||
pub fn set_inertia(&mut self, inertia: bool) -> Result<(), JsValue> {
|
||||
self.app.set_inertia(inertia);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the absolute orientation of the view
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -615,8 +625,23 @@ 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]>> {
|
||||
#[wasm_bindgen(js_name = world2pix)]
|
||||
pub fn world_to_pixel(
|
||||
&self,
|
||||
mut lon: f64,
|
||||
mut lat: f64,
|
||||
frame: Option<CooSystem>,
|
||||
) -> Option<Box<[f64]>> {
|
||||
if let Some(frame) = frame {
|
||||
// first convert the coo to the view frame
|
||||
use crate::math::lonlat::LonLat;
|
||||
let xyz =
|
||||
LonLatT::new(lon.to_radians().to_angle(), lat.to_radians().to_angle()).vector();
|
||||
let lonlat = coosys::apply_coo_system(frame, CooSystem::ICRS, &xyz).lonlat();
|
||||
lon = lonlat.lon().to_degrees();
|
||||
lat = lonlat.lat().to_degrees();
|
||||
}
|
||||
|
||||
self.app
|
||||
.world_to_screen(lon, lat)
|
||||
.map(|v| Box::new([v.x, v.y]) as Box<[f64]>)
|
||||
@@ -690,11 +715,24 @@ impl WebClient {
|
||||
///
|
||||
/// * `pos_x` - The x screen coordinate in pixels
|
||||
/// * `pos_y` - The y screen coordinate in pixels
|
||||
#[wasm_bindgen(js_name = screenToWorld)]
|
||||
pub fn screen_to_world(&self, pos_x: f64, pos_y: f64) -> Option<Box<[f64]>> {
|
||||
/// * `frame` - If not given, the coo given will be in the current view frame
|
||||
#[wasm_bindgen(js_name = pix2world)]
|
||||
pub fn pixel_to_world(
|
||||
&self,
|
||||
pos_x: f64,
|
||||
pos_y: f64,
|
||||
frame: Option<CooSystem>,
|
||||
) -> Option<Box<[f64]>> {
|
||||
self.app
|
||||
.screen_to_world(&Vector2::new(pos_x, pos_y))
|
||||
.map(|lonlat| {
|
||||
.map(|mut lonlat| {
|
||||
if let Some(frame) = frame {
|
||||
use crate::math::lonlat::LonLat;
|
||||
let xyz = lonlat.vector();
|
||||
lonlat =
|
||||
coosys::apply_coo_system(self.app.get_coo_system(), frame, &xyz).lonlat();
|
||||
}
|
||||
|
||||
let lon_deg: ArcDeg<f64> = lonlat.lon().into();
|
||||
let lat_deg: ArcDeg<f64> = lonlat.lat().into();
|
||||
|
||||
@@ -927,6 +965,11 @@ impl WebClient {
|
||||
self.app.is_rendering()
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = drawGridLabels)]
|
||||
pub fn draw_grid_labels(&mut self) -> Result<(), JsValue> {
|
||||
self.app.draw_grid_labels()
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = parseVOTable)]
|
||||
pub fn parse_votable(&mut self, s: &str) -> Result<JsValue, JsValue> {
|
||||
/*let votable: VOTableWrapper<votable::impls::mem::InMemTableDataRows> =
|
||||
|
||||
@@ -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<NodeEdgeNeigs>,
|
||||
}
|
||||
|
||||
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<Ordinal
|
||||
|
||||
None
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -17,11 +17,17 @@ use crate::renderable::line::RasterizedLineRenderer;
|
||||
use al_api::color::ColorRGBA;
|
||||
use al_api::coo_system::CooSystem;
|
||||
|
||||
use moclib::moc::RangeMOCIntoIterator;
|
||||
use moclib::moc::RangeMOCIterator;
|
||||
|
||||
use super::mode::Node;
|
||||
|
||||
use crate::HEALPixCell;
|
||||
use cgmath::Vector2;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use healpix::compass_point::OrdinalMap;
|
||||
|
||||
pub struct MOC {
|
||||
pub sky_fraction: f32,
|
||||
pub max_order: u8,
|
||||
@@ -149,11 +155,34 @@ pub enum RenderModeType {
|
||||
|
||||
impl MOCIntern {
|
||||
fn new(moc: &HEALPixCoverage, mode: RenderModeType) -> 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::<Vec<_>>();
|
||||
|
||||
let hpx_idx_vec = IdxVec::from_hpx_cells(nodes.iter().map(|n| &n.cell));
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -4,14 +4,15 @@ pub mod uv;
|
||||
|
||||
use al_api::hips::ImageExt;
|
||||
use al_api::hips::ImageMetadata;
|
||||
|
||||
use al_core::colormap::Colormap;
|
||||
use al_core::colormap::Colormaps;
|
||||
use al_core::image::format::ChannelType;
|
||||
use al_core::image::format::ImageFormatType;
|
||||
use al_core::image::Image;
|
||||
use al_core::log::console_log;
|
||||
use al_core::shader::Shader;
|
||||
use al_core::webgl_ctx::GlWrapper;
|
||||
use al_core::Texture2DArray;
|
||||
use al_core::VecData;
|
||||
use al_core::VertexArrayObject;
|
||||
use al_core::WebGlContext;
|
||||
@@ -30,6 +31,7 @@ use crate::math::angle::ToAngle;
|
||||
use crate::math::lonlat::LonLat;
|
||||
use crate::time::Time;
|
||||
use al_core::log;
|
||||
use std::collections::HashSet;
|
||||
|
||||
// Recursively compute the number of subdivision needed for a cell
|
||||
// to not be too much skewed
|
||||
@@ -42,6 +44,7 @@ use uv::{TileCorner, TileUVW};
|
||||
|
||||
use cgmath::{Matrix, Matrix4};
|
||||
use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen::JsValue;
|
||||
use web_sys::WebGl2RenderingContext;
|
||||
|
||||
@@ -282,9 +285,7 @@ pub fn get_raster_shader<'a>(
|
||||
shaders: &'a mut ShaderManager,
|
||||
config: &HiPSConfig,
|
||||
) -> Result<&'a Shader, JsValue> {
|
||||
let colored_hips = config.is_colored();
|
||||
|
||||
if colored_hips && cmap.label() == "native" {
|
||||
if config.get_format().is_colored() && cmap.label() == "native" {
|
||||
crate::shader::get_shader(gl, shaders, "RasterizerVS", "RasterizerColorFS")
|
||||
} else {
|
||||
if config.tex_storing_unsigned_int {
|
||||
@@ -318,8 +319,8 @@ pub fn get_raytracer_shader<'a>(
|
||||
shaders: &'a mut ShaderManager,
|
||||
config: &HiPSConfig,
|
||||
) -> Result<&'a Shader, JsValue> {
|
||||
let colored_hips = config.is_colored();
|
||||
if colored_hips && cmap.label() == "native" {
|
||||
//let colored_hips = config.is_colored();
|
||||
if config.get_format().is_colored() && cmap.label() == "native" {
|
||||
crate::shader::get_shader(gl, shaders, "RayTracerVS", "RayTracerColorFS")
|
||||
} else {
|
||||
if config.tex_storing_unsigned_int {
|
||||
@@ -382,11 +383,7 @@ pub struct HiPS {
|
||||
}
|
||||
|
||||
impl HiPS {
|
||||
pub fn new(
|
||||
config: HiPSConfig,
|
||||
gl: &WebGlContext,
|
||||
_camera: &CameraViewPort,
|
||||
) -> Result<Self, JsValue> {
|
||||
pub fn new(config: HiPSConfig, gl: &WebGlContext) -> Result<Self, JsValue> {
|
||||
let mut vao = VertexArrayObject::new(gl);
|
||||
|
||||
// layout (location = 0) in vec2 lonlat;
|
||||
@@ -498,8 +495,6 @@ impl HiPS {
|
||||
.unbind();
|
||||
|
||||
let num_idx = 0;
|
||||
//let min_depth_tile = config.get_min_depth_tile();
|
||||
|
||||
let textures = ImageSurveyTextures::new(gl, config)?;
|
||||
|
||||
let gl = gl.clone();
|
||||
@@ -530,11 +525,13 @@ impl HiPS {
|
||||
pub fn look_for_new_tiles<'a>(
|
||||
&'a mut self,
|
||||
camera: &'a mut CameraViewPort,
|
||||
) -> Option<impl Iterator<Item = &'a HEALPixCell> + 'a> {
|
||||
proj: &ProjectionType,
|
||||
) -> Option<impl Iterator<Item = HEALPixCell> + 'a> {
|
||||
// do not add tiles if the view is already at depth 0
|
||||
let depth_tile = (camera.get_texture_depth() + self.get_config().delta_depth())
|
||||
let mut depth_tile = (camera.get_texture_depth() + self.get_config().delta_depth())
|
||||
.min(self.get_config().get_max_depth_tile())
|
||||
.max(self.get_config().get_min_depth_tile());
|
||||
let dd = self.get_config().delta_depth();
|
||||
|
||||
//let min_depth_tile = self.get_min_depth_tile();
|
||||
//let delta_depth = self.get_config().delta_depth();
|
||||
@@ -549,13 +546,31 @@ impl HiPS {
|
||||
//if depth_tile >= min_bound_depth {
|
||||
//let depth_tile = depth_tile.max(min_bound_depth);
|
||||
let survey_frame = self.get_config().get_frame();
|
||||
let mut already_considered_tiles = HashSet::new();
|
||||
|
||||
// raytracer is rendering and the shader only renders HPX texture cells of depth 0
|
||||
if camera.is_raytracing(proj) {
|
||||
depth_tile = 0;
|
||||
}
|
||||
|
||||
let tile_cells_iter = camera
|
||||
.get_hpx_cells(depth_tile, survey_frame)
|
||||
//.flat_map(move |cell| {
|
||||
// let texture_cell = cell.get_texture_cell(delta_depth);
|
||||
// texture_cell.get_tile_cells(delta_depth)
|
||||
//})
|
||||
.flat_map(move |tile_cell| {
|
||||
let tex_cell = tile_cell.get_texture_cell(dd);
|
||||
//console_log(&format!("{:?}, dd:{:?}", tex_cell, dd));
|
||||
tex_cell.get_tile_cells(dd)
|
||||
})
|
||||
.filter(move |tile_cell| {
|
||||
if already_considered_tiles.contains(tile_cell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
already_considered_tiles.insert(*tile_cell);
|
||||
|
||||
if let Some(moc) = self.footprint_moc.as_ref() {
|
||||
moc.intersects_cell(tile_cell) && !self.update_priority_tile(tile_cell)
|
||||
} else {
|
||||
@@ -589,13 +604,8 @@ impl HiPS {
|
||||
self.textures.contains_tile(cell)
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
raytracer: &RayTracer,
|
||||
camera: &mut CameraViewPort,
|
||||
projection: &ProjectionType,
|
||||
) {
|
||||
let raytracing = raytracer.is_rendering(camera);
|
||||
pub fn update(&mut self, camera: &mut CameraViewPort, projection: &ProjectionType) {
|
||||
let raytracing = camera.is_raytracing(projection);
|
||||
|
||||
let vertices_recomputation_needed =
|
||||
!raytracing && (self.textures.reset_available_tiles() | camera.has_moved());
|
||||
@@ -618,7 +628,7 @@ impl HiPS {
|
||||
self.textures.set_format(&self.gl, ext)
|
||||
}
|
||||
|
||||
pub fn get_fading_factor(&self) -> f32 {
|
||||
/*pub fn get_fading_factor(&self) -> f32 {
|
||||
self.textures
|
||||
.start_time
|
||||
.map(|start_time| {
|
||||
@@ -626,7 +636,7 @@ impl HiPS {
|
||||
fading.clamp(0.0, 1.0)
|
||||
})
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
}*/
|
||||
|
||||
pub fn is_allsky(&self) -> bool {
|
||||
self.textures.config().is_allsky
|
||||
@@ -718,15 +728,22 @@ impl HiPS {
|
||||
|
||||
if let Some(cell) = cell {
|
||||
let texture_to_draw = if self.textures.contains(cell) {
|
||||
let parent_cell = self.textures.get_nearest_parent(cell);
|
||||
|
||||
if let Some(ending_cell_in_tex) = self.textures.get(cell) {
|
||||
if let Some(starting_cell_in_tex) = self.textures.get(&parent_cell) {
|
||||
Some(TextureToDraw::new(
|
||||
starting_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
if let Some(parent_cell) = self.textures.get_nearest_parent(cell) {
|
||||
if let Some(starting_cell_in_tex) = self.textures.get(&parent_cell) {
|
||||
Some(TextureToDraw::new(
|
||||
starting_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
} else {
|
||||
// no blending here
|
||||
Some(TextureToDraw::new(
|
||||
ending_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Some(TextureToDraw::new(
|
||||
ending_cell_in_tex,
|
||||
@@ -738,22 +755,36 @@ impl HiPS {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
let parent_cell = self.textures.get_nearest_parent(cell);
|
||||
let grand_parent_cell = self.textures.get_nearest_parent(&parent_cell);
|
||||
|
||||
if let Some(ending_cell_in_tex) = self.textures.get(&parent_cell) {
|
||||
if let Some(starting_cell_in_tex) = self.textures.get(&grand_parent_cell) {
|
||||
Some(TextureToDraw::new(
|
||||
starting_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
if let Some(parent_cell) = self.textures.get_nearest_parent(cell) {
|
||||
if let Some(ending_cell_in_tex) = self.textures.get(&parent_cell) {
|
||||
if let Some(grand_parent_cell) =
|
||||
self.textures.get_nearest_parent(&parent_cell)
|
||||
{
|
||||
if let Some(starting_cell_in_tex) =
|
||||
self.textures.get(&grand_parent_cell)
|
||||
{
|
||||
Some(TextureToDraw::new(
|
||||
starting_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
} else {
|
||||
// no blending
|
||||
Some(TextureToDraw::new(
|
||||
ending_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Some(TextureToDraw::new(
|
||||
ending_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Some(TextureToDraw::new(
|
||||
ending_cell_in_tex,
|
||||
ending_cell_in_tex,
|
||||
cell,
|
||||
))
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
@@ -978,6 +1009,7 @@ impl HiPS {
|
||||
camera: &CameraViewPort,
|
||||
raytracer: &RayTracer,
|
||||
cfg: &ImageMetadata,
|
||||
proj: &ProjectionType,
|
||||
) -> Result<(), JsValue> {
|
||||
// Get the coo system transformation matrix
|
||||
let selected_frame = camera.get_coo_system();
|
||||
@@ -989,7 +1021,7 @@ impl HiPS {
|
||||
let w2v = c * (*camera.get_w2m());
|
||||
let v2w = w2v.transpose();
|
||||
|
||||
let raytracing = raytracer.is_rendering(camera);
|
||||
let raytracing = camera.is_raytracing(proj);
|
||||
let config = self.get_config();
|
||||
|
||||
self.gl.enable(WebGl2RenderingContext::BLEND);
|
||||
@@ -1002,8 +1034,8 @@ impl HiPS {
|
||||
} = cfg;
|
||||
|
||||
// Add starting fading
|
||||
let fading = self.get_fading_factor();
|
||||
let opacity = opacity * fading;
|
||||
//let fading = self.get_fading_factor();
|
||||
//let opacity = opacity * fading;
|
||||
// Get the colormap from the color
|
||||
let cmap = colormaps.get(color.cmap_name.as_ref());
|
||||
|
||||
@@ -1021,7 +1053,7 @@ impl HiPS {
|
||||
.attach_uniform("model", &w2v)
|
||||
.attach_uniform("inv_model", &v2w)
|
||||
.attach_uniform("current_time", &utils::get_current_time())
|
||||
.attach_uniform("opacity", &opacity)
|
||||
.attach_uniform("opacity", opacity)
|
||||
.attach_uniforms_from(colormaps);
|
||||
|
||||
raytracer.draw(&shader);
|
||||
@@ -1049,7 +1081,7 @@ impl HiPS {
|
||||
.attach_uniform("model", &w2v)
|
||||
.attach_uniform("inv_model", &v2w)
|
||||
.attach_uniform("current_time", &utils::get_current_time())
|
||||
.attach_uniform("opacity", &opacity)
|
||||
.attach_uniform("opacity", opacity)
|
||||
.attach_uniforms_from(colormaps)
|
||||
.bind_vertex_array_object_ref(&self.vao)
|
||||
.draw_elements_with_i32(
|
||||
|
||||
@@ -239,11 +239,4 @@ impl RayTracer {
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_rendering(&self, camera: &CameraViewPort) -> bool {
|
||||
// Check whether the tile depth is 0 for square projection
|
||||
// definition domains i.e. Mercator
|
||||
let depth = camera.get_texture_depth();
|
||||
camera.is_allsky() || depth == 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ pub mod utils;
|
||||
use crate::renderable::image::Image;
|
||||
|
||||
use al_core::image::format::ChannelType;
|
||||
use al_core::Texture2DArray;
|
||||
pub use hips::HiPS;
|
||||
|
||||
pub use catalog::Manager;
|
||||
@@ -20,6 +21,7 @@ use al_api::hips::ImageMetadata;
|
||||
use al_api::image::ImageParams;
|
||||
|
||||
use al_core::colormap::Colormaps;
|
||||
use al_core::image::format::NUM_CHANNELS;
|
||||
use al_core::shader::Shader;
|
||||
use al_core::SliceData;
|
||||
use al_core::VertexArrayObject;
|
||||
@@ -38,6 +40,7 @@ use hips::raytracing::RayTracer;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen::JsValue;
|
||||
use web_sys::WebGl2RenderingContext;
|
||||
|
||||
@@ -47,15 +50,17 @@ pub trait Renderer {
|
||||
}
|
||||
|
||||
pub(crate) type Url = String;
|
||||
pub(crate) type CreatorDid = String;
|
||||
|
||||
type LayerId = String;
|
||||
pub struct Layers {
|
||||
// Surveys to query
|
||||
surveys: HashMap<Url, HiPS>,
|
||||
surveys: HashMap<CreatorDid, HiPS>,
|
||||
images: HashMap<Url, Image>,
|
||||
// The meta data associated with a layer
|
||||
meta: HashMap<LayerId, ImageMetadata>,
|
||||
// Hashmap between urls and layers
|
||||
urls: HashMap<LayerId, Url>,
|
||||
// Hashmap between FITS image urls/HiPS creatorDid and layers
|
||||
ids: HashMap<LayerId, String>,
|
||||
// Layers given in a specific order to draw
|
||||
layers: Vec<LayerId>,
|
||||
|
||||
@@ -112,7 +117,7 @@ impl Layers {
|
||||
let surveys = HashMap::new();
|
||||
let images = HashMap::new();
|
||||
let meta = HashMap::new();
|
||||
let urls = HashMap::new();
|
||||
let ids = HashMap::new();
|
||||
let layers = Vec::new();
|
||||
|
||||
// - The raytracer is a mesh covering the view. Each pixel of this mesh
|
||||
@@ -164,7 +169,7 @@ impl Layers {
|
||||
images,
|
||||
|
||||
meta,
|
||||
urls,
|
||||
ids,
|
||||
layers,
|
||||
|
||||
raytracer,
|
||||
@@ -176,19 +181,19 @@ impl Layers {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_survey_url(&mut self, past_url: String, new_url: String) -> Result<(), JsValue> {
|
||||
if let Some(mut survey) = self.surveys.remove(&past_url) {
|
||||
pub fn set_survey_url(&mut self, cdid: &CreatorDid, new_url: String) -> Result<(), JsValue> {
|
||||
if let Some(mut survey) = self.surveys.get_mut(cdid) {
|
||||
// update the root_url
|
||||
survey.get_config_mut().set_root_url(new_url.clone());
|
||||
|
||||
self.surveys.insert(new_url.clone(), survey);
|
||||
//self.surveys.insert(new_url.clone(), survey);
|
||||
|
||||
// update all the layer urls
|
||||
for url in self.urls.values_mut() {
|
||||
if *url == past_url {
|
||||
*url = new_url.clone();
|
||||
/*for id in self.ids.values_mut() {
|
||||
if *id == past_url {
|
||||
*id = new_url.clone();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -212,6 +217,10 @@ impl Layers {
|
||||
self.background_color = color;
|
||||
}
|
||||
|
||||
pub fn get_raytracer(&self) -> &RayTracer {
|
||||
&self.raytracer
|
||||
}
|
||||
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
camera: &mut CameraViewPort,
|
||||
@@ -220,15 +229,15 @@ impl Layers {
|
||||
projection: &ProjectionType,
|
||||
) -> Result<(), JsValue> {
|
||||
let raytracer = &self.raytracer;
|
||||
let raytracing = raytracer.is_rendering(camera);
|
||||
let raytracing = camera.is_raytracing(projection);
|
||||
|
||||
// Check whether a survey to plot is allsky
|
||||
// if neither are, we draw a font
|
||||
// if there are, we do not draw nothing
|
||||
let render_background_color = !self.layers.iter().any(|layer| {
|
||||
let meta = self.meta.get(layer).unwrap_abort();
|
||||
let url = self.urls.get(layer).unwrap_abort();
|
||||
if let Some(survey) = self.surveys.get(url) {
|
||||
let cdid = self.ids.get(layer).unwrap_abort();
|
||||
if let Some(survey) = self.surveys.get(cdid) {
|
||||
let hips_cfg = survey.get_config();
|
||||
(survey.is_allsky() || hips_cfg.get_format().get_channel() == ChannelType::RGB8U)
|
||||
&& meta.opacity == 1.0
|
||||
@@ -270,8 +279,8 @@ impl Layers {
|
||||
for (idx_layer, layer) in self.layers.iter().enumerate().skip(1) {
|
||||
let meta = self.meta.get(layer).expect("Meta should be found");
|
||||
|
||||
let url = self.urls.get(layer).expect("Url should be found");
|
||||
if let Some(survey) = self.surveys.get_mut(url) {
|
||||
let id = self.ids.get(layer).expect("Url should be found");
|
||||
if let Some(survey) = self.surveys.get_mut(id) {
|
||||
let hips_cfg = survey.get_config();
|
||||
|
||||
let fully_covering_survey = (survey.is_allsky()
|
||||
@@ -288,13 +297,13 @@ impl Layers {
|
||||
let draw_opt = self.meta.get(layer).expect("Meta should be found");
|
||||
if draw_opt.visible() {
|
||||
// 1. Update the survey if necessary
|
||||
let url = self.urls.get(layer).expect("Url should be found");
|
||||
if let Some(survey) = self.surveys.get_mut(url) {
|
||||
survey.update(&self.raytracer, camera, projection);
|
||||
let id = self.ids.get(layer).expect("Url should be found");
|
||||
if let Some(survey) = self.surveys.get_mut(id) {
|
||||
survey.update(camera, projection);
|
||||
|
||||
// 2. Draw it if its opacity is not null
|
||||
survey.draw(shaders, colormaps, camera, raytracer, draw_opt)?;
|
||||
} else if let Some(image) = self.images.get_mut(url) {
|
||||
survey.draw(shaders, colormaps, camera, raytracer, draw_opt, projection)?;
|
||||
} else if let Some(image) = self.images.get_mut(id) {
|
||||
image.update(camera, projection)?;
|
||||
|
||||
// 2. Draw it if its opacity is not null
|
||||
@@ -326,7 +335,7 @@ impl Layers {
|
||||
));
|
||||
// Color configs, and urls are indexed by layer
|
||||
self.meta.remove(layer).ok_or(err_layer_not_found.clone())?;
|
||||
let url = self.urls.remove(layer).ok_or(err_layer_not_found.clone())?;
|
||||
let id = self.ids.remove(layer).ok_or(err_layer_not_found.clone())?;
|
||||
// layer from layers does also need to be removed
|
||||
let id_layer = self
|
||||
.layers
|
||||
@@ -342,26 +351,26 @@ impl Layers {
|
||||
camera.set_longitude_reversed(longitude_reversed, proj);
|
||||
|
||||
// Check if the url is still used
|
||||
let url_still_used = self.urls.values().any(|rem_url| rem_url == &url);
|
||||
if url_still_used {
|
||||
let id_still_used = self.ids.values().any(|rem_id| rem_id == &id);
|
||||
if id_still_used {
|
||||
// Keep the resource whether it is a HiPS or a FITS
|
||||
Ok(id_layer)
|
||||
} else {
|
||||
// Resource not needed anymore
|
||||
if let Some(s) = self.surveys.remove(&url) {
|
||||
if let Some(s) = self.surveys.remove(&id) {
|
||||
// A HiPS has been found and removed
|
||||
let hips_frame = s.get_config().get_frame();
|
||||
// remove the frame
|
||||
camera.unregister_view_frame(hips_frame, proj);
|
||||
|
||||
Ok(id_layer)
|
||||
} else if let Some(_) = self.images.remove(&url) {
|
||||
} else if let Some(_) = self.images.remove(&id) {
|
||||
// A FITS image has been found and removed
|
||||
Ok(id_layer)
|
||||
} else {
|
||||
Err(JsValue::from_str(&format!(
|
||||
"Url found {:?} is associated to no surveys.",
|
||||
url
|
||||
id
|
||||
)))
|
||||
}
|
||||
}
|
||||
@@ -383,11 +392,11 @@ impl Layers {
|
||||
self.layers[id_layer] = new_layer.to_string();
|
||||
|
||||
let meta = self.meta.remove(layer).ok_or(err_layer_not_found.clone())?;
|
||||
let url = self.urls.remove(layer).ok_or(err_layer_not_found)?;
|
||||
let id = self.ids.remove(layer).ok_or(err_layer_not_found)?;
|
||||
|
||||
// Add the new
|
||||
self.meta.insert(new_layer.to_string(), meta);
|
||||
self.urls.insert(new_layer.to_string(), url);
|
||||
self.ids.insert(new_layer.to_string(), id);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -415,7 +424,7 @@ impl Layers {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_image_survey(
|
||||
pub fn add_image_hips(
|
||||
&mut self,
|
||||
gl: &WebGlContext,
|
||||
hips: HiPSCfg,
|
||||
@@ -451,13 +460,16 @@ impl Layers {
|
||||
camera.set_longitude_reversed(longitude_reversed, proj);
|
||||
|
||||
// 3. Add the image survey
|
||||
let url = String::from(properties.get_url());
|
||||
let creator_did = String::from(properties.get_creator_did());
|
||||
// The layer does not already exist
|
||||
// Let's check if no other hipses points to the
|
||||
// same url than `hips`
|
||||
let url_already_found = self.surveys.keys().any(|hips_url| hips_url == &url);
|
||||
let cdid_already_found = self
|
||||
.surveys
|
||||
.keys()
|
||||
.any(|hips_cdid| hips_cdid == &creator_did);
|
||||
|
||||
if !url_already_found {
|
||||
if !cdid_already_found {
|
||||
// The url is not processed yet
|
||||
let cfg = HiPSConfig::new(&properties, img_ext)?;
|
||||
|
||||
@@ -472,17 +484,17 @@ impl Layers {
|
||||
}*/
|
||||
camera.register_view_frame(cfg.get_frame(), proj);
|
||||
|
||||
let hips = HiPS::new(cfg, gl, camera)?;
|
||||
let hips = HiPS::new(cfg, gl)?;
|
||||
// add the frame to the camera
|
||||
|
||||
self.surveys.insert(url.clone(), hips);
|
||||
self.surveys.insert(creator_did.clone(), hips);
|
||||
}
|
||||
|
||||
self.urls.insert(layer.clone(), url.clone());
|
||||
self.ids.insert(layer.clone(), creator_did.clone());
|
||||
|
||||
let hips = self
|
||||
.surveys
|
||||
.get(&url)
|
||||
.get(&creator_did)
|
||||
.ok_or(JsValue::from_str("HiPS not found"))?;
|
||||
Ok(hips)
|
||||
}
|
||||
@@ -541,7 +553,7 @@ impl Layers {
|
||||
self.images.insert(url.clone(), image);
|
||||
}
|
||||
|
||||
self.urls.insert(layer.clone(), url.clone());
|
||||
self.ids.insert(layer.clone(), url.clone());
|
||||
|
||||
let fits = self
|
||||
.images
|
||||
@@ -604,39 +616,29 @@ impl Layers {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/*pub fn is_ready(&self) -> bool {
|
||||
let ready = self
|
||||
.surveys
|
||||
.iter()
|
||||
.map(|(_, survey)| survey.is_ready())
|
||||
.fold(true, |acc, x| acc & x);
|
||||
|
||||
ready
|
||||
}*/
|
||||
|
||||
// Accessors
|
||||
// HiPSes getters
|
||||
pub fn get_hips_from_layer(&self, layer: &str) -> Option<&HiPS> {
|
||||
self.urls
|
||||
self.ids
|
||||
.get(layer)
|
||||
.map(|url| self.surveys.get(url))
|
||||
.map(|cdid| self.surveys.get(cdid))
|
||||
.flatten()
|
||||
}
|
||||
|
||||
pub fn get_mut_hips_from_layer(&mut self, layer: &str) -> Option<&mut HiPS> {
|
||||
if let Some(url) = self.urls.get_mut(layer) {
|
||||
self.surveys.get_mut(url)
|
||||
if let Some(cdid) = self.ids.get_mut(layer) {
|
||||
self.surveys.get_mut(cdid)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut_hips_from_url(&mut self, root_url: &str) -> Option<&mut HiPS> {
|
||||
self.surveys.get_mut(root_url)
|
||||
pub fn get_mut_hips_from_cdid(&mut self, cdid: &str) -> Option<&mut HiPS> {
|
||||
self.surveys.get_mut(cdid)
|
||||
}
|
||||
|
||||
pub fn get_hips_from_url(&mut self, root_url: &str) -> Option<&HiPS> {
|
||||
self.surveys.get(root_url)
|
||||
pub fn get_hips_from_cdid(&mut self, cdid: &str) -> Option<&HiPS> {
|
||||
self.surveys.get(cdid)
|
||||
}
|
||||
|
||||
pub fn values_hips(&self) -> impl Iterator<Item = &HiPS> {
|
||||
@@ -649,7 +651,7 @@ impl Layers {
|
||||
|
||||
// Fits images getters
|
||||
pub fn get_mut_image_from_layer(&mut self, layer: &str) -> Option<&mut Image> {
|
||||
if let Some(url) = self.urls.get(layer) {
|
||||
if let Some(url) = self.ids.get(layer) {
|
||||
self.images.get_mut(url)
|
||||
} else {
|
||||
None
|
||||
@@ -657,7 +659,7 @@ impl Layers {
|
||||
}
|
||||
|
||||
pub fn get_image_from_layer(&self, layer: &str) -> Option<&Image> {
|
||||
self.urls
|
||||
self.ids
|
||||
.get(layer)
|
||||
.map(|url| self.images.get(url))
|
||||
.flatten()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::Renderer;
|
||||
use al_core::log::console_log;
|
||||
use web_sys::CanvasRenderingContext2d;
|
||||
|
||||
pub struct TextRenderManager {
|
||||
@@ -25,7 +26,7 @@ impl TextRenderManager {
|
||||
pub fn new(aladin_div: &HtmlElement) -> Result<Self, JsValue> {
|
||||
let canvas = aladin_div
|
||||
// Inside it, retrieve the canvas
|
||||
.get_elements_by_class_name("aladin-gridCanvas")
|
||||
.get_elements_by_class_name("aladin-catalogCanvas")
|
||||
.get_with_index(0)
|
||||
.unwrap_abort()
|
||||
.dyn_into::<web_sys::HtmlCanvasElement>()?;
|
||||
@@ -67,6 +68,7 @@ impl TextRenderManager {
|
||||
angle: A,
|
||||
) -> Result<(), JsValue> {
|
||||
self.ctx.save();
|
||||
|
||||
self.ctx
|
||||
.translate(screen_pos.x as f64, screen_pos.y as f64)?;
|
||||
|
||||
@@ -80,37 +82,19 @@ impl TextRenderManager {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
_camera: &CameraViewPort,
|
||||
_color: &ColorRGBA,
|
||||
_scale: f32,
|
||||
) -> Result<(), JsValue> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clear_text_canvas(&mut self) {
|
||||
self.ctx.clear_rect(
|
||||
0_f64,
|
||||
0_f64,
|
||||
self.canvas.width() as f64,
|
||||
self.canvas.height() as f64,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl Renderer for TextRenderManager {
|
||||
fn begin(&mut self) {
|
||||
self.ctx = self
|
||||
.canvas
|
||||
.get_context("2d")
|
||||
.unwrap_abort()
|
||||
.unwrap_abort()
|
||||
.dyn_into::<web_sys::CanvasRenderingContext2d>()
|
||||
.unwrap_abort();
|
||||
|
||||
self.clear_text_canvas();
|
||||
//self.clear_text_canvas();
|
||||
// Clear the Aladin Lite 2d canvas
|
||||
// This canvas is where catalogs, grid labels, Hpx grid are drawn
|
||||
/*self.ctx.clear_rect(
|
||||
0_f64,
|
||||
0_f64,
|
||||
self.canvas.width() as f64,
|
||||
self.canvas.height() as f64,
|
||||
);*/
|
||||
|
||||
// reset the font and color
|
||||
self.ctx
|
||||
|
||||
@@ -134,11 +134,11 @@ pub struct ImageSurveyTextures {
|
||||
size: usize,
|
||||
|
||||
pub textures: HashMap<HEALPixCell, Texture>,
|
||||
pub base_textures: [Texture; NUM_HPX_TILES_DEPTH_ZERO],
|
||||
//pub base_textures: [Texture; NUM_HPX_TILES_DEPTH_ZERO],
|
||||
//pub cutoff_values_tile: Rc<RefCell<HashMap<HEALPixCell, (f32, f32)>>>,
|
||||
|
||||
// Array of 2D textures
|
||||
texture_2d_array: Rc<Texture2DArray>,
|
||||
pub texture_2d_array: Texture2DArray,
|
||||
|
||||
// A boolean ensuring the root textures
|
||||
// have already been loaded
|
||||
@@ -146,6 +146,7 @@ pub struct ImageSurveyTextures {
|
||||
pub start_time: Option<Time>,
|
||||
|
||||
available_tiles_during_frame: bool,
|
||||
//num_base_textures: usize,
|
||||
//exec: Rc<RefCell<TaskExecutor>>,
|
||||
}
|
||||
|
||||
@@ -167,20 +168,16 @@ fn create_texture_array<F: ImageFormat>(
|
||||
}
|
||||
|
||||
impl ImageSurveyTextures {
|
||||
pub fn new(
|
||||
gl: &WebGlContext,
|
||||
config: HiPSConfig,
|
||||
//exec: Rc<RefCell<TaskExecutor>>,
|
||||
) -> Result<ImageSurveyTextures, JsValue> {
|
||||
pub fn new(gl: &WebGlContext, config: HiPSConfig) -> Result<ImageSurveyTextures, JsValue> {
|
||||
let size = config.num_textures();
|
||||
// Ensures there is at least space for the 12
|
||||
// root textures
|
||||
debug_assert!(size >= NUM_HPX_TILES_DEPTH_ZERO);
|
||||
let heap = HEALPixCellHeap::with_capacity(size - NUM_HPX_TILES_DEPTH_ZERO);
|
||||
let heap = HEALPixCellHeap::with_capacity(size);
|
||||
let textures = HashMap::with_capacity(size);
|
||||
|
||||
let now = Time::now();
|
||||
let base_textures = [
|
||||
/*let base_textures = [
|
||||
Texture::new(&HEALPixCell(0, 0), 0, now),
|
||||
Texture::new(&HEALPixCell(0, 1), 1, now),
|
||||
Texture::new(&HEALPixCell(0, 2), 2, now),
|
||||
@@ -193,34 +190,30 @@ impl ImageSurveyTextures {
|
||||
Texture::new(&HEALPixCell(0, 9), 9, now),
|
||||
Texture::new(&HEALPixCell(0, 10), 10, now),
|
||||
Texture::new(&HEALPixCell(0, 11), 11, now),
|
||||
];
|
||||
];*/
|
||||
let channel = config.get_format().get_channel();
|
||||
|
||||
#[cfg(feature = "webgl2")]
|
||||
let texture_2d_array = match channel {
|
||||
ChannelType::RGBA32F => unimplemented!(),
|
||||
ChannelType::RGB32F => unimplemented!(),
|
||||
ChannelType::RGBA8U => Rc::new(create_texture_array::<RGBA8U>(gl, &config)?),
|
||||
ChannelType::RGB8U => Rc::new(create_texture_array::<RGB8U>(gl, &config)?),
|
||||
ChannelType::R8UI => Rc::new(create_texture_array::<R8UI>(gl, &config)?),
|
||||
ChannelType::R16I => Rc::new(create_texture_array::<R16I>(gl, &config)?),
|
||||
ChannelType::R32I => Rc::new(create_texture_array::<R32I>(gl, &config)?),
|
||||
ChannelType::R32F => Rc::new(create_texture_array::<R32F>(gl, &config)?),
|
||||
ChannelType::R64F => Rc::new(create_texture_array::<R64F>(gl, &config)?),
|
||||
};
|
||||
#[cfg(feature = "webgl1")]
|
||||
let texture_2d_array = match config.get_format() {
|
||||
ChannelType::RGBA32F => unimplemented!(),
|
||||
ChannelType::RGB32F => unimplemented!(),
|
||||
ChannelType::RGBA8U => Rc::new(create_texture_array::<RGBA8U>(gl, &config)?),
|
||||
ChannelType::RGB8U => Rc::new(create_texture_array::<RGB8U>(gl, &config)?),
|
||||
ChannelType::R32F => Rc::new(create_texture_array::<R32F>(gl, &config)?),
|
||||
ChannelType::RGBA8U => create_texture_array::<RGBA8U>(gl, &config)?,
|
||||
ChannelType::RGB8U => create_texture_array::<RGB8U>(gl, &config)?,
|
||||
ChannelType::R32F => create_texture_array::<R32F>(gl, &config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R8UI => create_texture_array::<R8UI>(gl, &config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R16I => create_texture_array::<R16I>(gl, &config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R32I => create_texture_array::<R32I>(gl, &config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R64F => create_texture_array::<R64F>(gl, &config)?,
|
||||
};
|
||||
// The root textures have not been loaded
|
||||
//let ready = false;
|
||||
//let num_root_textures_available = 0;
|
||||
let available_tiles_during_frame = false;
|
||||
let start_time = None;
|
||||
//let num_base_textures = 0;
|
||||
Ok(ImageSurveyTextures {
|
||||
config,
|
||||
heap,
|
||||
@@ -228,8 +221,8 @@ impl ImageSurveyTextures {
|
||||
size,
|
||||
//num_root_textures_available,
|
||||
textures,
|
||||
base_textures,
|
||||
|
||||
//base_textures,
|
||||
//num_base_textures,
|
||||
texture_2d_array,
|
||||
available_tiles_during_frame,
|
||||
|
||||
@@ -246,21 +239,21 @@ impl ImageSurveyTextures {
|
||||
self.texture_2d_array = match channel {
|
||||
ChannelType::RGBA32F => unimplemented!(),
|
||||
ChannelType::RGB32F => unimplemented!(),
|
||||
ChannelType::RGBA8U => Rc::new(create_texture_array::<RGBA8U>(gl, &self.config)?),
|
||||
ChannelType::RGB8U => Rc::new(create_texture_array::<RGB8U>(gl, &self.config)?),
|
||||
ChannelType::R32F => Rc::new(create_texture_array::<R32F>(gl, &self.config)?),
|
||||
ChannelType::RGBA8U => create_texture_array::<RGBA8U>(gl, &self.config)?,
|
||||
ChannelType::RGB8U => create_texture_array::<RGB8U>(gl, &self.config)?,
|
||||
ChannelType::R32F => create_texture_array::<R32F>(gl, &self.config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R8UI => Rc::new(create_texture_array::<R8UI>(gl, &self.config)?),
|
||||
ChannelType::R8UI => create_texture_array::<R8UI>(gl, &self.config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R16I => Rc::new(create_texture_array::<R16I>(gl, &self.config)?),
|
||||
ChannelType::R16I => create_texture_array::<R16I>(gl, &self.config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R32I => Rc::new(create_texture_array::<R32I>(gl, &self.config)?),
|
||||
ChannelType::R32I => create_texture_array::<R32I>(gl, &self.config)?,
|
||||
#[cfg(feature = "webgl2")]
|
||||
ChannelType::R64F => Rc::new(create_texture_array::<R64F>(gl, &self.config)?),
|
||||
ChannelType::R64F => create_texture_array::<R64F>(gl, &self.config)?,
|
||||
};
|
||||
|
||||
let now = Time::now();
|
||||
self.base_textures = [
|
||||
/*self.base_textures = [
|
||||
Texture::new(&HEALPixCell(0, 0), 0, now),
|
||||
Texture::new(&HEALPixCell(0, 1), 1, now),
|
||||
Texture::new(&HEALPixCell(0, 2), 2, now),
|
||||
@@ -273,7 +266,7 @@ impl ImageSurveyTextures {
|
||||
Texture::new(&HEALPixCell(0, 9), 9, now),
|
||||
Texture::new(&HEALPixCell(0, 10), 10, now),
|
||||
Texture::new(&HEALPixCell(0, 11), 11, now),
|
||||
];
|
||||
];*/
|
||||
|
||||
self.heap.clear();
|
||||
self.textures.clear();
|
||||
@@ -326,7 +319,7 @@ impl ImageSurveyTextures {
|
||||
let tex_cell = cell.get_texture_cell(self.config.delta_depth());
|
||||
|
||||
let tex_cell_is_root = tex_cell.is_root(self.config.delta_depth());
|
||||
if !tex_cell_is_root && !self.textures.contains_key(&tex_cell) {
|
||||
if !self.textures.contains_key(&tex_cell) {
|
||||
// The texture is not among the essential ones
|
||||
// (i.e. is not a root texture)
|
||||
let texture = if self.is_heap_full() {
|
||||
@@ -340,6 +333,12 @@ impl ImageSurveyTextures {
|
||||
"Texture (oldest one) has not been found in the buffer of textures",
|
||||
);
|
||||
// Clear and assign it to tex_cell
|
||||
/*let idx = if tex_cell_is_root {
|
||||
self.num_base_textures += 1;
|
||||
Some(tex_cell.idx() as i32)
|
||||
} else {
|
||||
None
|
||||
};*/
|
||||
texture.replace(&tex_cell, time_request);
|
||||
|
||||
texture
|
||||
@@ -347,10 +346,18 @@ impl ImageSurveyTextures {
|
||||
// The heap buffer is not full, let's create a new
|
||||
// texture with an unique idx
|
||||
// The idx is computed based on the current size of the buffer
|
||||
let idx = NUM_HPX_TILES_DEPTH_ZERO + self.heap.len();
|
||||
/*let idx = if tex_cell_is_root {
|
||||
self.num_base_textures += 1;
|
||||
tex_cell.idx() as usize
|
||||
} else {
|
||||
//NUM_HPX_TILES_DEPTH_ZERO + (self.heap.len() - self.num_base_textures)
|
||||
self.heap.len()
|
||||
};*/
|
||||
let idx = self.heap.len();
|
||||
|
||||
Texture::new(&tex_cell, idx as i32, time_request)
|
||||
};
|
||||
|
||||
// Push it to the buffer
|
||||
self.heap.push(&texture);
|
||||
|
||||
@@ -363,50 +370,35 @@ impl ImageSurveyTextures {
|
||||
// We can safely push it
|
||||
// First get the texture
|
||||
|
||||
let texture = if !tex_cell_is_root {
|
||||
let texture = //if !tex_cell_is_root {
|
||||
self.textures
|
||||
.get_mut(&tex_cell)
|
||||
.expect("the cell has to be in the tile buffer")
|
||||
} else {
|
||||
.expect("the cell has to be in the tile buffer");
|
||||
/* } else {
|
||||
let HEALPixCell(_, idx) = tex_cell;
|
||||
&mut self.base_textures[idx as usize]
|
||||
};
|
||||
};*/
|
||||
|
||||
if let Some(image) = image {
|
||||
send_to_gpu(
|
||||
cell,
|
||||
texture,
|
||||
image,
|
||||
self.texture_2d_array.clone(),
|
||||
&self.config,
|
||||
)?;
|
||||
// Once the texture has been received in the GPU
|
||||
texture.append(
|
||||
cell, // The tile cell
|
||||
&self.config,
|
||||
false,
|
||||
);
|
||||
} else {
|
||||
send_to_gpu(
|
||||
cell,
|
||||
texture,
|
||||
self.config.get_default_image(),
|
||||
self.texture_2d_array.clone(),
|
||||
&self.config,
|
||||
)?;
|
||||
// Once the texture has been received in the GPU
|
||||
texture.append(
|
||||
cell, // The tile cell
|
||||
&self.config,
|
||||
true,
|
||||
);
|
||||
};
|
||||
let missing = image.is_none();
|
||||
send_to_gpu(
|
||||
cell,
|
||||
texture,
|
||||
image,
|
||||
&self.texture_2d_array,
|
||||
&mut self.config,
|
||||
)?;
|
||||
|
||||
texture.append(
|
||||
cell, // The tile cell
|
||||
&self.config,
|
||||
missing,
|
||||
);
|
||||
|
||||
self.available_tiles_during_frame = true;
|
||||
//self.ready = true;
|
||||
if self.start_time.is_none() {
|
||||
/*if self.start_time.is_none() {
|
||||
self.start_time = Some(Time::now());
|
||||
}
|
||||
}*/
|
||||
|
||||
/*if tex_cell.is_root(self.config.delta_depth()) && texture.is_available() {
|
||||
self.num_root_textures_available += 1;
|
||||
@@ -436,23 +428,15 @@ impl ImageSurveyTextures {
|
||||
// textures in the buffer
|
||||
let num_textures_heap = self.heap.len();
|
||||
|
||||
num_textures_heap == (self.size - NUM_HPX_TILES_DEPTH_ZERO)
|
||||
num_textures_heap == self.size
|
||||
}
|
||||
|
||||
// Tell if a texture is available meaning all its sub tiles
|
||||
// must have been written for the GPU
|
||||
pub fn contains(&self, texture_cell: &HEALPixCell) -> bool {
|
||||
if let Some(texture) = self.textures.get(texture_cell) {
|
||||
// The texture is in the buffer i.e. there is at least one
|
||||
// sub tile received
|
||||
|
||||
// It is possible that it is not available. Available means
|
||||
// all its sub tiles have been received and written to the
|
||||
// textures array!
|
||||
texture.is_available()
|
||||
if let Some(t) = self.get(texture_cell) {
|
||||
t.is_full()
|
||||
} else {
|
||||
// The texture is not contained in the buffer i.e.
|
||||
// even not one sub tile that has been received
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -463,20 +447,20 @@ impl ImageSurveyTextures {
|
||||
pub fn contains_tile(&self, cell: &HEALPixCell) -> bool {
|
||||
let texture_cell = cell.get_texture_cell(self.config.delta_depth());
|
||||
|
||||
let tex_cell_is_root = texture_cell.is_root(self.config.delta_depth());
|
||||
if tex_cell_is_root {
|
||||
let HEALPixCell(_, idx) = texture_cell;
|
||||
self.base_textures[idx as usize].contains(cell)
|
||||
//let tex_cell_is_root = texture_cell.is_root(self.config.delta_depth());
|
||||
//if tex_cell_is_root {
|
||||
// let HEALPixCell(_, idx) = texture_cell;
|
||||
// self.base_textures[idx as usize].contains(cell)
|
||||
//} else {
|
||||
if let Some(texture) = self.get(&texture_cell) {
|
||||
// The texture is present in the buffer
|
||||
// We must check whether it contains the tile
|
||||
texture.contains(cell)
|
||||
} else {
|
||||
if let Some(texture) = self.textures.get(&texture_cell) {
|
||||
// The texture is present in the buffer
|
||||
// We must check whether it contains the tile
|
||||
texture.contains(cell)
|
||||
} else {
|
||||
// The texture in which cell should be is not present
|
||||
false
|
||||
}
|
||||
// The texture in which cell should be is not present
|
||||
false
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
// Update the priority of the texture containing the tile
|
||||
@@ -486,9 +470,9 @@ impl ImageSurveyTextures {
|
||||
|
||||
// Get the texture cell in which the tile has to be
|
||||
let texture_cell = cell.get_texture_cell(self.config.delta_depth());
|
||||
if texture_cell.is_root(self.config().delta_depth()) {
|
||||
return;
|
||||
}
|
||||
//if texture_cell.is_root(self.config().delta_depth()) {
|
||||
// return;
|
||||
//}
|
||||
|
||||
let texture = self
|
||||
.textures
|
||||
@@ -520,7 +504,7 @@ impl ImageSurveyTextures {
|
||||
let (pix, dx, dy) = crate::healpix::utils::hash_with_dxdy(depth, lonlat);
|
||||
let texture_cell = HEALPixCell(depth, pix);
|
||||
|
||||
if let Some(texture) = self.textures.get(&texture_cell) {
|
||||
if let Some(texture) = self.get(&texture_cell) {
|
||||
let cfg = &self.config;
|
||||
|
||||
// Index of the texture in the total set of textures
|
||||
@@ -568,29 +552,33 @@ impl ImageSurveyTextures {
|
||||
|
||||
/// Accessors
|
||||
pub fn get(&self, texture_cell: &HEALPixCell) -> Option<&Texture> {
|
||||
if texture_cell.is_root(self.config().delta_depth()) {
|
||||
let HEALPixCell(_, idx) = texture_cell;
|
||||
Some(&self.base_textures[*idx as usize])
|
||||
} else {
|
||||
self.textures.get(texture_cell)
|
||||
}
|
||||
//if texture_cell.is_root(self.config().delta_depth()) {
|
||||
// let HEALPixCell(_, idx) = texture_cell;
|
||||
// Some(&self.base_textures[*idx as usize])
|
||||
//} else {
|
||||
self.textures.get(texture_cell)
|
||||
//}
|
||||
}
|
||||
|
||||
// Get the nearest parent tile found in the CPU buffer
|
||||
pub fn get_nearest_parent(&self, cell: &HEALPixCell) -> HEALPixCell {
|
||||
pub fn get_nearest_parent(&self, cell: &HEALPixCell) -> Option<HEALPixCell> {
|
||||
let dd = self.config.delta_depth();
|
||||
if cell.is_root(dd) {
|
||||
/*if cell.is_root(dd) {
|
||||
// Root cells are in the buffer by definition
|
||||
*cell
|
||||
} else {
|
||||
let mut parent_cell = cell.parent();
|
||||
} else {*/
|
||||
let mut parent_cell = cell.parent();
|
||||
|
||||
while !self.contains(&parent_cell) && !parent_cell.is_root(dd) {
|
||||
parent_cell = parent_cell.parent();
|
||||
}
|
||||
|
||||
parent_cell
|
||||
while !self.contains(&parent_cell) && !parent_cell.is_root(dd) {
|
||||
parent_cell = parent_cell.parent();
|
||||
}
|
||||
|
||||
if self.contains(&parent_cell) {
|
||||
Some(parent_cell)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
pub fn config(&self) -> &HiPSConfig {
|
||||
@@ -628,17 +616,17 @@ impl ImageSurveyTextures {
|
||||
]
|
||||
}*/
|
||||
|
||||
pub fn get_texture_array(&self) -> Rc<Texture2DArray> {
|
||||
self.texture_2d_array.clone()
|
||||
pub fn get_texture_array(&self) -> &Texture2DArray {
|
||||
&self.texture_2d_array
|
||||
}
|
||||
}
|
||||
|
||||
fn send_to_gpu<I: Image>(
|
||||
cell: &HEALPixCell,
|
||||
texture: &Texture,
|
||||
image: I,
|
||||
texture_array: Rc<Texture2DArray>,
|
||||
cfg: &HiPSConfig,
|
||||
image: Option<I>,
|
||||
texture_array: &Texture2DArray,
|
||||
cfg: &mut HiPSConfig,
|
||||
) -> Result<(), JsValue> {
|
||||
// Index of the texture in the total set of textures
|
||||
let texture_idx = texture.idx();
|
||||
@@ -670,24 +658,42 @@ fn send_to_gpu<I: Image>(
|
||||
idx_slice,
|
||||
);
|
||||
|
||||
image.tex_sub_image_3d(&texture_array, &offset)
|
||||
if let Some(image) = image {
|
||||
image.tex_sub_image_3d(&texture_array, &offset)
|
||||
} else {
|
||||
cfg.get_default_image()
|
||||
.tex_sub_image_3d(&texture_array, &offset)
|
||||
}
|
||||
}
|
||||
|
||||
impl SendUniforms for ImageSurveyTextures {
|
||||
// Send only the allsky textures
|
||||
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
|
||||
// Send the textures
|
||||
let textures = &self.base_textures;
|
||||
/*let textures = &self.base_textures;
|
||||
for (idx, texture) in textures.iter().enumerate() {
|
||||
let texture_uniforms = TextureUniforms::new(texture, idx as i32);
|
||||
shader.attach_uniforms_from(&texture_uniforms);
|
||||
}
|
||||
}*/
|
||||
|
||||
//if self.raytracing {
|
||||
for idx in 0..NUM_HPX_TILES_DEPTH_ZERO {
|
||||
let cell = HEALPixCell(0, idx as u64);
|
||||
|
||||
if let Some(texture) = self.get(&cell) {
|
||||
let texture_uniforms = TextureUniforms::new(texture, idx as i32);
|
||||
shader.attach_uniforms_from(&texture_uniforms);
|
||||
} else {
|
||||
let texture = &Texture::new(&cell, idx as i32, Time::now());
|
||||
let texture_uniforms = TextureUniforms::new(texture, idx as i32);
|
||||
shader.attach_uniforms_from(&texture_uniforms);
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
let num_tiles = textures.len() as i32;
|
||||
let shader = shader
|
||||
.attach_uniform("num_tiles", &num_tiles)
|
||||
.attach_uniforms_from(&self.config)
|
||||
.attach_uniforms_from(&*self.texture_2d_array);
|
||||
.attach_uniforms_from(&self.texture_2d_array);
|
||||
|
||||
shader
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use al_api::hips::ImageExt;
|
||||
use al_core::log::console_log;
|
||||
use al_core::{image::format::ImageFormat, image::raw::ImageBuffer};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -156,6 +157,7 @@ pub struct HiPSConfig {
|
||||
// TODO: store this values in the ImageSurvey
|
||||
// These are proper to the survey (FITS one) and not
|
||||
// to a specific survey color
|
||||
pub fits_metadata: bool,
|
||||
pub scale: f32,
|
||||
pub offset: f32,
|
||||
pub blank: f32,
|
||||
@@ -168,8 +170,8 @@ pub struct HiPSConfig {
|
||||
pub frame: CooSystem,
|
||||
pub bitpix: Option<i32>,
|
||||
format: ImageFormatType,
|
||||
dataproduct_subtype: Option<Vec<String>>,
|
||||
colored: bool,
|
||||
//dataproduct_subtype: Option<Vec<String>>,
|
||||
//colored: bool,
|
||||
pub creator_did: String,
|
||||
}
|
||||
|
||||
@@ -272,7 +274,7 @@ impl HiPSConfig {
|
||||
}),
|
||||
}?;
|
||||
|
||||
let dataproduct_subtype = properties.get_dataproduct_subtype().clone();
|
||||
/*let dataproduct_subtype = properties.get_dataproduct_subtype().clone();
|
||||
let colored = if tex_storing_fits {
|
||||
false
|
||||
} else {
|
||||
@@ -281,7 +283,7 @@ impl HiPSConfig {
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
};*/
|
||||
|
||||
let empty_image = EmptyTileImage::new(tile_size, format.get_channel());
|
||||
|
||||
@@ -328,6 +330,7 @@ impl HiPSConfig {
|
||||
|
||||
is_allsky,
|
||||
|
||||
fits_metadata: false,
|
||||
scale: 1.0,
|
||||
offset: 0.0,
|
||||
blank: -1.0, // by default, set it to -1
|
||||
@@ -341,8 +344,8 @@ impl HiPSConfig {
|
||||
bitpix,
|
||||
format,
|
||||
tile_size,
|
||||
dataproduct_subtype,
|
||||
colored,
|
||||
//dataproduct_subtype,
|
||||
//colored,
|
||||
};
|
||||
|
||||
Ok(hips_config)
|
||||
@@ -421,7 +424,7 @@ impl HiPSConfig {
|
||||
self.empty_image = EmptyTileImage::new(self.tile_size, self.format.get_channel());
|
||||
|
||||
// Recompute if the survey will be colored or not
|
||||
self.colored = if self.tex_storing_fits {
|
||||
/*self.colored = if self.tex_storing_fits {
|
||||
false
|
||||
} else {
|
||||
if let Some(subtypes) = &self.dataproduct_subtype {
|
||||
@@ -429,7 +432,7 @@ impl HiPSConfig {
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
};*/
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -449,6 +452,7 @@ impl HiPSConfig {
|
||||
self.scale = bscale;
|
||||
self.offset = bzero;
|
||||
self.blank = blank;
|
||||
self.fits_metadata = true;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -528,7 +532,7 @@ impl HiPSConfig {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_colored(&self) -> bool {
|
||||
self.colored
|
||||
self.format.is_colored()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
||||
@@ -105,14 +105,10 @@ impl Texture {
|
||||
self.full
|
||||
}
|
||||
|
||||
pub fn is_available(&self) -> bool {
|
||||
self.is_full()
|
||||
}
|
||||
|
||||
// Getter
|
||||
// Returns the current time if the texture is not full
|
||||
pub fn start_time(&self) -> Time {
|
||||
if self.is_available() {
|
||||
if self.is_full() {
|
||||
self.start_time.unwrap_abort()
|
||||
} else {
|
||||
Time::now()
|
||||
|
||||
@@ -92,6 +92,7 @@ impl TileFetcherQueue {
|
||||
// Try to fetch the MOC
|
||||
downloader.fetch(query::Moc::new(
|
||||
format!("{}/Moc.fits", cfg.get_root_url()),
|
||||
cfg.get_creator_did().to_string(),
|
||||
al_api::moc::MOC::default(),
|
||||
));
|
||||
|
||||
|
||||
@@ -1,26 +1,18 @@
|
||||
body { overscroll-behavior: contain; }
|
||||
|
||||
.aladin-container {
|
||||
position: relative;
|
||||
border: 1px solid #ddd;
|
||||
height: 100%;
|
||||
|
||||
border: 0px solid #ddd;
|
||||
/* SVG inside divs add a 4px height: https://stackoverflow.com/questions/75751593/why-there-is-additional-4px-height-for-div-when-there-is-svg-inside-it */
|
||||
/* disable x swipe on chrome, firefox */
|
||||
/* see. https://stackoverflow.com/questions/30636930/disable-web-page-navigation-on-swipeback-and-forward */
|
||||
overscroll-behavior-x: none;
|
||||
|
||||
/* Hide the draggable boxes that goes out of the view */
|
||||
overflow: hidden;
|
||||
/* media query on the aladin lite container. not supported everywhere.
|
||||
There can be a more supported alternative here: https://caniuse.com/?search=grid-template-columns */
|
||||
/*container-type: inline-size;*/
|
||||
}
|
||||
|
||||
.aladin-imageCanvas {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.aladin-gridCanvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
@@ -57,18 +49,6 @@ body { overscroll-behavior: contain; }
|
||||
padding-top: 58.45%; /* aspect ratio of the background image */
|
||||
}
|
||||
|
||||
.aladin-col {
|
||||
float: left;
|
||||
width: 45.00%;
|
||||
margin-right: 5.0%;
|
||||
}
|
||||
/* Clear floats after the columns */
|
||||
.aladin-row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.aladin-clipboard::before {
|
||||
content: ' 📋';
|
||||
cursor:pointer;
|
||||
@@ -80,7 +60,7 @@ body { overscroll-behavior: contain; }
|
||||
|
||||
display: block;
|
||||
|
||||
max-height: 15em;
|
||||
max-height: 30vh;
|
||||
max-width: 100%;
|
||||
-ms-overflow-style: none;
|
||||
overscroll-behavior-x: none;
|
||||
@@ -115,56 +95,34 @@ body { overscroll-behavior: contain; }
|
||||
|
||||
.aladin-measurement-div.aladin-dark-theme table thead {
|
||||
background-color: #000;
|
||||
}
|
||||
color: white;
|
||||
|
||||
.aladin-measurement-div table td.aladin-href-td-container a:hover {
|
||||
overflow: visible;
|
||||
display: inline-block;
|
||||
animation: leftright 5s infinite normal linear;
|
||||
}
|
||||
|
||||
@keyframes leftright {
|
||||
0%,
|
||||
20% {
|
||||
transform: translateX(0%);
|
||||
left: 0%;
|
||||
}
|
||||
80%,
|
||||
100% {
|
||||
/* the max width is 150px and a padding of 0.8em is added for href link */
|
||||
transform: translateX(-100%);
|
||||
left: -100%;
|
||||
}
|
||||
}
|
||||
|
||||
.aladin-measurement-div table th {
|
||||
padding: 0.3em 0.5em;
|
||||
}
|
||||
|
||||
.aladin-measurement-div table td.aladin-href-td-container {
|
||||
border: 1px solid #d2d2d2;
|
||||
.aladin-measurement-div table tr td a {
|
||||
color: green;
|
||||
}
|
||||
.aladin-measurement-div table tr td a:hover {
|
||||
color: greenyellow;
|
||||
}
|
||||
|
||||
border-radius: 3px;
|
||||
.aladin-measurement-div table tr td {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.aladin-measurement-div table tr td, .aladin-measurement-div table tr td a {
|
||||
max-width: 10rem;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
padding: 0.5em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
max-width: 150px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.aladin-measurement-div table td.aladin-text-td-container {
|
||||
padding: 0.5em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
max-width: 150px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.aladin-measurement-div table td.aladin-href-td-container:hover {
|
||||
background-color: #fff;
|
||||
word-wrap:break-word;
|
||||
}
|
||||
|
||||
.aladin-marker-measurement {
|
||||
@@ -180,10 +138,6 @@ body { overscroll-behavior: contain; }
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aladin-marker-measurement table tr td{
|
||||
word-wrap:break-word;
|
||||
}
|
||||
|
||||
.aladin-marker-measurement tr:nth-child(even) {
|
||||
background-color: #dddddd;
|
||||
}
|
||||
@@ -244,8 +198,6 @@ body { overscroll-behavior: contain; }
|
||||
}
|
||||
|
||||
.aladin-box {
|
||||
display: none;
|
||||
|
||||
padding: 0.2rem;
|
||||
background: whitesmoke;
|
||||
border-radius: 2px;
|
||||
@@ -267,28 +219,9 @@ body { overscroll-behavior: contain; }
|
||||
overflow-y: none;
|
||||
max-height: 500px;
|
||||
max-width: fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.aladin-box::-webkit-scrollbar {
|
||||
display: none; /* for Chrome, Safari, and Opera */
|
||||
}
|
||||
|
||||
.aladin-dialog {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: #eee;
|
||||
border-radius: 4px;
|
||||
/*font-family: Verdana, Geneva, Tahoma, sans-serif;*/
|
||||
line-height: 1.3;
|
||||
color: #222;
|
||||
max-width: 500px;
|
||||
padding: 0.8em;
|
||||
}
|
||||
|
||||
|
||||
canvas {
|
||||
image-rendering: optimizeSpeed; /* Older versions of FF */
|
||||
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
|
||||
@@ -370,18 +303,6 @@ canvas {
|
||||
background-position:center center;
|
||||
}
|
||||
|
||||
.aladin-fullscreen {
|
||||
position: fixed !important;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
border: 0 !important;
|
||||
max-width: none !important;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* smartphones, iPhone, portrait 480x320 phones */
|
||||
.aladin-btn {
|
||||
all:unset;
|
||||
@@ -407,16 +328,15 @@ canvas {
|
||||
.aladin-btn.aladin-dark-theme.toggled {
|
||||
border-color: greenyellow;
|
||||
}
|
||||
.aladin-btn.aladin-dark-theme:hover, .aladin-input-select.aladin-dark-theme:hover {
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.aladin-btn.disabled {
|
||||
cursor: not-allowed;
|
||||
filter: brightness(70%);
|
||||
}
|
||||
|
||||
.aladin-btn:not(.disabled):hover {
|
||||
filter: brightness(105%);
|
||||
}
|
||||
|
||||
.aladin-btn.svg-icon {
|
||||
background-repeat: no-repeat;
|
||||
background-position:center center;
|
||||
@@ -427,6 +347,13 @@ canvas {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.aladin-icon img {
|
||||
vertical-align:middle;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.aladin-icon.aladin-dark-theme {
|
||||
@@ -445,6 +372,9 @@ canvas {
|
||||
.aladin-measurement-div.aladin-dark-theme {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.aladin-measurement-div.aladin-dark-theme table {
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -468,52 +398,40 @@ canvas {
|
||||
height: 1.7rem;
|
||||
}
|
||||
|
||||
.aladin-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aladin-fov, .aladin-cooFrame, .aladin-location {
|
||||
font-family: monospace;
|
||||
|
||||
color: white;
|
||||
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
height: 1.7rem;
|
||||
.aladin-input-text.aladin-dark-theme:focus, .aladin-input-number.aladin-dark-theme:focus {
|
||||
border-color: dodgerblue;
|
||||
}
|
||||
|
||||
.aladin-input-text.aladin-dark-theme.search {
|
||||
width: 15rem;
|
||||
text-shadow: 0px 0px 2px #000;
|
||||
}
|
||||
|
||||
.aladin-input-text.aladin-dark-theme.search:focus {
|
||||
.aladin-input-text.search:focus, .aladin-input-text.search:hover {
|
||||
background-image: url(../../assets/icons/search-white.svg);
|
||||
background-size: 1.8rem;
|
||||
background-repeat: no-repeat;
|
||||
text-indent: 1.8rem;
|
||||
padding-left: 1.8rem;
|
||||
}
|
||||
|
||||
|
||||
.aladin-input-text.search {
|
||||
background-image:none;
|
||||
text-indent: 0rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
|
||||
.aladin-input-text.search.aladin-unknownObject {
|
||||
-webkit-box-shadow:inset 0px 0px 0px 3px #f00;
|
||||
-moz-box-shadow:inset 0px 0px 0px 3px #f00;
|
||||
box-shadow:inset 0px 0px 0px 3px #f00;
|
||||
.aladin-input-text.search.aladin-not-valid {
|
||||
-webkit-box-shadow:inset 0px 0px 0px 1px #f00;
|
||||
-moz-box-shadow:inset 0px 0px 0px 1px #f00;
|
||||
box-shadow:inset 0px 0px 0px 1px #f00;
|
||||
}
|
||||
|
||||
.aladin-dark-theme {
|
||||
color: white;
|
||||
.aladin-input-text.aladin-dark-theme.aladin-not-valid {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.aladin-input-text.aladin-dark-theme.aladin-valid {
|
||||
border: 1px solid yellowgreen;
|
||||
}
|
||||
|
||||
.aladin-cancelBtn {
|
||||
@@ -551,12 +469,12 @@ canvas {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.aladin-vertical-list > *:first-of-type {
|
||||
.aladin-vertical-list > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.aladin-vertical-list > * {
|
||||
margin-top: 0.2rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.aladin-horizontal-list {
|
||||
@@ -570,11 +488,14 @@ canvas {
|
||||
margin-right: 0.2rem;
|
||||
}
|
||||
|
||||
.aladin-horizontal-list > *::last-of-type {
|
||||
vertical-align: middle;
|
||||
.aladin-horizontal-list > *:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.aladin-form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aladin-form .aladin-form-input {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
@@ -582,8 +503,17 @@ canvas {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.aladin-form .aladin-form-input:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.aladin-form .aladin-form-group {
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aladin-form .aladin-form-group:last-of-type {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.aladin-form .aladin-form-input select {
|
||||
@@ -697,10 +627,14 @@ canvas {
|
||||
.aladin-status-bar-message {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
max-width: 300px;
|
||||
text-wrap: nowrap;
|
||||
-ms-overflow-style: none;
|
||||
overscroll-behavior-x: none;
|
||||
overflow-y: scroll;
|
||||
scrollbar-width: none;
|
||||
|
||||
max-width: 20rem;
|
||||
|
||||
font-size: 1rem;
|
||||
}
|
||||
@@ -762,8 +696,6 @@ canvas {
|
||||
.aladin-context-sub-menu,
|
||||
.aladin-context-menu {
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
|
||||
font-family: monospace;
|
||||
width: max-content;
|
||||
@@ -790,10 +722,13 @@ canvas {
|
||||
padding: 0.2rem 0.4rem;
|
||||
position: relative;
|
||||
|
||||
color: lightgray;
|
||||
background-color: black;
|
||||
|
||||
box-shadow:inset 1px 1px 0px 0px #fff;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
|
||||
margin: 0;
|
||||
box-sizing: content-box;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.aladin-context-menu .aladin-context-menu-item:first-of-type {
|
||||
@@ -880,6 +815,7 @@ canvas {
|
||||
border-radius: 5px;
|
||||
font-family: monospace;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.aladin-input-text.aladin-dark-theme, .aladin-input-number.aladin-dark-theme {
|
||||
@@ -909,18 +845,20 @@ canvas {
|
||||
/* Remove focus outline */
|
||||
/* Remove IE arrow */
|
||||
}
|
||||
|
||||
.aladin-input-select option {
|
||||
color: inherit;
|
||||
background-color: #320a28;
|
||||
}
|
||||
|
||||
.aladin-input-select:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.aladin-input-select::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Frames */
|
||||
.aladin-input-color {
|
||||
appearance: none;
|
||||
@@ -950,11 +888,17 @@ canvas {
|
||||
/********** Range Input Styles **********/
|
||||
/*Range Reset*/
|
||||
.aladin-input-range {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
width: 5em;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
width: 5em;
|
||||
height: 0.1rem;
|
||||
margin:0;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
|
||||
.aladin-input-range.aladin-reversed {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
/* Removes default focus */
|
||||
@@ -963,60 +907,48 @@ canvas {
|
||||
}
|
||||
|
||||
/***** Chrome, Safari, Opera and Edge Chromium styles *****/
|
||||
/* slider track */
|
||||
.aladin-input-range::-webkit-slider-runnable-track {
|
||||
background-color: #bababa;
|
||||
border-radius: 0.1rem;
|
||||
height: 0.1rem;
|
||||
|
||||
.aladin-input-range::-webkit-slider-container {
|
||||
background: white;
|
||||
height: 0.1rem;
|
||||
min-height: 0.1rem;
|
||||
}
|
||||
|
||||
/* slider thumb */
|
||||
.aladin-input-range::-webkit-slider-thumb {
|
||||
-webkit-appearance: none; /* Override default look */
|
||||
/*
|
||||
.aladin-input-range-datalist {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
margin-top: -7px; /* Centers thumb on the track */
|
||||
|
||||
/*custom styles*/
|
||||
background-color: #bababa;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
.aladin-input-range:hover::-webkit-slider-thumb {
|
||||
filter: brightness(105%);
|
||||
}
|
||||
|
||||
/* aladin input text */
|
||||
display: none;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
padding:0;
|
||||
margin:0;
|
||||
height: 0.1rem;
|
||||
top: 0rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******** Firefox styles ********/
|
||||
/* slider track */
|
||||
.aladin-input-range::-moz-range-track {
|
||||
background-color: #bababa;
|
||||
.aladin-input-range-datalist option {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
position: absolute;
|
||||
transform: translate(-50%, 0);
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
width: 0.1rem;
|
||||
border-radius: 0.1rem;
|
||||
height: 0.1rem;
|
||||
}
|
||||
height: 0.1rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: #D3D3D3;
|
||||
}*/
|
||||
|
||||
/* slider thumb */
|
||||
.aladin-input-range::-moz-range-thumb {
|
||||
border: none; /*Removes extra border that FF applies*/
|
||||
border-radius: 0; /*Removes default border-radius that FF applies*/
|
||||
|
||||
/*custom styles*/
|
||||
background-color: #bababa;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
.aladin-dark-theme {
|
||||
color: white;
|
||||
}
|
||||
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.aladin-input-range:hover::-moz-range-thumb {
|
||||
filter: brightness(105%);
|
||||
}
|
||||
|
||||
|
||||
/* *********************************************** */
|
||||
|
||||
/* Tooltip */
|
||||
@@ -1026,22 +958,27 @@ canvas {
|
||||
/* take the size of its inner div child */
|
||||
|
||||
font-family: monospace;
|
||||
line-height: 1rem;
|
||||
|
||||
|
||||
float: left;
|
||||
}
|
||||
|
||||
.aladin-tooltip-container .aladin-tooltip {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
visibility: hidden;
|
||||
background-color: black;
|
||||
background-color: white;
|
||||
color: black;
|
||||
|
||||
width: max-content;
|
||||
color: #fff;
|
||||
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
border-radius: 2px;
|
||||
|
||||
top:0%;
|
||||
left:0%;
|
||||
|
||||
z-index: 100;
|
||||
|
||||
@@ -1050,6 +987,13 @@ canvas {
|
||||
|
||||
/*font-family: Verdana, Geneva, Tahoma, sans-serif;*/
|
||||
font-size: 0.9rem;
|
||||
|
||||
transition-delay: 100ms;
|
||||
}
|
||||
|
||||
.aladin-tooltip-container .aladin-tooltip.aladin-dark-theme {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Show the tooltip text when you mouse over the tooltip container */
|
||||
@@ -1109,32 +1053,182 @@ canvas {
|
||||
cursor: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEIEwUMBS20MQAAApRJREFUWEfdV7GO2zAMfXY7x1luzOFwDeB/KHCAB87eumvqmI/JWhTwF3TIrMFAv8JbgWyHG3IpOjbpcKJC02KipECHclIU+j2KfKRlAABRUyFYak3UgKiZiXUJAIt1d1ysu2PYn53DsPCucpbkRE3JAdxKTtQgWo6zJAfGGbAwLuEV7OB9/yrXIbqZ9/0+rMuhdb+RYfWmm+fged8fihzyoXXxlNcYB2KRxwwA6SzI9Crgd973B/5/u3IF8FYSw98M5D2QR86kRE3pfX+AMqKm8iEQoqYaWrfj/4bW7QgokMhCeSs5KeVrDM4K29C6Y6oE0YGEUlndocVGyg/rGZDXBQpr0kmjLiAlOOvk3vf7RJZM5Q+te2W/7coVEq+wnC1yCZYyS3B8MMYF3vBKK9Jz5PWmm8sab1eu4N9D63aaHEAsH88SzmQpnSHsHDmnWvlXIoiJ4JTviY8FRUJ8ZAiOEiJbLpcjARM1M0twpmjZOeGQrXYm1/7yMLz/eH8fnyus6XXOtmLgWBrKtdMguNKYPPystIausn9egsVDfI674KxS6003F/sX357AdOBwcADwWD9EjBKJubxYd0cml4RhP5IPrduFk04GjiZXMyZiRHKdAU3OWeB2lLNAk+tpl9IHY0zSlBo4OgsaTJpFzs+F0pxKYEXK73Nd8+3KFfWmG71qGfgSeQqPN0fvdlZrSvmUoXaJJ7EiocArZaS6tgzA+5RQe3gumUl5gPLXzy+6pEQNzDuhvFKx1ZuuEuTxliwmY/KuoHxGhzGv5QDw9PTx7senz88aLHUpJeOu8OHb17u+//4CTMm97/eFVQK5vqR8y6xOyipByjn3+0C3moUH4O++D1UX3PR9eJWzJCf6Tz5O/wDUeIfTLPlbywAAAABJRU5ErkJggg==') 15 15, auto;
|
||||
}
|
||||
|
||||
/* Aladin Lite pre-defined UI features */
|
||||
/**
|
||||
* Aladin Lite pre-defined UI features.
|
||||
*
|
||||
* User may need to overwrite those classes if they want
|
||||
* change their position. They can also add media query on them.
|
||||
*
|
||||
*/
|
||||
|
||||
.aladin-stack-control {
|
||||
position: absolute;
|
||||
top: 3rem;
|
||||
left: 0;
|
||||
left: 0.2rem;
|
||||
}
|
||||
|
||||
.aladin-settings-control {
|
||||
position: absolute;
|
||||
top: 5.4rem;
|
||||
left: 0;
|
||||
left: 0.2rem;
|
||||
}
|
||||
|
||||
.aladin-simbadPointer-control {
|
||||
position: absolute;
|
||||
top: 7.8rem;
|
||||
left: 0;
|
||||
left: 0.2rem;
|
||||
}
|
||||
|
||||
.aladin-grid-control {
|
||||
position: absolute;
|
||||
top: 10.2rem;
|
||||
left: 0;
|
||||
left: 0.2rem;
|
||||
}
|
||||
|
||||
.aladin-cooFrame {
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
left: 0.2rem;
|
||||
|
||||
font-family: monospace;
|
||||
|
||||
color: white;
|
||||
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
height: 1.7rem;
|
||||
}
|
||||
|
||||
/*
|
||||
.aladin-input-text.aladin-dark-theme.search.aladin-HiPS-search {
|
||||
width: 100%;
|
||||
|
||||
}*/
|
||||
|
||||
.aladin-stack-box {
|
||||
width: 17rem;
|
||||
}
|
||||
|
||||
.aladin-HiPS-filter-box {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.aladin-HiPS-browser-box .aladin-input-text {
|
||||
width: 300px;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.aladin-stack-box .aladin-input-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aladin-location {
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
left: 6.9rem;
|
||||
font-family: monospace;
|
||||
|
||||
color: white;
|
||||
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
height: 1.7rem;
|
||||
}
|
||||
|
||||
.aladin-location .aladin-input-text {
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
.aladin-fov {
|
||||
position: absolute;
|
||||
bottom: 0.2rem;
|
||||
left: 0.2rem;
|
||||
|
||||
background-color: red;
|
||||
|
||||
font-family: monospace;
|
||||
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
line-height: 1.7rem;
|
||||
}
|
||||
|
||||
.aladin-fov .aladin-zoom-in {
|
||||
margin-right: 0;
|
||||
border-right: none;
|
||||
border-radius: 5px 0px 0px 5px;
|
||||
}
|
||||
|
||||
.aladin-fov .aladin-zoom-out {
|
||||
border-radius: 0px 5px 5px 0px;
|
||||
}
|
||||
|
||||
.aladin-status-bar {
|
||||
border-radius: 3px;
|
||||
padding: 0.4rem;
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.aladin-status-bar.aladin-dark-theme {
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.aladin-fov.aladin-dark-theme {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.aladin-table {
|
||||
position: absolute;
|
||||
bottom: 2.8rem;
|
||||
left: 0.2rem;
|
||||
max-width: calc(100% - 0.4rem);
|
||||
line-height: 1rem;
|
||||
}
|
||||
.aladin-measurement-div.aladin-dark-theme {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.aladin-share-control {
|
||||
position: absolute;
|
||||
top: 12.6rem;
|
||||
left: 0.2rem;
|
||||
}
|
||||
|
||||
.aladin-fullScreen-control {
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
right: 0.2rem;
|
||||
}
|
||||
|
||||
.aladin-projection-control {
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
right: 3rem;
|
||||
}
|
||||
|
||||
.aladin-fullscreen {
|
||||
position: fixed !important;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
border: 0 !important;
|
||||
max-width: none !important;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* Media query */
|
||||
/*@media screen and (max-width: 31rem) {
|
||||
.aladin-projection-control {
|
||||
display: none;
|
||||
}
|
||||
}*/
|
||||
/*@container (max-width: 40rem) {
|
||||
.aladin-input-text.aladin-dark-theme.search {
|
||||
width: 6rem;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//const int MAX_NUM_TEX = 3;
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
uniform sampler2D tex3;
|
||||
//uniform sampler2D tex3;
|
||||
|
||||
uniform int num_tex;
|
||||
|
||||
@@ -23,16 +23,16 @@ uniform int tex_storing_fits;
|
||||
#include ./hsv.glsl;
|
||||
|
||||
vec4 get_pixels(vec3 uv) {
|
||||
int idx_texture = int(uv.z);
|
||||
if (idx_texture == 0) {
|
||||
|
||||
/*if (idx_texture == 0) {
|
||||
return texture(tex1, uv.xy);
|
||||
} else if (idx_texture == 1) {
|
||||
return texture(tex2, uv.xy);
|
||||
} else if (idx_texture == 2) {
|
||||
return texture(tex3, uv.xy);
|
||||
} else {
|
||||
return vec4(0.0, 1.0, 0.0, 1.0);
|
||||
}
|
||||
}*/
|
||||
int idx_texture = int(uv.z);
|
||||
return mix(texture(tex1, uv.xy), texture(tex2, uv.xy), float(idx_texture));
|
||||
}
|
||||
|
||||
vec3 reverse_uv(vec3 uv) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//const int MAX_NUM_TEX = 3;
|
||||
uniform isampler2D tex1;
|
||||
uniform isampler2D tex2;
|
||||
uniform isampler2D tex3;
|
||||
//uniform isampler2D tex3;
|
||||
uniform int num_tex;
|
||||
|
||||
uniform float scale;
|
||||
@@ -22,7 +22,7 @@ uniform int tex_storing_fits;
|
||||
#include ./tonal_corrections.glsl;
|
||||
|
||||
ivec4 get_pixels(vec3 uv) {
|
||||
int idx_texture = int(uv.z);
|
||||
/*int idx_texture = int(uv.z);
|
||||
if (idx_texture == 0) {
|
||||
return texture(tex1, uv.xy);
|
||||
} else if (idx_texture == 1) {
|
||||
@@ -31,7 +31,10 @@ ivec4 get_pixels(vec3 uv) {
|
||||
return texture(tex3, uv.xy);
|
||||
} else {
|
||||
return ivec4(0, 0, 0, 1);
|
||||
}
|
||||
}*/
|
||||
//return texture(tex1, uv.xy);
|
||||
int idx_texture = int(uv.z);
|
||||
return ivec4(mix(vec4(texture(tex1, uv.xy)), vec4(texture(tex2, uv.xy)), float(idx_texture)));
|
||||
}
|
||||
|
||||
vec3 reverse_uv(vec3 uv) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//const int MAX_NUM_TEX = 3;
|
||||
uniform usampler2D tex1;
|
||||
uniform usampler2D tex2;
|
||||
uniform usampler2D tex3;
|
||||
//uniform usampler2D tex3;
|
||||
uniform int num_tex;
|
||||
|
||||
uniform float scale;
|
||||
@@ -22,7 +22,7 @@ uniform int tex_storing_fits;
|
||||
#include ./tonal_corrections.glsl;
|
||||
|
||||
uvec4 get_pixels(vec3 uv) {
|
||||
int idx_texture = int(uv.z);
|
||||
/*int idx_texture = int(uv.z);
|
||||
if (idx_texture == 0) {
|
||||
return texture(tex1, uv.xy);
|
||||
} else if (idx_texture == 1) {
|
||||
@@ -31,7 +31,11 @@ uvec4 get_pixels(vec3 uv) {
|
||||
return texture(tex3, uv.xy);
|
||||
} else {
|
||||
return uvec4(0, 0, 0, 1);
|
||||
}
|
||||
}*/
|
||||
//return texture(tex1, uv.xy);
|
||||
//int idx_texture = int(uv.z);
|
||||
int idx_texture = int(uv.z);
|
||||
return uvec4(mix(vec4(texture(tex1, uv.xy)), vec4(texture(tex2, uv.xy)), float(idx_texture)));
|
||||
}
|
||||
|
||||
vec3 reverse_uv(vec3 uv) {
|
||||
|
||||
@@ -17,7 +17,6 @@ struct Tile {
|
||||
};
|
||||
|
||||
uniform Tile textures_tiles[12];
|
||||
uniform int num_tiles;
|
||||
|
||||
#include ../color.glsl;
|
||||
#include ./healpix.glsl;
|
||||
@@ -29,7 +28,6 @@ vec4 get_tile_color(vec3 pos) {
|
||||
|
||||
int idx = result.idx;
|
||||
vec2 uv = vec2(result.dy, result.dx);
|
||||
|
||||
Tile tile = textures_tiles[idx];
|
||||
|
||||
int idx_texture = tile.texture_idx >> 6;
|
||||
@@ -41,6 +39,7 @@ vec4 get_tile_color(vec3 pos) {
|
||||
vec3 UV = vec3(offset, float(idx_texture));
|
||||
|
||||
vec4 color = get_color_from_texture(UV);
|
||||
color.a *= (1.0 - tile.empty);
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ vec4 get_tile_color(vec3 pos) {
|
||||
// For empty tiles we set the alpha of the pixel to 0.0
|
||||
// so that what is behind will be plotted
|
||||
color.a *= (1.0 - tile.empty);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
410
src/js/A.js
410
src/js/A.js
@@ -29,10 +29,12 @@
|
||||
*****************************************************************************/
|
||||
|
||||
import { MOC } from "./MOC.js";
|
||||
import { Overlay } from "./Overlay.js";
|
||||
import { Circle } from "./Circle.js";
|
||||
import { Ellipse } from "./Ellipse.js";
|
||||
import { Polyline } from "./Polyline.js";
|
||||
import { GraphicOverlay } from "./Overlay.js";
|
||||
import { Circle } from "./shapes/Circle.js";
|
||||
import { Ellipse } from "./shapes/Ellipse.js";
|
||||
import { Polyline } from "./shapes/Polyline.js";
|
||||
import { Line } from "./shapes/Line.js";
|
||||
|
||||
import { Catalog } from "./Catalog.js";
|
||||
import { ProgressiveCat } from "./ProgressiveCat.js";
|
||||
import { Source } from "./Source.js";
|
||||
@@ -43,6 +45,9 @@ import { Footprint } from './Footprint.js';
|
||||
import { Aladin } from "./Aladin.js";
|
||||
import { ActionButton } from "./gui/Widgets/ActionButton.js";
|
||||
import { Box } from "./gui/Widgets/Box.js";
|
||||
import { AladinUtils } from "./AladinUtils.js";
|
||||
import { Sesame } from "./Sesame.js";
|
||||
|
||||
// Wasm top level import
|
||||
import init, * as module from './../core/pkg';
|
||||
|
||||
@@ -87,6 +92,7 @@ let A = {};
|
||||
*/
|
||||
A.aladin = function (divSelector, options) {
|
||||
let divElement;
|
||||
|
||||
if (!(divSelector instanceof HTMLElement)) {
|
||||
divElement = document.querySelector(divSelector)
|
||||
} else {
|
||||
@@ -95,6 +101,45 @@ A.aladin = function (divSelector, options) {
|
||||
return new Aladin(divElement, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a HiPS image object
|
||||
*
|
||||
* @function
|
||||
* @name A.imageHiPS
|
||||
* @memberof A
|
||||
* @param {string} id - Can be either an `url` that refers to a HiPS.
|
||||
* Or it can be a "CDS ID" pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}.
|
||||
* @param {ImageHiPSOptions} [options] - Options describing the survey
|
||||
* @returns {ImageHiPS} - A HiPS image object
|
||||
*/
|
||||
A.imageHiPS = function (id, options) {
|
||||
let url = id;
|
||||
return Aladin.createImageSurvey(
|
||||
id,
|
||||
options && options.name,
|
||||
url,
|
||||
options && options.cooFrame,
|
||||
options && options.maxOrder,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a celestial source object with the given coordinates.
|
||||
*
|
||||
* @function
|
||||
* @name A.imageFITS
|
||||
* @memberof A
|
||||
* @param {string} url - Options describing the fits file. An url is mandatory
|
||||
* @param {ImageFITSOptions} [options] - Options describing the fits file. An url is mandatory
|
||||
* @returns {ImageFITS} - A HiPS image object
|
||||
* @example
|
||||
* const sourceObj = A.source(180.0, 30.0, data, options);
|
||||
*/
|
||||
A.imageFITS = function (url, options) {
|
||||
return Aladin.createImageFITS(url, options.name, options, options.successCallback, options.errorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a celestial source object with the given coordinates.
|
||||
*
|
||||
@@ -103,7 +148,7 @@ A.aladin = function (divSelector, options) {
|
||||
* @memberof A
|
||||
* @param {number} ra - Right Ascension (RA) coordinate in degrees.
|
||||
* @param {number} dec - Declination (Dec) coordinate in degrees.
|
||||
* @param {*} [data] - Additional data associated with the source.
|
||||
* @param {Object} [data] - Additional data associated with the source.
|
||||
* @param {SourceOptions} [options] - Options for configuring the source object.
|
||||
* @returns {Source} A celestial source object.
|
||||
* @example
|
||||
@@ -122,7 +167,7 @@ A.source = function (ra, dec, data, options) {
|
||||
* @param {number} ra - Right Ascension (RA) coordinate in degrees.
|
||||
* @param {number} dec - Declination (Dec) coordinate in degrees.
|
||||
* @param {MarkerOptions} [options] - Options for configuring the marker.
|
||||
* @param {*} [data] - Additional data associated with the marker.
|
||||
* @param {Object} [data] - Additional data associated with the marker.
|
||||
* @returns {Source} A marker source object.
|
||||
* @example
|
||||
* const markerObj = A.marker(180.0, 30.0, data, options);
|
||||
@@ -140,10 +185,11 @@ A.marker = function (ra, dec, options, data) {
|
||||
* @memberof A
|
||||
* @name polygon
|
||||
*
|
||||
* @param {Array} raDecArray - Array of celestial coordinates representing the vertices of the polygon.
|
||||
* Each element should be an object with properties `ra` (Right Ascension) in degrees and `dec` (Declination) in degrees.
|
||||
* @param {Object} options - Options for configuring the polygon.
|
||||
* @param {Array.<number[]>} radecArray - right-ascension/declination 2-tuple array describing the polyline's vertices in degrees
|
||||
* @param {ShapeOptions} options - Options for configuring the polygon
|
||||
* @throws {string} Throws an error if the number of vertices is less than 3.
|
||||
*
|
||||
* @returns {Polyline}
|
||||
*/
|
||||
A.polygon = function (raDecArray, options) {
|
||||
const numVertices = raDecArray.length;
|
||||
@@ -168,15 +214,16 @@ A.polygon = function (raDecArray, options) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a polyline object using an array of celestial coordinates (RA, Dec).
|
||||
* Creates a polyline shape
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name polyline
|
||||
*
|
||||
* @param {Array} raDecArray - Array of celestial coordinates representing the vertices of the polyline.
|
||||
* Each element should be an object with properties `ra` (Right Ascension) in degrees and `dec` (Declination) in degrees.
|
||||
* @param {Object} options - Options for configuring the polyline.
|
||||
* @param {Array.<number[]>} radecArray - right-ascension/declination 2-tuple array describing the polyline's vertices in degrees
|
||||
* @param {ShapeOptions} options - Options for configuring the polyline.
|
||||
*
|
||||
* @returns {Polyline}
|
||||
*/
|
||||
A.polyline = function (raDecArray, options) {
|
||||
return new Polyline(raDecArray, options);
|
||||
@@ -184,7 +231,7 @@ A.polyline = function (raDecArray, options) {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a circle object
|
||||
* Creates a circle shape
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
@@ -194,14 +241,15 @@ A.polyline = function (raDecArray, options) {
|
||||
* @param {number} dec - Declination (Dec) coordinate of the center in degrees.
|
||||
* @param {number} radiusDeg - Radius in degrees.
|
||||
|
||||
* @param {Object} options - Options for configuring the circle.
|
||||
* @param {ShapeOptions} options - Options for configuring the circle.
|
||||
* @returns {Circle}
|
||||
*/
|
||||
A.circle = function (ra, dec, radiusDeg, options) {
|
||||
return new Circle([ra, dec], radiusDeg, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a ellipse object
|
||||
* Creates an ellipse shape
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
@@ -213,12 +261,54 @@ A.circle = function (ra, dec, radiusDeg, options) {
|
||||
* @param {number} radiusDecDeg - the radius along the dec axis in degrees
|
||||
* @param {number} rotationDeg - the rotation angle in degrees
|
||||
|
||||
* @param {Object} options - Options for configuring the ellipse.
|
||||
* @param {ShapeOptions} options - Options for configuring the ellipse.
|
||||
* @returns {Ellipse}
|
||||
*/
|
||||
A.ellipse = function (ra, dec, radiusRaDeg, radiusDecDeg, rotationDeg, options) {
|
||||
return new Ellipse([ra, dec], radiusRaDeg, radiusDecDeg, rotationDeg, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a line shape
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name line
|
||||
*
|
||||
* @param {number} ra1 - Right Ascension (RA) coordinate of the center in degrees.
|
||||
* @param {number} dec1 - Declination (Dec) coordinate of the center in degrees.
|
||||
* @param {number} ra2 - Right Ascension (RA) coordinate of the center in degrees.
|
||||
* @param {number} dec2 - Declination (Dec) coordinate of the center in degrees.
|
||||
* @param {CooFrame} [frame] - Frame in which the coordinates are given. If none, the frame used is icrs/j2000.
|
||||
* @param {ShapeOptions} options - Options for configuring the line.
|
||||
*
|
||||
* @returns {Line}
|
||||
*/
|
||||
A.line = function (ra1, dec1, ra2, dec2, frame, options) {
|
||||
return new Line(ra1, dec1, ra2, dec2, frame, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a vector shape
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name vector
|
||||
*
|
||||
* @param {number} ra1 - Right Ascension (RA) coordinate of the center in degrees.
|
||||
* @param {number} dec1 - Declination (Dec) coordinate of the center in degrees.
|
||||
* @param {number} ra2 - Right Ascension (RA) coordinate of the center in degrees.
|
||||
* @param {number} dec2 - Declination (Dec) coordinate of the center in degrees.
|
||||
* @param {ShapeOptions} options - Options for configuring the vector.
|
||||
*
|
||||
* @returns {Line}
|
||||
*/
|
||||
A.vector = function (ra1, dec1, ra2, dec2, options) {
|
||||
options['arrow'] = true;
|
||||
|
||||
return A.line(ra1, dec1, ra2, dec2, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a graphic overlay on the Aladin Lite view.
|
||||
*
|
||||
@@ -229,13 +319,14 @@ A.ellipse = function (ra, dec, radiusRaDeg, radiusDecDeg, rotationDeg, options)
|
||||
* @param {Object} options - Options for configuring the graphic overlay.
|
||||
* @param {string} [options.color] - The color of the graphic overlay.
|
||||
* @param {number} [options.lineWidth] - The width of the lines in the graphic overlay.
|
||||
* @param {Array} [options.lineDash] - The dash pattern for the lines in the graphic overlay.
|
||||
* @returns {Overlay} Returns a new Overlay object representing the graphic overlay.
|
||||
*
|
||||
* @example
|
||||
* var overlay = A.graphicOverlay({ color: '#ee2345', lineWidth: 3 });
|
||||
* var overlay = A.graphicOverlay({ color: '#ee2345', lineWidth: 3, lineDash: [2, 4]});
|
||||
*/
|
||||
A.graphicOverlay = function (options) {
|
||||
return new Overlay(options);
|
||||
return new GraphicOverlay(options);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -274,27 +365,68 @@ A.coo = function (longitude, latitude, prec) {
|
||||
return new Coo(longitude, latitude, prec);
|
||||
};
|
||||
|
||||
// API
|
||||
A.footprint = function(shapes, source) {
|
||||
return new Footprint(shapes, source);
|
||||
};
|
||||
|
||||
// API
|
||||
/**
|
||||
* Parse shapes from a STC-S string
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name footprintsFromSTCS
|
||||
*
|
||||
* @param {string} stcs - The STC-S string describing the shapes
|
||||
* @param {ShapeOptions} [options] - Options for the shape
|
||||
* @returns {Array.<Polyline|Circle>} Returns a list of shapes from the STC-S string
|
||||
*/
|
||||
A.footprintsFromSTCS = function (stcs, options) {
|
||||
var footprints = Overlay.parseSTCS(stcs, options);
|
||||
|
||||
var footprints = GraphicOverlay.parseSTCS(stcs, options);
|
||||
return footprints;
|
||||
}
|
||||
|
||||
// API
|
||||
A.MOCFromURL = function (url, options, successCallback) {
|
||||
/**
|
||||
* Creates a new MOC (Multi-Order-Coverage) from an url
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name MOCFromURL
|
||||
*
|
||||
* @param {string} url - The url to the MOC (e.g. stored as FITS file)
|
||||
* @param {MOCOptions} [options] - Display options for the MOC
|
||||
* @param {function} [successCallback] - Callback function when the MOC loads
|
||||
* @param {function} [errorCallback] - Callback function when the MOC fails loading
|
||||
* @returns {MOC} Returns a new MOC object
|
||||
*/
|
||||
A.MOCFromURL = function (url, options, successCallback, errorCallback) {
|
||||
var moc = new MOC(options);
|
||||
moc.parse(url, successCallback);
|
||||
moc.parse(url, successCallback, errorCallback);
|
||||
|
||||
return moc;
|
||||
};
|
||||
|
||||
// API
|
||||
/**
|
||||
* Creates a new MOC (Multi-Order-Coverage) from a JSON-like dictionary (javascript Object)
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name MOCFromJSON
|
||||
*
|
||||
* @param {Object} jsonMOC - The MOC stores as a JSON-like dictionary
|
||||
* @param {MOCOptions} [options] - Display options for the MOC
|
||||
* @param {function} [successCallback] - Callback function when the MOC loads
|
||||
* @param {function} [errorCallback] - Callback function when the MOC fails loading
|
||||
* @returns {MOC} Returns a new MOC object
|
||||
*
|
||||
* @example
|
||||
* var json = {"3":[517],
|
||||
* "4":[2065,2066,2067,2112,2344,2346,2432],
|
||||
* "5":[8221,8257,8258,8259,8293,8304,8305,8307,8308,8452,8456,9346,9352,9354,9736],
|
||||
* "6":[32861,32862,32863,32881,32882,32883,32892,32893,33025,33026,33027,33157,33168,33169,33171,
|
||||
* 33181,33224,33225,33227,33236,33240,33812,33816,33828,33832,37377,37378,37379,37382,37388,
|
||||
* 37390,37412,37414,37420,37422,37562,38928,38930,38936,38948,38952],
|
||||
* "7":[131423,131439,131443,131523,131556,131557,131580,131581,132099,132612,132613,132624,132625,132627,132637,
|
||||
* 132680,132681,132683,132709,132720,132721,132904,132905,132948,132952,132964,132968,133008,133009,133012,135252,135256,135268,135316,135320,135332,135336,148143,148152,148154,149507,149520
|
||||
* ,149522,149523,149652,149654,149660,149662,149684,149686,149692,149694,149695,150120,150122,150208,150210,150216,150218,150240,150242,150243,155748,155752,155796,155800,155812,155816]};
|
||||
* var moc = A.MOCFromJSON(json, {opacity: 0.25, color: 'magenta', lineWidth: 3});
|
||||
* aladin.addMOC(moc);
|
||||
*/
|
||||
A.MOCFromJSON = function (jsonMOC, options, successCallback, errorCallback) {
|
||||
var moc = new MOC(options);
|
||||
moc.parse(jsonMOC, successCallback, errorCallback);
|
||||
@@ -302,14 +434,44 @@ A.MOCFromJSON = function (jsonMOC, options, successCallback, errorCallback) {
|
||||
return moc;
|
||||
};
|
||||
|
||||
// API
|
||||
A.MOCFromCircle = function (circle, options, successCallback, errorCallback) {
|
||||
/**
|
||||
* Creates a new MOC (Multi-Order-Coverage) from an object describing a cone on the sky
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name MOCFromCone
|
||||
*
|
||||
* @param {Object} circle - A object describing a cone in the sky
|
||||
* @param {number} circle.ra - Right-ascension of the circle's center (in deg)
|
||||
* @param {number} circle.dec - Declination of the circle's center (in deg)
|
||||
* @param {number} circle.radius - Radius of the circle (in deg)
|
||||
* @param {MOCOptions} [options] - Display options for the MOC
|
||||
* @param {function} [successCallback] - Callback function when the MOC loads
|
||||
* @param {function} [errorCallback] - Callback function when the MOC fails loading
|
||||
* @returns {MOC} Returns a new MOC object
|
||||
*/
|
||||
A.MOCFromCone = function (circle, options, successCallback, errorCallback) {
|
||||
var moc = new MOC(options);
|
||||
moc.parse(circle, successCallback, errorCallback);
|
||||
|
||||
return moc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new MOC (Multi-Order-Coverage) from an object describing a polygon on the sky
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name MOCFromPolygon
|
||||
*
|
||||
* @param {Object} polygon - A object describing a polygon in the sky
|
||||
* @param {number[]} polygon.ra - Right-ascensions of the polygon's vertices (in deg)
|
||||
* @param {number[]} polygon.dec - Declination of the polygon's vertices (in deg)
|
||||
* @param {MOCOptions} [options] - Display options for the MOC
|
||||
* @param {function} [successCallback] - Callback function when the MOC loads
|
||||
* @param {function} [errorCallback] - Callback function when the MOC fails loading
|
||||
* @returns {MOC} Returns a new MOC object
|
||||
*/
|
||||
A.MOCFromPolygon= function (polygon, options, successCallback, errorCallback) {
|
||||
var moc = new MOC(options);
|
||||
moc.parse(polygon, successCallback, errorCallback);
|
||||
@@ -334,6 +496,7 @@ A.MOCFromPolygon= function (polygon, options, successCallback, errorCallback) {
|
||||
* @property {string} [decField] - The ID or name of the field holding Declination (dec).
|
||||
* @property {function} [filter] - The filtering function for sources. Returns a boolean
|
||||
* @property {boolean} [displayLabel=false] - Whether to display labels for sources.
|
||||
* @property {string} [labelColumn] - The name of the column to be used for the label.
|
||||
* @property {string} [labelColor] - The color of the source labels.
|
||||
* @property {string} [labelFont="10px sans-serif"] - The font for the source labels.
|
||||
*/
|
||||
@@ -391,18 +554,24 @@ A.catalogFromURL = function (url, options, successCallback, errorCallback, usePr
|
||||
options.url = url;
|
||||
var catalog = A.catalog(options);
|
||||
const processVOTable = function (table) {
|
||||
let {sources, footprints, fields, type} = table;
|
||||
let {sources, fields} = table;
|
||||
catalog.setFields(fields);
|
||||
|
||||
if (catalog.type === 'ObsCore') {
|
||||
// The fields corresponds to obscore ones
|
||||
// Set the name of the catalog to be ObsCore:<catalog name>
|
||||
catalog.name = "ObsCore:" + url;
|
||||
}
|
||||
|
||||
catalog.addFootprints(footprints)
|
||||
catalog.addSources(sources);
|
||||
|
||||
if ('s_region' in fields && typeof catalog.shape !== 'function') {
|
||||
// set the shape
|
||||
catalog.setShape((s) => {
|
||||
if (!s.data.s_region)
|
||||
return;
|
||||
|
||||
const shapes = A.footprintsFromSTCS(s.data.s_region, options)
|
||||
let fp = new Footprint(shapes, s);
|
||||
fp.setColor(catalog.color);
|
||||
|
||||
return fp;
|
||||
})
|
||||
}
|
||||
|
||||
if (successCallback) {
|
||||
successCallback(catalog);
|
||||
}
|
||||
@@ -459,9 +628,9 @@ A.catalogFromURL = function (url, options, successCallback, errorCallback, usePr
|
||||
* @param {number} target.dec - Declination in degrees of the cone's center
|
||||
* @param {number} radius - Radius of the cone in degrees
|
||||
* @param {Object|CatalogOptions} [options] - Additional configuration options for SIMBAD cone search. See the {@link https://simbad.cds.unistra.fr/cone/help/#/ConeSearch/get_ SIMBAD cone search} parameters.
|
||||
* @param {Object} [options.limit] - The max number of sources to return
|
||||
* @param {Object} [options.orderBy] - Order the result by specific
|
||||
*
|
||||
* @param {number} [options.limit] - The max number of sources to return
|
||||
* @param {string} [options.orderBy='nb_ref'] - Order the result by specific ref number
|
||||
* @param {number} [options.verbosity=2] - Verbosity, put 3 if you want all the column
|
||||
* @param {function} [successCallback] - The callback function to execute on successful catalog creation.
|
||||
* @param {function} [errorCallback] - The callback function to execute on error during catalog creation.
|
||||
* @returns {Catalog} A new instance of the Catalog class created from the SIMBAD cone search.
|
||||
@@ -476,8 +645,8 @@ A.catalogFromSimbad = function (target, radius, options, successCallback, errorC
|
||||
if (!('name' in options)) {
|
||||
options['name'] = 'Simbad';
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let cat = A.catalog(options);
|
||||
new Promise((resolve, reject) => {
|
||||
let coo;
|
||||
if (target && (typeof target === "object")) {
|
||||
if ('ra' in target && 'dec' in target) {
|
||||
@@ -513,8 +682,33 @@ A.catalogFromSimbad = function (target, radius, options, successCallback, errorC
|
||||
}
|
||||
}).then((coo) => {
|
||||
const url = URLBuilder.buildSimbadCSURL(coo.lon, coo.lat, radius, options)
|
||||
return A.catalogFromURL(url, options, successCallback, errorCallback, false);
|
||||
const processVOTable = function (table) {
|
||||
let {sources, fields} = table;
|
||||
cat.setFields(fields);
|
||||
cat.addSources(sources);
|
||||
cat.url = url;
|
||||
|
||||
if (successCallback) {
|
||||
successCallback(cat);
|
||||
}
|
||||
|
||||
if (sources.length === 0) {
|
||||
console.warn(cat.name + ' has no sources!')
|
||||
}
|
||||
};
|
||||
|
||||
Catalog.parseVOTable(
|
||||
url,
|
||||
processVOTable,
|
||||
errorCallback,
|
||||
cat.maxNbSources,
|
||||
false,
|
||||
cat.raField, cat.decField
|
||||
);
|
||||
|
||||
})
|
||||
|
||||
return cat;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -668,37 +862,77 @@ A.catalogFromSkyBot = function (ra, dec, radius, epoch, queryOptions, options, s
|
||||
* @returns {ActionButton} Returns a new button object representing the graphic overlay.
|
||||
*
|
||||
* @example
|
||||
* let btn = A.button({
|
||||
* content: 'Draw your coverage',
|
||||
* cssStyle: {
|
||||
* backgroundColor: 'pink',
|
||||
* },
|
||||
* tooltip: {cssStyle: {color: 'red'}, content: 'Create a moc in pink!', position: {direction: 'top'}},
|
||||
* action(o) {
|
||||
* // Enter a polygonal selection mode
|
||||
* aladin.select('poly', p => {
|
||||
* // Create a moc from the polygon
|
||||
* try {
|
||||
* let ra = []
|
||||
* let dec = []
|
||||
* for (const v of p.vertices) {
|
||||
* let [lon, lat] = aladin.pix2world(v.x, v.y);
|
||||
* ra.push(lon)
|
||||
* dec.push(lat)
|
||||
* }
|
||||
*
|
||||
* let moc = A.MOCFromPolygon(
|
||||
* {ra, dec},
|
||||
* {name: 'poly', lineWidth: 3.0, color: 'pink'},
|
||||
* );
|
||||
* aladin.addMOC(moc)
|
||||
* } catch(_) {
|
||||
* alert('Selection covers a region out of the projection definition domain.');
|
||||
* }
|
||||
* })
|
||||
* }
|
||||
* });
|
||||
* aladin.addUI(btn)
|
||||
* <!-- This example instanciates a customized button that when clicked, enters the user in
|
||||
* the polygonal selection mode. Once the polygon selection is done, the vertices are converted
|
||||
* to sky coords and a Multi-Order Coverage (MOC) is created from that list of sky coords. -->
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div id="aladin-lite-div" style="width: 512px; height: 512px"></div>
|
||||
|
||||
<script type="module">
|
||||
import A from aladin-lite;
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
var aladin = A.aladin(
|
||||
'#aladin-lite-div',
|
||||
{
|
||||
survey: 'P/allWISE/color', // set initial image survey
|
||||
projection: 'AIT', // set a projection
|
||||
fov: 1.5, // initial field of view in degrees
|
||||
target: 'NGC 2175', // initial target
|
||||
cooFrame: 'icrs', // set galactic frame
|
||||
reticleColor: '#ff89ff', // change reticle color
|
||||
reticleSize: 64, // change reticle size
|
||||
showContextMenu: true,
|
||||
}
|
||||
);
|
||||
|
||||
let btn = A.button({
|
||||
content: 'My button',
|
||||
classList: ['myButton'],
|
||||
tooltip: {cssStyle: {color: 'red'}, content: 'Create a moc in pink!', position: {direction: 'top'}},
|
||||
action(o) {
|
||||
aladin.select('poly', p => {
|
||||
try {
|
||||
let ra = []
|
||||
let dec = []
|
||||
for (const v of p.vertices) {
|
||||
let [lon, lat] = aladin.pix2world(v.x, v.y);
|
||||
ra.push(lon)
|
||||
dec.push(lat)
|
||||
}
|
||||
|
||||
let moc = A.MOCFromPolygon(
|
||||
{ra, dec},
|
||||
{name: 'poly', lineWidth: 3.0, color: 'pink'},
|
||||
);
|
||||
aladin.addMOC(moc)
|
||||
} catch(_) {
|
||||
alert('Selection covers a region out of the projection definition domain.');
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
aladin.addUI(btn)
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.myButton {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
background-color: pink;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
*/
|
||||
A.button = function(options) {
|
||||
return new ActionButton(options);
|
||||
@@ -726,10 +960,9 @@ A.button = function(options) {
|
||||
* title: "My window",
|
||||
* draggable: true,
|
||||
* },
|
||||
* // Adding a CSS class allowing you to position your window on the aladin lite view
|
||||
* classList: ['myBox'],
|
||||
* content: "This is the content of my window<br/> I can write proper html",
|
||||
* position: {
|
||||
* anchor: 'center center'
|
||||
* }
|
||||
* })
|
||||
* aladin.addUI(box)
|
||||
*/
|
||||
@@ -741,6 +974,19 @@ A.getAvailableListOfColormaps = function() {
|
||||
return ColorCfg.COLORMAPS;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns utils object
|
||||
*
|
||||
* This contains utilitary methods such as HEALPix basic or projection methods.
|
||||
*
|
||||
* @function
|
||||
* @memberof A
|
||||
* @name Utils
|
||||
*
|
||||
* @returns {AladinUtils} Returns a new box window object.
|
||||
*/
|
||||
A.Utils = AladinUtils;
|
||||
|
||||
/**
|
||||
* Initializes the Aladin Lite library, checking for WebGL2 support.
|
||||
* This method must be called before instancing an Aladin Lite object.
|
||||
|
||||
2085
src/js/Aladin.js
2085
src/js/Aladin.js
File diff suppressed because it is too large
Load Diff
@@ -27,8 +27,6 @@
|
||||
* Author: Thomas Boch[CDS]
|
||||
*
|
||||
*****************************************************************************/
|
||||
import { HPXVertices } from "../core/pkg/core";
|
||||
import A from "./A";
|
||||
import { Aladin } from "./Aladin";
|
||||
|
||||
/**
|
||||
@@ -147,69 +145,13 @@ export let AladinUtils = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* passage de xy projection à xy dans la vue écran
|
||||
* @param x
|
||||
* @param y
|
||||
* @param width
|
||||
* @param height
|
||||
* @param largestDim largest dimension of the view
|
||||
* @returns position in the view
|
||||
*/
|
||||
/*
|
||||
xyToView: function(x, y, width, height, largestDim, zoomFactor, round) {
|
||||
if (round==undefined) {
|
||||
// we round by default
|
||||
round = true;
|
||||
}
|
||||
|
||||
if (round) {
|
||||
// we round the result for potential performance gains
|
||||
return {vx: AladinUtils.myRound(largestDim/2*(1+zoomFactor*x)-(largestDim-width)/2), vy: AladinUtils.myRound(largestDim/2*(1+zoomFactor*y)-(largestDim-height)/2)};
|
||||
|
||||
}
|
||||
else {
|
||||
return {vx: largestDim/2*(1+zoomFactor*x)-(largestDim-width)/2, vy: largestDim/2*(1+zoomFactor*y)-(largestDim-height)/2};
|
||||
}
|
||||
},*/
|
||||
|
||||
/**
|
||||
* passage de xy dans la vue écran à xy projection
|
||||
* @param vx
|
||||
* @param vy
|
||||
* @param width
|
||||
* @param height
|
||||
* @param largestDim
|
||||
* @param zoomFactor
|
||||
* @returns position in xy projection
|
||||
*/
|
||||
/*viewToXy: function(vx, vy, width, height, largestDim, zoomFactor) {
|
||||
return {x: ((2*vx+(largestDim-width))/largestDim-1)/zoomFactor, y: ((2*vy+(largestDim-height))/largestDim-1)/zoomFactor};
|
||||
},*/
|
||||
|
||||
/**
|
||||
* convert a
|
||||
* @returns position x,y in the view. Null if projection is impossible
|
||||
*/
|
||||
/*radecToViewXy: function(ra, dec, currentProjection, currentFrame, width, height, largestDim, zoomFactor) {
|
||||
var xy;
|
||||
if (currentFrame.system != CooFrameEnum.SYSTEMS.J2000) {
|
||||
var lonlat = CooConversion.J2000ToGalactic([ra, dec]);
|
||||
xy = currentProjection.project(lonlat[0], lonlat[1]);
|
||||
}
|
||||
else {
|
||||
xy = currentProjection.project(ra, dec);
|
||||
}
|
||||
if (!xy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return AladinUtils.xyToView(xy.X, xy.Y, width, height, largestDim, zoomFactor, false);
|
||||
},*/
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* Converts celestial coordinates (ra, dec) to screen coordinates (x, y) in pixels within the view.
|
||||
*
|
||||
* Use {@link Aladin.world2pix} instead
|
||||
*
|
||||
*
|
||||
* @function
|
||||
* @memberof AladinUtils
|
||||
* @name radecToViewXy
|
||||
@@ -220,152 +162,13 @@ export let AladinUtils = {
|
||||
* @returns {number[]} xy - A 2 elements array representing the screen coordinates [X, Y] in pixels.
|
||||
*/
|
||||
radecToViewXy: function(ra, dec, aladin) {
|
||||
let xy = aladin.view.wasm.worldToScreen(ra, dec);
|
||||
return xy;
|
||||
return aladin.world2pix(ra, dec);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts screen coordinates (X, Y) to clip coordinates within the view (coordinates lying between 0 and 1).
|
||||
*
|
||||
* @function
|
||||
* @memberof AladinUtils
|
||||
* @name viewXyToClipXy
|
||||
*
|
||||
* @param {number} x - X-coordinate in pixel screen coordinates
|
||||
* @param {number} y - Y-coordinate in pixel screen coordinates.
|
||||
* @param {Aladin} aladin - Aladin Lite object containing the WebAssembly API.
|
||||
* @returns {number[]} xy - An array representing the coordinates [X, Y] in clipping space.
|
||||
*/
|
||||
viewXyToClipXy: function(x, y, aladin) {
|
||||
let xy = aladin.view.wasm.screenToClip(x, y);
|
||||
return xy;
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated since version 2.0
|
||||
*/
|
||||
/*myRound: function(a) {
|
||||
if (a<0) {
|
||||
return -1*( (-a) | 0);
|
||||
}
|
||||
else {
|
||||
return a | 0;
|
||||
}
|
||||
},*/
|
||||
|
||||
/**
|
||||
* Test whether a xy position is the view
|
||||
* @param vx
|
||||
* @param vy
|
||||
* @param width
|
||||
* @param height
|
||||
* @returns a boolean whether (vx, vy) is in the screen
|
||||
*/
|
||||
/*isInsideViewXy: function(vx, vy, width, height) {
|
||||
return vx >= 0 && vx < width && vy >= 0 && vy < height
|
||||
},*/
|
||||
|
||||
/**
|
||||
* tests whether a healpix pixel is visible or not
|
||||
* @param pixCorners array of position (xy view) of the corners of the pixel
|
||||
* @param viewW
|
||||
*/
|
||||
/*isHpxPixVisible: function(pixCorners, viewWidth, viewHeight) {
|
||||
for (var i = 0; i<pixCorners.length; i++) {
|
||||
if ( pixCorners[i].vx>=-20 && pixCorners[i].vx<(viewWidth+20) &&
|
||||
pixCorners[i].vy>=-20 && pixCorners[i].vy<(viewHeight+20) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},*/
|
||||
|
||||
// Zoom is handled in the backend
|
||||
/*getZoomFactorForAngle: function(angleInDegrees, projectionMethod) {
|
||||
var p1 = {ra: 0, dec: 0};
|
||||
var p2 = {ra: angleInDegrees, dec: 0};
|
||||
var projection = new Projection(angleInDegrees/2, 0);
|
||||
projection.setProjection(projectionMethod);
|
||||
var p1Projected = projection.project(p1.ra, p1.dec);
|
||||
var p2Projected = projection.project(p2.ra, p2.dec);
|
||||
|
||||
var zoomFactor = 1/Math.abs(p1Projected.X - p2Projected.Y);
|
||||
|
||||
return zoomFactor;
|
||||
},*/
|
||||
|
||||
/*counterClockwiseTriangle: function(x1, y1, x2, y2, x3, y3) {
|
||||
// From: https://math.stackexchange.com/questions/1324179/how-to-tell-if-3-connected-points-are-connected-clockwise-or-counter-clockwise
|
||||
// | x1, y1, 1 |
|
||||
// | x2, y2, 1 | > 0 => the triangle is given in anticlockwise order
|
||||
// | x3, y3, 1 |
|
||||
|
||||
return x1*y2 + y1*x3 + x2*y3 - x3*y2 - y3*x1 - x2*y1 >= 0;
|
||||
},*/
|
||||
|
||||
// grow array b of vx,vy view positions by *val* pixels
|
||||
/*grow2: function(b, val) {
|
||||
var j=0;
|
||||
for ( var i=0; i<4; i++ ) {
|
||||
if ( b[i]==null ) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if( j>1 ) {
|
||||
return b;
|
||||
}
|
||||
|
||||
var b1 = [];
|
||||
for ( var i=0; i<4; i++ ) {
|
||||
b1.push( {vx: b[i].vx, vy: b[i].vy} );
|
||||
}
|
||||
|
||||
for ( var i=0; i<2; i++ ) {
|
||||
var a = i==1 ? 1 : 0;
|
||||
var c = i==1 ? 3 : 2;
|
||||
|
||||
if ( b1[a]==null ) {
|
||||
var d,g;
|
||||
if ( a==0 || a==3 ) {
|
||||
d=1;
|
||||
g=2;
|
||||
}
|
||||
else {
|
||||
d=0;
|
||||
g=3;
|
||||
}
|
||||
b1[a] = {vx: (b1[d].vx+b1[g].vx)/2, vy: (b1[d].vy+b1[g].vy)/2};
|
||||
}
|
||||
if ( b1[c]==null ) {
|
||||
var d,g;
|
||||
if ( c==0 || c==3 ) {
|
||||
d=1;
|
||||
g=2;
|
||||
}
|
||||
else {
|
||||
d=0;
|
||||
g=3;
|
||||
}
|
||||
b1[c] = {vx: (b1[d].vx+b1[g].vx)/2, vy: (b1[d].vy+b1[g].vy)/2};
|
||||
}
|
||||
if( b1[a]==null || b1[c]==null ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var angle = Math.atan2(b1[c].vy-b1[a].vy, b1[c].vx-b1[a].vx);
|
||||
var chouilla = val*Math.cos(angle);
|
||||
b1[a].vx -= chouilla;
|
||||
b1[c].vx += chouilla;
|
||||
chouilla = val*Math.sin(angle);
|
||||
b1[a].vy-=chouilla;
|
||||
b1[c].vy+=chouilla;
|
||||
}
|
||||
return b1;
|
||||
},*/
|
||||
|
||||
/**
|
||||
* @function degreesToString
|
||||
* @function
|
||||
* @memberof AladinUtils
|
||||
* @name degreesToString
|
||||
* Convert a number in degrees into a string<br>
|
||||
*
|
||||
* @param numberDegrees number in degrees (integer or decimal)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -222,7 +222,31 @@
|
||||
return [this.minCut, this.maxCut];
|
||||
};
|
||||
|
||||
ColorCfg.COLORMAPS = [];
|
||||
ColorCfg.COLORMAPS = [
|
||||
"blues",
|
||||
"cividis",
|
||||
"cubehelix",
|
||||
"eosb",
|
||||
"grayscale",
|
||||
"inferno",
|
||||
"magma",
|
||||
"native",
|
||||
"parula",
|
||||
"plasma",
|
||||
"rainbow",
|
||||
"rdbu",
|
||||
"rdylbu",
|
||||
"redtemperature",
|
||||
"sinebow",
|
||||
"spectral",
|
||||
"summer",
|
||||
"viridis",
|
||||
"ylgnbu",
|
||||
"ylorbr",
|
||||
"red",
|
||||
"green",
|
||||
"blue"
|
||||
];
|
||||
|
||||
return ColorCfg;
|
||||
})();
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
// 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 ColorMap.js
|
||||
*
|
||||
* Author: Thomas Boch[CDS]
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
import { AladinUtils } from "./AladinUtils.js";
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.0
|
||||
*/
|
||||
export let ColorMap = (function() {
|
||||
|
||||
|
||||
// constructor
|
||||
let ColorMap = function(view) {
|
||||
this.view = view;
|
||||
this.reversed = false;
|
||||
this.mapName = 'native';
|
||||
this.sig = this.signature();
|
||||
};
|
||||
|
||||
ColorMap.MAPS = {};
|
||||
|
||||
ColorMap.MAPS['eosb'] = {
|
||||
name: 'Eos B',
|
||||
r: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,9,18,27,36,45,49,57,72,81,91,100,109,118,127,
|
||||
136,131,139,163,173,182,191,200,209,218,227,213,221,255,255,255,255,255,
|
||||
255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,
|
||||
255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,
|
||||
255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,
|
||||
229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,
|
||||
255,229,229,255,255,255,255,255,255,255,255,229,229,255,253,251,249,247,
|
||||
245,243,241,215,214,235,234,232,230,228,226,224,222,198,196,216,215,213,
|
||||
211,209,207,205,203,181,179,197,196,194,192,190,188,186,184,164,162,178,
|
||||
176,175,173,171,169,167,165,147,145,159,157,156,154,152,150,148,146,130,
|
||||
128,140,138,137,135,133,131,129,127,113,111,121,119,117,117],
|
||||
g: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,15,23,31,39,47,55,57,64,79,87,95,
|
||||
103,111,119,127,135,129,136,159,167,175,183,191,199,207,215,200,207,239,
|
||||
247,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,
|
||||
229,255,255,255,255,255,255,255,255,229,229,255,250,246,242,238,233,229,
|
||||
225,198,195,212,208,204,199,195,191,187,182,160,156,169,165,161,157,153,
|
||||
148,144,140,122,118,127,125,123,121,119,116,114,112,99,97,106,104,102,
|
||||
99,97,95,93,91,80,78,84,82,80,78,76,74,72,70,61,59,63,61,59,57,55,53,50,
|
||||
48,42,40,42,40,38,36,33,31,29,27,22,21,21,19,16,14,12,13,8,6,3,1,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
b: [116,121,127,131,136,140,144,148,153,
|
||||
157,145,149,170,174,178,182,187,191,195,199,183,187,212,216,221,225,229,
|
||||
233,238,242,221,225,255,247,239,231,223,215,207,199,172,164,175,167,159,
|
||||
151,143,135,127,119,100,93,95,87,79,71,63,55,47,39,28,21,15,7,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0]
|
||||
};
|
||||
ColorMap.MAPS['rainbow'] = {
|
||||
name: 'Rainbow',
|
||||
r: [0,4,9,13,18,22,27,31,36,40,45,50,54,
|
||||
58,61,64,68,69,72,74,77,79,80,82,83,85,84,86,87,88,86,87,87,87,85,84,84,
|
||||
84,83,79,78,77,76,71,70,68,66,60,58,55,53,46,43,40,36,33,25,21,16,12,4,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,12,21,25,29,33,42,
|
||||
46,51,55,63,67,72,76,80,89,93,97,101,110,114,119,123,131,135,140,144,153,
|
||||
157,161,165,169,178,182,187,191,199,203,208,212,221,225,229,233,242,246,
|
||||
250,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255],
|
||||
g: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,4,8,16,21,25,29,38,42,46,51,55,63,67,72,76,84,89,93,97,
|
||||
106,110,114,119,127,131,135,140,144,152,157,161,165,174,178,182,187,195,
|
||||
199,203,208,216,220,225,229,233,242,246,250,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,250,242,238,233,229,221,216,212,208,199,195,191,187,178,174,170,165,
|
||||
161,153,148,144,140,131,127,123,119,110,106,102,97,89,85,80,76,72,63,59,
|
||||
55,51,42,38,34,29,21,17,12,8,0],
|
||||
b: [0,3,7,10,14,19,23,28,32,38,43,48,53,
|
||||
59,63,68,72,77,81,86,91,95,100,104,109,113,118,122,127,132,136,141,145,
|
||||
150,154,159,163,168,173,177,182,186,191,195,200,204,209,214,218,223,227,
|
||||
232,236,241,245,250,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
255,255,255,255,255,255,246,242,238,233,225,220,216,212,203,199,195,191,
|
||||
187,178,174,170,165,157,152,148,144,135,131,127,123,114,110,106,102,97,
|
||||
89,84,80,76,67,63,59,55,46,42,38,34,25,21,16,12,8,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
||||
};
|
||||
ColorMap.MAPS['cubehelix'] = {
|
||||
name: 'Cubehelix',
|
||||
r: [0,1,3,4,6,8,9,10,12,13,14,15,17,18,
|
||||
19,20,20,21,22,23,23,24,24,25,25,25,26,26,26,26,26,26,26,26,26,26,26,25,
|
||||
25,25,25,24,24,24,23,23,23,23,22,22,22,21,21,21,21,21,21,20,20,20,21,21,
|
||||
21,21,21,22,22,22,23,23,24,25,26,27,27,28,30,31,32,33,35,36,38,39,41,43,
|
||||
45,47,49,51,53,55,57,60,62,65,67,70,72,75,78,81,83,86,89,92,95,98,101,104,
|
||||
107,110,113,116,120,123,126,129,132,135,138,141,144,147,150,153,155,158,
|
||||
161,164,166,169,171,174,176,178,181,183,185,187,189,191,193,194,196,198,
|
||||
199,201,202,203,204,205,206,207,208,209,209,210,211,211,211,212,212,212,
|
||||
212,212,212,212,212,211,211,211,210,210,210,209,208,208,207,207,206,205,
|
||||
205,204,203,203,202,201,201,200,199,199,198,197,197,196,196,195,195,194,
|
||||
194,194,193,193,193,193,193,193,193,193,193,193,194,194,195,195,196,196,
|
||||
197,198,199,200,200,202,203,204,205,206,208,209,210,212,213,215,217,218,
|
||||
220,222,223,225,227,229,231,232,234,236,238,240,242,244,245,247,249,251,
|
||||
253,255],
|
||||
g: [0,0,1,1,2,2,3,4,4,5,6,6,7,8,9,10,
|
||||
11,11,12,13,14,15,17,18,19,20,21,22,24,25,26,28,29,31,32,34,35,37,38,40,
|
||||
41,43,45,46,48,50,52,53,55,57,58,60,62,64,66,67,69,71,73,74,76,78,79,81,
|
||||
83,84,86,88,89,91,92,94,95,97,98,99,101,102,103,104,106,107,108,109,110,
|
||||
111,112,113,114,114,115,116,116,117,118,118,119,119,120,120,120,121,121,
|
||||
121,121,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,121,
|
||||
121,121,121,121,121,121,121,121,120,120,120,120,120,120,120,120,120,120,
|
||||
121,121,121,121,121,122,122,122,123,123,124,124,125,125,126,127,127,128,
|
||||
129,130,131,131,132,133,135,136,137,138,139,140,142,143,144,146,147,149,
|
||||
150,152,154,155,157,158,160,162,164,165,167,169,171,172,174,176,178,180,
|
||||
182,183,185,187,189,191,193,194,196,198,200,202,203,205,207,208,210,212,
|
||||
213,215,216,218,219,221,222,224,225,226,228,229,230,231,232,233,235,236,
|
||||
237,238,239,240,240,241,242,243,244,244,245,246,247,247,248,248,249,250,
|
||||
250,251,251,252,252,253,253,254,255],
|
||||
b: [0,1,3,4,6,8,9,11,13,15,17,19,21,23,
|
||||
25,27,29,31,33,35,37,39,41,43,45,47,48,50,52,54,56,57,59,60,62,63,65,66,
|
||||
67,69,70,71,72,73,74,74,75,76,76,77,77,77,78,78,78,78,78,78,78,77,77,77,
|
||||
76,76,75,75,74,73,73,72,71,70,69,68,67,66,66,65,64,63,61,60,59,58,58,57,
|
||||
56,55,54,53,52,51,51,50,49,49,48,48,47,47,47,46,46,46,46,46,47,47,47,48,
|
||||
48,49,50,50,51,52,53,55,56,57,59,60,62,64,65,67,69,71,74,76,78,81,83,86,
|
||||
88,91,94,96,99,102,105,108,111,114,117,120,124,127,130,133,136,140,143,
|
||||
146,149,153,156,159,162,165,169,172,175,178,181,184,186,189,192,195,197,
|
||||
200,203,205,207,210,212,214,216,218,220,222,224,226,227,229,230,231,233,
|
||||
234,235,236,237,238,239,239,240,241,241,242,242,242,243,243,243,243,243,
|
||||
243,243,243,243,243,242,242,242,242,241,241,241,241,240,240,240,239,239,
|
||||
239,239,239,238,238,238,238,238,238,238,238,239,239,239,240,240,240,241,
|
||||
242,242,243,244,245,246,247,248,249,250,252,253,255]
|
||||
};
|
||||
|
||||
|
||||
|
||||
ColorMap.MAPS_CUSTOM = ['cubehelix', 'eosb', 'rainbow'];
|
||||
ColorMap.MAPS_NAMES = ['native', 'grayscale'].concat(ColorMap.MAPS_CUSTOM);
|
||||
|
||||
ColorMap.prototype.reverse = function(val) {
|
||||
if (val) {
|
||||
this.reversed = val;
|
||||
}
|
||||
else {
|
||||
this.reversed = ! this.reversed;
|
||||
}
|
||||
this.sig = this.signature();
|
||||
this.view.requestRedraw();
|
||||
};
|
||||
|
||||
|
||||
ColorMap.prototype.signature = function() {
|
||||
var s = this.mapName;
|
||||
|
||||
if (this.reversed) {
|
||||
s += ' reversed';
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
|
||||
ColorMap.prototype.update = function(mapName) {
|
||||
this.mapName = mapName;
|
||||
this.sig = this.signature();
|
||||
this.view.requestRedraw();
|
||||
};
|
||||
|
||||
ColorMap.prototype.apply = function(img) {
|
||||
if ( this.sig=='native' ) {
|
||||
return img;
|
||||
}
|
||||
|
||||
if (img.cmSig==this.sig) {
|
||||
return img.cmImg; // return cached pixels
|
||||
}
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
var pixelData = imageData.data;
|
||||
var length = pixelData.length;
|
||||
var a, b, c;
|
||||
var switchCase = 3;
|
||||
if (this.mapName=='grayscale') {
|
||||
switchCase = 1;
|
||||
}
|
||||
else if (ColorMap.MAPS_CUSTOM.indexOf(this.mapName)>=0) {
|
||||
switchCase = 2;
|
||||
}
|
||||
for (var i = 0; i < length; i+= 4) {
|
||||
switch(switchCase) {
|
||||
case 1:
|
||||
a = b = c = AladinUtils.myRound((pixelData[i]+pixelData[i+1]+pixelData[i+2])/3);
|
||||
break;
|
||||
case 2:
|
||||
if (this.reversed) {
|
||||
a = ColorMap.MAPS[this.mapName].r[255-pixelData[i]];
|
||||
b = ColorMap.MAPS[this.mapName].g[255-pixelData[i+1]];
|
||||
c = ColorMap.MAPS[this.mapName].b[255-pixelData[i+2]];
|
||||
}
|
||||
else {
|
||||
a = ColorMap.MAPS[this.mapName].r[pixelData[i]];
|
||||
b = ColorMap.MAPS[this.mapName].g[pixelData[i+1]];
|
||||
c = ColorMap.MAPS[this.mapName].b[pixelData[i+2]];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
a = pixelData[i];
|
||||
b = pixelData[i + 1];
|
||||
c = pixelData[i + 2];
|
||||
|
||||
}
|
||||
if (switchCase!=2 && this.reversed) {
|
||||
a = 255-a;
|
||||
b = 255-b;
|
||||
c = 255-c;
|
||||
|
||||
}
|
||||
pixelData[i] = a;
|
||||
pixelData[i + 1] = b;
|
||||
pixelData[i + 2] = c;
|
||||
|
||||
}
|
||||
//imageData.data = pixelData; // not needed, and create an error in strict mode !
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
// cache image with color map applied
|
||||
img.cmSig = this.sig;
|
||||
img.cmImg = canvas;
|
||||
|
||||
return img.cmImg;
|
||||
};
|
||||
|
||||
return ColorMap;
|
||||
})();
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
import { GenericPointer } from "./GenericPointer.js";
|
||||
import A from "./A.js";
|
||||
import { CatalogQueryBox } from "./gui/Box/CatalogQueryBox.js";
|
||||
import cameraIconUrl from '../../assets/icons/camera.svg'
|
||||
import targetIconUrl from '../../assets/icons/target.svg';
|
||||
import uploadIconUrl from '../../assets/icons/upload.svg';
|
||||
|
||||
export let DefaultActionsForContextMenu = (function () {
|
||||
|
||||
@@ -45,31 +48,43 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
return [
|
||||
{
|
||||
label: "Copy position", action(o) {
|
||||
var r = document.createRange();
|
||||
r.selectNode(o.target);
|
||||
window.getSelection().removeAllRanges();
|
||||
window.getSelection().addRange(r);
|
||||
let statusBarMsg;
|
||||
try {
|
||||
let successful = document.execCommand('copy');
|
||||
statusBarMsg = successful ? 'Position copied!' : 'Position could not be copied!';
|
||||
} catch (err) {
|
||||
statusBarMsg = 'Oops, unable to copy to clipboard';
|
||||
let msg;
|
||||
let text = o.target.innerText;
|
||||
if (!text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.statusBar) {
|
||||
a.statusBar.appendMessage({
|
||||
message: statusBarMsg,
|
||||
duration: 2000,
|
||||
type: 'info'
|
||||
navigator.clipboard.writeText(text)
|
||||
.then(() => {
|
||||
msg = 'successful'
|
||||
if (aladinInstance.statusBar) {
|
||||
aladinInstance.statusBar.appendMessage({
|
||||
message: 'Reticle location saved!',
|
||||
duration: 2000,
|
||||
type: 'info'
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
msg = 'unsuccessful'
|
||||
console.info('Oops, unable to copy', e);
|
||||
})
|
||||
.finally(() => {
|
||||
console.info('Copying text command was ' + msg);
|
||||
})
|
||||
}
|
||||
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Take snapshot", action(o) { a.exportAsPNG(); }
|
||||
label: {
|
||||
icon: {
|
||||
tooltip: {content: 'Download a PNG image file of the view', position: {direction: 'top'}},
|
||||
monochrome: true,
|
||||
url: cameraIconUrl,
|
||||
size: 'small',
|
||||
},
|
||||
content: 'Take a snapshot'
|
||||
},
|
||||
action(o) { a.exportAsPNG(); }
|
||||
},
|
||||
{
|
||||
label: "Add",
|
||||
@@ -85,23 +100,30 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
{
|
||||
label: 'New catalogue layer', action(o) {
|
||||
let catBox = new CatalogQueryBox(a)
|
||||
if (catBox.isHidden) {
|
||||
catBox._show({
|
||||
header: {
|
||||
title: 'Add a new catalogue',
|
||||
draggable: true
|
||||
},
|
||||
position: {
|
||||
anchor :'center center'
|
||||
},
|
||||
});
|
||||
}
|
||||
catBox._show({
|
||||
header: {
|
||||
title: 'Add a new catalogue',
|
||||
draggable: true
|
||||
},
|
||||
position: {
|
||||
anchor :'center center'
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Load local file",
|
||||
label: {
|
||||
icon: {
|
||||
monochrome: true,
|
||||
url: uploadIconUrl,
|
||||
cssStyle: {
|
||||
cursor: 'help',
|
||||
}
|
||||
},
|
||||
content: "Load a local file"
|
||||
},
|
||||
subMenu: [
|
||||
{
|
||||
label: 'FITS image', action(o) {
|
||||
@@ -169,8 +191,21 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "What is this?", action(o) {
|
||||
GenericPointer(a.view, o);
|
||||
label: {
|
||||
icon: {
|
||||
tooltip: {content: 'Use Sesame, our name resolver!', position: {direction: 'top'}},
|
||||
monochrome: true,
|
||||
url: targetIconUrl,
|
||||
size: 'small',
|
||||
},
|
||||
content: 'What is this?'
|
||||
},
|
||||
|
||||
action(o, ctxMenu) {
|
||||
GenericPointer(a.view, {
|
||||
x: parseInt(ctxMenu.element().style.left),
|
||||
y: parseInt(ctxMenu.element().style.top)
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user