iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0

目標:製作一個人類圖模組
輸入:生日日期時間
輸出:一 2x13(共 26 個數字)的人類圖矩陣

遭遇問題

swe_solcross_ut() is not a function

swe_solcross_ut() 是後來版本的 Swiss Ephemeris 新加入的方法,目前 NodeJS 的 swisseph 模組並未更新至該版本,導致找不到 swe_solcross_ut() 方法。

解法 1:重新打包

延續昨天遇到的問題,試著以 gyp 重新打包新版的 Swiss Ephemeris。

這邊有兩個 repository,其一是 aloistr/swisseph,下文以 swisseph 表示,是用 C 撰寫的 Swiss Ephemeris 函式庫;另一個是 mivion/swisseph,下文以 swisseph.js 表示,是提供給 NodeJS 呼叫的 bindings。swisseph.js 依賴 swisseph 的原始碼透過 gyp 打包,提供 NodeJS 的呼叫介面。

  1. 首先 fork 兩的 repository 下來,將 swisseph 的原始碼放進 swisseph.js 的 deps/swisseph 路徑下。
  2. 接著處理介面橋接的部分,主要是輸入輸出的資料型態。分別在 src/pos.ccsrc/pos.h 中加入下列片段:
// src/pos.cc

NAN_METHOD(node_swe_solcross_ut) {
	Nan::HandleScope scope;

	if (info.Length () < 3) {
		Nan::ThrowTypeError ("Wrong number of arguments");
	};

	if (
		!info [0]->IsNumber () ||
		!info [1]->IsNumber () ||
		!info [2]->IsNumber ()
	) {
		Nan::ThrowTypeError ("Wrong type of arguments");
	};

	double x2cross = Nan::To<double>(info[0]).FromJust();
	double tjd_ut = Nan::To<double>(info[1]).FromJust();
	int32_t iflag = Nan::To<int32_t>(info[1]).FromJust();
	char serr [AS_MAXCH];
	
	double jx = ::swe_solcross_ut(x2cross, tjd_ut, iflag, serr);

	Local <Object> result = Nan::New<Object> ();
	
	if (jx < tjd_ut) {
		Nan::Set(result,Nan::New<String> ("error").ToLocalChecked(), Nan::New<String> (serr).ToLocalChecked());
	} else {
		Nan::Set(result,Nan::New<String> ("jx").ToLocalChecked(), Nan::New<Number> (jx));
	}

    info.GetReturnValue().Set (result);
}
// src/pos.h

NAN_METHOD(node_swe_solcross_ut);
  1. src/swisseph.cc 的 Initialize 方法中將其導出為 NodeJS 介面:
// src/swisseph.cc

Nan::SetMethod (exports, "swe_solcross_ut", node_swe_solcross_ut);
  1. lib/swisseph.d.ts 宣告 TypeScript 型別
// lib/swisseph.d.ts

function swe_solcross_ut(
    x2cross: number,
    tjd: number,
    flags: number,
): { jx: number };
  1. 編譯。生成的 bindings 在 build/Release/swisseph.node
npm run install
  1. 以下列程式碼測試:
const jd = swisseph.swe_julday(1993, 3, 30, 11, swisseph.SEFLG_SWIEPH);

const result = swisseph.swe_calc_ut(jd, swisseph.SE_SUN, swisseph.SEFLG_SWIEPH);

const { x360 } = swisseph.swe_degnorm(result.longitude - 88);

const designDate = swisseph.swe_solcross_ut(x360, jd - 100, 0 , swisseph.SEFLG_SWIEPH);

console.log(designDate)

測試過程中一直出現找不到資料檔的錯誤,如下:

{
  "error": "SwissEph file 'sepl_462.se1' not found in PATH '<dir>/swisseph.js/test/../ephe/'",
}

遇到缺少方法的問題,至少略看得懂 C 的話還能試著解決,也順利從原 C 庫導出該方法;但資料檔的問題可是一點頭緒也沒有🫠

解法 2:仿作

顧名思義,模仿 C 庫 swisseph 的 swe_solcross_ut() 方法,以 TS 實現一個。

這部份只能先仰賴明天的自己,看太多 C code 人生會陷入低潮😵‍💫


晚安,瑪卡巴卡。


上一篇
人類圖基礎:從生辰到星盤(2)
下一篇
人類圖基礎:從生辰到星盤(4)
系列文
「莫忘初衷,從猴子到超人」:一個獻給自由精靈的社群媒合引擎18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言