siderust-js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +166 -0
- package/.gitmodules +9 -0
- package/CHANGELOG.md +26 -0
- package/LICENSE +661 -0
- package/README.md +138 -0
- package/package.json +12 -0
- package/qtty-js/.github/workflows/ci.yml +151 -0
- package/qtty-js/.gitmodules +3 -0
- package/qtty-js/CHANGELOG.md +31 -0
- package/qtty-js/LICENSE +661 -0
- package/qtty-js/README.md +132 -0
- package/qtty-js/package.json +20 -0
- package/qtty-js/qtty/.github/workflows/ci.yml +155 -0
- package/qtty-js/qtty/CHANGELOG.md +120 -0
- package/qtty-js/qtty/Cargo.lock +1462 -0
- package/qtty-js/qtty/Cargo.toml +12 -0
- package/qtty-js/qtty/LICENSE +661 -0
- package/qtty-js/qtty/README.md +9 -0
- package/qtty-js/qtty/qtty/Cargo.toml +41 -0
- package/qtty-js/qtty/qtty/README.md +8 -0
- package/qtty-js/qtty/qtty/examples/angles.rs +14 -0
- package/qtty-js/qtty/qtty/examples/astronomy.rs +17 -0
- package/qtty-js/qtty/qtty/examples/dimensional_arithmetic.rs +83 -0
- package/qtty-js/qtty/qtty/examples/python_integration.rs +61 -0
- package/qtty-js/qtty/qtty/examples/quickstart.rs +15 -0
- package/qtty-js/qtty/qtty/examples/ratios.rs +12 -0
- package/qtty-js/qtty/qtty/examples/serde_with_unit.rs +234 -0
- package/qtty-js/qtty/qtty/examples/serialization.rs +141 -0
- package/qtty-js/qtty/qtty/examples/serialization_advanced.rs +155 -0
- package/qtty-js/qtty/qtty/src/f32.rs +108 -0
- package/qtty-js/qtty/qtty/src/f64.rs +30 -0
- package/qtty-js/qtty/qtty/src/i128.rs +111 -0
- package/qtty-js/qtty/qtty/src/i16.rs +111 -0
- package/qtty-js/qtty/qtty/src/i32.rs +111 -0
- package/qtty-js/qtty/qtty/src/i64.rs +111 -0
- package/qtty-js/qtty/qtty/src/i8.rs +111 -0
- package/qtty-js/qtty/qtty/src/lib.rs +238 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.lock +83 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.toml +10 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/src/lib.rs +7 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.lock +83 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.toml +10 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/src/lib.rs +7 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.lock +83 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.toml +10 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/src/lib.rs +5 -0
- package/qtty-js/qtty/qtty/tests/integration_tests.rs +529 -0
- package/qtty-js/qtty/qtty/tests/qtty_vec_feature_matrix.rs +58 -0
- package/qtty-js/qtty/qtty-core/Cargo.toml +41 -0
- package/qtty-js/qtty/qtty-core/README.md +8 -0
- package/qtty-js/qtty/qtty-core/examples/diesel_integration.rs +145 -0
- package/qtty-js/qtty/qtty-core/examples/quantity_db_serde.rs +215 -0
- package/qtty-js/qtty/qtty-core/src/dimension.rs +249 -0
- package/qtty-js/qtty/qtty-core/src/feature_diesel.rs +318 -0
- package/qtty-js/qtty/qtty-core/src/feature_pyo3.rs +27 -0
- package/qtty-js/qtty/qtty-core/src/feature_serde.rs +203 -0
- package/qtty-js/qtty/qtty-core/src/feature_tiberius.rs +28 -0
- package/qtty-js/qtty/qtty-core/src/lib.rs +744 -0
- package/qtty-js/qtty/qtty-core/src/macros.rs +93 -0
- package/qtty-js/qtty/qtty-core/src/quantity.rs +810 -0
- package/qtty-js/qtty/qtty-core/src/scalar.rs +1742 -0
- package/qtty-js/qtty/qtty-core/src/unit.rs +332 -0
- package/qtty-js/qtty/qtty-core/src/units/angular.rs +1228 -0
- package/qtty-js/qtty/qtty-core/src/units/area.rs +243 -0
- package/qtty-js/qtty/qtty-core/src/units/frequency.rs +179 -0
- package/qtty-js/qtty/qtty-core/src/units/length.rs +1270 -0
- package/qtty-js/qtty/qtty-core/src/units/mass.rs +488 -0
- package/qtty-js/qtty/qtty-core/src/units/mod.rs +26 -0
- package/qtty-js/qtty/qtty-core/src/units/power.rs +324 -0
- package/qtty-js/qtty/qtty-core/src/units/time.rs +667 -0
- package/qtty-js/qtty/qtty-core/src/units/unitless.rs +212 -0
- package/qtty-js/qtty/qtty-core/src/units/velocity.rs +210 -0
- package/qtty-js/qtty/qtty-core/src/units/volume.rs +269 -0
- package/qtty-js/qtty/qtty-core/tests/core.rs +628 -0
- package/qtty-js/qtty/qtty-core/tests/diesel.rs +461 -0
- package/qtty-js/qtty/qtty-core/tests/integers.rs +632 -0
- package/qtty-js/qtty/qtty-core/tests/no_cross_unit_ops.rs +35 -0
- package/qtty-js/qtty/qtty-core/tests/pyo3.rs +334 -0
- package/qtty-js/qtty/qtty-core/tests/quantity_f32.rs +276 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_decimal.rs +258 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_f32.rs +286 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_f64_real.rs +287 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_rational.rs +260 -0
- package/qtty-js/qtty/qtty-core/tests/serde.rs +256 -0
- package/qtty-js/qtty/qtty-core/tests/tiberius.rs +208 -0
- package/qtty-js/qtty/qtty-derive/Cargo.toml +23 -0
- package/qtty-js/qtty/qtty-derive/README.md +8 -0
- package/qtty-js/qtty/qtty-derive/src/lib.rs +340 -0
- package/qtty-js/qtty/qtty-ffi/ARCHITECTURE.md +3 -0
- package/qtty-js/qtty/qtty-ffi/Cargo.toml +31 -0
- package/qtty-js/qtty/qtty-ffi/README.md +9 -0
- package/qtty-js/qtty/qtty-ffi/build.rs +326 -0
- package/qtty-js/qtty/qtty-ffi/cbindgen.toml +105 -0
- package/qtty-js/qtty/qtty-ffi/include/qtty_ffi.h +1126 -0
- package/qtty-js/qtty/qtty-ffi/src/ffi.rs +1251 -0
- package/qtty-js/qtty/qtty-ffi/src/ffi_serde.rs +294 -0
- package/qtty-js/qtty/qtty-ffi/src/helpers.rs +310 -0
- package/qtty-js/qtty/qtty-ffi/src/lib.rs +229 -0
- package/qtty-js/qtty/qtty-ffi/src/macros.rs +121 -0
- package/qtty-js/qtty/qtty-ffi/src/registry.rs +274 -0
- package/qtty-js/qtty/qtty-ffi/src/types.rs +620 -0
- package/qtty-js/qtty/qtty-ffi/tests/integration_tests.rs +842 -0
- package/qtty-js/qtty/qtty-ffi/units.csv +156 -0
- package/qtty-js/qtty/qtty-ffi/units.csv.md +3 -0
- package/qtty-js/qtty-node/.prettierignore +6 -0
- package/qtty-js/qtty-node/.prettierrc.json +6 -0
- package/qtty-js/qtty-node/README.md +250 -0
- package/qtty-js/qtty-node/c8.config.json +11 -0
- package/qtty-js/qtty-node/eslint.config.js +31 -0
- package/qtty-js/qtty-node/examples/arithmetic.mjs +64 -0
- package/qtty-js/qtty-node/examples/astronomy.mjs +90 -0
- package/qtty-js/qtty-node/examples/quickstart.mjs +36 -0
- package/qtty-js/qtty-node/examples/serialization.mjs +125 -0
- package/qtty-js/qtty-node/examples/unit_factories.mjs +74 -0
- package/qtty-js/qtty-node/index.d.ts +219 -0
- package/qtty-js/qtty-node/index.js +323 -0
- package/qtty-js/qtty-node/lib/DerivedQuantity.js +122 -0
- package/qtty-js/qtty-node/lib/Quantity.js +151 -0
- package/qtty-js/qtty-node/lib/backend.js +25 -0
- package/qtty-js/qtty-node/native.cjs +306 -0
- package/qtty-js/qtty-node/package-lock.json +3223 -0
- package/qtty-js/qtty-node/package.json +70 -0
- package/qtty-js/qtty-node/units.d.ts +299 -0
- package/qtty-js/qtty-node/units.js +210 -0
- package/qtty-js/qtty-web/Cargo.lock +767 -0
- package/qtty-js/qtty-web/Cargo.toml +21 -0
- package/qtty-js/qtty-web/index.d.ts +140 -0
- package/qtty-js/qtty-web/index.js +20 -0
- package/qtty-js/qtty-web/lib/DerivedQuantity.js +58 -0
- package/qtty-js/qtty-web/lib/Quantity.js +75 -0
- package/qtty-js/qtty-web/lib/backend.js +80 -0
- package/qtty-js/qtty-web/package.json +45 -0
- package/qtty-js/qtty-web/src/lib.rs +111 -0
- package/qtty-js/scripts/ci.sh +73 -0
- package/scripts/ci.sh +123 -0
- package/siderust-core/Cargo.lock +787 -0
- package/siderust-core/Cargo.toml +18 -0
- package/siderust-core/DEDUPLICATION.md +124 -0
- package/siderust-core/src/body.rs +120 -0
- package/siderust-core/src/events.rs +184 -0
- package/siderust-core/src/lib.rs +20 -0
- package/siderust-core/src/observer.rs +55 -0
- package/siderust-core/src/position.rs +213 -0
- package/siderust-node/.prettierignore +7 -0
- package/siderust-node/.prettierrc.json +6 -0
- package/siderust-node/Cargo.lock +906 -0
- package/siderust-node/Cargo.toml +29 -0
- package/siderust-node/README.md +109 -0
- package/siderust-node/__test__/index.test.mjs +248 -0
- package/siderust-node/build.rs +5 -0
- package/siderust-node/c8.config.json +3 -0
- package/siderust-node/eslint.config.js +31 -0
- package/siderust-node/examples/01_basic_coordinates.mjs +24 -0
- package/siderust-node/examples/02_coordinate_transformations.mjs +25 -0
- package/siderust-node/examples/03_all_frames_conversions.mjs +26 -0
- package/siderust-node/examples/04_all_center_conversions.mjs +24 -0
- package/siderust-node/examples/05_target_tracking.mjs +22 -0
- package/siderust-node/examples/06_night_events.mjs +18 -0
- package/siderust-node/examples/07_moon_properties.mjs +21 -0
- package/siderust-node/examples/08_solar_system.mjs +19 -0
- package/siderust-node/examples/09_star_observability.mjs +22 -0
- package/siderust-node/examples/10_time_periods.mjs +9 -0
- package/siderust-node/examples/11_serialization.mjs +31 -0
- package/siderust-node/examples/12_runtime_ephemeris.mjs +27 -0
- package/siderust-node/examples/13_coordinate_operations.mjs +20 -0
- package/siderust-node/index.d.ts +623 -0
- package/siderust-node/index.js +79 -0
- package/siderust-node/lib/Observer.js +112 -0
- package/siderust-node/lib/Star.js +118 -0
- package/siderust-node/lib/backend.js +63 -0
- package/siderust-node/lib/wrappers.js +566 -0
- package/siderust-node/main.js +20 -0
- package/siderust-node/native.cjs +360 -0
- package/siderust-node/package-lock.json +3261 -0
- package/siderust-node/package.json +71 -0
- package/siderust-node/src/body.rs +74 -0
- package/siderust-node/src/coordinates.rs +372 -0
- package/siderust-node/src/ephemeris.rs +462 -0
- package/siderust-node/src/events.rs +577 -0
- package/siderust-node/src/lib.rs +43 -0
- package/siderust-node/src/observer.rs +132 -0
- package/siderust-node/src/phase.rs +218 -0
- package/siderust-node/src/position.rs +292 -0
- package/siderust-node/src/star.rs +200 -0
- package/siderust-web/Cargo.lock +855 -0
- package/siderust-web/Cargo.toml +34 -0
- package/siderust-web/README.md +100 -0
- package/siderust-web/__test__/index.test.mjs +118 -0
- package/siderust-web/examples/github-pages/README.md +31 -0
- package/siderust-web/examples/github-pages/index.html +135 -0
- package/siderust-web/index.d.ts +311 -0
- package/siderust-web/index.js +66 -0
- package/siderust-web/lib/Observer.js +103 -0
- package/siderust-web/lib/Star.js +116 -0
- package/siderust-web/lib/backend.js +400 -0
- package/siderust-web/lib/wrappers.js +512 -0
- package/siderust-web/package.json +55 -0
- package/siderust-web/src/body.rs +69 -0
- package/siderust-web/src/coordinates.rs +302 -0
- package/siderust-web/src/ephemeris.rs +456 -0
- package/siderust-web/src/events.rs +520 -0
- package/siderust-web/src/lib.rs +51 -0
- package/siderust-web/src/observer.rs +117 -0
- package/siderust-web/src/phase.rs +190 -0
- package/siderust-web/src/position.rs +291 -0
- package/siderust-web/src/star.rs +178 -0
- package/tempoch-js/.github/workflows/ci.yml +142 -0
- package/tempoch-js/.gitmodules +3 -0
- package/tempoch-js/CHANGELOG.md +25 -0
- package/tempoch-js/LICENSE +661 -0
- package/tempoch-js/README.md +126 -0
- package/tempoch-js/package.json +20 -0
- package/tempoch-js/scripts/ci.sh +73 -0
- package/tempoch-js/tempoch/.github/workflows/ci.yml +113 -0
- package/tempoch-js/tempoch/CHANGELOG.md +82 -0
- package/tempoch-js/tempoch/Cargo.lock +947 -0
- package/tempoch-js/tempoch/Cargo.toml +3 -0
- package/tempoch-js/tempoch/LICENSE +661 -0
- package/tempoch-js/tempoch/README.md +76 -0
- package/tempoch-js/tempoch/tempoch/Cargo.toml +27 -0
- package/tempoch-js/tempoch/tempoch/examples/periods.rs +45 -0
- package/tempoch-js/tempoch/tempoch/examples/quickstart.rs +13 -0
- package/tempoch-js/tempoch/tempoch/src/lib.rs +49 -0
- package/tempoch-js/tempoch/tempoch/tests/integration.rs +57 -0
- package/tempoch-js/tempoch/tempoch-core/Cargo.toml +24 -0
- package/tempoch-js/tempoch/tempoch-core/src/delta_t.rs +345 -0
- package/tempoch-js/tempoch/tempoch-core/src/instant.rs +811 -0
- package/tempoch-js/tempoch/tempoch-core/src/julian_date_ext.rs +142 -0
- package/tempoch-js/tempoch/tempoch-core/src/lib.rs +81 -0
- package/tempoch-js/tempoch/tempoch-core/src/period.rs +1168 -0
- package/tempoch-js/tempoch/tempoch-core/src/scales.rs +779 -0
- package/tempoch-js/tempoch/tempoch-ffi/Cargo.lock +889 -0
- package/tempoch-js/tempoch/tempoch-ffi/Cargo.toml +26 -0
- package/tempoch-js/tempoch/tempoch-ffi/build.rs +24 -0
- package/tempoch-js/tempoch/tempoch-ffi/cbindgen.toml +30 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/error.rs +19 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/lib.rs +82 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/period.rs +101 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/time.rs +711 -0
- package/tempoch-js/tempoch/tempoch-ffi/tests/ffi.rs +265 -0
- package/tempoch-js/tempoch-node/.prettierignore +6 -0
- package/tempoch-js/tempoch-node/.prettierrc.json +6 -0
- package/tempoch-js/tempoch-node/Cargo.lock +496 -0
- package/tempoch-js/tempoch-node/Cargo.toml +29 -0
- package/tempoch-js/tempoch-node/README.md +265 -0
- package/tempoch-js/tempoch-node/__test__/index.test.mjs +598 -0
- package/tempoch-js/tempoch-node/build.rs +5 -0
- package/tempoch-js/tempoch-node/c8.config.json +3 -0
- package/tempoch-js/tempoch-node/eslint.config.js +31 -0
- package/tempoch-js/tempoch-node/examples/periods.mjs +79 -0
- package/tempoch-js/tempoch-node/examples/quickstart.mjs +71 -0
- package/tempoch-js/tempoch-node/examples/timescales.mjs +92 -0
- package/tempoch-js/tempoch-node/index.d.ts +280 -0
- package/tempoch-js/tempoch-node/index.js +32 -0
- package/tempoch-js/tempoch-node/lib/JulianDate.js +176 -0
- package/tempoch-js/tempoch-node/lib/ModifiedJulianDate.js +156 -0
- package/tempoch-js/tempoch-node/lib/Period.js +133 -0
- package/tempoch-js/tempoch-node/lib/backend.js +38 -0
- package/tempoch-js/tempoch-node/lib/qttyCompat.js +92 -0
- package/tempoch-js/tempoch-node/native.cjs +317 -0
- package/tempoch-js/tempoch-node/package-lock.json +3223 -0
- package/tempoch-js/tempoch-node/package.json +56 -0
- package/tempoch-js/tempoch-node/src/lib.rs +573 -0
- package/tempoch-js/tempoch-web/Cargo.toml +23 -0
- package/tempoch-js/tempoch-web/index.d.ts +95 -0
- package/tempoch-js/tempoch-web/index.js +27 -0
- package/tempoch-js/tempoch-web/lib/JulianDate.js +170 -0
- package/tempoch-js/tempoch-web/lib/ModifiedJulianDate.js +145 -0
- package/tempoch-js/tempoch-web/lib/Period.js +121 -0
- package/tempoch-js/tempoch-web/lib/backend.js +118 -0
- package/tempoch-js/tempoch-web/package.json +46 -0
- package/tempoch-js/tempoch-web/src/lib.rs +184 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@siderust/siderust",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "High-precision astronomy for Node.js — observer setup, celestial body tracking, altitude/azimuth events, coordinate transforms, ephemerides, and lunar phases. Powered by Rust.",
|
|
5
|
+
"main": "main.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"require": "./main.js",
|
|
10
|
+
"import": "./main.js",
|
|
11
|
+
"types": "./index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "napi build --release --platform",
|
|
16
|
+
"build:debug": "napi build --platform",
|
|
17
|
+
"format": "prettier --write .",
|
|
18
|
+
"format:check": "prettier --check .",
|
|
19
|
+
"lint": "eslint .",
|
|
20
|
+
"test": "node --test __test__/*.test.mjs",
|
|
21
|
+
"test:coverage": "c8 --config c8.config.json node --test __test__/*.test.mjs",
|
|
22
|
+
"ci": "npm run format:check && npm run lint && npm run build:debug && npm test && npm run test:coverage",
|
|
23
|
+
"prepublishOnly": "napi build --release --platform"
|
|
24
|
+
},
|
|
25
|
+
"napi": {
|
|
26
|
+
"name": "siderust",
|
|
27
|
+
"triples": {
|
|
28
|
+
"defaults": true
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"index.js",
|
|
33
|
+
"main.js",
|
|
34
|
+
"index.d.ts",
|
|
35
|
+
"native.cjs",
|
|
36
|
+
"lib/",
|
|
37
|
+
"examples/",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"keywords": [
|
|
41
|
+
"astronomy",
|
|
42
|
+
"astrometry",
|
|
43
|
+
"ephemeris",
|
|
44
|
+
"coordinates",
|
|
45
|
+
"altitude",
|
|
46
|
+
"azimuth",
|
|
47
|
+
"solar-system",
|
|
48
|
+
"moon-phase",
|
|
49
|
+
"vsop87",
|
|
50
|
+
"napi",
|
|
51
|
+
"rust",
|
|
52
|
+
"native"
|
|
53
|
+
],
|
|
54
|
+
"license": "AGPL-3.0",
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/Siderust/siderust"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@siderust/qtty": "file:../qtty-js/qtty-node",
|
|
61
|
+
"@siderust/tempoch": "file:../tempoch-js/tempoch-node"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@eslint/js": "^10.0.1",
|
|
65
|
+
"@napi-rs/cli": "^3.5.1",
|
|
66
|
+
"c8": "^11.0.0",
|
|
67
|
+
"eslint": "^10.0.3",
|
|
68
|
+
"globals": "^17.4.0",
|
|
69
|
+
"prettier": "^3.6.2"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Vallés Puig, Ramon
|
|
3
|
+
|
|
4
|
+
//! Solar-system body identifiers and planet data.
|
|
5
|
+
|
|
6
|
+
use napi_derive::napi;
|
|
7
|
+
|
|
8
|
+
// Re-export shared types from the binding core.
|
|
9
|
+
pub(crate) use siderust_binding_core::body::BodyKind;
|
|
10
|
+
pub(crate) use siderust_binding_core::dispatch_body;
|
|
11
|
+
|
|
12
|
+
/// Convert a body name string to BodyKind, mapping errors to napi::Error.
|
|
13
|
+
pub(crate) fn parse_body(s: &str) -> napi::Result<BodyKind> {
|
|
14
|
+
BodyKind::from_str(s).map_err(napi::Error::from_reason)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
+
// Planet info (value object)
|
|
19
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
/// Physical parameters of a solar-system planet.
|
|
22
|
+
#[napi(object)]
|
|
23
|
+
pub struct PlanetInfo {
|
|
24
|
+
/// Planet name.
|
|
25
|
+
pub name: String,
|
|
26
|
+
/// Mass in kilograms.
|
|
27
|
+
pub mass_kg: f64,
|
|
28
|
+
/// Mean equatorial radius in kilometres.
|
|
29
|
+
pub radius_km: f64,
|
|
30
|
+
/// Semi-major axis in AU.
|
|
31
|
+
pub semi_major_axis_au: f64,
|
|
32
|
+
/// Orbital eccentricity.
|
|
33
|
+
pub eccentricity: f64,
|
|
34
|
+
/// Orbital inclination in degrees.
|
|
35
|
+
pub inclination_deg: f64,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
impl From<siderust_binding_core::body::PlanetInfo> for PlanetInfo {
|
|
39
|
+
fn from(p: siderust_binding_core::body::PlanetInfo) -> Self {
|
|
40
|
+
Self {
|
|
41
|
+
name: p.name,
|
|
42
|
+
mass_kg: p.mass_kg,
|
|
43
|
+
radius_km: p.radius_km,
|
|
44
|
+
semi_major_axis_au: p.semi_major_axis_au,
|
|
45
|
+
eccentricity: p.eccentricity,
|
|
46
|
+
inclination_deg: p.inclination_deg,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Get physical parameters for a named planet.
|
|
52
|
+
///
|
|
53
|
+
/// Valid names: `"Mercury"`, `"Venus"`, `"Earth"`, `"Mars"`, `"Jupiter"`,
|
|
54
|
+
/// `"Saturn"`, `"Uranus"`, `"Neptune"`.
|
|
55
|
+
///
|
|
56
|
+
/// ```js
|
|
57
|
+
/// const { getPlanet } = require('@siderust/siderust');
|
|
58
|
+
/// const mars = getPlanet('Mars');
|
|
59
|
+
/// console.log(mars.massKg, mars.radiusKm);
|
|
60
|
+
/// ```
|
|
61
|
+
#[napi(js_name = "getPlanet")]
|
|
62
|
+
pub fn get_planet(name: String) -> napi::Result<PlanetInfo> {
|
|
63
|
+
siderust_binding_core::body::get_planet_info(&name)
|
|
64
|
+
.map(PlanetInfo::from)
|
|
65
|
+
.ok_or_else(|| napi::Error::from_reason(format!(
|
|
66
|
+
"Unknown planet: \"{name}\". Valid: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune."
|
|
67
|
+
)))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// List the names of all available solar-system bodies for altitude/azimuth queries.
|
|
71
|
+
#[napi(js_name = "listBodies")]
|
|
72
|
+
pub fn list_bodies() -> Vec<String> {
|
|
73
|
+
BodyKind::all_names().iter().map(|s| s.to_string()).collect()
|
|
74
|
+
}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Vallés Puig, Ramon
|
|
3
|
+
|
|
4
|
+
//! Coordinate transform utilities exposed to Node.js.
|
|
5
|
+
//!
|
|
6
|
+
//! Provides spherical-direction frame transforms and geodetic↔ECEF conversion.
|
|
7
|
+
|
|
8
|
+
use napi_derive::napi;
|
|
9
|
+
|
|
10
|
+
use crate::observer::JsObserver;
|
|
11
|
+
|
|
12
|
+
use qtty::*;
|
|
13
|
+
use siderust::coordinates::frames::{
|
|
14
|
+
EclipticMeanJ2000, EquatorialMeanJ2000, EquatorialMeanOfDate, EquatorialTrueOfDate,
|
|
15
|
+
ICRS,
|
|
16
|
+
};
|
|
17
|
+
use siderust::coordinates::spherical;
|
|
18
|
+
use siderust::coordinates::transform::{DirectionAstroExt, SphericalDirectionAstroExt};
|
|
19
|
+
use siderust::time::JulianDate;
|
|
20
|
+
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
22
|
+
// Result types
|
|
23
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
/// A spherical direction (two angles in degrees) with a frame label.
|
|
26
|
+
#[napi(object)]
|
|
27
|
+
pub struct SphericalDirection {
|
|
28
|
+
/// First angle in degrees (Dec / polar / altitude).
|
|
29
|
+
pub polar_deg: f64,
|
|
30
|
+
/// Second angle in degrees (RA / azimuth / longitude).
|
|
31
|
+
pub azimuth_deg: f64,
|
|
32
|
+
/// Reference frame name.
|
|
33
|
+
pub frame: String,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Cartesian ECEF coordinates in metres.
|
|
37
|
+
#[napi(object)]
|
|
38
|
+
pub struct CartesianEcef {
|
|
39
|
+
/// X coordinate in metres.
|
|
40
|
+
pub x: f64,
|
|
41
|
+
/// Y coordinate in metres.
|
|
42
|
+
pub y: f64,
|
|
43
|
+
/// Z coordinate in metres.
|
|
44
|
+
pub z: f64,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
48
|
+
// Spherical direction transforms
|
|
49
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
/// Transform a spherical direction between celestial reference frames.
|
|
52
|
+
///
|
|
53
|
+
/// Supported source and destination frames: `"ICRS"`, `"EclipticMeanJ2000"`,
|
|
54
|
+
/// `"EquatorialMeanJ2000"`, `"EquatorialMeanOfDate"`, `"EquatorialTrueOfDate"`.
|
|
55
|
+
///
|
|
56
|
+
/// @param polarDeg — Declination / polar angle in degrees.
|
|
57
|
+
/// @param azimuthDeg — Right ascension / longitude in degrees.
|
|
58
|
+
/// @param srcFrame — Source frame name.
|
|
59
|
+
/// @param dstFrame — Destination frame name.
|
|
60
|
+
/// @param jd — Julian Date (needed for of-date frames; use J2000 = 2451545.0 for epoch-independent frames).
|
|
61
|
+
///
|
|
62
|
+
/// ```js
|
|
63
|
+
/// const { transformDirection } = require('@siderust/siderust');
|
|
64
|
+
/// const result = transformDirection(38.78, 279.23, 'EquatorialMeanJ2000', 'EclipticMeanJ2000', 2451545.0);
|
|
65
|
+
/// ```
|
|
66
|
+
#[napi(js_name = "transformDirection")]
|
|
67
|
+
pub fn transform_direction(
|
|
68
|
+
polar_deg: f64,
|
|
69
|
+
azimuth_deg: f64,
|
|
70
|
+
src_frame: String,
|
|
71
|
+
dst_frame: String,
|
|
72
|
+
jd: f64,
|
|
73
|
+
) -> napi::Result<SphericalDirection> {
|
|
74
|
+
if !polar_deg.is_finite() || !azimuth_deg.is_finite() || !jd.is_finite() {
|
|
75
|
+
return Err(napi::Error::from_reason(
|
|
76
|
+
"polarDeg, azimuthDeg and jd must be finite",
|
|
77
|
+
));
|
|
78
|
+
}
|
|
79
|
+
let t = JulianDate::new(jd);
|
|
80
|
+
|
|
81
|
+
// Build a source direction in the given frame, then transform.
|
|
82
|
+
// We route through ICRS as the hub frame.
|
|
83
|
+
let icrs_dir = src_to_icrs(polar_deg, azimuth_deg, &src_frame, &t)?;
|
|
84
|
+
|
|
85
|
+
// Now convert from ICRS to destination
|
|
86
|
+
icrs_to_dst(&icrs_dir, &dst_frame, &t)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// Transform a spherical direction to the local Horizontal frame.
|
|
90
|
+
///
|
|
91
|
+
/// @returns `{ polarDeg, azimuthDeg, frame }` where polarDeg is altitude
|
|
92
|
+
/// and azimuthDeg is azimuth (N=0° E=90°).
|
|
93
|
+
#[napi(js_name = "directionToHorizontal")]
|
|
94
|
+
pub fn direction_to_horizontal(
|
|
95
|
+
polar_deg: f64,
|
|
96
|
+
azimuth_deg: f64,
|
|
97
|
+
src_frame: String,
|
|
98
|
+
jd: f64,
|
|
99
|
+
observer: &JsObserver,
|
|
100
|
+
) -> napi::Result<SphericalDirection> {
|
|
101
|
+
if !polar_deg.is_finite() || !azimuth_deg.is_finite() || !jd.is_finite() {
|
|
102
|
+
return Err(napi::Error::from_reason(
|
|
103
|
+
"polarDeg, azimuthDeg and jd must be finite",
|
|
104
|
+
));
|
|
105
|
+
}
|
|
106
|
+
let t = JulianDate::new(jd);
|
|
107
|
+
let icrs_dir = src_to_icrs(polar_deg, azimuth_deg, &src_frame, &t)?;
|
|
108
|
+
|
|
109
|
+
// ICRS → EquatorialTrueOfDate → Horizontal
|
|
110
|
+
let eq_tod =
|
|
111
|
+
SphericalDirectionAstroExt::to_frame::<EquatorialTrueOfDate>(&icrs_dir, &t);
|
|
112
|
+
let cart = eq_tod.to_cartesian();
|
|
113
|
+
let hz = DirectionAstroExt::to_horizontal(&cart, &t, &observer.inner);
|
|
114
|
+
let hz_sph = spherical::Direction::from_cartesian(&hz);
|
|
115
|
+
|
|
116
|
+
Ok(SphericalDirection {
|
|
117
|
+
polar_deg: hz_sph.polar.value(),
|
|
118
|
+
azimuth_deg: hz_sph.azimuth.value(),
|
|
119
|
+
frame: "Horizontal".to_string(),
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/// Convert a geodetic position (WGS84) to ECEF Cartesian coordinates.
|
|
124
|
+
///
|
|
125
|
+
/// @param observer — Observer with lon/lat/height.
|
|
126
|
+
/// @returns `{ x, y, z }` in metres.
|
|
127
|
+
#[napi(js_name = "geodeticToEcef")]
|
|
128
|
+
pub fn geodetic_to_ecef(observer: &JsObserver) -> CartesianEcef {
|
|
129
|
+
let cart = observer.inner.to_cartesian::<Meter>();
|
|
130
|
+
CartesianEcef {
|
|
131
|
+
x: cart.x().value(),
|
|
132
|
+
y: cart.y().value(),
|
|
133
|
+
z: cart.z().value(),
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
138
|
+
// Angular separation
|
|
139
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
/// Compute the angular separation between two spherical directions (Vincenty formula).
|
|
142
|
+
///
|
|
143
|
+
/// Both directions must be in the same reference frame.
|
|
144
|
+
///
|
|
145
|
+
/// @param polar1Deg — Declination / polar angle of first direction in degrees.
|
|
146
|
+
/// @param azimuth1Deg — RA / azimuth of first direction in degrees.
|
|
147
|
+
/// @param polar2Deg — Declination / polar angle of second direction in degrees.
|
|
148
|
+
/// @param azimuth2Deg — RA / azimuth of second direction in degrees.
|
|
149
|
+
/// @param frame — Reference frame (both directions must share the same frame).
|
|
150
|
+
/// @returns Angular separation in degrees.
|
|
151
|
+
///
|
|
152
|
+
/// ```js
|
|
153
|
+
/// const { angularSeparation } = require('@siderust/siderust');
|
|
154
|
+
/// const sep = angularSeparation(89.26, 37.95, -16.72, 101.29, 'EquatorialMeanJ2000');
|
|
155
|
+
/// ```
|
|
156
|
+
#[napi(js_name = "angularSeparation")]
|
|
157
|
+
pub fn angular_separation(
|
|
158
|
+
polar1_deg: f64,
|
|
159
|
+
azimuth1_deg: f64,
|
|
160
|
+
polar2_deg: f64,
|
|
161
|
+
azimuth2_deg: f64,
|
|
162
|
+
frame: String,
|
|
163
|
+
) -> napi::Result<f64> {
|
|
164
|
+
if !polar1_deg.is_finite()
|
|
165
|
+
|| !azimuth1_deg.is_finite()
|
|
166
|
+
|| !polar2_deg.is_finite()
|
|
167
|
+
|| !azimuth2_deg.is_finite()
|
|
168
|
+
{
|
|
169
|
+
return Err(napi::Error::from_reason(
|
|
170
|
+
"All angle parameters must be finite",
|
|
171
|
+
));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Angular separation only depends on the geometry, not the specific frame type,
|
|
175
|
+
// but we dispatch to maintain type correctness.
|
|
176
|
+
let sep = match frame.as_str() {
|
|
177
|
+
"ICRS" => {
|
|
178
|
+
let d1 = spherical::Direction::<ICRS>::new(
|
|
179
|
+
Degrees::new(azimuth1_deg),
|
|
180
|
+
Degrees::new(polar1_deg),
|
|
181
|
+
);
|
|
182
|
+
let d2 = spherical::Direction::<ICRS>::new(
|
|
183
|
+
Degrees::new(azimuth2_deg),
|
|
184
|
+
Degrees::new(polar2_deg),
|
|
185
|
+
);
|
|
186
|
+
d1.angular_separation(&d2)
|
|
187
|
+
}
|
|
188
|
+
"EclipticMeanJ2000" => {
|
|
189
|
+
let d1 = spherical::Direction::<EclipticMeanJ2000>::new(
|
|
190
|
+
Degrees::new(azimuth1_deg),
|
|
191
|
+
Degrees::new(polar1_deg),
|
|
192
|
+
);
|
|
193
|
+
let d2 = spherical::Direction::<EclipticMeanJ2000>::new(
|
|
194
|
+
Degrees::new(azimuth2_deg),
|
|
195
|
+
Degrees::new(polar2_deg),
|
|
196
|
+
);
|
|
197
|
+
d1.angular_separation(&d2)
|
|
198
|
+
}
|
|
199
|
+
"EquatorialMeanJ2000" => {
|
|
200
|
+
let d1 = spherical::Direction::<EquatorialMeanJ2000>::new(
|
|
201
|
+
Degrees::new(azimuth1_deg),
|
|
202
|
+
Degrees::new(polar1_deg),
|
|
203
|
+
);
|
|
204
|
+
let d2 = spherical::Direction::<EquatorialMeanJ2000>::new(
|
|
205
|
+
Degrees::new(azimuth2_deg),
|
|
206
|
+
Degrees::new(polar2_deg),
|
|
207
|
+
);
|
|
208
|
+
d1.angular_separation(&d2)
|
|
209
|
+
}
|
|
210
|
+
_ => {
|
|
211
|
+
return Err(napi::Error::from_reason(format!(
|
|
212
|
+
"Unsupported frame for angular separation: \"{frame}\". Valid: ICRS, EclipticMeanJ2000, EquatorialMeanJ2000."
|
|
213
|
+
)));
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
Ok(sep.value())
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/// Compute the Euclidean distance between two 3D Cartesian positions.
|
|
220
|
+
///
|
|
221
|
+
/// The positions must be in the same frame and center. Units follow input.
|
|
222
|
+
///
|
|
223
|
+
/// @returns Distance in the same units as the input coordinates.
|
|
224
|
+
#[napi(js_name = "cartesianDistance")]
|
|
225
|
+
pub fn cartesian_distance(
|
|
226
|
+
x1: f64,
|
|
227
|
+
y1: f64,
|
|
228
|
+
z1: f64,
|
|
229
|
+
x2: f64,
|
|
230
|
+
y2: f64,
|
|
231
|
+
z2: f64,
|
|
232
|
+
) -> f64 {
|
|
233
|
+
let dx = x2 - x1;
|
|
234
|
+
let dy = y2 - y1;
|
|
235
|
+
let dz = z2 - z1;
|
|
236
|
+
(dx * dx + dy * dy + dz * dz).sqrt()
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/// Compute the magnitude (distance from origin) of a 3D Cartesian vector.
|
|
240
|
+
///
|
|
241
|
+
/// @returns Distance from origin in the same units.
|
|
242
|
+
#[napi(js_name = "cartesianMagnitude")]
|
|
243
|
+
pub fn cartesian_magnitude(x: f64, y: f64, z: f64) -> f64 {
|
|
244
|
+
(x * x + y * y + z * z).sqrt()
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/// Compute the dot product of two 3D Cartesian vectors.
|
|
248
|
+
///
|
|
249
|
+
/// @returns The scalar dot product.
|
|
250
|
+
#[napi(js_name = "dotProduct")]
|
|
251
|
+
pub fn dot_product(x1: f64, y1: f64, z1: f64, x2: f64, y2: f64, z2: f64) -> f64 {
|
|
252
|
+
x1 * x2 + y1 * y2 + z1 * z2
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/// Convert a direction (unit vector) from spherical to Cartesian.
|
|
256
|
+
///
|
|
257
|
+
/// @param polarDeg — Declination / polar angle in degrees.
|
|
258
|
+
/// @param azimuthDeg — RA / azimuth in degrees.
|
|
259
|
+
/// @returns `{ x, y, z }` unit vector.
|
|
260
|
+
#[napi(js_name = "directionToCartesian")]
|
|
261
|
+
pub fn direction_to_cartesian(polar_deg: f64, azimuth_deg: f64) -> CartesianEcef {
|
|
262
|
+
let d = spherical::Direction::<ICRS>::new(
|
|
263
|
+
Degrees::new(azimuth_deg),
|
|
264
|
+
Degrees::new(polar_deg),
|
|
265
|
+
);
|
|
266
|
+
let c = d.to_cartesian();
|
|
267
|
+
CartesianEcef {
|
|
268
|
+
x: c.x(),
|
|
269
|
+
y: c.y(),
|
|
270
|
+
z: c.z(),
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
275
|
+
// Internal helpers
|
|
276
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
277
|
+
|
|
278
|
+
/// Convert from any supported source frame to ICRS.
|
|
279
|
+
fn src_to_icrs(
|
|
280
|
+
polar_deg: f64,
|
|
281
|
+
azimuth_deg: f64,
|
|
282
|
+
src_frame: &str,
|
|
283
|
+
jd: &JulianDate,
|
|
284
|
+
) -> napi::Result<spherical::Direction<ICRS>> {
|
|
285
|
+
match src_frame {
|
|
286
|
+
"ICRS" => {
|
|
287
|
+
let d = spherical::Direction::<ICRS>::new(Degrees::new(azimuth_deg), Degrees::new(polar_deg));
|
|
288
|
+
Ok(d)
|
|
289
|
+
}
|
|
290
|
+
"EclipticMeanJ2000" => {
|
|
291
|
+
let d = spherical::Direction::<EclipticMeanJ2000>::new(
|
|
292
|
+
Degrees::new(azimuth_deg),
|
|
293
|
+
Degrees::new(polar_deg),
|
|
294
|
+
);
|
|
295
|
+
Ok(SphericalDirectionAstroExt::to_frame::<ICRS>(&d, jd))
|
|
296
|
+
}
|
|
297
|
+
"EquatorialMeanJ2000" => {
|
|
298
|
+
let d = spherical::Direction::<EquatorialMeanJ2000>::new(
|
|
299
|
+
Degrees::new(azimuth_deg),
|
|
300
|
+
Degrees::new(polar_deg),
|
|
301
|
+
);
|
|
302
|
+
Ok(SphericalDirectionAstroExt::to_frame::<ICRS>(&d, jd))
|
|
303
|
+
}
|
|
304
|
+
"EquatorialMeanOfDate" => {
|
|
305
|
+
let d = spherical::Direction::<EquatorialMeanOfDate>::new(
|
|
306
|
+
Degrees::new(azimuth_deg),
|
|
307
|
+
Degrees::new(polar_deg),
|
|
308
|
+
);
|
|
309
|
+
Ok(SphericalDirectionAstroExt::to_frame::<ICRS>(&d, jd))
|
|
310
|
+
}
|
|
311
|
+
"EquatorialTrueOfDate" => {
|
|
312
|
+
let d = spherical::Direction::<EquatorialTrueOfDate>::new(
|
|
313
|
+
Degrees::new(azimuth_deg),
|
|
314
|
+
Degrees::new(polar_deg),
|
|
315
|
+
);
|
|
316
|
+
Ok(SphericalDirectionAstroExt::to_frame::<ICRS>(&d, jd))
|
|
317
|
+
}
|
|
318
|
+
_ => Err(napi::Error::from_reason(format!(
|
|
319
|
+
"Unsupported source frame: \"{src_frame}\". Valid: ICRS, EclipticMeanJ2000, EquatorialMeanJ2000, EquatorialMeanOfDate, EquatorialTrueOfDate."
|
|
320
|
+
))),
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/// Convert from ICRS to any supported destination frame.
|
|
325
|
+
fn icrs_to_dst(
|
|
326
|
+
icrs: &spherical::Direction<ICRS>,
|
|
327
|
+
dst_frame: &str,
|
|
328
|
+
jd: &JulianDate,
|
|
329
|
+
) -> napi::Result<SphericalDirection> {
|
|
330
|
+
match dst_frame {
|
|
331
|
+
"ICRS" => Ok(SphericalDirection {
|
|
332
|
+
polar_deg: icrs.polar.value(),
|
|
333
|
+
azimuth_deg: icrs.azimuth.value(),
|
|
334
|
+
frame: "ICRS".to_string(),
|
|
335
|
+
}),
|
|
336
|
+
"EclipticMeanJ2000" => {
|
|
337
|
+
let d = SphericalDirectionAstroExt::to_frame::<EclipticMeanJ2000>(icrs, jd);
|
|
338
|
+
Ok(SphericalDirection {
|
|
339
|
+
polar_deg: d.polar.value(),
|
|
340
|
+
azimuth_deg: d.azimuth.value(),
|
|
341
|
+
frame: "EclipticMeanJ2000".to_string(),
|
|
342
|
+
})
|
|
343
|
+
}
|
|
344
|
+
"EquatorialMeanJ2000" => {
|
|
345
|
+
let d = SphericalDirectionAstroExt::to_frame::<EquatorialMeanJ2000>(icrs, jd);
|
|
346
|
+
Ok(SphericalDirection {
|
|
347
|
+
polar_deg: d.polar.value(),
|
|
348
|
+
azimuth_deg: d.azimuth.value(),
|
|
349
|
+
frame: "EquatorialMeanJ2000".to_string(),
|
|
350
|
+
})
|
|
351
|
+
}
|
|
352
|
+
"EquatorialMeanOfDate" => {
|
|
353
|
+
let d = SphericalDirectionAstroExt::to_frame::<EquatorialMeanOfDate>(icrs, jd);
|
|
354
|
+
Ok(SphericalDirection {
|
|
355
|
+
polar_deg: d.polar.value(),
|
|
356
|
+
azimuth_deg: d.azimuth.value(),
|
|
357
|
+
frame: "EquatorialMeanOfDate".to_string(),
|
|
358
|
+
})
|
|
359
|
+
}
|
|
360
|
+
"EquatorialTrueOfDate" => {
|
|
361
|
+
let d = SphericalDirectionAstroExt::to_frame::<EquatorialTrueOfDate>(icrs, jd);
|
|
362
|
+
Ok(SphericalDirection {
|
|
363
|
+
polar_deg: d.polar.value(),
|
|
364
|
+
azimuth_deg: d.azimuth.value(),
|
|
365
|
+
frame: "EquatorialTrueOfDate".to_string(),
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
_ => Err(napi::Error::from_reason(format!(
|
|
369
|
+
"Unsupported destination frame: \"{dst_frame}\". Valid: ICRS, EclipticMeanJ2000, EquatorialMeanJ2000, EquatorialMeanOfDate, EquatorialTrueOfDate."
|
|
370
|
+
))),
|
|
371
|
+
}
|
|
372
|
+
}
|