PR

【Python】「真の日の入り」時刻を計算!地形データを考慮して太陽が山に隠れる瞬間を予測する

Python

こんにちは、Tech Samuraiです!
天気予報で「今日の日の入りは17:00です」と言われても、実際に山間部に住んでいると、そのずっと前に太陽は山の向こうに沈んでしまいますよね。

これは、一般的な日の出・日の入り時刻が「標高0mの地平線/水平線」を基準に計算されているからです。山登りをする方や、写真撮影をする方、あるいは山の近くに住む方にとって、本当に知りたいのは「自分の場所から見て、実際に太陽が隠れる時刻」ではないでしょうか?

そこで今回は、「指定した座標から見た地形(山並み)を考慮し、真の日の出・日の入り時刻」を計算するPythonスクリプトを自作しました。APIを使った地形データの取得から、計算ロジックの工夫、そして開発中にハマったポイントまでを共有します。


なぜ作ろうと思ったのか?

きっかけは単純な疑問でした。「この場所からだと、具体的に何時まで日が当たるのか?」
既存のアプリ(「日の出日の入りマピオン」など)もありますが、エンジニアとしては「どうやって計算しているのか?」という仕組み自体に興味が湧きます。

勉強も兼ねて、「地形データ × 太陽軌道計算」を組み合わせて、自分だけの計算機をPythonで実装してみることにしました。


実装のアプローチ:どうやって「山の向こう」を知るか

計算の基本的なロジックは以下の3ステップです。

  1. 太陽の位置計算: 天体計算ライブラリ ephem を使用して、その瞬間の太陽の方位と高度を算出。
  2. 地形データの取得: 無料API Open-Elevation を使用して、現在地から太陽の方角にある「山の標高」を取得し、そこから「山の仰角(見上げる角度)」を計算。
  3. 判定: 「太陽の高度」 < 「山の仰角」 となった瞬間が、実質的な日の入り(または日の出)。

効率化の工夫:時間を「巻き戻す」

最初は「正午から1分ずつ時間を進めて判定しよう」と考えましたが、これでは計算回数が膨大になり、APIのレート制限にかかるリスクがありました。

そこで採用したのが、「標準的な日の入り時刻(地平線基準)」を起点にして、時間を過去に巻き戻していく(遡る)」という方法です。
時間を戻していき、「太陽が山からひょっこり顔を出した!」という瞬間が見つかれば、その直後が「山に沈む時刻」ということになります。これにより、計算回数を劇的に減らすことに成功しました。


開発奮闘記:直面したトラブルと解決策

理論は完璧だと思ったのですが、実装してみるといくつかの壁にぶつかりました。

1. APIリクエストの落とし穴

最初は requests.get でAPIを叩いていたのですが、座標のリストが長くなると API Error: Extra data... というエラーが発生し、標高が取得できずデフォルトの「0m」として計算されてしまいました。

→ 解決策:
HTTPメソッドを GET から POST に変更し、JSON形式で座標データを渡すように修正しました。これにより、大量の座標データも安定して送れるようになりました。

2. 「自分より低い山」問題

標高1000mの地点から計算した際、遠くの山並みが自分より低い(例:標高800m)場合に、計算結果が無視されてしまうバグがありました。
自分より標高が低くても、遠くにあれば「地平線」よりは高く見えるため、太陽を遮る可能性があります。

→ 解決策:
仰角計算の初期値を「0度」ではなくマイナス(見下ろす角度)まで許容するようにロジックを修正しました。これにより、眼下に広がる山並みに沈む夕日も正しく計算できるようになりました。


完成したツールと使い方

完成したコードはGitHubで公開しています。

ディレクトリ構成

true-horizon/
├── config.yaml      # 設定ファイル(場所や日付を指定)
└── src/
    └── mountain_sunset/
        └── main.py  # メインスクリプト

設定ファイル (config.yaml)

コードを書き換えなくても、config.yaml を編集するだけで好きな場所、好きな日付の計算ができます。

# 観測地点の設定(例: 富士山周辺)
location:
  latitude: 35.0153
  longitude: 138.5187 

# 計算対象の日付 ("today" または "YYYY-MM-DD")
target:
  date: "today"

# モード: "sunset" (日の入り), "sunrise" (日の出), "both" (両方)
mode: "both"

# 詳細設定
settings:
  check_distance_km: 60   # 何km先の山まで考慮するか

実行結果

スクリプトを実行すると、以下のように計算結果が出力されます。

計算対象日: 2025-12-03, 座標: 35.0153, 138.5187
観測地点: 標高 250.0m

【日の入り(Sunset)の計算】
標準的な日の入り(地平線): 16:45:00 (JST)
...
時刻: 16:12 | 方位: 240.5° | 高度: 3.20° | 山仰角: 3.50°
★ 太陽が山の上に顔を出しました(遡り完了)

【計算結果】
日の出: 07:15:20 (JST)
日の入り: 16:14:30 (JST)

標準の日の入りより30分も早く太陽が隠れることが分かったりして、なかなか面白い結果が得られます。


まとめ

「地形データ」と「天体計算」を組み合わせることで、より現実に即した太陽の動きをシミュレーションすることができました。
Pythonを使えば、このように「自分だけのニッチなツール」をサクッと作れるのが楽しいですね。アウトドアの計画や、撮影のロケハンに、ぜひ活用してみてください!

コメント

タイトルとURLをコピーしました