瑞士星历表

本仓库包含 瑞士星历表,并封装了一个用 Swift 编写的包装器。所有瑞士星历表 C 代码均未修改,可访问,导入包后可直接调用。如果您使用 C 语言编程,或者熟悉原始库,则可以忽略 Swift 代码。

我正在开发一个 Swift 包装器,以便为不熟悉 C 但又想利用该星历表功能的开发人员提供便利性和可访问性。这仍在进行中,并且包装器的当前状态仅利用了星历表提供的一小部分功能。

该软件包可通过 Swift Package Manager 获取。

许可

本项目采用 a) GNU public license version 2 or later 许可模式,该模式在 Astrodienst 瑞士星历表 描述的 How to license the Swiss Ephemeris 部分中进行了概述。在开始使用之前,请熟悉许可要求。

喷气推进实验室开发星历表 文件

目前,包含的 JPL 星历表文件如下:

天体 文件 时间段
行星 sepl_18.se1 公元 1800 年 – 公元 2399 年
月亮 semo_18.se1 公元 1800 年 – 公元 2399 年
小行星 seas_18.se1 公元 1800 年 – 公元 2399 年

如果您希望支持 公元 1800 年 – 公元 2399 年 之外的日期,请在 Sources/SwissEphemeris/JPL 中包含其他 JPL 文件。

设置星历表文件

至关重要的是,在获取任何占星数据之前,必须在运行时设置 JPL 星历表文件的路径。现有的各种文档和示例将此步骤视为可选步骤,但如果不采取此步骤,该库的功能将受到极大的限制。自 Swift 工具版本 5.3 以来,可以 将资源捆绑为 Swift 包的一部分。这允许将 JPL 文件作为资源添加到包中,并将资源路径设置为星历表文件的路径。

应在应用程序的入口点调用此方法一次。默认情况下,此包的保存 JPL 文件的 Bundle.module 资源路径设置为星历表路径。但是,也可以传入 path 参数来设置您已在应用程序中捆绑的不同星历表文件。

// Sets ephemeris path to the JPL resources.
JPLFileManager.setEphemerisPath()
// Set a path to JPL files added to your app bundle.
let path = "URL to your ephemeris files"
JPLFileManager.setEphemerisPath(path: )

用法

天文和占星坐标

要获取行星、月球或月球交点的坐标数据,请创建一个 Coordinate,其中 T 是 IPL 天体类别的类型。此类型包含的不仅仅是占星数据,还包括任何行星天体的纬度和经度速度以及以天文单位 (AU) 为单位的距离。

let now = Date()
// Astronomical and astrological information for the moon at this point in time.
let moonCoordinate = Coordinate<Planet>(planet: .moon, date: now)
// The moon's longitude.
moonCoordinate.longitude
// The moon's latitude.
moonCoordinate.latitude
// The distance in AU from the earth.
moonCoordinate.distance
// The speed in longitude (deg/day).
moonCoordinate.speedLongitude
// The speed in latitude (deg/day).
moonCoordinate.speedLatitude
// The speed in distance (AU/day).
moonCoordinate.speedDistance

关于天体黄道和恒星黄道位置的占星信息也可以通过 Coordinate 类型的 tropicalsidereal 属性获得。

// Date for 12.14.2019 13:39 UT/GMT
let date = Date(timeIntervalSince1970: 598023482.487818)
// Astronomical and astrological information for the sun on December 14th 2019.
let sunCoordinate = Coordinate<Planet>(planet: .sun, date: date)
// This will return 21 Degrees Sagittarius ♐︎ 46' 49''.
sunCoordinate.tropical.formatted
// It is also possible to get the degree, minute and second as properties of the Coordinate.
let degree = sunCoordinate.tropical.degree
let minute = sunCoordinate.tropical.minute
let second = sunCoordinate.tropical.second

占星相位

要在两个 CelestialBody 类型之间创建相位,请使用 AspectTransit 包含Transit的开始和结束日期属性,精度为一小时。

// Create a pair of celestial bodies.
let moonTrueNode = Pair<Planet, LunarNorthNode>(a: .moon, b: .trueNode)
// Transit contains start and end date properties.
let transit = Transit(pair: moonTrueNode, date: Date(), orb: 8.0)

占星宫位

要获取日期、位置和宫位系统的宫位布局,请创建一个 HouseCuspsHouseSystem 决定了设置的占星宫位系统的类型。所有宫位 Cusp 属性都可用于创建与 CelestialBodyAspect。每个宫位的黄道信息可通过 tropicalsidereal 属性获得。

// Create a date and location
let now = Date()
let latitude: Double = 37.5081153
let longitude: Double = -122.2854528
// All house cusps, Ascendent, and MC are properties on `houses`.
let houses = HouseCusps(date: date, latitude: latitude, longitude: longitude, houseSystem: .placidus)
// Get the formatted sidereal astrological position.
let ascendentFormatted = houses.ascendent.sidereal.formatted
// Or the precise degree for the sidereal zodiac.
let degree = houses.ascendent.sidereal.degree

IPL 编号

PlanetAsteroidLunarNorthNodeenum 类型对应于星历表中的 IPL 编号。其他天体,例如恒星作为虚构点,仍需要添加。类型编号不全面,但可以很容易地扩展以匹配包中不可用的天体。所有类型都符合 CelestialBody 协议,这使得不同类别的天体点可以在相位和位置上映射到黄道带。

批量计算

要充分利用星历表,您可能需要一次进行大量计算。批量计算是一项昂贵的操作,绝不应在主线程上完成。如果您一次进行数百次计算,建议使用 BatchRequest 来提高性能并避免因并发进行大量计算而导致的未定义行为。

例如,要计算一段时间内太阳的精确坐标

let request = PlanetsRequest(body: .sun)
let now = Date()
let end = now.addingTimeInterval(60 * 60 * 24 * 30)
// Asynchronously returns an array of `.sun` `Coordinate`s for every hour between now and 720 hours in the future.
let batchCoordinates = await request.fetch(start: now, end: end, interval: 60.0 * 60.0)

测试

准确性

为了测试此包的准确性,请按照原始瑞士星历表文档中的建议,使用 测试页面。我还发现 Astrodienst 页面 对于当前行星很有帮助。