mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-25 20:34:50 -08:00
Compare commits
96 Commits
cssUI
...
new-line-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e89769c87d | ||
|
|
253c272262 | ||
|
|
05c3eb5911 | ||
|
|
631b2cdf4b | ||
|
|
3fee4a345d | ||
|
|
2b69ae8a0d | ||
|
|
957f2b2414 | ||
|
|
d8cb01ddef | ||
|
|
1ad97180f3 | ||
|
|
8d9ca2e2b9 | ||
|
|
776cd36969 | ||
|
|
49061a746b | ||
|
|
1065dbe714 | ||
|
|
dcbefb6daa | ||
|
|
4d1a3f08d7 | ||
|
|
2b5f8a751a | ||
|
|
6df2ee9757 | ||
|
|
813589bfdc | ||
|
|
51a1c514ae | ||
|
|
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,41 @@
|
||||
# Changelogs
|
||||
|
||||
## 3.4.2-beta
|
||||
|
||||
* [impr] Improve `WCS` view export with 3rd euler rotation encoding: <https://github.com/cds-astro/aladin-lite/issues/170>. Still some cases are to be handled like: crval on the equator or cylindrical with a galactic frame rotation.
|
||||
* [fixed] Change `RADECSYS` to `RADESYS` for `Aladin#getViewWCS` to follow fits standard deprecation
|
||||
* [feat] Add new method `Aladin#getViewImageBuffer` to get the current view as a PNG buffer
|
||||
* [feat] New line rasterizer using GL instancing. This enhances the rendering speed of MOCs.
|
||||
|
||||
## 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
|
||||
@@ -326,4 +360,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();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, maximum-scale=1.0, initial-scale=1.0, user-scalable=no">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@@ -22,6 +23,7 @@
|
||||
reticleColor: '#ff89ff', // change reticle color
|
||||
reticleSize: 64, // change reticle size
|
||||
showContextMenu: true,
|
||||
fullScreen: true,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -70,7 +72,7 @@
|
||||
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>
|
||||
@@ -89,11 +91,12 @@
|
||||
|
||||
.myButton {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
bottom: 100px;
|
||||
left: 0;
|
||||
|
||||
background-color: pink;
|
||||
}
|
||||
|
||||
</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,21 +21,21 @@ 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'}));
|
||||
|
||||
|
||||
|
||||
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>
|
||||
@@ -1,6 +1,8 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||
@@ -12,7 +14,7 @@
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {showReticle: true, showSurveyStackControl: true, showOverlayStackControl: false, projection: "TAN", target: '15 16 57.636 -60 55 7.49', showProjectionControl: true, realFullscreen: true, showZoomControl: true, showSimbadPointerControl: true, showShareControl: true, showContextMenu: true, showCooGridControl: true, fullScreen: true, showCooGrid: true, fov: 90});
|
||||
|
||||
var moc_0_99 = A.MOCFromURL("./data//gw/gw_0.9.fits",{ name: "GW 90%", color: "#ff0000", opacity: 0.0, lineWidth: 3, fill: false, perimeter: true});
|
||||
var moc_0_99 = A.MOCFromURL("./data//gw/gw_0.9.fits",{ name: "GW 90%", color: "#ff0000", opacity: 0.0, lineWidth: 10, fill: false, perimeter: true});
|
||||
var moc_0_95 = A.MOCFromURL("./data/gw/gw_0.6.fits",{ name: "GW 60%", color: "#00ff00", opacity: 0.5, lineWidth: 3, fill: true, perimeter: true});
|
||||
var moc_0_5 = A.MOCFromURL("./data/gw/gw_0.3.fits",{ name: "GW 30%", color: "#00ffff", opacity: 0.5, lineWidth: 3, fill: true, perimeter: true});
|
||||
var moc_0_2 = A.MOCFromURL("./data/gw/gw_0.1.fits",{ name: "GW 10%", color: "#ff00ff", opacity: 0.5, lineWidth: 3, fill: true, perimeter: true});
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -1,40 +1,34 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<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: 1024px; height: 768px"></div>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 768px; height: 512px"></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
|
||||
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,
|
||||
cooFrame: 'icrs', // set galactic frame
|
||||
reticleColor: '#ff89ff', // change reticle color
|
||||
reticleSize: 64, // change reticle size
|
||||
showContextMenu: true,
|
||||
showCooGridControl: true,
|
||||
showSimbadPointerControl: true,
|
||||
showFullscreenControl: true,
|
||||
showCooGrid: true,
|
||||
showFrame: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,7 +1,8 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<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: 1024px; height: 768px">
|
||||
<div id="ui" class="ui">
|
||||
@@ -11,13 +12,13 @@
|
||||
import A from '../src/js/A.js';
|
||||
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) => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: '00 00 00 +07 00 00', fov: 130, survey: 'P/Mellinger/color', showContextMenu: true});
|
||||
var moc11 = A.MOCFromURL('http://skies.esac.esa.int/HST/NICMOS/Moc.fits', {color: '#84f', lineWidth: 3}, (moc) => {
|
||||
// moc is ready
|
||||
console.log(moc.contains(205.9019247, +2.4492764));
|
||||
console.log(moc.contains(-205.9019247, +2.4492764));
|
||||
});
|
||||
var moc10 = A.MOCFromURL('https://alasky.unistra.fr/MocServer/query?ivorn=ivo%3A%2F%2FCDS%2FV%2F139%2Fsdss9&get=moc&order=11&fmt=fits', {color: '#ffffff', perimeter: true, fillColor: '#aabbcc', opacity: 0.1, lineWidth: 3});
|
||||
var moc10 = A.MOCFromURL('https://alasky.unistra.fr/MocServer/query?ivorn=ivo%3A%2F%2FCDS%2FV%2F139%2Fsdss9&get=moc&order=11&fmt=fits', {color: '#ffffff', perimeter: true, fillColor: '#aabbcc', opacity: 0.3, lineWidth: 3});
|
||||
var moc9 = A.MOCFromURL('https://alasky.unistra.fr/MocServer/query?ivorn=ivo%3A%2F%2FCDS%2FV%2F139%2Fsdss9&get=moc&order=4&fmt=fits', {color: '#00ff00', opacity: 0.5, lineWidth: 3, perimeter: true});
|
||||
|
||||
aladin.addMOC(moc11);
|
||||
|
||||
@@ -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>
|
||||
|
||||
34
examples/al-save-colormap.html
Normal file
34
examples/al-save-colormap.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<!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);
|
||||
|
||||
aladin.removeHiPSFromFavorites(survey3);
|
||||
});
|
||||
</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>
|
||||
@@ -11,10 +11,10 @@
|
||||
|
||||
A.init.then(() => {
|
||||
// Start up Aladin Lite
|
||||
let aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'Sgr a*', fov: 0.5, showContextMenu: true});
|
||||
let aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'Sgr a*', fov: 0.5, showContextMenu: true, showCooGrid: 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
|
||||
});
|
||||
}
|
||||
|
||||
22
jsdoc.json
Normal file
22
jsdoc.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"plugins": [],
|
||||
"recurseDepth": 10,
|
||||
"source": {
|
||||
"includePattern": ".+\\.js(doc|x)?$",
|
||||
"excludePattern": "(^|\\/|\\\\)_"
|
||||
},
|
||||
"sourceType": "module",
|
||||
"tags": {
|
||||
"allowUnknownTags": true,
|
||||
"dictionaries": ["jsdoc","closure"]
|
||||
},
|
||||
"templates": {
|
||||
"cleverLinks": true,
|
||||
"monospaceLinks": true
|
||||
},
|
||||
"opts": {
|
||||
"readme": "./README.md",
|
||||
"destination": "./docs/",
|
||||
"tutorials": "./tutorials"
|
||||
}
|
||||
}
|
||||
14
package.json
14
package.json
@@ -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,16 +33,20 @@
|
||||
],
|
||||
"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",
|
||||
"wasm:dbg": "wasm-pack build --dev ./src/core --target web --out-name core -- --features=webgl2,dbg -Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort ",
|
||||
"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",
|
||||
"build:dbg": "npm run wasm:dbg && vite build && cp examples/index.html dist/index.html",
|
||||
"dev": "npm run build && vite",
|
||||
"dev:dbg": "npm run build:dbg && vite",
|
||||
"serve": "npm run dev",
|
||||
"serve:dbg": "npm run dev:dbg",
|
||||
"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:dev": "npm run doc && open doc/index.html"
|
||||
"doc": "jsdoc -c jsdoc.json src/js src/js/shapes && cp aladin-logo.png docs/",
|
||||
"doc:dev": "npm run doc && open docs/index.html"
|
||||
},
|
||||
"devDependencies": {
|
||||
"happy-dom": "^10.11.0",
|
||||
@@ -50,7 +54,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"
|
||||
|
||||
@@ -29,24 +29,27 @@ mapproj = "0.3.0"
|
||||
fitsrs = "0.2.9"
|
||||
wcs = "0.2.8"
|
||||
colorgrad = "0.6.2"
|
||||
lyon = "1.0.1"
|
||||
#lyon = "1.0.1"
|
||||
console_error_panic_hook = {version = "0.1.7", optional = true}
|
||||
|
||||
[features]
|
||||
webgl1 = [ "al-core/webgl1", "al-api/webgl1", "web-sys/WebGlRenderingContext", "web-sys/AngleInstancedArrays", "web-sys/ExtSRgb", "web-sys/OesTextureFloat",]
|
||||
webgl2 = [ "al-core/webgl2", "al-api/webgl2", "web-sys/WebGl2RenderingContext", "web-sys/WebGlVertexArrayObject", "web-sys/ExtColorBufferFloat",]
|
||||
dbg = ['dep:console_error_panic_hook']
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8"
|
||||
|
||||
[dependencies.healpix]
|
||||
package = "cdshealpix"
|
||||
git = "https://github.com/bmatthieu3/cds-healpix-rust"
|
||||
branch = "polygonIntersectVertices"
|
||||
git = "https://github.com/cds-astro/cds-healpix-rust"
|
||||
branch = "master"
|
||||
|
||||
[dependencies.moclib]
|
||||
package = "moc"
|
||||
#path = "../../../cds-moc-rust/"
|
||||
git = "https://github.com/bmatthieu3/cds-moc-rust"
|
||||
branch = "cellsWithUnidirectionalNeigs"
|
||||
branch = "overlap"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "^1.0.183"
|
||||
@@ -68,16 +71,12 @@ version = "0.24.2"
|
||||
default-features = false
|
||||
features = [ "jpeg", "png",]
|
||||
|
||||
[build-dependencies]
|
||||
# Shader preprocessing
|
||||
walkdir = "2.3.2"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = "z"
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
overflow-checks = true
|
||||
lto = true
|
||||
panic = "unwind"
|
||||
incremental = true
|
||||
codegen-units = 256
|
||||
rpath = false
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
|
||||
@@ -43,11 +43,11 @@ 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>>,
|
||||
|
||||
#[allow(unused)]
|
||||
is_planetary_body: Option<bool>,
|
||||
|
||||
bitpix: Option<i32>,
|
||||
@@ -59,7 +59,9 @@ pub struct HiPSProperties {
|
||||
hips_initial_dec: Option<f64>,
|
||||
|
||||
// Parametrable by the user
|
||||
#[allow(unused)]
|
||||
min_cutout: Option<f32>,
|
||||
#[allow(unused)]
|
||||
max_cutout: Option<f32>,
|
||||
|
||||
creator_did: String,
|
||||
@@ -103,7 +105,7 @@ impl HiPSProperties {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_frame(&self) -> CooSystem {
|
||||
self.frame
|
||||
self.coo_frame
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -125,11 +127,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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::webgl_ctx::WebGlContext;
|
||||
pub struct ArrayBufferInstanced {
|
||||
buffer: WebGlBuffer,
|
||||
|
||||
len: usize,
|
||||
num_packed_data: usize,
|
||||
offset_idx: u32,
|
||||
|
||||
@@ -39,7 +40,7 @@ impl ArrayBufferInstanced {
|
||||
offset_idx: u32,
|
||||
stride: usize,
|
||||
sizes: &[usize],
|
||||
_offsets: &[usize],
|
||||
offsets: &[usize],
|
||||
usage: u32,
|
||||
data: B,
|
||||
) -> ArrayBufferInstanced {
|
||||
@@ -49,29 +50,43 @@ impl ArrayBufferInstanced {
|
||||
let num_f32_in_buf = data.len() as i32;
|
||||
|
||||
let num_instances = num_f32_in_buf / (num_f32_per_instance as i32);
|
||||
let len = data.len();
|
||||
|
||||
let buffer = gl.create_buffer().ok_or("failed to create buffer").unwrap_abort();
|
||||
let buffer = gl
|
||||
.create_buffer()
|
||||
.ok_or("failed to create buffer")
|
||||
.unwrap_abort();
|
||||
|
||||
// Bind the buffer
|
||||
gl.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, Some(buffer.as_ref()));
|
||||
// Pass the vertices data to the buffer
|
||||
f32::buffer_data_with_array_buffer_view(gl, data, WebGlRenderingCtx::ARRAY_BUFFER, usage);
|
||||
// Link to the shader
|
||||
let idx = offset_idx;
|
||||
for (idx, (size, offset)) in sizes.iter().zip(offsets.iter()).enumerate() {
|
||||
let idx = (idx as u32) + offset_idx;
|
||||
|
||||
f32::vertex_attrib_pointer_with_i32(gl, idx, *sizes.first().unwrap_abort() as i32, 0, 0);
|
||||
gl.enable_vertex_attrib_array(idx);
|
||||
f32::vertex_attrib_pointer_with_i32(
|
||||
gl,
|
||||
idx,
|
||||
*size as i32,
|
||||
stride as i32,
|
||||
*offset as i32,
|
||||
);
|
||||
|
||||
#[cfg(feature = "webgl2")]
|
||||
gl.vertex_attrib_divisor(idx, 1);
|
||||
#[cfg(feature = "webgl1")]
|
||||
gl.ext.angles.vertex_attrib_divisor_angle(idx, 1);
|
||||
gl.enable_vertex_attrib_array(idx);
|
||||
|
||||
#[cfg(feature = "webgl2")]
|
||||
gl.vertex_attrib_divisor(idx, 1);
|
||||
#[cfg(feature = "webgl1")]
|
||||
gl.ext.angles.vertex_attrib_divisor_angle(idx, 1);
|
||||
}
|
||||
|
||||
let num_packed_data = sizes.len();
|
||||
let gl = gl.clone();
|
||||
// Returns an instance that keeps only the buffer
|
||||
ArrayBufferInstanced {
|
||||
buffer,
|
||||
len,
|
||||
num_packed_data,
|
||||
offset_idx,
|
||||
|
||||
@@ -119,13 +134,30 @@ impl ArrayBufferInstanced {
|
||||
self.gl.disable_vertex_attrib_array(loc as u32);
|
||||
}
|
||||
|
||||
pub fn update<'a, B: BufferDataStorage<'a, f32>>(&self, buffer: B) {
|
||||
pub fn update<'a, B: BufferDataStorage<'a, f32>>(&mut self, usage: u32, data: B) {
|
||||
self.bind();
|
||||
f32::buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
if self.len >= data.len() {
|
||||
f32::buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
&self.gl,
|
||||
data,
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
);
|
||||
} else {
|
||||
self.len = data.len();
|
||||
|
||||
f32::buffer_data_with_array_buffer_view(
|
||||
&self.gl,
|
||||
data,
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
usage,
|
||||
);
|
||||
}
|
||||
|
||||
/*f32::buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
&self.gl,
|
||||
buffer,
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
);
|
||||
);*/
|
||||
/*self.gl.buffer_sub_data_with_i32_and_array_buffer_view(
|
||||
WebGlRenderingCtx::ARRAY_BUFFER,
|
||||
0,
|
||||
|
||||
@@ -41,3 +41,20 @@ where
|
||||
self.0.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> BufferDataStorage<'a, T> for &'a [T]
|
||||
where
|
||||
T: VertexAttribPointerType,
|
||||
{
|
||||
fn get_slice(&self) -> &[T] {
|
||||
self
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.as_ref().len()
|
||||
}
|
||||
|
||||
fn ptr(&self) -> *const T {
|
||||
self.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@ pub mod buffer_data;
|
||||
pub mod element_array_buffer;
|
||||
pub mod vertex_array_object;
|
||||
|
||||
pub use array_buffer::ArrayBuffer;
|
||||
pub use array_buffer::VertexAttribPointerType;
|
||||
pub use framebuffer::FrameBufferObject;
|
||||
pub use vertex_array_object::vao::{
|
||||
ShaderVertexArrayObjectBound, ShaderVertexArrayObjectBoundRef, VertexArrayObject,
|
||||
};
|
||||
|
||||
@@ -9,8 +9,8 @@ pub mod vao {
|
||||
use crate::object::element_array_buffer::ElementArrayBuffer;
|
||||
|
||||
use crate::webgl_ctx::WebGlContext;
|
||||
use std::collections::HashMap;
|
||||
use crate::Abort;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct VertexArrayObject {
|
||||
array_buffer: HashMap<&'static str, ArrayBuffer>,
|
||||
@@ -88,7 +88,10 @@ pub mod vao {
|
||||
}*/
|
||||
|
||||
pub fn num_elements(&self) -> usize {
|
||||
self.element_array_buffer.as_ref().unwrap_abort().num_elements()
|
||||
self.element_array_buffer
|
||||
.as_ref()
|
||||
.unwrap_abort()
|
||||
.num_elements()
|
||||
}
|
||||
|
||||
pub fn num_instances(&self) -> i32 {
|
||||
@@ -143,13 +146,14 @@ pub mod vao {
|
||||
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
|
||||
&mut self,
|
||||
attr: &'static str,
|
||||
usage: u32,
|
||||
array_data: B,
|
||||
) -> &mut Self {
|
||||
self.vao
|
||||
.array_buffer_instanced
|
||||
.get_mut(attr)
|
||||
.unwrap_abort()
|
||||
.update(array_data);
|
||||
.update(usage, array_data);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -333,13 +337,14 @@ pub mod vao {
|
||||
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
|
||||
&mut self,
|
||||
attr: &'static str,
|
||||
usage: u32,
|
||||
array_data: B,
|
||||
) -> &mut Self {
|
||||
self.vao
|
||||
.array_buffer_instanced
|
||||
.get_mut(attr)
|
||||
.unwrap_abort()
|
||||
.update(array_data);
|
||||
.update(usage, array_data);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -444,7 +449,10 @@ pub mod vao {
|
||||
}*/
|
||||
|
||||
pub fn num_elements(&self) -> usize {
|
||||
self.element_array_buffer.as_ref().unwrap_abort().num_elements()
|
||||
self.element_array_buffer
|
||||
.as_ref()
|
||||
.unwrap_abort()
|
||||
.num_elements()
|
||||
}
|
||||
|
||||
pub fn num_instances(&self) -> i32 {
|
||||
@@ -694,13 +702,14 @@ pub mod vao {
|
||||
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
|
||||
&mut self,
|
||||
attr: &'static str,
|
||||
usage: u32,
|
||||
array_data: B,
|
||||
) -> &mut Self {
|
||||
self.vao
|
||||
.array_buffer_instanced
|
||||
.get_mut(attr)
|
||||
.expect("cannot get attribute from the array buffer")
|
||||
.update(array_data);
|
||||
.update(usage, array_data);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use web_sys::{WebGlProgram, WebGlShader, WebGlUniformLocation};
|
||||
use wasm_bindgen::JsValue;
|
||||
use web_sys::{WebGlProgram, WebGlShader, WebGlUniformLocation};
|
||||
|
||||
use crate::Colormaps;
|
||||
use crate::webgl_ctx::WebGlRenderingCtx;
|
||||
use crate::Colormaps;
|
||||
fn compile_shader(
|
||||
gl: &WebGlContext,
|
||||
shader_type: u32,
|
||||
@@ -289,17 +289,6 @@ impl UniformType for TransferFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/*use al_api::hips::GrayscaleParameter;
|
||||
impl SendUniforms for GrayscaleParameter {
|
||||
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
|
||||
shader
|
||||
.attach_uniforms_from(&self.h)
|
||||
.attach_uniform("min_value", &self.min_value)
|
||||
.attach_uniform("max_value", &self.max_value);
|
||||
|
||||
shader
|
||||
}
|
||||
}*/
|
||||
use al_api::hips::HiPSColor;
|
||||
use al_api::hips::ImageMetadata;
|
||||
|
||||
@@ -314,7 +303,7 @@ impl SendUniforms for ImageMetadata {
|
||||
}
|
||||
|
||||
impl SendUniforms for HiPSColor {
|
||||
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
|
||||
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
|
||||
let reversed = self.reversed as u8 as f32;
|
||||
|
||||
shader
|
||||
@@ -326,14 +315,17 @@ impl SendUniforms for HiPSColor {
|
||||
.attach_uniform("k_brightness", &self.k_brightness)
|
||||
.attach_uniform("k_contrast", &self.k_contrast)
|
||||
.attach_uniform("reversed", &reversed);
|
||||
|
||||
|
||||
shader
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl SendUniformsWithParams<Colormaps> for HiPSColor {
|
||||
fn attach_uniforms_with_params<'a>(&self, shader: &'a ShaderBound<'a>, cmaps: &Colormaps) -> &'a ShaderBound<'a> {
|
||||
fn attach_uniforms_with_params<'a>(
|
||||
&self,
|
||||
shader: &'a ShaderBound<'a>,
|
||||
cmaps: &Colormaps,
|
||||
) -> &'a ShaderBound<'a> {
|
||||
let reversed = self.reversed as u8 as f32;
|
||||
|
||||
let cmap = cmaps.get(&self.cmap_name.as_ref());
|
||||
@@ -347,7 +339,7 @@ impl SendUniformsWithParams<Colormaps> for HiPSColor {
|
||||
.attach_uniform("k_brightness", &self.k_brightness)
|
||||
.attach_uniform("k_contrast", &self.k_contrast)
|
||||
.attach_uniform("reversed", &reversed);
|
||||
|
||||
|
||||
shader
|
||||
}
|
||||
}
|
||||
@@ -375,7 +367,11 @@ impl<'a> ShaderBound<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn attach_uniforms_with_params_from<P, T: SendUniformsWithParams<P>>(&'a self, t: &T, params: &P) -> &'a Self {
|
||||
pub fn attach_uniforms_with_params_from<P, T: SendUniformsWithParams<P>>(
|
||||
&'a self,
|
||||
t: &T,
|
||||
params: &P,
|
||||
) -> &'a Self {
|
||||
t.attach_uniforms_with_params(self, params);
|
||||
|
||||
self
|
||||
@@ -422,5 +418,9 @@ pub trait SendUniforms {
|
||||
}
|
||||
|
||||
pub trait SendUniformsWithParams<T> {
|
||||
fn attach_uniforms_with_params<'a>(&self, shader: &'a ShaderBound<'a>, params: &T) -> &'a ShaderBound<'a>;
|
||||
fn attach_uniforms_with_params<'a>(
|
||||
&self,
|
||||
shader: &'a ShaderBound<'a>,
|
||||
params: &T,
|
||||
) -> &'a ShaderBound<'a>;
|
||||
}
|
||||
|
||||
@@ -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?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
105
src/core/build.rs
Normal file
105
src/core/build.rs
Normal file
@@ -0,0 +1,105 @@
|
||||
use std::{error::Error, fs};
|
||||
use walkdir::WalkDir;
|
||||
extern crate walkdir;
|
||||
use std::io::BufRead;
|
||||
|
||||
// All my shaders reside in the 'src/shaders' directory
|
||||
fn generate_shaders() -> std::result::Result<(), Box<dyn Error>> {
|
||||
println!("generate shaders");
|
||||
let mut shaders = HashMap::new();
|
||||
|
||||
for entry in WalkDir::new("../glsl/webgl2/")
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
{
|
||||
if entry.file_type().is_file() {
|
||||
let path = entry.path();
|
||||
if let Some(ext) = path.extension() {
|
||||
if ext == "vert" || ext == "frag" {
|
||||
let file_name = path.file_name().unwrap().to_str().unwrap();
|
||||
|
||||
let out_file_name = path
|
||||
.strip_prefix("../glsl/webgl2/")
|
||||
.unwrap()
|
||||
//.with_extension("")
|
||||
.to_string_lossy()
|
||||
.to_owned()
|
||||
.replace("/", "_");
|
||||
//let out_name = format!("{}/{}", OUT_PATH, out_file_name);
|
||||
|
||||
let src = read_shader(path)?;
|
||||
shaders.insert(out_file_name, src);
|
||||
|
||||
//fs::write(&out_name, result)?;
|
||||
println!("cargo:rerun-if-changed=src/shaders/{}", file_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write("src/shaders.rs".into(), shaders)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_shader<P: AsRef<std::path::Path>>(path: P) -> std::io::Result<String> {
|
||||
let path = path.as_ref();
|
||||
let file = fs::File::open(path.to_str().unwrap())?;
|
||||
|
||||
let shader_src = std::io::BufReader::new(file)
|
||||
.lines()
|
||||
.flatten()
|
||||
.map(|l| {
|
||||
if l.starts_with("#include") {
|
||||
let incl_file_names: Vec<_> = l.split_terminator(&[';', ' '][..]).collect();
|
||||
let incl_file_name_rel = incl_file_names[1];
|
||||
let incl_file_name = path.parent().unwrap().join(incl_file_name_rel);
|
||||
|
||||
read_shader(incl_file_name.to_str().unwrap()).unwrap()
|
||||
} else {
|
||||
l
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
Ok(shader_src)
|
||||
}
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn write(path: PathBuf, entries: HashMap<String, String>) -> Result<(), Box<dyn Error>> {
|
||||
let mut all_the_files = File::create(&path)?;
|
||||
|
||||
writeln!(&mut all_the_files, r#"use std::collections::HashMap;"#,)?;
|
||||
writeln!(&mut all_the_files, r#""#,)?;
|
||||
writeln!(&mut all_the_files, r#"#[allow(dead_code)]"#,)?;
|
||||
writeln!(
|
||||
&mut all_the_files,
|
||||
r#"pub fn get_all() -> HashMap<&'static str, &'static str> {{"#,
|
||||
)?;
|
||||
writeln!(&mut all_the_files, r#" let mut out = HashMap::new();"#,)?;
|
||||
|
||||
for (name, content) in entries {
|
||||
writeln!(
|
||||
&mut all_the_files,
|
||||
r##" out.insert("{name}", r#"{content}"#);"##,
|
||||
)?;
|
||||
}
|
||||
|
||||
writeln!(&mut all_the_files, r#" out"#,)?;
|
||||
writeln!(&mut all_the_files, r#"}}"#,)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let Err(err) = generate_shaders() {
|
||||
// panic here for a nicer error message, otherwise it will
|
||||
// be flattened to one line for some reason
|
||||
panic!("Unable to generate shaders\n{}", err);
|
||||
}
|
||||
}
|
||||
@@ -2,26 +2,22 @@ use crate::{
|
||||
//async_task::{BuildCatalogIndex, ParseTableTask, TaskExecutor, TaskResult, TaskType},
|
||||
camera::CameraViewPort,
|
||||
downloader::Downloader,
|
||||
grid::ProjetedGrid,
|
||||
healpix::coverage::HEALPixCoverage,
|
||||
inertia::Inertia,
|
||||
math::{
|
||||
self,
|
||||
angle::{Angle, ArcDeg, ToAngle},
|
||||
angle::{Angle, ArcDeg},
|
||||
lonlat::{LonLat, LonLatT},
|
||||
},
|
||||
renderable::grid::ProjetedGrid,
|
||||
renderable::Layers,
|
||||
renderable::{
|
||||
catalog::Manager, coverage::MOCRenderer, line::RasterizedLineRenderer, ImageCfg, Renderer,
|
||||
catalog::Manager, line::RasterizedLineRenderer, moc::MOCRenderer, ImageCfg, Renderer,
|
||||
},
|
||||
shader::ShaderManager,
|
||||
tile_fetcher::TileFetcherQueue,
|
||||
time::DeltaTime,
|
||||
};
|
||||
use al_core::{
|
||||
info, inforec,
|
||||
log::{self, console_log},
|
||||
};
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
@@ -56,7 +52,7 @@ pub struct App {
|
||||
|
||||
//ui: GuiRef,
|
||||
shaders: ShaderManager,
|
||||
camera: CameraViewPort,
|
||||
pub camera: CameraViewPort,
|
||||
|
||||
downloader: Downloader,
|
||||
tile_fetcher: TileFetcherQueue,
|
||||
@@ -98,7 +94,7 @@ pub struct App {
|
||||
|
||||
colormaps: Colormaps,
|
||||
|
||||
projection: ProjectionType,
|
||||
pub projection: ProjectionType,
|
||||
|
||||
// Async data receivers
|
||||
fits_send: async_channel::Sender<ImageCfg>,
|
||||
@@ -106,16 +102,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 futures::io::BufReader; // 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 +126,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()));
|
||||
@@ -150,6 +145,7 @@ impl App {
|
||||
|
||||
//gl.enable(WebGl2RenderingContext::CULL_FACE);
|
||||
//gl.cull_face(WebGl2RenderingContext::BACK);
|
||||
//gl.enable(WebGl2RenderingContext::CULL_FACE);
|
||||
|
||||
// The tile buffer responsible for the tile requests
|
||||
let downloader = Downloader::new();
|
||||
@@ -170,7 +166,7 @@ impl App {
|
||||
let manager = Manager::new(&gl, &mut shaders, &camera, &resources)?;
|
||||
|
||||
// Grid definition
|
||||
let grid = ProjetedGrid::new(aladin_div)?;
|
||||
let grid = ProjetedGrid::new(gl.clone(), aladin_div)?;
|
||||
|
||||
// Variable storing the location to move to
|
||||
let inertia = None;
|
||||
@@ -195,7 +191,7 @@ impl App {
|
||||
|
||||
let request_for_new_tiles = true;
|
||||
|
||||
let moc = MOCRenderer::new()?;
|
||||
let moc = MOCRenderer::new(&gl)?;
|
||||
gl.clear_color(0.15, 0.15, 0.15, 1.0);
|
||||
|
||||
let (fits_send, fits_recv) = async_channel::unbounded::<ImageCfg>();
|
||||
@@ -261,8 +257,7 @@ impl App {
|
||||
fits_recv,
|
||||
ack_send,
|
||||
ack_recv,
|
||||
|
||||
callback_position_changed,
|
||||
//callback_position_changed,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -270,6 +265,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 +287,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),
|
||||
@@ -407,7 +405,7 @@ use al_api::cell::HEALPixCellProjeted;
|
||||
|
||||
use crate::downloader::request::tile::Tile;
|
||||
use crate::healpix::cell::HEALPixCell;
|
||||
use crate::renderable::coverage::moc::MOC;
|
||||
|
||||
use al_api::color::ColorRGB;
|
||||
|
||||
impl App {
|
||||
@@ -503,7 +501,7 @@ impl App {
|
||||
|
||||
pub(crate) fn add_moc(
|
||||
&mut self,
|
||||
mut cfg: al_api::moc::MOC,
|
||||
cfg: al_api::moc::MOC,
|
||||
moc: HEALPixCoverage,
|
||||
) -> Result<(), JsValue> {
|
||||
self.moc
|
||||
@@ -525,20 +523,19 @@ impl App {
|
||||
|
||||
pub(crate) fn set_moc_cfg(&mut self, cfg: al_api::moc::MOC) -> Result<(), JsValue> {
|
||||
self.moc
|
||||
.set_cfg(
|
||||
cfg,
|
||||
&mut self.camera,
|
||||
&self.projection,
|
||||
&mut self.line_renderer,
|
||||
)
|
||||
.set_cfg(cfg, &mut self.camera, &self.projection, &mut self.shaders)
|
||||
.ok_or_else(|| JsValue::from_str("MOC not found"))?;
|
||||
self.request_redraw = true;
|
||||
|
||||
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 +554,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 +572,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 +601,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 +618,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 +644,65 @@ impl App {
|
||||
} else {
|
||||
Some(image)
|
||||
};
|
||||
use al_core::image::ImageType;
|
||||
use fitsrs::fits::Fits;
|
||||
use std::io::Cursor;
|
||||
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 +714,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,8 +745,9 @@ impl App {
|
||||
}
|
||||
}
|
||||
Resource::PixelMetadata(metadata) => {
|
||||
if let Some(hips) = self.layers.get_mut_hips_from_url(&metadata.hips_url) {
|
||||
let mut cfg = hips.get_config_mut();
|
||||
if let Some(hips) = self.layers.get_mut_hips_from_cdid(&metadata.hips_cdid)
|
||||
{
|
||||
let cfg = hips.get_config_mut();
|
||||
|
||||
if let Some(metadata) = *metadata.value.lock().unwrap_abort() {
|
||||
cfg.blank = metadata.blank;
|
||||
@@ -702,9 +757,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 +811,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 +841,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)?;
|
||||
@@ -796,16 +849,6 @@ impl App {
|
||||
Ok(has_camera_moved)
|
||||
}
|
||||
|
||||
pub(crate) fn reset_north_orientation(&mut self) {
|
||||
// Reset the rotation around the center if there is one
|
||||
self.camera
|
||||
.set_rotation_around_center(Angle(0.0), &self.projection);
|
||||
// Reset the camera position to its current position
|
||||
// this will keep the current position but reset the orientation
|
||||
// so that the north pole is at the top of the center.
|
||||
self.set_center(&self.get_center());
|
||||
}
|
||||
|
||||
pub(crate) fn read_pixel(&self, pos: &Vector2<f64>, layer: &str) -> Result<JsValue, JsValue> {
|
||||
if let Some(lonlat) = self.screen_to_world(pos) {
|
||||
if let Some(survey) = self.layers.get_hips_from_layer(layer) {
|
||||
@@ -820,6 +863,10 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn draw_grid_labels(&mut self) -> Result<(), JsValue> {
|
||||
self.grid.draw_labels()
|
||||
}
|
||||
|
||||
pub(crate) fn draw(&mut self, force_render: bool) -> Result<(), JsValue> {
|
||||
/*let scene_redraw = self.rendering | force_render;
|
||||
let mut ui = self.ui.lock();
|
||||
@@ -901,26 +948,24 @@ impl App {
|
||||
//let fbo_view = &self.fbo_view;
|
||||
//catalogs.draw(&gl, shaders, camera, colormaps, fbo_view)?;
|
||||
//catalogs.draw(&gl, shaders, camera, colormaps, None, self.projection)?;
|
||||
self.line_renderer.begin();
|
||||
//Time::measure_perf("moc draw", || {
|
||||
self.moc.draw(
|
||||
&mut self.shaders,
|
||||
&mut self.camera,
|
||||
&self.projection,
|
||||
&mut self.line_renderer,
|
||||
);
|
||||
&mut self.shaders,
|
||||
//&mut self.line_renderer,
|
||||
)?;
|
||||
|
||||
self.line_renderer.begin();
|
||||
//Time::measure_perf("moc draw", || {
|
||||
|
||||
// Ok(())
|
||||
//})?;
|
||||
|
||||
self.grid.draw(
|
||||
&self.camera,
|
||||
&mut self.shaders,
|
||||
&self.projection,
|
||||
&mut self.line_renderer,
|
||||
)?;
|
||||
self.grid
|
||||
.draw(&self.camera, &self.projection, &mut self.shaders)?;
|
||||
self.line_renderer.end();
|
||||
self.line_renderer.draw(&self.camera)?;
|
||||
self.line_renderer
|
||||
.draw(&mut self.shaders, &self.camera, &self.projection)?;
|
||||
|
||||
//let dpi = self.camera.get_dpi();
|
||||
//ui.draw(&gl, dpi)?;
|
||||
@@ -962,10 +1007,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 +1234,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(())
|
||||
}
|
||||
@@ -1259,9 +1300,9 @@ impl App {
|
||||
self.camera.get_longitude_reversed()
|
||||
}
|
||||
|
||||
pub(crate) fn add_catalog(&mut self, name: String, table: JsValue, _colormap: String) {
|
||||
pub(crate) fn add_catalog(&mut self, _name: String, table: JsValue, _colormap: String) {
|
||||
//let mut exec_ref = self.exec.borrow_mut();
|
||||
let table = table;
|
||||
let _table = table;
|
||||
|
||||
/*exec_ref
|
||||
.spawner()
|
||||
@@ -1302,12 +1343,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(
|
||||
@@ -1358,10 +1395,10 @@ impl App {
|
||||
|
||||
pub(crate) fn world_to_screen(&self, ra: f64, dec: f64) -> Option<Vector2<f64>> {
|
||||
let lonlat = LonLatT::new(ArcDeg(ra).into(), ArcDeg(dec).into());
|
||||
let model_pos_xyz = lonlat.vector();
|
||||
let icrs_pos = lonlat.vector();
|
||||
|
||||
self.projection
|
||||
.view_to_screen_space(&model_pos_xyz, &self.camera)
|
||||
.icrs_celestial_to_screen_space(&icrs_pos, &self.camera)
|
||||
}
|
||||
|
||||
pub(crate) fn screen_to_world(&self, pos: &Vector2<f64>) -> Option<LonLatT<f64>> {
|
||||
@@ -1376,6 +1413,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();
|
||||
@@ -1388,11 +1429,11 @@ impl App {
|
||||
LonLatT::new(ra, dec)
|
||||
}
|
||||
|
||||
/// lonlat must be given in icrs frame
|
||||
pub(crate) fn set_center(&mut self, lonlat: &LonLatT<f64>) {
|
||||
self.prev_cam_position = self.camera.get_center().truncate();
|
||||
|
||||
self.camera
|
||||
.set_center(lonlat, CooSystem::ICRS, &self.projection);
|
||||
self.camera.set_center(lonlat, &self.projection);
|
||||
self.request_for_new_tiles = true;
|
||||
|
||||
// And stop the current inertia as well if there is one
|
||||
@@ -1483,17 +1524,17 @@ impl App {
|
||||
self.inertia = Some(Inertia::new(ampl.to_radians(), axis))
|
||||
}
|
||||
|
||||
pub(crate) fn rotate_around_center(&mut self, theta: ArcDeg<f64>) {
|
||||
pub(crate) fn set_view_center_pos_angle(&mut self, theta: ArcDeg<f64>) {
|
||||
self.camera
|
||||
.set_rotation_around_center(theta.into(), &self.projection);
|
||||
.set_view_center_pos_angle(theta.into(), &self.projection);
|
||||
// New tiles can be needed and some tiles can be removed
|
||||
self.request_for_new_tiles = true;
|
||||
|
||||
self.request_redraw = true;
|
||||
}
|
||||
|
||||
pub(crate) fn get_rotation_around_center(&self) -> &Angle<f64> {
|
||||
self.camera.get_rotation_around_center()
|
||||
pub(crate) fn get_north_shift_angle(&self) -> Angle<f64> {
|
||||
self.camera.get_north_shift_angle()
|
||||
}
|
||||
|
||||
pub(crate) fn set_fov(&mut self, fov: Angle<f64>) {
|
||||
@@ -1504,6 +1545,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();
|
||||
|
||||
@@ -5,17 +5,16 @@ use crate::math::projection::coo_space::{XYZWModel, XYZWWorld, XYNDC};
|
||||
use crate::math::sph_geom::region::{Intersection, PoleContained, Region};
|
||||
use crate::math::{projection::Projection, sph_geom::bbox::BoundingBox};
|
||||
use crate::LonLatT;
|
||||
use cgmath::Vector3;
|
||||
|
||||
use crate::ProjectionType;
|
||||
use std::iter;
|
||||
|
||||
fn ndc_to_world(
|
||||
ndc_coo: &[XYNDC],
|
||||
ndc_coo: &[XYNDC<f64>],
|
||||
ndc_to_clip: &Vector2<f64>,
|
||||
clip_zoom_factor: f64,
|
||||
projection: &ProjectionType,
|
||||
) -> Option<Vec<XYZWWorld>> {
|
||||
) -> Option<Vec<XYZWWorld<f64>>> {
|
||||
// Deproject the FOV from ndc to the world space
|
||||
let mut world_coo = Vec::with_capacity(ndc_coo.len());
|
||||
|
||||
@@ -35,7 +34,7 @@ fn ndc_to_world(
|
||||
|
||||
Some(world_coo)
|
||||
}
|
||||
fn world_to_model(world_coo: &[XYZWWorld], w2m: &Matrix4<f64>) -> Vec<XYZWModel> {
|
||||
fn world_to_model(world_coo: &[XYZWWorld<f64>], w2m: &Matrix4<f64>) -> Vec<XYZWModel<f64>> {
|
||||
let mut model_coo = Vec::with_capacity(world_coo.len());
|
||||
|
||||
for w in world_coo.iter() {
|
||||
@@ -61,9 +60,9 @@ const NUM_VERTICES: usize = 4 + 2 * NUM_VERTICES_WIDTH + 2 * NUM_VERTICES_HEIGHT
|
||||
// This struct belongs to the CameraViewPort
|
||||
pub struct FieldOfView {
|
||||
// Vertices
|
||||
ndc_vertices: Vec<XYNDC>,
|
||||
world_vertices: Option<Vec<XYZWWorld>>,
|
||||
model_vertices: Option<Vec<XYZWModel>>,
|
||||
ndc_vertices: Vec<XYNDC<f64>>,
|
||||
world_vertices: Option<Vec<XYZWWorld<f64>>>,
|
||||
model_vertices: Option<Vec<XYZWModel<f64>>>,
|
||||
|
||||
reg: Region,
|
||||
}
|
||||
@@ -163,9 +162,9 @@ impl FieldOfView {
|
||||
self.reg.intersects_meridian(lon)
|
||||
}
|
||||
|
||||
pub fn intersects_great_circle(&self, n: &Vector3<f64>) -> Intersection {
|
||||
/*pub fn intersects_great_circle(&self, n: &Vector3<f64>) -> Intersection {
|
||||
self.reg.intersects_great_circle(n)
|
||||
}
|
||||
}*/
|
||||
|
||||
pub fn intersects_great_circle_arc(
|
||||
&self,
|
||||
@@ -183,7 +182,7 @@ impl FieldOfView {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vertices(&self) -> Option<&Vec<XYZWModel>> {
|
||||
pub fn get_vertices(&self) -> Option<&Vec<XYZWModel<f64>>> {
|
||||
self.model_vertices.as_ref()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pub mod viewport;
|
||||
use crate::math::lonlat::LonLat;
|
||||
use crate::math::projection::coo_space::XYZWModel;
|
||||
pub use viewport::{CameraViewPort, UserAction};
|
||||
pub use viewport::CameraViewPort;
|
||||
|
||||
pub mod fov;
|
||||
pub use fov::FieldOfView;
|
||||
@@ -14,7 +14,7 @@ use crate::ProjectionType;
|
||||
pub fn build_fov_coverage(
|
||||
depth: u8,
|
||||
fov: &FieldOfView,
|
||||
camera_center: &XYZWModel,
|
||||
camera_center: &XYZWModel<f64>,
|
||||
camera_frame: CooSystem,
|
||||
frame: CooSystem,
|
||||
proj: &ProjectionType,
|
||||
|
||||
@@ -1,62 +1,11 @@
|
||||
use crate::healpix::cell::HEALPixCell;
|
||||
use crate::healpix::cell::MAX_HPX_DEPTH;
|
||||
|
||||
use crate::camera::XYZWModel;
|
||||
use crate::healpix::cell::HEALPixCell;
|
||||
|
||||
use crate::math::projection::*;
|
||||
|
||||
use crate::HEALPixCoverage;
|
||||
|
||||
use std::ops::Range;
|
||||
|
||||
use al_api::cell::HEALPixCellProjeted;
|
||||
|
||||
pub fn project(
|
||||
cell: HEALPixCellProjeted,
|
||||
camera: &CameraViewPort,
|
||||
projection: &ProjectionType,
|
||||
) -> Option<HEALPixCellProjeted> {
|
||||
match projection {
|
||||
/*ProjectionType::Hpx(_) => {
|
||||
let tri_idx_in_collignon_zone = |x: f64, y: f64| -> u8 {
|
||||
let zoom_factor = camera.get_clip_zoom_factor() as f32;
|
||||
let x = (((x as f32) / camera.get_width()) - 0.5) * zoom_factor;
|
||||
let y = (((y as f32) / camera.get_height()) - 0.5) * zoom_factor;
|
||||
|
||||
let x_zone = ((x + 0.5) * 4.0).floor() as u8;
|
||||
x_zone + 4 * ((y > 0.0) as u8)
|
||||
};
|
||||
|
||||
let is_in_collignon = |_x: f64, y: f64| -> bool {
|
||||
let y = (((y as f32) / camera.get_height()) - 0.5)
|
||||
* (camera.get_clip_zoom_factor() as f32);
|
||||
!(-0.25..=0.25).contains(&y)
|
||||
};
|
||||
|
||||
if is_in_collignon(cell.vx[0], cell.vy[0])
|
||||
&& is_in_collignon(cell.vx[1], cell.vy[1])
|
||||
&& is_in_collignon(cell.vx[2], cell.vy[2])
|
||||
&& is_in_collignon(cell.vx[3], cell.vy[3])
|
||||
{
|
||||
let all_vertices_in_same_collignon_region =
|
||||
tri_idx_in_collignon_zone(cell.vx[0], cell.vy[0])
|
||||
== tri_idx_in_collignon_zone(cell.vx[1], cell.vy[1])
|
||||
&& (tri_idx_in_collignon_zone(cell.vx[0], cell.vy[0])
|
||||
== tri_idx_in_collignon_zone(cell.vx[2], cell.vy[2]))
|
||||
&& (tri_idx_in_collignon_zone(cell.vx[0], cell.vy[0])
|
||||
== tri_idx_in_collignon_zone(cell.vx[3], cell.vy[3]));
|
||||
if !all_vertices_in_same_collignon_region {
|
||||
None
|
||||
} else {
|
||||
Some(cell)
|
||||
}
|
||||
} else {
|
||||
Some(cell)
|
||||
}
|
||||
}*/
|
||||
_ => Some(cell),
|
||||
}
|
||||
}
|
||||
use moclib::moc::{range::op::degrade::degrade, RangeMOCIterator};
|
||||
|
||||
pub(super) struct ViewHpxCells {
|
||||
hpx_cells: [HpxCells; NUM_COOSYSTEM],
|
||||
@@ -81,7 +30,7 @@ impl ViewHpxCells {
|
||||
&mut self,
|
||||
camera_depth: u8,
|
||||
fov: &FieldOfView,
|
||||
center: &XYZWModel,
|
||||
center: &XYZWModel<f64>,
|
||||
camera_frame: CooSystem,
|
||||
proj: &ProjectionType,
|
||||
// survey frame
|
||||
@@ -99,7 +48,7 @@ impl ViewHpxCells {
|
||||
&mut self,
|
||||
camera_depth: u8,
|
||||
fov: &FieldOfView,
|
||||
center: &XYZWModel,
|
||||
center: &XYZWModel<f64>,
|
||||
camera_frame: CooSystem,
|
||||
proj: &ProjectionType,
|
||||
// survey frame
|
||||
@@ -119,7 +68,7 @@ impl ViewHpxCells {
|
||||
&mut self,
|
||||
camera_depth: u8,
|
||||
fov: &FieldOfView,
|
||||
center: &XYZWModel,
|
||||
center: &XYZWModel<f64>,
|
||||
camera_frame: CooSystem,
|
||||
proj: &ProjectionType,
|
||||
) {
|
||||
@@ -131,28 +80,38 @@ impl ViewHpxCells {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_cells<'a>(
|
||||
&'a mut self,
|
||||
depth: u8,
|
||||
frame: CooSystem,
|
||||
) -> impl Iterator<Item = &'a HEALPixCell> {
|
||||
pub(super) fn get_cells(&self, depth: u8, frame: CooSystem) -> Vec<HEALPixCell> {
|
||||
self.hpx_cells[frame as usize].get_cells(depth)
|
||||
}
|
||||
|
||||
pub(super) fn get_cov(&self, frame: CooSystem) -> &HEALPixCoverage {
|
||||
self.hpx_cells[frame as usize].get_cov()
|
||||
}
|
||||
|
||||
/*pub(super) fn has_changed(&mut self) -> bool {
|
||||
let mut c = false;
|
||||
for (frame, num_req) in self.reg_frames.iter().enumerate() {
|
||||
// if there are surveys/camera requesting the coverage
|
||||
if *num_req > 0 {
|
||||
c |= self.hpx_cells[frame].has_view_changed();
|
||||
}
|
||||
}
|
||||
|
||||
c
|
||||
}*/
|
||||
}
|
||||
|
||||
// Contains the cells being in the FOV for a specific
|
||||
pub struct HpxCells {
|
||||
frame: CooSystem,
|
||||
// the set of cells all depth
|
||||
cells: Vec<HEALPixCell>,
|
||||
//cells: Vec<HEALPixCell>,
|
||||
// An index vector referring to the indices of each depth cells
|
||||
idx_rng: [Option<Range<usize>>; MAX_HPX_DEPTH as usize + 1],
|
||||
//idx_rng: [Option<Range<usize>>; MAX_HPX_DEPTH as usize + 1],
|
||||
// Coverage created in the frame
|
||||
cov: HEALPixCoverage,
|
||||
// boolean refering to if the cells in the view has changed
|
||||
//new_cells: bool,
|
||||
}
|
||||
|
||||
impl Default for HpxCells {
|
||||
@@ -161,24 +120,24 @@ impl Default for HpxCells {
|
||||
}
|
||||
}
|
||||
|
||||
use crate::camera::CameraViewPort;
|
||||
use al_api::coo_system::{CooSystem, NUM_COOSYSTEM};
|
||||
use moclib::moc::RangeMOCIntoIterator;
|
||||
|
||||
use super::FieldOfView;
|
||||
impl HpxCells {
|
||||
pub fn new(frame: CooSystem) -> Self {
|
||||
let cells = Vec::new();
|
||||
//let cells = Vec::new();
|
||||
let cov = HEALPixCoverage::empty(29);
|
||||
|
||||
let idx_rng = Default::default();
|
||||
//let idx_rng = Default::default();
|
||||
|
||||
Self {
|
||||
cells,
|
||||
|
||||
idx_rng,
|
||||
//cells,
|
||||
|
||||
//idx_rng,
|
||||
cov,
|
||||
frame,
|
||||
//new_cells: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +149,7 @@ impl HpxCells {
|
||||
&mut self,
|
||||
camera_depth: u8,
|
||||
fov: &FieldOfView,
|
||||
center: &XYZWModel,
|
||||
center: &XYZWModel<f64>,
|
||||
camera_frame: CooSystem,
|
||||
proj: &ProjectionType,
|
||||
) {
|
||||
@@ -199,63 +158,72 @@ impl HpxCells {
|
||||
super::build_fov_coverage(camera_depth, fov, center, camera_frame, self.frame, proj);
|
||||
|
||||
// Clear the old cells
|
||||
self.cells.clear();
|
||||
/*let r = self.idx_rng[camera_depth as usize]
|
||||
.as_ref()
|
||||
.unwrap_or(&(0..0));
|
||||
let old_cells = &self.cells[r.clone()];
|
||||
|
||||
self.idx_rng = Default::default();
|
||||
|
||||
let mut new_cells = false;
|
||||
// Compute the cells at the tile_depth
|
||||
let tile_depth_cells_iter = self
|
||||
let cells = self
|
||||
.cov
|
||||
.flatten_to_fixed_depth_cells()
|
||||
.map(|idx| HEALPixCell(camera_depth, idx));
|
||||
.enumerate()
|
||||
.map(|(j, idx)| {
|
||||
let c = HEALPixCell(camera_depth, idx);
|
||||
|
||||
let num_past = self.cells.len();
|
||||
self.cells.extend(tile_depth_cells_iter);
|
||||
if j >= old_cells.len() || old_cells[j] != c {
|
||||
new_cells = true;
|
||||
}
|
||||
|
||||
c
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if cells.len() != old_cells.len() {
|
||||
new_cells = true;
|
||||
}
|
||||
|
||||
self.cells = cells;
|
||||
let num_cur = self.cells.len();
|
||||
self.idx_rng[camera_depth as usize] = Some(0..num_cur);
|
||||
|
||||
self.idx_rng[camera_depth as usize] = Some(num_past..num_cur);
|
||||
if new_cells {
|
||||
self.new_cells = true;
|
||||
}*/
|
||||
}
|
||||
|
||||
// Accessors
|
||||
// depth MUST be < to camera tile depth
|
||||
pub fn get_cells<'a>(&'a mut self, depth: u8) -> impl Iterator<Item = &'a HEALPixCell> {
|
||||
let Range { start, end } = if let Some(idx) = self.idx_rng[depth as usize].as_ref() {
|
||||
idx.start..idx.end
|
||||
pub fn get_cells(&self, depth: u8) -> Vec<HEALPixCell> {
|
||||
let cov_depth = self.cov.depth_max();
|
||||
|
||||
if depth == cov_depth {
|
||||
self.cov
|
||||
.flatten_to_fixed_depth_cells()
|
||||
.map(move |idx| HEALPixCell(depth, idx))
|
||||
.collect()
|
||||
} else if depth > self.cov.depth_max() {
|
||||
let cov_d = self.cov.depth_max();
|
||||
let dd = depth - cov_d;
|
||||
// compute the cells from the coverage
|
||||
let cells_iter = self
|
||||
.cov
|
||||
|
||||
self.cov
|
||||
.flatten_to_fixed_depth_cells()
|
||||
.map(|idx| {
|
||||
.flat_map(move |idx| {
|
||||
// idx is at depth_max
|
||||
HEALPixCell(cov_d, idx).get_children_cells(dd)
|
||||
})
|
||||
.flatten();
|
||||
// add them and store the cells for latter reuse
|
||||
let num_past = self.cells.len();
|
||||
self.cells.extend(cells_iter);
|
||||
let num_cur = self.cells.len();
|
||||
|
||||
self.idx_rng[depth as usize] = Some(num_past..num_cur);
|
||||
num_past..num_cur
|
||||
.collect()
|
||||
} else {
|
||||
// compute the cells from the coverage
|
||||
let degraded_moc = self.cov.degraded(depth);
|
||||
let cells_iter = degraded_moc
|
||||
degrade((&self.cov.0).into_range_moc_iter(), depth)
|
||||
.flatten_to_fixed_depth_cells()
|
||||
.map(|idx| HEALPixCell(depth, idx));
|
||||
|
||||
// add them and store the cells for latter reuse
|
||||
let num_past = self.cells.len();
|
||||
self.cells.extend(cells_iter);
|
||||
let num_cur = self.cells.len();
|
||||
|
||||
self.idx_rng[depth as usize] = Some(num_past..num_cur);
|
||||
num_past..num_cur
|
||||
};
|
||||
|
||||
self.cells[start..end].iter()
|
||||
.map(move |idx| HEALPixCell(depth, idx))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -300,8 +268,9 @@ impl HpxCells {
|
||||
}*/
|
||||
|
||||
/*#[inline]
|
||||
pub fn has_view_changed(&self) -> bool {
|
||||
//self.new_cells.is_there_new_cells_added()
|
||||
!self.view_unchanged
|
||||
pub fn has_view_changed(&mut self) -> bool {
|
||||
let new_cells = self.new_cells;
|
||||
self.new_cells = false;
|
||||
new_cells
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -6,20 +6,25 @@ pub enum UserAction {
|
||||
Starting = 4,
|
||||
}
|
||||
|
||||
// Longitude reversed identity matrix
|
||||
const ID_R: &Matrix4<f64> = &Matrix4::new(
|
||||
-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
);
|
||||
|
||||
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::{info, inforec, log};
|
||||
|
||||
use cgmath::{Matrix4, Vector2};
|
||||
pub struct CameraViewPort {
|
||||
// The field of view angle
|
||||
aperture: Angle<f64>,
|
||||
center: Vector4<f64>,
|
||||
// The rotation of the camera
|
||||
rotation_center_angle: Angle<f64>,
|
||||
center: Vector4<f64>,
|
||||
w2m_rot: Rotation<f64>,
|
||||
center_rot: Angle<f64>,
|
||||
|
||||
w2m: Matrix4<f64>,
|
||||
m2w: Matrix4<f64>,
|
||||
@@ -96,8 +101,8 @@ impl CameraViewPort {
|
||||
|
||||
let w2m = Matrix4::identity();
|
||||
let m2w = w2m;
|
||||
let center = Vector4::new(0.0, 0.0, 1.0, 1.0);
|
||||
|
||||
let center_rot = Angle(0.0);
|
||||
let center = Vector4::new(0.0, 0.0, 0.0, 1.0);
|
||||
let moved = false;
|
||||
let zoomed = false;
|
||||
|
||||
@@ -117,9 +122,6 @@ impl CameraViewPort {
|
||||
let width = width * dpi;
|
||||
let height = height * dpi;
|
||||
|
||||
//let dpi = 1.0;
|
||||
//gl.scissor(0, 0, width as i32, height as i32);
|
||||
|
||||
let aspect = height / width;
|
||||
let ndc_to_clip = Vector2::new(1.0, (height as f64) / (width as f64));
|
||||
let clip_zoom_factor = 1.0;
|
||||
@@ -129,7 +131,6 @@ impl CameraViewPort {
|
||||
|
||||
let is_allsky = true;
|
||||
let time_last_move = Time::now();
|
||||
let rotation_center_angle = Angle(0.0);
|
||||
let reversed_longitude = false;
|
||||
|
||||
let texture_depth = 0;
|
||||
@@ -138,6 +139,7 @@ impl CameraViewPort {
|
||||
CameraViewPort {
|
||||
// The field of view angle
|
||||
aperture,
|
||||
center_rot,
|
||||
center,
|
||||
// The rotation of the cameraq
|
||||
w2m_rot,
|
||||
@@ -145,7 +147,6 @@ impl CameraViewPort {
|
||||
m2w,
|
||||
|
||||
dpi,
|
||||
rotation_center_angle,
|
||||
// The width over height ratio
|
||||
aspect,
|
||||
// The width of the screen in pixels
|
||||
@@ -204,18 +205,37 @@ impl CameraViewPort {
|
||||
);
|
||||
}
|
||||
|
||||
/*pub fn has_new_hpx_cells(&mut self) -> bool {
|
||||
self.view_hpx_cells.has_changed()
|
||||
}*/
|
||||
|
||||
pub fn get_cov(&self, frame: CooSystem) -> &HEALPixCoverage {
|
||||
self.view_hpx_cells.get_cov(frame)
|
||||
}
|
||||
|
||||
pub fn get_hpx_cells<'a>(
|
||||
&'a mut self,
|
||||
depth: u8,
|
||||
frame: CooSystem,
|
||||
) -> impl Iterator<Item = &'a HEALPixCell> {
|
||||
pub fn get_hpx_cells(&self, depth: u8, frame: CooSystem) -> Vec<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 >= 120.0_f64.to_radians().to_angle(),
|
||||
ProjectionType::Stg(_) => self.aperture >= 200.0_f64.to_radians().to_angle(),
|
||||
ProjectionType::Sin(_) => false,
|
||||
ProjectionType::Ait(_) => self.aperture >= 100.0_f64.to_radians().to_angle(),
|
||||
ProjectionType::Mol(_) => self.aperture >= 100.0_f64.to_radians().to_angle(),
|
||||
ProjectionType::Zea(_) => self.aperture >= 140.0_f64.to_radians().to_angle(),
|
||||
}
|
||||
}
|
||||
|
||||
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 +273,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 +295,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();
|
||||
}
|
||||
@@ -344,7 +340,7 @@ impl CameraViewPort {
|
||||
self.last_user_action
|
||||
};
|
||||
|
||||
let can_unzoom_more = match proj {
|
||||
let _can_unzoom_more = match proj {
|
||||
ProjectionType::Tan(_)
|
||||
| ProjectionType::Mer(_)
|
||||
//| ProjectionType::Air(_)
|
||||
@@ -384,6 +380,8 @@ impl CameraViewPort {
|
||||
}
|
||||
};
|
||||
|
||||
//console_log(&format!("clip factor {:?}", self.aperture));
|
||||
|
||||
// Project this vertex into the screen
|
||||
self.moved = true;
|
||||
self.zoomed = true;
|
||||
@@ -444,7 +442,7 @@ impl CameraViewPort {
|
||||
(smallest_cell_size_px / w_screen_px) * self.get_aperture().to_radians();
|
||||
|
||||
while depth_pixel > 0 {
|
||||
if (crate::healpix::utils::MEAN_HPX_CELL_RES[depth_pixel] > hpx_cell_size_rad) {
|
||||
if crate::healpix::utils::MEAN_HPX_CELL_RES[depth_pixel] > hpx_cell_size_rad {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -475,10 +473,11 @@ impl CameraViewPort {
|
||||
self.update_rot_matrices(proj);
|
||||
}
|
||||
|
||||
pub fn set_center(&mut self, lonlat: &LonLatT<f64>, coo_sys: CooSystem, proj: &ProjectionType) {
|
||||
/// lonlat must be given in icrs frame
|
||||
pub fn set_center(&mut self, lonlat: &LonLatT<f64>, proj: &ProjectionType) {
|
||||
let icrs_pos: Vector4<_> = lonlat.vector();
|
||||
|
||||
let view_pos = coosys::apply_coo_system(coo_sys, self.get_coo_system(), &icrs_pos);
|
||||
let view_pos = CooSystem::ICRS.to(self.get_coo_system()) * icrs_pos;
|
||||
let rot = Rotation::from_sky_position(&view_pos);
|
||||
|
||||
// Apply the rotation to the camera to go
|
||||
@@ -525,13 +524,8 @@ impl CameraViewPort {
|
||||
if self.reversed_longitude != reversed_longitude {
|
||||
self.reversed_longitude = reversed_longitude;
|
||||
|
||||
self.rotation_center_angle = -self.rotation_center_angle;
|
||||
self.update_rot_matrices(proj);
|
||||
}
|
||||
|
||||
// The camera is reversed => it has moved
|
||||
self.moved = true;
|
||||
self.time_last_move = Time::now();
|
||||
}
|
||||
|
||||
pub fn get_longitude_reversed(&self) -> bool {
|
||||
@@ -559,7 +553,7 @@ impl CameraViewPort {
|
||||
self.clip_zoom_factor
|
||||
}
|
||||
|
||||
pub fn get_vertices(&self) -> Option<&Vec<XYZWModel>> {
|
||||
pub fn get_vertices(&self) -> Option<&Vec<XYZWModel<f64>>> {
|
||||
self.fov.get_vertices()
|
||||
}
|
||||
|
||||
@@ -597,14 +591,17 @@ impl CameraViewPort {
|
||||
self.zoomed = false;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_aperture(&self) -> Angle<f64> {
|
||||
self.aperture
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_center(&self) -> &Vector4<f64> {
|
||||
&self.center
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_allsky(&self) -> bool {
|
||||
self.is_allsky
|
||||
}
|
||||
@@ -617,13 +614,14 @@ impl CameraViewPort {
|
||||
self.coo_sys
|
||||
}
|
||||
|
||||
pub fn set_rotation_around_center(&mut self, theta: Angle<f64>, proj: &ProjectionType) {
|
||||
self.rotation_center_angle = theta;
|
||||
pub fn set_view_center_pos_angle(&mut self, phi: Angle<f64>, proj: &ProjectionType) {
|
||||
self.center_rot = phi;
|
||||
|
||||
self.update_rot_matrices(proj);
|
||||
}
|
||||
|
||||
pub fn get_rotation_around_center(&self) -> &Angle<f64> {
|
||||
&self.rotation_center_angle
|
||||
pub fn get_north_shift_angle(&self) -> Angle<f64> {
|
||||
(self.w2m.x.y).atan2(self.w2m.y.y).to_angle()
|
||||
}
|
||||
}
|
||||
use crate::ProjectionType;
|
||||
@@ -655,21 +653,14 @@ impl CameraViewPort {
|
||||
}
|
||||
|
||||
fn update_center(&mut self) {
|
||||
// Longitude reversed identity matrix
|
||||
const ID_R: &Matrix4<f64> = &Matrix4::new(
|
||||
-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
);
|
||||
|
||||
// The center position is on the 3rd column of the w2m matrix
|
||||
self.center = self.w2m.z;
|
||||
|
||||
let axis = &self.center.truncate();
|
||||
let center_rot = Rotation::from_axis_angle(axis, self.rotation_center_angle);
|
||||
|
||||
// The center position is on the 3rd column of the w2m matrix
|
||||
let center_axis = &self.center.truncate();
|
||||
// Re-update the model matrix to take into account the rotation
|
||||
// by theta around the center axis
|
||||
let final_rot = center_rot * self.w2m_rot;
|
||||
self.w2m = (&final_rot).into();
|
||||
let r = Rotation::from_axis_angle(center_axis, self.center_rot) * self.w2m_rot;
|
||||
|
||||
self.w2m = (&r).into();
|
||||
if self.reversed_longitude {
|
||||
self.w2m = self.w2m * ID_R;
|
||||
}
|
||||
@@ -682,15 +673,8 @@ use al_core::shader::{SendUniforms, ShaderBound};
|
||||
impl SendUniforms for CameraViewPort {
|
||||
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
|
||||
shader
|
||||
//.attach_uniforms_from(&self.last_user_action)
|
||||
//.attach_uniform("to_icrs", &self.system.to_icrs_j2000::<f32>())
|
||||
//.attach_uniform("to_galactic", &self.system.to_gal::<f32>())
|
||||
//.attach_uniform("model", &self.w2m)
|
||||
//.attach_uniform("inv_model", &self.m2w)
|
||||
.attach_uniform("ndc_to_clip", &self.ndc_to_clip) // Send ndc to clip
|
||||
.attach_uniform("czf", &self.clip_zoom_factor) // Send clip zoom factor
|
||||
.attach_uniform("window_size", &self.get_screen_size()) // Window size
|
||||
.attach_uniform("fov", &self.aperture);
|
||||
.attach_uniform("czf", &self.clip_zoom_factor); // Send clip zoom factor
|
||||
|
||||
shader
|
||||
}
|
||||
|
||||
@@ -2,18 +2,20 @@ use cgmath::{BaseFloat, Vector4};
|
||||
|
||||
use al_api::coo_system::CooBaseFloat;
|
||||
use al_api::coo_system::CooSystem;
|
||||
|
||||
|
||||
/// 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 {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pub mod query;
|
||||
pub mod request;
|
||||
|
||||
use crate::renderable::Url;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use query::QueryId;
|
||||
@@ -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,30 +4,31 @@ 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;
|
||||
}
|
||||
|
||||
pub type QueryId = String;
|
||||
|
||||
use al_core::image::format::ImageFormatType;
|
||||
use al_core::log::console_log;
|
||||
|
||||
#[derive(Eq, Hash, PartialEq, Clone)]
|
||||
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,
|
||||
@@ -27,7 +28,6 @@ use crate::renderable::Url;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{RequestInit, RequestMode, Response};
|
||||
|
||||
use crate::downloader::query::Query;
|
||||
use al_core::{image::raw::ImageBuffer, texture::pixel::Pixel};
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen::JsValue;
|
||||
@@ -76,7 +76,7 @@ impl From<query::Allsky> for AllskyRequest {
|
||||
format,
|
||||
tile_size,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
texture_size,
|
||||
id,
|
||||
} = query;
|
||||
@@ -207,7 +207,7 @@ impl From<query::Allsky> for AllskyRequest {
|
||||
|
||||
Self {
|
||||
id,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
depth_tile,
|
||||
url,
|
||||
request,
|
||||
@@ -309,7 +309,7 @@ pub struct Allsky {
|
||||
pub time_req: Time,
|
||||
pub depth_tile: u8,
|
||||
|
||||
pub hips_url: Url,
|
||||
pub hips_cdid: CreatorDid,
|
||||
url: Url,
|
||||
}
|
||||
|
||||
@@ -320,8 +320,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 +333,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 +346,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>,
|
||||
}
|
||||
|
||||
@@ -37,7 +38,6 @@ impl From<PixelMetadataRequest> for RequestType {
|
||||
}
|
||||
}
|
||||
|
||||
use crate::downloader::query::Query;
|
||||
use crate::renderable::Url;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen::JsValue;
|
||||
@@ -49,7 +49,7 @@ impl From<query::PixelMetadata> for PixelMetadataRequest {
|
||||
let query::PixelMetadata {
|
||||
format,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
id,
|
||||
} = query;
|
||||
|
||||
@@ -126,7 +126,7 @@ impl From<query::PixelMetadata> for PixelMetadataRequest {
|
||||
Self {
|
||||
id,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
request,
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,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 +144,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 +152,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,14 +1,15 @@
|
||||
use crate::downloader::query;
|
||||
use crate::renderable::CreatorDid;
|
||||
|
||||
use super::{Request, RequestType};
|
||||
use crate::downloader::QueryId;
|
||||
|
||||
use crate::healpix::coverage::Smoc;
|
||||
use moclib::deser::fits::MocType;
|
||||
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>,
|
||||
}
|
||||
@@ -36,7 +37,7 @@ pub fn from_fits_hpx<T: Idx>(moc: MocType<T, Hpx<T>, Cursor<&[u8]>>) -> Smoc {
|
||||
}
|
||||
}
|
||||
}
|
||||
use crate::downloader::query::Query;
|
||||
|
||||
use crate::healpix::coverage::HEALPixCoverage;
|
||||
use crate::Abort;
|
||||
use moclib::deser::fits::MocIdxType;
|
||||
@@ -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 {
|
||||
|
||||
@@ -87,7 +87,7 @@ pub enum RequestType {
|
||||
PixelMetadata(PixelMetadataRequest),
|
||||
Moc(MOCRequest), //..
|
||||
}
|
||||
use super::query::Url;
|
||||
|
||||
use crate::downloader::QueryId;
|
||||
impl RequestType {
|
||||
pub fn id(&self) -> &QueryId {
|
||||
@@ -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,18 +1,18 @@
|
||||
use crate::healpix::cell::HEALPixCell;
|
||||
use crate::renderable::CreatorDid;
|
||||
use al_core::image::format::{ChannelType, ImageFormatType, RGB8U, RGBA8U};
|
||||
|
||||
use crate::downloader::query;
|
||||
use al_core::image::ImageType;
|
||||
|
||||
use super::{Request, RequestType};
|
||||
use crate::downloader::query::Query;
|
||||
use crate::downloader::QueryId;
|
||||
|
||||
pub struct TileRequest {
|
||||
pub id: QueryId,
|
||||
|
||||
cell: HEALPixCell,
|
||||
hips_url: Url,
|
||||
hips_cdid: CreatorDid,
|
||||
url: Url,
|
||||
format: ImageFormatType,
|
||||
|
||||
@@ -57,7 +57,7 @@ impl From<query::Tile> for TileRequest {
|
||||
format,
|
||||
cell,
|
||||
url,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
id,
|
||||
} = query;
|
||||
|
||||
@@ -177,7 +177,7 @@ impl From<query::Tile> for TileRequest {
|
||||
cell,
|
||||
format,
|
||||
id,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
request,
|
||||
}
|
||||
@@ -191,7 +191,7 @@ pub struct Tile {
|
||||
pub time_req: Time,
|
||||
pub cell: HEALPixCell,
|
||||
pub format: ImageFormatType,
|
||||
hips_url: Url,
|
||||
hips_cdid: CreatorDid,
|
||||
url: Url,
|
||||
}
|
||||
|
||||
@@ -203,8 +203,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 +228,7 @@ impl<'a> From<&'a TileRequest> for Option<Tile> {
|
||||
let TileRequest {
|
||||
cell,
|
||||
request,
|
||||
hips_url,
|
||||
hips_cdid,
|
||||
url,
|
||||
format,
|
||||
..
|
||||
@@ -242,7 +242,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,
|
||||
})
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
pub mod label;
|
||||
pub mod meridian;
|
||||
pub mod parallel;
|
||||
|
||||
use crate::math::projection::coo_space::XYScreen;
|
||||
use crate::Abort;
|
||||
|
||||
use crate::camera::CameraViewPort;
|
||||
use crate::math::angle;
|
||||
use crate::math::HALF_PI;
|
||||
use crate::renderable::line;
|
||||
use crate::renderable::line::PathVertices;
|
||||
use crate::renderable::Renderer;
|
||||
use crate::ProjectionType;
|
||||
use al_api::color::ColorRGBA;
|
||||
|
||||
use al_api::grid::GridCfg;
|
||||
use cgmath::InnerSpace;
|
||||
|
||||
use crate::grid::label::Label;
|
||||
pub struct ProjetedGrid {
|
||||
// Properties
|
||||
pub color: ColorRGBA,
|
||||
pub show_labels: bool,
|
||||
pub enabled: bool,
|
||||
pub label_scale: f32,
|
||||
thickness: f32,
|
||||
|
||||
// Render Text Manager
|
||||
text_renderer: TextRenderManager,
|
||||
fmt: angle::SerializeFmt,
|
||||
|
||||
line_style: line::Style,
|
||||
}
|
||||
|
||||
use crate::shader::ShaderManager;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
use crate::renderable::line::RasterizedLineRenderer;
|
||||
use crate::renderable::text::TextRenderManager;
|
||||
use web_sys::HtmlElement;
|
||||
|
||||
impl ProjetedGrid {
|
||||
pub fn new(aladin_div: &HtmlElement) -> Result<ProjetedGrid, JsValue> {
|
||||
let text_renderer = TextRenderManager::new(aladin_div)?;
|
||||
|
||||
let color = ColorRGBA {
|
||||
r: 0.0,
|
||||
g: 1.0,
|
||||
b: 0.0,
|
||||
a: 0.5,
|
||||
};
|
||||
let show_labels = true;
|
||||
let enabled = false;
|
||||
let label_scale = 1.0;
|
||||
let line_style = line::Style::None;
|
||||
let fmt = angle::SerializeFmt::DMS;
|
||||
let thickness = 2.0;
|
||||
|
||||
let grid = ProjetedGrid {
|
||||
color,
|
||||
line_style,
|
||||
show_labels,
|
||||
enabled,
|
||||
label_scale,
|
||||
thickness,
|
||||
|
||||
text_renderer,
|
||||
fmt,
|
||||
};
|
||||
// Initialize the vertices & labels
|
||||
//grid.force_update(camera, projection, line_renderer);
|
||||
|
||||
Ok(grid)
|
||||
}
|
||||
|
||||
pub fn set_cfg(
|
||||
&mut self,
|
||||
new_cfg: GridCfg,
|
||||
_camera: &CameraViewPort,
|
||||
_projection: &ProjectionType,
|
||||
) -> Result<(), JsValue> {
|
||||
let GridCfg {
|
||||
color,
|
||||
opacity,
|
||||
thickness,
|
||||
show_labels,
|
||||
label_size,
|
||||
enabled,
|
||||
fmt,
|
||||
} = new_cfg;
|
||||
|
||||
if let Some(color) = color {
|
||||
self.color = ColorRGBA {
|
||||
r: color.r,
|
||||
g: color.g,
|
||||
b: color.b,
|
||||
a: self.color.a,
|
||||
};
|
||||
self.text_renderer.set_color(&self.color);
|
||||
}
|
||||
|
||||
if let Some(opacity) = opacity {
|
||||
self.color.a = opacity;
|
||||
self.text_renderer.set_color(&self.color);
|
||||
}
|
||||
|
||||
if let Some(thickness) = thickness {
|
||||
// convert thickness in pixels to ndc
|
||||
self.thickness = thickness;
|
||||
}
|
||||
|
||||
if let Some(show_labels) = show_labels {
|
||||
self.show_labels = show_labels;
|
||||
}
|
||||
|
||||
if let Some(fmt) = fmt {
|
||||
self.fmt = fmt.into();
|
||||
}
|
||||
|
||||
if let Some(label_size) = label_size {
|
||||
self.label_scale = label_size;
|
||||
self.text_renderer.set_font_size(label_size as u32);
|
||||
}
|
||||
|
||||
if let Some(enabled) = enabled {
|
||||
self.enabled = enabled;
|
||||
|
||||
if !self.enabled {
|
||||
self.text_renderer.clear_text_canvas();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Update the grid whenever the camera moved
|
||||
fn update(
|
||||
&mut self,
|
||||
camera: &CameraViewPort,
|
||||
projection: &ProjectionType,
|
||||
rasterizer: &mut RasterizedLineRenderer,
|
||||
) -> Result<(), JsValue> {
|
||||
let fov = camera.get_field_of_view();
|
||||
let bbox = fov.get_bounding_box();
|
||||
let max_dim_px = camera.get_width().max(camera.get_height()) as f64;
|
||||
let step_line_px = max_dim_px * 0.2;
|
||||
|
||||
// update meridians
|
||||
let 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);
|
||||
let step_lon = select_fixed_step(step_lon_precised);
|
||||
|
||||
// Add meridians
|
||||
let start_lon = bbox.lon_min() - (bbox.lon_min() % step_lon);
|
||||
let mut stop_lon = bbox.lon_max();
|
||||
if bbox.all_lon() {
|
||||
stop_lon -= 1e-3;
|
||||
}
|
||||
|
||||
let mut meridians = vec![];
|
||||
let mut lon = start_lon;
|
||||
while lon < stop_lon {
|
||||
if let Some(p) =
|
||||
meridian::get_intersecting_meridian(lon, camera, projection, &self.fmt)
|
||||
{
|
||||
meridians.push(p);
|
||||
}
|
||||
lon += step_lon;
|
||||
}
|
||||
meridians
|
||||
};
|
||||
|
||||
let 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);
|
||||
|
||||
let mut start_lat = bbox.lat_min() - (bbox.lat_min() % step_lat);
|
||||
if start_lat == -HALF_PI {
|
||||
start_lat += step_lat;
|
||||
}
|
||||
let stop_lat = bbox.lat_max();
|
||||
let mut lat = start_lat;
|
||||
|
||||
let mut parallels = vec![];
|
||||
while lat < stop_lat {
|
||||
if let Some(p) = parallel::get_intersecting_parallel(lat, camera, projection) {
|
||||
parallels.push(p);
|
||||
}
|
||||
lat += step_lat;
|
||||
}
|
||||
parallels
|
||||
};
|
||||
|
||||
// update the line buffers
|
||||
let paths = meridians
|
||||
.iter()
|
||||
.map(|meridian| meridian.get_lines_vertices())
|
||||
.chain(
|
||||
parallels
|
||||
.iter()
|
||||
.map(|parallel| parallel.get_lines_vertices()),
|
||||
)
|
||||
.flatten()
|
||||
.map(|vertices| PathVertices {
|
||||
closed: false,
|
||||
vertices,
|
||||
});
|
||||
|
||||
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
|
||||
.iter()
|
||||
.filter_map(|m| m.get_label())
|
||||
.chain(parallels.iter().filter_map(|p| p.get_label()));
|
||||
|
||||
let dpi = camera.get_dpi();
|
||||
self.text_renderer.begin();
|
||||
for Label {
|
||||
content,
|
||||
position,
|
||||
rot,
|
||||
} in labels
|
||||
{
|
||||
let position = position.cast::<f32>().unwrap_abort();
|
||||
self.text_renderer
|
||||
.add_label(&content, &position, cgmath::Rad(*rot as f32))?;
|
||||
}
|
||||
self.text_renderer.end();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
camera: &CameraViewPort,
|
||||
_shaders: &mut ShaderManager,
|
||||
projection: &ProjectionType,
|
||||
rasterizer: &mut RasterizedLineRenderer,
|
||||
) -> Result<(), JsValue> {
|
||||
if self.enabled {
|
||||
self.update(camera, projection, rasterizer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const GRID_STEPS: &[f64] = &[
|
||||
0.0000000000048481367,
|
||||
0.000000000009696274,
|
||||
0.000000000024240685,
|
||||
0.000000000048481369,
|
||||
0.000000000096962737,
|
||||
0.00000000024240683,
|
||||
0.00000000048481364,
|
||||
0.0000000009696274,
|
||||
0.0000000024240686,
|
||||
0.000000004848138,
|
||||
0.000000009696275,
|
||||
0.000000024240685,
|
||||
0.00000004848138,
|
||||
0.00000009696275,
|
||||
0.00000024240687,
|
||||
0.0000004848138,
|
||||
0.0000009696275,
|
||||
0.0000024240686,
|
||||
0.000004848138,
|
||||
0.000009696275,
|
||||
0.000024240685,
|
||||
0.000048481369,
|
||||
0.000072722055,
|
||||
0.00014544412,
|
||||
0.00029088823,
|
||||
0.00058177644,
|
||||
0.0014544412,
|
||||
0.0029088823,
|
||||
0.004363324,
|
||||
0.008726647,
|
||||
0.017453293,
|
||||
0.034906586,
|
||||
0.08726647,
|
||||
0.17453293,
|
||||
0.34906585,
|
||||
std::f64::consts::FRAC_PI_4,
|
||||
];
|
||||
|
||||
fn select_fixed_step(fov: f64) -> f64 {
|
||||
match GRID_STEPS.binary_search_by(|v| {
|
||||
v.partial_cmp(&fov)
|
||||
.expect("Couldn't compare values, maybe because the fov given is NaN")
|
||||
}) {
|
||||
Ok(idx) => GRID_STEPS[idx],
|
||||
Err(idx) => {
|
||||
if idx == 0 {
|
||||
GRID_STEPS[0]
|
||||
} else if idx == GRID_STEPS.len() {
|
||||
GRID_STEPS[idx - 1]
|
||||
} else {
|
||||
let a = GRID_STEPS[idx];
|
||||
let b = GRID_STEPS[idx - 1];
|
||||
|
||||
if a - fov > fov - b {
|
||||
b
|
||||
} else {
|
||||
a
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ pub struct HEALPixCell(pub u8, pub u64);
|
||||
#[derive(Debug)]
|
||||
pub struct CellVertices {
|
||||
pub vertices: Vec<Box<[(f64, f64)]>>,
|
||||
pub closed: bool,
|
||||
}
|
||||
|
||||
const BIT_MASK_ALL_ONE_EXCEPT_FIRST: u32 = !0x1;
|
||||
@@ -281,26 +280,21 @@ impl HEALPixCell {
|
||||
self.path_along_cell_side(Cardinal::S, Cardinal::E, false, *se),
|
||||
self.path_along_cell_side(Cardinal::E, Cardinal::N, true, *ne),
|
||||
],
|
||||
closed: true,
|
||||
}),
|
||||
// no edges
|
||||
(None, None, None, None) => None,
|
||||
// 1 edge found
|
||||
(Some(s), None, None, None) => Some(CellVertices {
|
||||
vertices: vec![self.path_along_cell_side(Cardinal::N, Cardinal::W, true, *s)],
|
||||
closed: false,
|
||||
}),
|
||||
(None, Some(s), None, None) => Some(CellVertices {
|
||||
vertices: vec![self.path_along_cell_side(Cardinal::W, Cardinal::S, true, *s)],
|
||||
closed: false,
|
||||
}),
|
||||
(None, None, Some(s), None) => Some(CellVertices {
|
||||
vertices: vec![self.path_along_cell_side(Cardinal::S, Cardinal::E, true, *s)],
|
||||
closed: false,
|
||||
}),
|
||||
(None, None, None, Some(s)) => Some(CellVertices {
|
||||
vertices: vec![self.path_along_cell_side(Cardinal::E, Cardinal::N, true, *s)],
|
||||
closed: false,
|
||||
}),
|
||||
// 2 edges cases
|
||||
(Some(nw), Some(sw), None, None) => Some(CellVertices {
|
||||
@@ -308,42 +302,36 @@ impl HEALPixCell {
|
||||
&[Cardinal::N, Cardinal::W, Cardinal::S],
|
||||
&[*nw, *sw],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
(Some(nw), None, Some(se), None) => Some(CellVertices {
|
||||
vertices: vec![
|
||||
self.path_along_cell_side(Cardinal::N, Cardinal::W, true, *nw),
|
||||
self.path_along_cell_side(Cardinal::S, Cardinal::E, true, *se),
|
||||
],
|
||||
closed: false,
|
||||
}),
|
||||
(Some(nw), None, None, Some(ne)) => Some(CellVertices {
|
||||
vertices: vec![chain_edge_vertices(
|
||||
&[Cardinal::E, Cardinal::N, Cardinal::W],
|
||||
&[*ne, *nw],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
(None, Some(sw), Some(se), None) => Some(CellVertices {
|
||||
vertices: vec![chain_edge_vertices(
|
||||
&[Cardinal::W, Cardinal::S, Cardinal::E],
|
||||
&[*sw, *se],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
(None, Some(sw), None, Some(ne)) => Some(CellVertices {
|
||||
vertices: vec![
|
||||
self.path_along_cell_side(Cardinal::W, Cardinal::S, true, *sw),
|
||||
self.path_along_cell_side(Cardinal::E, Cardinal::N, true, *ne),
|
||||
],
|
||||
closed: false,
|
||||
}),
|
||||
(None, None, Some(se), Some(ne)) => Some(CellVertices {
|
||||
vertices: vec![chain_edge_vertices(
|
||||
&[Cardinal::S, Cardinal::E, Cardinal::N],
|
||||
&[*se, *ne],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
// 3 edges cases
|
||||
(Some(nw), Some(sw), Some(se), None) => Some(CellVertices {
|
||||
@@ -351,28 +339,24 @@ impl HEALPixCell {
|
||||
&[Cardinal::N, Cardinal::W, Cardinal::S, Cardinal::E],
|
||||
&[*nw, *sw, *se],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
(Some(nw), Some(sw), None, Some(ne)) => Some(CellVertices {
|
||||
vertices: vec![chain_edge_vertices(
|
||||
&[Cardinal::E, Cardinal::N, Cardinal::W, Cardinal::S],
|
||||
&[*ne, *nw, *sw],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
(Some(nw), None, Some(se), Some(ne)) => Some(CellVertices {
|
||||
vertices: vec![chain_edge_vertices(
|
||||
&[Cardinal::S, Cardinal::E, Cardinal::N, Cardinal::W],
|
||||
&[*se, *ne, *nw],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
(None, Some(sw), Some(se), Some(ne)) => Some(CellVertices {
|
||||
vertices: vec![chain_edge_vertices(
|
||||
&[Cardinal::W, Cardinal::S, Cardinal::E, Cardinal::N],
|
||||
&[*sw, *se, *ne],
|
||||
)],
|
||||
closed: false,
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -468,6 +452,7 @@ pub fn nside2depth(nside: u32) -> u8 {
|
||||
crate::math::utils::log_2_unchecked(nside) as u8
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::HEALPixCell;
|
||||
|
||||
|
||||
@@ -2,8 +2,12 @@ use crate::math::lonlat::LonLatT;
|
||||
use crate::math::PI;
|
||||
use crate::math::{self, lonlat::LonLat};
|
||||
|
||||
use cgmath::{Vector3, Vector4};
|
||||
use moclib::{moc::range::RangeMOC, qty::Hpx, ranges::SNORanges};
|
||||
use cgmath::{Vector4};
|
||||
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,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ impl IdxVec {
|
||||
}
|
||||
|
||||
// Create an index vector from a list of segments
|
||||
#[allow(unused)]
|
||||
pub fn from_great_circle_arc(arcs: &mut [GreatCircleArc]) -> Self {
|
||||
arcs.sort_unstable_by(|a1, a2| {
|
||||
let bbox1 = a1.get_containing_hpx_cell();
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn vertices_lonlat<S: BaseFloat>(cell: &HEALPixCell) -> [LonLatT<S>; 4] {
|
||||
}
|
||||
use crate::Abort;
|
||||
/// Get the grid
|
||||
#[allow(dead_code)]
|
||||
pub fn grid_lonlat<S: BaseFloat>(cell: &HEALPixCell, n_segments_by_side: u16) -> Vec<LonLatT<S>> {
|
||||
debug_assert!(n_segments_by_side > 0);
|
||||
healpix::nested::grid(cell.depth(), cell.idx(), n_segments_by_side)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
pub mod fits;
|
||||
pub mod jpg;
|
||||
@@ -16,7 +16,8 @@
|
||||
//extern crate itertools_num;
|
||||
//extern crate num;
|
||||
//extern crate num_traits;
|
||||
use crate::time::Time;
|
||||
//use crate::time::Time;
|
||||
#[cfg(feature = "dbg")]
|
||||
use std::panic;
|
||||
|
||||
pub trait Abort {
|
||||
@@ -74,7 +75,7 @@ extern "C" {
|
||||
mod utils;
|
||||
|
||||
use math::projection::*;
|
||||
use renderable::coverage::moc::MOC;
|
||||
|
||||
//use votable::votable::VOTableWrapper;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use web_sys::HtmlElement;
|
||||
@@ -84,11 +85,11 @@ use crate::math::angle::ToAngle;
|
||||
mod app;
|
||||
pub mod async_task;
|
||||
mod camera;
|
||||
mod shaders;
|
||||
|
||||
mod coosys;
|
||||
mod downloader;
|
||||
mod fifo_cache;
|
||||
mod grid;
|
||||
mod healpix;
|
||||
mod inertia;
|
||||
pub mod math;
|
||||
@@ -140,7 +141,6 @@ pub struct WebClient {
|
||||
|
||||
use al_api::hips::ImageMetadata;
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl WebClient {
|
||||
/// Create the Aladin Lite webgl backend
|
||||
@@ -153,26 +153,19 @@ impl WebClient {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(
|
||||
aladin_div: &HtmlElement,
|
||||
shaders: JsValue,
|
||||
//_shaders: JsValue,
|
||||
resources: JsValue,
|
||||
) -> Result<WebClient, JsValue> {
|
||||
//panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||
#[cfg(feature = "dbg")]
|
||||
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||
|
||||
let shaders = serde_wasm_bindgen::from_value(shaders)?;
|
||||
//let shaders = serde_wasm_bindgen::from_value(shaders)?;
|
||||
let resources = serde_wasm_bindgen::from_value(resources)?;
|
||||
let gl = WebGlContext::new(aladin_div)?;
|
||||
|
||||
let shaders = ShaderManager::new(&gl, shaders).unwrap_abort();
|
||||
let shaders = ShaderManager::new().unwrap_abort();
|
||||
|
||||
// Event listeners callbacks
|
||||
let callback_position_changed = js_sys::Function::new_no_args("");
|
||||
let app = App::new(
|
||||
&gl,
|
||||
aladin_div,
|
||||
shaders,
|
||||
resources,
|
||||
callback_position_changed,
|
||||
)?;
|
||||
let app = App::new(&gl, aladin_div, shaders, resources)?;
|
||||
|
||||
let dt = DeltaTime::zero();
|
||||
|
||||
@@ -181,9 +174,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 +361,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 +402,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 +420,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 +440,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,25 +482,42 @@ 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
|
||||
///
|
||||
/// * `theta` - The rotation angle in degrees
|
||||
#[wasm_bindgen(js_name = setRotationAroundCenter)]
|
||||
pub fn rotate_around_center(&mut self, theta: f64) -> Result<(), JsValue> {
|
||||
#[wasm_bindgen(js_name = setViewCenterPosAngle)]
|
||||
pub fn set_view_center_pos_angle(&mut self, theta: f64) -> Result<(), JsValue> {
|
||||
let theta = ArcDeg(theta);
|
||||
self.app.rotate_around_center(theta);
|
||||
self.app.set_view_center_pos_angle(theta);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the absolute orientation angle of the view
|
||||
#[wasm_bindgen(js_name = getRotationAroundCenter)]
|
||||
pub fn get_rotation_around_center(&mut self) -> Result<f64, JsValue> {
|
||||
let theta = self.app.get_rotation_around_center();
|
||||
#[wasm_bindgen(js_name = getViewCenterFromNorthPoleAngle)]
|
||||
pub fn get_north_shift_angle(&mut self) -> Result<f64, JsValue> {
|
||||
let phi = self.app.get_north_shift_angle();
|
||||
Ok(phi.to_degrees())
|
||||
}
|
||||
|
||||
Ok(theta.0 * 360.0 / (2.0 * std::f64::consts::PI))
|
||||
#[wasm_bindgen(js_name = getNorthPoleCelestialPosition)]
|
||||
pub fn get_north_pole_celestial_position(&mut self) -> Result<Box<[f64]>, JsValue> {
|
||||
let np = self
|
||||
.app
|
||||
.projection
|
||||
.north_pole_celestial_space(&self.app.camera);
|
||||
|
||||
let (lon, lat) = (np.lon().to_degrees(), np.lat().to_degrees());
|
||||
Ok(Box::new([lon, lat]))
|
||||
}
|
||||
|
||||
/// Get if the longitude axis is reversed
|
||||
@@ -566,12 +581,6 @@ impl WebClient {
|
||||
Ok(Box::new([lon_deg.0, lat_deg.0]))
|
||||
}
|
||||
|
||||
/// Rest the north pole orientation to the top of the screen
|
||||
#[wasm_bindgen(js_name = resetNorthOrientation)]
|
||||
pub fn reset_north_orientation(&mut self) {
|
||||
self.app.reset_north_orientation();
|
||||
}
|
||||
|
||||
/// Go from a location to another one
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -615,8 +624,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 +714,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,8 +964,13 @@ 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> {
|
||||
pub fn parse_votable(&mut self, _s: &str) -> Result<JsValue, JsValue> {
|
||||
/*let votable: VOTableWrapper<votable::impls::mem::InMemTableDataRows> =
|
||||
votable::votable::VOTableWrapper::from_ivoa_xml_str(s)
|
||||
.map_err(|err| JsValue::from_str(&format!("Error parsing votable: {:?}", err)))?;
|
||||
@@ -1009,7 +1051,6 @@ impl WebClient {
|
||||
ra_deg: &[f64],
|
||||
dec_deg: &[f64],
|
||||
) -> Result<(), JsValue> {
|
||||
use cgmath::InnerSpace;
|
||||
let tile_d = self.app.get_norder();
|
||||
let pixel_d = tile_d + 9;
|
||||
|
||||
@@ -1075,14 +1116,14 @@ impl WebClient {
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Clone, Copy)]
|
||||
struct LonLat {
|
||||
pub struct LonLat {
|
||||
pub lon: f64,
|
||||
pub lat: f64,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Clone, Copy)]
|
||||
struct HPXVertices {
|
||||
pub struct HPXVertices {
|
||||
pub v1: LonLat,
|
||||
pub v2: LonLat,
|
||||
pub v3: LonLat,
|
||||
|
||||
@@ -24,6 +24,7 @@ where
|
||||
}
|
||||
|
||||
use cgmath::{Deg, Rad};
|
||||
use serde::Deserialize;
|
||||
// Convert a Rad<T> to an ArcDeg<T>
|
||||
impl<T> From<Rad<T>> for ArcDeg<T>
|
||||
where
|
||||
@@ -244,7 +245,7 @@ pub enum SerializeFmt {
|
||||
DMS,
|
||||
HMS,
|
||||
DMM,
|
||||
DD
|
||||
DD,
|
||||
}
|
||||
|
||||
use al_api::angle_fmt::AngleSerializeFmt;
|
||||
@@ -362,7 +363,8 @@ impl FormatType for HMS {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[repr(C)]
|
||||
pub struct Angle<S: BaseFloat>(pub S);
|
||||
impl<S> Angle<S>
|
||||
@@ -452,14 +454,14 @@ where
|
||||
|
||||
pub trait ToAngle<S>
|
||||
where
|
||||
S: BaseFloat
|
||||
S: BaseFloat,
|
||||
{
|
||||
fn to_angle(self) -> Angle<S>;
|
||||
}
|
||||
|
||||
impl<S> ToAngle<S> for S
|
||||
where
|
||||
S: BaseFloat
|
||||
S: BaseFloat,
|
||||
{
|
||||
fn to_angle(self) -> Angle<S> {
|
||||
Angle(self)
|
||||
|
||||
@@ -8,9 +8,11 @@ pub trait LonLat<S: BaseFloat> {
|
||||
fn lonlat(&self) -> LonLatT<S>;
|
||||
fn from_lonlat(lonlat: &LonLatT<S>) -> Self;
|
||||
}
|
||||
|
||||
use crate::math::angle::Angle;
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
use serde::Deserialize;
|
||||
#[derive(Clone, Copy, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[repr(C)]
|
||||
pub struct LonLatT<S: BaseFloat>(pub Angle<S>, pub Angle<S>);
|
||||
|
||||
impl<S> LonLatT<S>
|
||||
@@ -107,11 +109,10 @@ where
|
||||
let theta = lonlat.lon();
|
||||
let delta = lonlat.lat();
|
||||
|
||||
Vector3::<S>::new(
|
||||
delta.cos() * theta.sin(),
|
||||
delta.sin(),
|
||||
delta.cos() * theta.cos(),
|
||||
)
|
||||
let (dc, ds) = (delta.cos(), delta.sin());
|
||||
let (tc, ts) = (theta.cos(), theta.sin());
|
||||
|
||||
Vector3::<S>::new(dc * ts, ds, dc * tc)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,21 +181,17 @@ pub fn xyzw_to_radec<S: BaseFloat>(v: &Vector4<S>) -> (Angle<S>, Angle<S>) {
|
||||
|
||||
#[inline]
|
||||
pub fn radec_to_xyz<S: BaseFloat>(theta: Angle<S>, delta: Angle<S>) -> Vector3<S> {
|
||||
Vector3::<S>::new(
|
||||
delta.cos() * theta.sin(),
|
||||
delta.sin(),
|
||||
delta.cos() * theta.cos(),
|
||||
)
|
||||
let (dc, ds) = (delta.cos(), delta.sin());
|
||||
let (tc, ts) = (theta.cos(), theta.sin());
|
||||
|
||||
Vector3::<S>::new(dc * ts, ds, dc * tc)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn radec_to_xyzw<S: BaseFloat>(theta: Angle<S>, delta: Angle<S>) -> Vector4<S> {
|
||||
Vector4::<S>::new(
|
||||
delta.cos() * theta.sin(),
|
||||
delta.sin(),
|
||||
delta.cos() * theta.cos(),
|
||||
S::one(),
|
||||
)
|
||||
let xyz = radec_to_xyz(theta, delta);
|
||||
|
||||
Vector4::<S>::new(xyz.x, xyz.y, xyz.z, S::one())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -225,14 +222,14 @@ pub fn proj(
|
||||
lonlat: &LonLatT<f64>,
|
||||
projection: &ProjectionType,
|
||||
camera: &CameraViewPort,
|
||||
) -> Option<XYNDC> {
|
||||
) -> Option<XYNDC<f64>> {
|
||||
let xyzw = lonlat.vector();
|
||||
projection.model_to_normalized_device_space(&xyzw, camera)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unproj(
|
||||
ndc_xy: &XYNDC,
|
||||
ndc_xy: &XYNDC<f64>,
|
||||
projection: &ProjectionType,
|
||||
camera: &CameraViewPort,
|
||||
) -> Option<LonLatT<f64>> {
|
||||
@@ -246,14 +243,14 @@ pub fn proj_to_screen(
|
||||
lonlat: &LonLatT<f64>,
|
||||
projection: &ProjectionType,
|
||||
camera: &CameraViewPort,
|
||||
) -> Option<XYScreen> {
|
||||
) -> Option<XYScreen<f64>> {
|
||||
let xyzw = lonlat.vector();
|
||||
projection.model_to_screen_space(&xyzw, camera)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unproj_from_screen(
|
||||
xy: &XYScreen,
|
||||
xy: &XYScreen<f64>,
|
||||
projection: &ProjectionType,
|
||||
camera: &CameraViewPort,
|
||||
) -> Option<LonLatT<f64>> {
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
use cgmath::{
|
||||
Vector2,
|
||||
Vector3,
|
||||
Vector4,
|
||||
};
|
||||
use cgmath::{Vector2, Vector3, Vector4};
|
||||
|
||||
pub type XYScreen = Vector2<f64>;
|
||||
pub type XYNDC = Vector2<f64>;
|
||||
pub type XYClip = Vector2<f64>;
|
||||
pub type XYZWorld = Vector3<f64>;
|
||||
pub type XYZWWorld = Vector4<f64>;
|
||||
pub type XYZWModel = Vector4<f64>;
|
||||
pub type XYZModel = Vector3<f64>;
|
||||
pub type XYScreen<S> = Vector2<S>;
|
||||
pub type XYNDC<S> = Vector2<S>;
|
||||
pub type XYClip<S> = Vector2<S>;
|
||||
pub type XYZWorld<S> = Vector3<S>;
|
||||
pub type XYZModel<S> = Vector3<S>;
|
||||
pub type XYZWWorld<S> = Vector4<S>;
|
||||
pub type XYZWModel<S> = Vector4<S>;
|
||||
|
||||
pub enum CooSpace {
|
||||
Screen,
|
||||
NDC,
|
||||
Clip,
|
||||
World,
|
||||
Model,
|
||||
LonLat,
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use crate::math::projection::coo_space::XYClip;
|
||||
|
||||
pub struct Disk {
|
||||
pub radius: f64
|
||||
pub radius: f64,
|
||||
}
|
||||
|
||||
use cgmath::InnerSpace;
|
||||
use super::super::sdf::ProjDef;
|
||||
use cgmath::InnerSpace;
|
||||
|
||||
impl ProjDef for Disk {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
xy.magnitude() - self.radius
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ pub struct Ellipse {
|
||||
pub b: f64,
|
||||
}
|
||||
|
||||
use cgmath::InnerSpace;
|
||||
use super::super::sdf::ProjDef;
|
||||
use cgmath::InnerSpace;
|
||||
|
||||
impl ProjDef for Ellipse {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
let mut p = Vector2::new( xy.x.abs(), xy.y.abs() );
|
||||
let mut ab = Vector2::new( self.a, self.b );
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let mut p = Vector2::new(xy.x.abs(), xy.y.abs());
|
||||
let mut ab = Vector2::new(self.a, self.b);
|
||||
|
||||
let sdf = if p.x == 0.0 {
|
||||
-(self.b - p.y)
|
||||
@@ -25,44 +25,44 @@ impl ProjDef for Ellipse {
|
||||
p = Vector2::new(p.y, p.x);
|
||||
ab = Vector2::new(ab.y, ab.x);
|
||||
}
|
||||
|
||||
let l = ab.y*ab.y - ab.x*ab.x;
|
||||
let m = ab.x*p.x/l;
|
||||
let m2 = m*m;
|
||||
let n = ab.y*p.y/l;
|
||||
let n2 = n*n;
|
||||
let c = (m2 + n2 - 1.0)/3.0;
|
||||
let c3 = c*c*c;
|
||||
let q = c3 + m2*n2*2.0;
|
||||
let d = c3 + m2*n2;
|
||||
let g = m + m*n2;
|
||||
|
||||
|
||||
let l = ab.y * ab.y - ab.x * ab.x;
|
||||
let m = ab.x * p.x / l;
|
||||
let m2 = m * m;
|
||||
let n = ab.y * p.y / l;
|
||||
let n2 = n * n;
|
||||
let c = (m2 + n2 - 1.0) / 3.0;
|
||||
let c3 = c * c * c;
|
||||
let q = c3 + m2 * n2 * 2.0;
|
||||
let d = c3 + m2 * n2;
|
||||
let g = m + m * n2;
|
||||
|
||||
let co = if d < 0.0 {
|
||||
let p = (q/c3).acos()/3.0;
|
||||
let p = (q / c3).acos() / 3.0;
|
||||
let s = p.cos();
|
||||
let t = p.sin()*(3.0_f64).sqrt();
|
||||
let rx = ( -c*(s + t + 2.0) + m2 ).sqrt();
|
||||
let ry = ( -c*(s - t + 2.0) + m2 ).sqrt();
|
||||
|
||||
( ry + (l).signum()*rx + ((g).abs()/(rx*ry)) - m)/2.0
|
||||
let t = p.sin() * (3.0_f64).sqrt();
|
||||
let rx = (-c * (s + t + 2.0) + m2).sqrt();
|
||||
let ry = (-c * (s - t + 2.0) + m2).sqrt();
|
||||
|
||||
(ry + (l).signum() * rx + ((g).abs() / (rx * ry)) - m) / 2.0
|
||||
} else {
|
||||
let h = 2.0*m*n*(( d ).sqrt());
|
||||
let s = (q+h).signum()*( (q+h).abs() ).powf( 1.0/3.0 );
|
||||
let u = (q-h).signum()*( (q-h).abs() ).powf( 1.0/3.0 );
|
||||
let rx = -s - u - c*4.0 + 2.0*m2;
|
||||
let ry = (s - u)*(3.0_f64).sqrt();
|
||||
|
||||
let rm = ( rx*rx + ry*ry ).sqrt();
|
||||
let p = ry/((rm-rx).sqrt());
|
||||
(p + (2.0*g/rm) - m)/2.0
|
||||
let h = 2.0 * m * n * ((d).sqrt());
|
||||
let s = (q + h).signum() * ((q + h).abs()).powf(1.0 / 3.0);
|
||||
let u = (q - h).signum() * ((q - h).abs()).powf(1.0 / 3.0);
|
||||
let rx = -s - u - c * 4.0 + 2.0 * m2;
|
||||
let ry = (s - u) * (3.0_f64).sqrt();
|
||||
|
||||
let rm = (rx * rx + ry * ry).sqrt();
|
||||
let p = ry / ((rm - rx).sqrt());
|
||||
(p + (2.0 * g / rm) - m) / 2.0
|
||||
};
|
||||
|
||||
let si = ( 1.0 - co*co ).sqrt();
|
||||
let q = Vector2::new( ab.x*co, ab.y*si );
|
||||
|
||||
(q-p).magnitude() * (p.y-q.y).signum()
|
||||
|
||||
let si = (1.0 - co * co).sqrt();
|
||||
let q = Vector2::new(ab.x * co, ab.y * si);
|
||||
|
||||
(q - p).magnitude() * (p.y - q.y).signum()
|
||||
};
|
||||
|
||||
sdf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@ use crate::math::projection::coo_space::XYClip;
|
||||
use cgmath::Vector2;
|
||||
pub struct Parabola {
|
||||
// Quadratic coefficient
|
||||
pub k: f64
|
||||
pub k: f64,
|
||||
}
|
||||
|
||||
use super::super::sdf::ProjDef;
|
||||
|
||||
use cgmath::InnerSpace;
|
||||
impl ProjDef for Parabola {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let mut xy = *xy;
|
||||
|
||||
// There is a singularity around x == 0
|
||||
@@ -20,21 +20,17 @@ impl ProjDef for Parabola {
|
||||
xy.x += 1e-4;
|
||||
}
|
||||
xy.x = xy.x.abs();
|
||||
let ik = 1.0/self.k;
|
||||
let p = ik*(xy.y - 0.5*ik)/3.0;
|
||||
let q = 0.25*ik*ik*xy.x;
|
||||
let h = q*q - p*p*p;
|
||||
let ik = 1.0 / self.k;
|
||||
let p = ik * (xy.y - 0.5 * ik) / 3.0;
|
||||
let q = 0.25 * ik * ik * xy.x;
|
||||
let h = q * q - p * p * p;
|
||||
let r = h.abs().sqrt();
|
||||
let x = if h>0.0 {
|
||||
(q+r).powf(1.0/3.0) - (q-r).abs().powf(1.0/3.0)*(r-q).signum()
|
||||
let x = if h > 0.0 {
|
||||
(q + r).powf(1.0 / 3.0) - (q - r).abs().powf(1.0 / 3.0) * (r - q).signum()
|
||||
} else {
|
||||
2.0*(r.atan2(q)/3.0).cos()*p.sqrt()
|
||||
2.0 * (r.atan2(q) / 3.0).cos() * p.sqrt()
|
||||
};
|
||||
let a = if xy.x - x < 0.0 {
|
||||
-1.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
(xy-Vector2::new(x, self.k*x*x)).magnitude() * a
|
||||
let a = if xy.x - x < 0.0 { -1.0 } else { 1.0 };
|
||||
(xy - Vector2::new(x, self.k * x * x)).magnitude() * a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,19 @@ use crate::math::projection::coo_space::XYClip;
|
||||
|
||||
use cgmath::Vector2;
|
||||
pub struct Rect {
|
||||
pub dim: Vector2<f64>
|
||||
pub dim: Vector2<f64>,
|
||||
}
|
||||
|
||||
use super::super::sdf::ProjDef;
|
||||
|
||||
use cgmath::InnerSpace;
|
||||
impl ProjDef for Rect {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
let d = Vector2::new(
|
||||
xy.x.abs() - self.dim.x,
|
||||
xy.y.abs() - self.dim.y
|
||||
);
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let d = Vector2::new(xy.x.abs() - self.dim.x, xy.y.abs() - self.dim.y);
|
||||
|
||||
let a = Vector2::new(d.x.max(0.0), d.y.max(0.0));
|
||||
let b = (d.x.max(d.y)).min(0.0);
|
||||
|
||||
|
||||
a.magnitude() + b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,30 +10,27 @@ pub struct Triangle {
|
||||
use super::super::sdf::ProjDef;
|
||||
use cgmath::InnerSpace;
|
||||
impl ProjDef for Triangle {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let e0 = self.p1 - self.p0;
|
||||
let e1 = self.p2 - self.p1;
|
||||
let e2 = self.p0 - self.p2;
|
||||
|
||||
|
||||
let v0 = xy - self.p0;
|
||||
let v1 = xy - self.p1;
|
||||
let v2 = xy - self.p2;
|
||||
|
||||
let pq0 = v0 - e0 * ( v0.dot(e0) / e0.dot(e0) ).clamp( 0.0, 1.0 );
|
||||
let pq1 = v1 - e1 * ( v1.dot(e1) / e1.dot(e1) ).clamp( 0.0, 1.0 );
|
||||
let pq2 = v2 - e2 * ( v2.dot(e2) / e2.dot(e2) ).clamp( 0.0, 1.0 );
|
||||
|
||||
let s = e0.x*e2.y - e0.y*e2.x;
|
||||
|
||||
let d1 = Vector2::new(pq0.dot( pq0 ), s*(v0.x*e0.y-v0.y*e0.x));
|
||||
let d2 = Vector2::new(pq1.dot( pq1 ), s*(v1.x*e1.y-v1.y*e1.x));
|
||||
let d3 = Vector2::new(pq2.dot( pq2 ), s*(v2.x*e2.y-v2.y*e2.x));
|
||||
|
||||
let d = Vector2::new(
|
||||
d1.x.min(d2.x.min(d3.x)),
|
||||
d1.y.min(d2.y.min(d3.y))
|
||||
);
|
||||
|
||||
-d.x.sqrt()*(d.y.signum())
|
||||
|
||||
let pq0 = v0 - e0 * (v0.dot(e0) / e0.dot(e0)).clamp(0.0, 1.0);
|
||||
let pq1 = v1 - e1 * (v1.dot(e1) / e1.dot(e1)).clamp(0.0, 1.0);
|
||||
let pq2 = v2 - e2 * (v2.dot(e2) / e2.dot(e2)).clamp(0.0, 1.0);
|
||||
|
||||
let s = e0.x * e2.y - e0.y * e2.x;
|
||||
|
||||
let d1 = Vector2::new(pq0.dot(pq0), s * (v0.x * e0.y - v0.y * e0.x));
|
||||
let d2 = Vector2::new(pq1.dot(pq1), s * (v1.x * e1.y - v1.y * e1.x));
|
||||
let d3 = Vector2::new(pq2.dot(pq2), s * (v2.x * e2.y - v2.y * e2.x));
|
||||
|
||||
let d = Vector2::new(d1.x.min(d2.x.min(d3.x)), d1.y.min(d2.y.min(d3.y)));
|
||||
|
||||
-d.x.sqrt() * (d.y.signum())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
use crate::math::projection::coo_space::XYClip;
|
||||
use cgmath::Vector2;
|
||||
|
||||
use crate::math::HALF_PI;
|
||||
use crate::math::angle::PI;
|
||||
use super::{
|
||||
sdf::ProjDef,
|
||||
basic::{ellipse::Ellipse, triangle::Triangle},
|
||||
op::{Diff, Translate},
|
||||
basic::{
|
||||
triangle::Triangle,
|
||||
ellipse::Ellipse,
|
||||
}
|
||||
sdf::ProjDef,
|
||||
};
|
||||
use crate::math::angle::PI;
|
||||
use crate::math::HALF_PI;
|
||||
|
||||
pub struct Cod {
|
||||
pub r_max: f64,
|
||||
@@ -41,7 +38,7 @@ impl Cod {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_clip(&self, xy: &Vector2<f64>) -> XYClip {
|
||||
fn to_clip(&self, xy: &Vector2<f64>) -> XYClip<f64> {
|
||||
let x = (xy.x - self.x_min) / (self.x_max - self.x_min);
|
||||
let y = (xy.y - self.y_min) / (self.y_max - self.y_min);
|
||||
|
||||
@@ -50,20 +47,26 @@ impl Cod {
|
||||
}
|
||||
|
||||
impl ProjDef for Cod {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
let y_mean = (self.y_min + self.y_max)*0.5;
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let y_mean = (self.y_min + self.y_max) * 0.5;
|
||||
let center_ellipse = self.to_clip(&Vector2::new(0.0, self.y0 + y_mean));
|
||||
|
||||
// Big frontier ellipse
|
||||
let a = 1.0;
|
||||
let b = 2.0 * (2.356194490192345 + self.y0) / (2.356194490192345 + 3.0328465566001492);
|
||||
let e = b / a;
|
||||
let ext_ellipse = Translate { off: center_ellipse, def: Ellipse { a: a, b: b } };
|
||||
let ext_ellipse = Translate {
|
||||
off: center_ellipse,
|
||||
def: Ellipse { a: a, b: b },
|
||||
};
|
||||
|
||||
// Small ellipse where projection is not defined
|
||||
let b_int = 2.0 * self.r_min / (2.356194490192345 + 3.0328465566001492);
|
||||
let a_int = b_int / e;
|
||||
let int_ellipse = Translate { off: center_ellipse, def: Ellipse { a: a_int, b: b_int } };
|
||||
let int_ellipse = Translate {
|
||||
off: center_ellipse,
|
||||
def: Ellipse { a: a_int, b: b_int },
|
||||
};
|
||||
|
||||
// The top edges
|
||||
let gamma = PI * self.c - HALF_PI;
|
||||
@@ -75,9 +78,9 @@ impl ProjDef for Cod {
|
||||
let tri = Triangle {
|
||||
p0: center_ellipse,
|
||||
p1: self.to_clip(&b),
|
||||
p2: self.to_clip(&c)
|
||||
p2: self.to_clip(&c),
|
||||
};
|
||||
|
||||
Diff::new(Diff::new(ext_ellipse, int_ellipse), tri).sdf(xy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ use cgmath::Vector2;
|
||||
|
||||
pub struct FullScreen;
|
||||
|
||||
use super::{
|
||||
basic::rect::Rect,
|
||||
sdf::ProjDef,
|
||||
};
|
||||
use super::{basic::rect::Rect, sdf::ProjDef};
|
||||
impl ProjDef for FullScreen {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
Rect { dim: Vector2::new(1.0, 1.0) }.sdf(xy)
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
Rect {
|
||||
dim: Vector2::new(1.0, 1.0),
|
||||
}
|
||||
.sdf(xy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,58 +5,57 @@ pub struct Hpx;
|
||||
|
||||
use super::sdf::ProjDef;
|
||||
use super::{
|
||||
basic::{rect::Rect, triangle::Triangle},
|
||||
op::Union,
|
||||
basic::{
|
||||
triangle::Triangle,
|
||||
rect::Rect
|
||||
}
|
||||
};
|
||||
impl ProjDef for Hpx {
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
let rect = Rect { dim: Vector2::new(1.0, 0.5) };
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let rect = Rect {
|
||||
dim: Vector2::new(1.0, 0.5),
|
||||
};
|
||||
|
||||
let t1 = Triangle {
|
||||
p0: Vector2::new(1.0, 0.5),
|
||||
p1: Vector2::new(0.5, 0.5),
|
||||
p2: Vector2::new(0.75, 1.0)
|
||||
p2: Vector2::new(0.75, 1.0),
|
||||
};
|
||||
let t2 = Triangle {
|
||||
p0: Vector2::new(0.5, 0.5),
|
||||
p1: Vector2::new(0.0, 0.5),
|
||||
p2: Vector2::new(0.25, 1.0)
|
||||
p2: Vector2::new(0.25, 1.0),
|
||||
};
|
||||
|
||||
let t3 = Triangle {
|
||||
p0: Vector2::new(-1.0, 0.5),
|
||||
p1: Vector2::new(-0.5, 0.5),
|
||||
p2: Vector2::new(-0.75, 1.0)
|
||||
p2: Vector2::new(-0.75, 1.0),
|
||||
};
|
||||
let t4 = Triangle {
|
||||
p0: Vector2::new(-0.5, 0.5),
|
||||
p1: Vector2::new(-0.0, 0.5),
|
||||
p2: Vector2::new(-0.25, 1.0)
|
||||
p2: Vector2::new(-0.25, 1.0),
|
||||
};
|
||||
|
||||
let t5 = Triangle {
|
||||
p0: Vector2::new(-1.0, -0.5),
|
||||
p1: Vector2::new(-0.5, -0.5),
|
||||
p2: Vector2::new(-0.75, -1.0)
|
||||
p2: Vector2::new(-0.75, -1.0),
|
||||
};
|
||||
let t6 = Triangle {
|
||||
p0: Vector2::new(-0.5, -0.5),
|
||||
p1: Vector2::new(-0.0, -0.5),
|
||||
p2: Vector2::new(-0.25, -1.0)
|
||||
p2: Vector2::new(-0.25, -1.0),
|
||||
};
|
||||
|
||||
let t7 = Triangle {
|
||||
p0: Vector2::new(1.0, -0.5),
|
||||
p1: Vector2::new(0.5, -0.5),
|
||||
p2: Vector2::new(0.75, -1.0)
|
||||
p2: Vector2::new(0.75, -1.0),
|
||||
};
|
||||
let t8 = Triangle {
|
||||
p0: Vector2::new(0.5, -0.5),
|
||||
p1: Vector2::new(0.0, -0.5),
|
||||
p2: Vector2::new(0.25, -1.0)
|
||||
p2: Vector2::new(0.25, -1.0),
|
||||
};
|
||||
|
||||
let t12 = Union::new(t1, t2);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::sdf::ProjDef;
|
||||
use crate::math::projection::XYClip;
|
||||
use cgmath::Vector2;
|
||||
use super::sdf::ProjDef;
|
||||
|
||||
pub struct Scale<T>
|
||||
where
|
||||
T: ProjDef
|
||||
T: ProjDef,
|
||||
{
|
||||
pub scale: Vector2<f64>,
|
||||
pub def: T,
|
||||
@@ -12,17 +12,18 @@ where
|
||||
|
||||
impl<T> ProjDef for Scale<T>
|
||||
where
|
||||
T: ProjDef
|
||||
T: ProjDef,
|
||||
{
|
||||
/// Signed distance function to the definition domain region
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
self.def.sdf(&Vector2::new(xy.x / self.scale.x, xy.y / self.scale.y))
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
self.def
|
||||
.sdf(&Vector2::new(xy.x / self.scale.x, xy.y / self.scale.y))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Translate<T>
|
||||
where
|
||||
T: ProjDef
|
||||
T: ProjDef,
|
||||
{
|
||||
pub off: Vector2<f64>,
|
||||
pub def: T,
|
||||
@@ -30,10 +31,10 @@ where
|
||||
|
||||
impl<T> ProjDef for Translate<T>
|
||||
where
|
||||
T: ProjDef
|
||||
T: ProjDef,
|
||||
{
|
||||
/// Signed distance function to the definition domain region
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
self.def.sdf(&(*xy - self.off))
|
||||
}
|
||||
}
|
||||
@@ -42,7 +43,7 @@ where
|
||||
pub struct Union<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
sdf1: T,
|
||||
sdf2: U,
|
||||
@@ -51,23 +52,20 @@ where
|
||||
impl<T, U> Union<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
pub fn new(sdf1: T, sdf2: U) -> Self {
|
||||
Self {
|
||||
sdf1,
|
||||
sdf2,
|
||||
}
|
||||
Self { sdf1, sdf2 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> ProjDef for Union<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
/// Signed distance function to the definition domain region
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let s1 = self.sdf1.sdf(xy);
|
||||
let s2 = self.sdf2.sdf(xy);
|
||||
|
||||
@@ -79,7 +77,7 @@ where
|
||||
pub struct Inter<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
sdf1: T,
|
||||
sdf2: U,
|
||||
@@ -88,23 +86,20 @@ where
|
||||
impl<T, U> Inter<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
pub fn new(sdf1: T, sdf2: U) -> Self {
|
||||
Self {
|
||||
sdf1,
|
||||
sdf2,
|
||||
}
|
||||
Self { sdf1, sdf2 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> ProjDef for Inter<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
/// Signed distance function to the definition domain region
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let s1 = self.sdf1.sdf(xy);
|
||||
let s2 = self.sdf2.sdf(xy);
|
||||
|
||||
@@ -116,7 +111,7 @@ where
|
||||
pub struct Diff<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
sdf1: T,
|
||||
sdf2: U,
|
||||
@@ -125,27 +120,24 @@ where
|
||||
impl<T, U> Diff<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
pub fn new(sdf1: T, sdf2: U) -> Self {
|
||||
Self {
|
||||
sdf1,
|
||||
sdf2,
|
||||
}
|
||||
Self { sdf1, sdf2 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> ProjDef for Diff<T, U>
|
||||
where
|
||||
T: ProjDef,
|
||||
U: ProjDef
|
||||
U: ProjDef,
|
||||
{
|
||||
/// Signed distance function to the definition domain region
|
||||
fn sdf(&self, xy: &XYClip) -> f64 {
|
||||
fn sdf(&self, xy: &XYClip<f64>) -> f64 {
|
||||
let s1 = self.sdf1.sdf(xy);
|
||||
let s2 = self.sdf2.sdf(xy);
|
||||
|
||||
// intersection
|
||||
(-s2).max(s1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user