feat: 引入可切换星历模型并扩展天象观测链路
- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算 - 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询 - 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出 - 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解 - 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤 - 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持 - 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理 - 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
This commit is contained in:
+3
-131
@@ -1,11 +1,8 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -39,124 +36,6 @@ type StarData struct {
|
||||
CstChinese string
|
||||
}
|
||||
|
||||
func parseStarData(star []byte) (InnerStarData, error) {
|
||||
var err error
|
||||
var stardata InnerStarData
|
||||
if len(star) < 160 {
|
||||
return stardata, errors.New("invalid stardat")
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
if star[i] == ' ' {
|
||||
continue
|
||||
}
|
||||
stardata.HR = stardata.HR*10 + uint16(star[i]-48)
|
||||
}
|
||||
stardata.Name = string(bytes.TrimSpace(star[4:14]))
|
||||
for i := 25; i < 31; i++ {
|
||||
if star[i] == ' ' {
|
||||
continue
|
||||
}
|
||||
stardata.HD = stardata.HD*10 + uint32(star[i]-48)
|
||||
}
|
||||
stardata.Ra, err = parseRa(star)
|
||||
if err != nil {
|
||||
return stardata, fmt.Errorf("parse ra failed:%v", err)
|
||||
}
|
||||
stardata.Dec, err = parseDec(star)
|
||||
if err != nil {
|
||||
return stardata, fmt.Errorf("parse dec failed:%v", err)
|
||||
}
|
||||
magOri := string(bytes.TrimSpace(star[102:107]))
|
||||
if magOri != "" {
|
||||
stardata.Mag, err = strconv.ParseFloat(magOri, 64)
|
||||
if err != nil {
|
||||
return stardata, fmt.Errorf("parse mag failed:%v", err)
|
||||
}
|
||||
} else {
|
||||
stardata.Mag = 9999.9999
|
||||
}
|
||||
stardata.PmRA, _ = strconv.ParseFloat(string(bytes.TrimSpace(star[148:154])), 64)
|
||||
stardata.PmDec, _ = strconv.ParseFloat(string(bytes.TrimSpace(star[154:160])), 64)
|
||||
if len(star) >= 170 {
|
||||
stardata.RadVel, _ = strconv.ParseFloat(string(bytes.TrimSpace(star[166:170])), 64)
|
||||
}
|
||||
if len(star) >= 179 {
|
||||
stardata.RotVel, _ = strconv.ParseFloat(string(bytes.TrimSpace(star[176:179])), 64)
|
||||
}
|
||||
if len(star) > 161 {
|
||||
rc, _ := strconv.ParseFloat(string(bytes.TrimSpace(star[162:166])), 64)
|
||||
if rc != 0 {
|
||||
stardata.Pc = 1 / rc
|
||||
}
|
||||
}
|
||||
return stardata, nil
|
||||
}
|
||||
|
||||
func parseRa(star []byte) (float64, error) {
|
||||
var sec float64
|
||||
var err error
|
||||
ra := float64(0)
|
||||
for i := 75; i < 77; i++ {
|
||||
if star[i] == ' ' {
|
||||
continue
|
||||
}
|
||||
ra = ra*10 + float64(star[i]-48)
|
||||
}
|
||||
minute := uint8(0)
|
||||
for i := 77; i < 79; i++ {
|
||||
if star[i] == ' ' {
|
||||
continue
|
||||
}
|
||||
minute = minute*10 + (star[i] - 48)
|
||||
}
|
||||
ori := string(bytes.TrimSpace(star[79:83]))
|
||||
if ori != "" {
|
||||
sec, err = strconv.ParseFloat(ori, 64)
|
||||
if err != nil {
|
||||
return ra, err
|
||||
}
|
||||
}
|
||||
ra += float64(minute)/60 + sec/3600
|
||||
return ra * 15, nil
|
||||
}
|
||||
|
||||
func parseDec(star []byte) (float64, error) {
|
||||
var sec float64
|
||||
var err error
|
||||
underZero := false
|
||||
if star[83] == '-' {
|
||||
underZero = true
|
||||
}
|
||||
dec := float64(0)
|
||||
for i := 84; i < 86; i++ {
|
||||
if star[i] == ' ' {
|
||||
continue
|
||||
}
|
||||
dec = dec*10 + float64(star[i]-48)
|
||||
}
|
||||
minute := uint8(0)
|
||||
for i := 86; i < 88; i++ {
|
||||
if star[i] == ' ' {
|
||||
continue
|
||||
}
|
||||
minute = minute*10 + (star[i] - 48)
|
||||
}
|
||||
ori := string(bytes.TrimSpace(star[88:90]))
|
||||
if ori != "" {
|
||||
sec, err = strconv.ParseFloat(ori, 64)
|
||||
if err != nil {
|
||||
return dec, err
|
||||
}
|
||||
}
|
||||
dec += float64(minute)/60 + sec/3600
|
||||
if underZero {
|
||||
dec = -dec
|
||||
}
|
||||
return dec, nil
|
||||
}
|
||||
|
||||
var stardat [][]byte
|
||||
var starhdindex map[string]int
|
||||
var hr2detail map[uint16][]string
|
||||
var hr2hip map[uint16]uint32
|
||||
var chnidx map[string]uint16
|
||||
@@ -173,16 +52,9 @@ func LoadStarData() error {
|
||||
}
|
||||
|
||||
func initStarData() error {
|
||||
data := initStarCatalogData()
|
||||
stardat = bytes.Split(data, []byte("\n"))
|
||||
parsedStarData = make([]InnerStarData, len(stardat))
|
||||
cachedStarData = make([]StarData, len(stardat))
|
||||
for i, row := range stardat {
|
||||
parsed, err := parseStarData(row)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse star %d failed: %w", i+1, err)
|
||||
}
|
||||
parsedStarData[i] = parsed
|
||||
parsedStarData = initStarCatalogData()
|
||||
cachedStarData = make([]StarData, len(parsedStarData))
|
||||
for i, parsed := range parsedStarData {
|
||||
cachedStarData[i] = fullStarData(parsed)
|
||||
}
|
||||
chnidx = make(map[string]uint16, len(hr2detail)*2)
|
||||
|
||||
Reference in New Issue
Block a user