import os
import json
from pybufrkit.decoder import Decoder
from pybufrkit.renderer import FlatJsonRenderer
def extract_amedas_point(bufr_filepath, target_block=47, target_station=412, tables_dir=None):
"""
アメダスのBUFRファイルから特定地点(例:札幌 47-412)のデータを抽出するテスト
"""
# 1. デコーダの初期化
# デフォルトテーブルでエラーが出る場合は、ダウンロードしたtablesディレクトリのパスを指定
if tables_dir and os.path.exists(tables_dir):
decoder = Decoder(tables_root_dir=tables_dir)
else:
decoder = Decoder()
try:
# 2. BUFRファイルの読み込みとデコード
print(f"Reading BUFR file: {bufr_filepath}")
with open(bufr_filepath, 'rb') as f:
bufr_message = decoder.process(f.read())
# 3. JSON(辞書)形式への変換
renderer = FlatJsonRenderer()
json_data = renderer.render(bufr_message)
# 【デバッグ用】実際の要素キー(記述子)を確認したい場合は以下をアンコメント
# print(json.dumps(json_data, indent=2, ensure_ascii=False))
# 4. 特定地点の抽出
# FlatJsonRendererは通常、記述子をキーとし、全地点のデータを配列として持ちます。
# WMOブロック番号: '001001', WMO地点番号: '001002'
block_list = json_data.get("001001", [])
station_list = json_data.get("001002", [])
target_index = -1
for i in range(len(block_list)):
if block_list[i] == target_block and station_list[i] == target_station:
target_index = i
break
if target_index != -1:
print(f"\n【データ発見】 地点番号: {target_block}-{target_station} (インデックス: {target_index})")
# 観測時刻の抽出 (BUFR内部の時刻はUTC)
# データ同期の際のエラーを防ぐため、内部処理はUTCを基準に行います
year = json_data.get("004001", [])[target_index]
month = json_data.get("004002", [])[target_index]
day = json_data.get("004003", [])[target_index]
hour = json_data.get("004004", [])[target_index]
minute = json_data.get("004005", [])[target_index]
print(f" 観測時刻 (UTC): {year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}")
# 気象要素の抽出 (例)
# 012001: 温度(K), 013011: 降水量(mm), 011001: 風向(度), 011002: 風速(m/s) など
# ※正確な記述子は気象庁「配信資料に関する技術情報」のBUFR表と照合してください
temp_list = json_data.get("012001", [])
if temp_list and target_index < len(temp_list):
temp_k = temp_list[target_index]
if temp_k is not None:
print(f" 気温: {temp_k - 273.15:.1f} ℃")
precip_list = json_data.get("013011", [])
if precip_list and target_index < len(precip_list):
precip = precip_list[target_index]
if precip is not None:
print(f" 降水量: {precip} mm")
else:
print(f"指定された地点 ({target_block}-{target_station}) のデータは見つかりませんでした。")
except Exception as e:
print(f"デコードエラーが発生しました: {e}")
if __name__ == "__main__":
# 実環境のファイルパスとディレクトリ構成に合わせて書き換えて実行してください
bufr_file = "test_amedas.bufr"
# テーブルディレクトリを用意した場合は指定 (例: tables_dir="./tables")
extract_amedas_point(bufr_file, target_block=47, target_station=412, tables_dir=None)