未分類

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)