[English](README.md) | 中文

# jspredict-dc v3

`jspredict-dc` 是一个基于 [`satellite.js`](https://github.com/shashwatak/satellite-js) 重构的卫星轨道传播与可见性工具库。

v3 版本的核心目标有三个：

- 统一轨道输入层，让 TLE、OMM XML、OMM KVN、CSV、JSON GP 使用同一套入口
- 直接依赖 `satellite.js` 作为核心轨道数学基础，不再维护独立传播内核
- 只保留主 API 名称，减少历史别名带来的歧义

## 这个包能做什么

- 按 UTC 时刻传播卫星位置
- 按时间窗采样星历
- 预测地面观测者的过境和可见窗口
- 根据轨道源或笛卡尔半径估算轨道周期
- 接受 TLE/2LE/3LE、OMM XML、OMM KVN、CSV、JSON GP 或已构建好的 `satrec` 输入
- 提供统一的轨道元数据与轨道根数解析接口

## 快速上手

```bash
npm install jspredict-dc
```

```js
const jspredict = require('jspredict-dc');

const tle = `ISS (ZARYA)
1 25544U 98067A   26111.20666667  .00010600  00000+0  19000-3 0  9990
2 25544  51.6416 160.4574 0004684  38.4897 102.1035 15.50271675444743`;

const observer = [39.9042, 116.4074, 0.05];
const time = new Date('2026-04-20T08:27:14Z');

const observation = jspredict.observeAt(tle, observer, time);
const ephemeris = jspredict.ephemeris(tle, observer, time, new Date('2026-04-20T09:27:14Z'), { minutes: 5 });
const transits = jspredict.findTransits(tle, observer, time, new Date('2026-04-23T08:27:14Z'), 0);
const debug = jspredict.findTransitsDebug(tle, observer, time, new Date('2026-04-23T08:27:14Z'), 0, 20, { scanStepMs: { minutes: 1 } });
```

## Demo 和官网

- GitHub Pages 演示地址：`https://fanqie.github.io/jspredict-dc/`
- 仓库根目录演示页：[`index.html`](./index.html)

演示页基于 Cesium，用来做浏览器里的快速可视化验证，包含：

- 实时轨道渲染
- 2D 星下点轨迹查看
- UTC 时间轴拖动
- 采样预览面板
- 纯文本数据页，用于检查原始输出

## v3 相对 2.0 的变化

### 改动重点

- v3 基于 `satellite.js` 6.x
- v3 不再把独立传播内核作为公共设计的一部分
- v3 接受统一后的轨道源输入，而不是只接受一种固定格式
- v3 使用原生 `Date`，不再依赖 moment 风格时间层

旧的 2.0 风格名称不再保留，文档只描述当前主 API。

## 支持的轨道输入

`jspredict-dc` 支持以下输入：

- TLE 字符串，包括 `2LE` 和 `3LE`
- OMM XML 字符串
- OMM KVN 字符串
- 单记录 CSV 字符串
- JSON GP 对象
- JSON 字符串，包括 CelesTrak 的单记录数组返回
- 已经构建好的 `satrec` 对象

当前对 CelesTrak “Obtain GP Data” 的兼容目标是单记录载荷。多记录 catalog/feed 目前还没有单独的批量解析 API。

推荐使用的 v3 新入口：

- `normalizeOrbitSource(source)`
- `parseOrbitMetadata(source)`
- `parseOrbitElements(source)`
- `parseTle(source)`
- `fromTle(line1, line2)`
- `fromJsonGp(record)`
- `fromOmmXml(xml)`

## 主要 API

### 观测

- `observeAt(source, observerLocation?, time?)`

返回某个 UTC 时刻的单次观测结果。传入观测者位置后，还会附带方位角、仰角、斜距和多普勒相关信息。
`observerLocation` 对象输入额外支持 `altMeters` / `altitudeMeters` / `heightMeters`（米制高度）。

### 星历

- `ephemeris(source, observerLocation, start, end, interval?)`

在时间窗内按固定步长采样，返回一组观测结果。

### 过境预测

- `findTransits(source, observerLocation, start, end, minElevation?, maxTransits?)`
- `findTransitsDebug(source, observerLocation, start, end, minElevation?, maxTransits?, options?)`
- `transitSegment(source, observerLocation, start, end)`

用于搜索地面观测者的可见过境窗口。
`findTransitsDebug` 会同时返回过境结果与诊断信息（如扫描步长、窗口最大仰角、接近地平线时间点）。

### 可见窗口

- `visibilityWindows(source, observerLocation, start, end)`
- `groundVisibilityWindows(source, observerLocation, start, end)`
- `satelliteVisibilityWindows(source1, source2, start, end, stepSeconds?)`

前者计算地面观测窗口，后者计算两颗卫星之间的互见窗口。

### 轨道周期

- `orbitalPeriodFromOrbitSource(source)`
- `orbitalPeriodFromCartesian3([x, y, z])`

根据轨道源或笛卡尔半径估算轨道周期。

### 运行时配置

- `setIterationLimit(max)`
- `printIntervalInfo(open)`

用于控制搜索算法的最大迭代次数和调试日志输出。
`findTransits` 和 `findTransitsDebug` 在未显式传入 `maxTransits` 时默认使用 `DEFAULT_MAX_TRANSITS = 100`。如果你搜索的是多天窗口、低仰角阈值或高频 LEO 目标，建议主动传更大的值。

## 全部导出 API

| API | 说明 |
| --- | --- |
| `DEFAULT_MAX_TRANSITS` | `findTransits` / `findTransitsDebug` 默认使用的过境条目上限。 |
| `normalizeOrbitSource(source)` | 将任意支持的轨道输入归一化为标准内部结构。 |
| `parseOrbitMetadata(source)` | 返回统一后的身份信息、历元、轨道根数和派生轨道分类信息。 |
| `parseOrbitElements(source)` | 只返回统一后的轨道根数字段。 |
| `parseTle(source)` | 解析 TLE 专有元数据，如 NORAD 编号、国际代号、历元、圈次等。 |
| `fromTle(line1, line2)` | 从 TLE 两行文本构建标准轨道源。 |
| `fromJsonGp(record)` | 从 JSON GP 对象构建标准轨道源。 |
| `fromOmmXml(xml)` | 从 OMM XML 构建标准轨道源。 |
| `observeAt(source, observerLocation?, time?)` | 计算单个时刻的卫星观测结果。 |
| `ephemeris(source, observerLocation, start, end, interval?)` | 按时间步长采样星历。 |
| `findTransits(...)` | 搜索可见过境窗口。 |
| `findTransitsDebug(...)` | 搜索过境并返回诊断信息，便于排查无过境原因。 |
| `transitSegment(...)` | 搜索单个过境窗口。 |
| `visibilityWindows(...)` | 返回地面观测窗口，格式为 `[startMs, endMs]`。 |
| `groundVisibilityWindows(...)` | 语义更明确的地面可见窗口接口（与 `visibilityWindows` 等价）。 |
| `satelliteVisibilityWindows(...)` | 返回两颗卫星之间的互见窗口。 |
| `orbitalPeriodFromOrbitSource(source)` | 从轨道源估算轨道周期。 |
| `orbitalPeriodFromCartesian3([x, y, z])` | 从笛卡尔半径估算轨道周期。 |
| `setIterationLimit(max)` | 设置搜索算法允许的最大迭代次数。 |
| `printIntervalInfo(open)` | 开关调试日志输出。 |

## 示例

```js
const jspredict = require('jspredict-dc');

const tle = `STARLINK-1008
1 44714U 19074B   26109.91670139  .01912102  00000+0  47462-1 0  9994
2 44714  53.1550 346.4090 0001914  94.7468 310.9927 15.36899644  5865`;

const observer = [39.9042, 116.4074, 0.05];
const start = new Date('2026-04-20T08:00:00Z');
const end = new Date('2026-04-20T09:00:00Z');

const current = jspredict.observeAt(tle, observer, new Date('2026-04-20T08:27:14Z'));
const samples = jspredict.ephemeris(tle, observer, start, end, { minutes: 5 });
const passes = jspredict.findTransits(tle, observer, start, end, 0, 5);
const windows = jspredict.visibilityWindows(tle, observer, start, end);
const metadata = jspredict.parseOrbitMetadata(tle);
const elements = jspredict.parseOrbitElements(tle);
```

## 格式覆盖

仓库测试当前已经验证以下 CelesTrak GP 单记录格式都可以被归一化、解析并用于传播：

- `TLE` / `3LE`
- `2LE`
- `OMM XML`
- `OMM KVN`
- `JSON` 单记录数组返回
- `CSV`

## 依赖说明

### 运行时依赖

- [`satellite.js`](https://github.com/shashwatak/satellite-js) `^6.0.1`

### 开发依赖

- Rollup
- Jest
- CommonJS / JSON / Node resolve / 压缩等 Rollup 插件

### Demo 依赖

仓库根目录的演示页在浏览器里使用 Cesium，但 Cesium 不是这个包的运行时 npm 依赖。

## 协议

MIT
